aboutsummaryrefslogtreecommitdiff
path: root/include/thread.h
blob: 10aac284824e67af1bff25a3ed7d25090769550d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef _THREADH_
#define _THREADH_ 1

/* avoid conflicts with socket library */
#undef send
#define send _threadsend
#undef recv
#define recv _threadrecv

typedef struct Alt	Alt;
typedef struct Channel	Channel;
typedef struct Ref	Ref;

/* Channel structure.  S is the size of the buffer.  For unbuffered channels
 * s is zero.  v is an array of s values.  If s is zero, v is unused.
 * f and n represent the state of the queue pointed to by v.
 */

enum {
	Nqwds = 2,
	Nqshift = 5,	// 2log #of bits in long
	Nqmask =  - 1,
	Nqbits = (1 << Nqshift) * 2,
};

struct Channel {
	int			s;		// Size of the channel (may be zero)
	unsigned int	f;		// Extraction point (insertion pt: (f + n) % s)
	unsigned int	n;		// Number of values in the channel
	int			e;		// Element size
	int			freed;	// Set when channel is being deleted
	volatile Alt	**qentry;	// Receivers/senders waiting (malloc)
	volatile int	nentry;	// # of entries malloc-ed
	unsigned char		v[1];		// Array of s values in the channel
};


/* Channel operations for alt: */
typedef enum {
	CHANEND,
	CHANSND,
	CHANRCV,
	CHANNOP,
	CHANNOBLK,
} ChanOp;

struct Alt {
	Channel	*c;		/* channel */
	void		*v;		/* pointer to value */
	ChanOp	op;		/* operation */

	/* the next variables are used internally to alt
	 * they need not be initialized
	 */
	Channel	**tag;	/* pointer to rendez-vous tag */
	int		entryno;	/* entry number */
};

struct Ref {
	long ref;
};

int		alt(Alt alts[]);
Channel*	chancreate(int elemsize, int bufsize);
int		chaninit(Channel *c, int elemsize, int elemcnt);
void		chanfree(Channel *c);
int		chanprint(Channel *, char *, ...);
long		decref(Ref *r);		/* returns 0 iff value is now zero */
void		incref(Ref *r);
int		nbrecv(Channel *c, void *v);
void*		nbrecvp(Channel *c);
unsigned long		nbrecvul(Channel *c);
int		nbsend(Channel *c, void *v);
int		nbsendp(Channel *c, void *v);
int		nbsendul(Channel *c, unsigned long v);
int		proccreate(void (*f)(void *arg), void *arg, unsigned int stacksize);
int		procrfork(void (*f)(void *arg), void *arg, unsigned int stacksize, int flag);
void**		procdata(void);
void		procexec(Channel *, char *, char *[]);
void		procexecl(Channel *, char *, ...);
int		recv(Channel *c, void *v);
void*		recvp(Channel *c);
unsigned long		recvul(Channel *c);
int		send(Channel *c, void *v);
int		sendp(Channel *c, void *v);
int		sendul(Channel *c, unsigned long v);
int		threadcreate(void (*f)(void *arg), void *arg, unsigned int stacksize);
void**		threaddata(void);
void		threadexits(char *);
void		threadexitsall(char *);
int		threadgetgrp(void);	/* return thread group of current thread */
char*		threadgetname(void);
void		threadint(int);	/* interrupt thread */
void		threadintgrp(int);	/* interrupt threads in grp */
void		threadkill(int);	/* kill thread */
void		threadkillgrp(int);	/* kill threads in group */
void		threadmain(int argc, char *argv[]);
void		threadnonotes(void);
int		threadnotify(int (*f)(void*, char*), int in);
int		threadid(void);
int		threadpid(int);
int		threadsetgrp(int);	/* set thread group, return old */
void		threadsetname(char *name);
Channel*	threadwaitchan(void);
int	tprivalloc(void);
void	tprivfree(int);
void	**tprivaddr(int);
void		yield(void);

long		threadstack(void);

extern	int		mainstacksize;

/* slave I/O processes */
typedef struct Ioproc Ioproc;

Ioproc*	ioproc(void);
void		closeioproc(Ioproc*);
void		iointerrupt(Ioproc*);

int		ioclose(Ioproc*, int);
int		iodial(Ioproc*, char*, char*, char*, int*);
int		ioopen(Ioproc*, char*, int);
long		ioread(Ioproc*, int, void*, long);
long		ioreadn(Ioproc*, int, void*, long);
long		iowrite(Ioproc*, int, void*, long);
int		iosleep(Ioproc*, long);

long		iocall(Ioproc*, long (*)(va_list*), ...);
void		ioret(Ioproc*, int);

#endif	/* _THREADH_ */