aboutsummaryrefslogtreecommitdiff
path: root/include/thread.h
blob: 356d7b6289e32ec7a4c47d690a5d271da7b2ca51 (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifndef _THREAD_H_
#define _THREAD_H_ 1
#if defined(__cplusplus)
extern "C" { 
#endif

/* 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 {
	Lock lk;
	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		threadexec(Channel *, int[3], char *, char *[]);
void		threadexecl(Channel *, int[3], char *, ...);
int		threadspawn(int[3], char*, 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);
int		threadcreateidle(void (*f)(void*), void*, unsigned int);
void**		threaddata(void);
void		threadexits(char *);
void		threadexitsall(char *);
void		threadfdwait(int, int);
void		threadfdwaitsetup(void);
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		threadfdnoblock(int);
void		threadnonotes(void);
int		threadnotify(int (*f)(void*, char*), int in);
int		threadid(void);
int		threadpid(int);
long		threadread(int, void*, long);
long		threadreadn(int, void*, long);
int		threadread9pmsg(int, void*, uint);
int		threadrecvfd(int);
long		threadwrite(int, const void*, long);
int		threadsendfd(int, int);
int		threadsetgrp(int);	/* set thread group, return old */
void		threadsetname(char *fmt, ...);
void		threadsleep(int);
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);

#if defined(__cplusplus)
}
#endif
#endif	/* _THREADH_ */