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
152
153
154
155
156
157
|
#ifndef _THREAD_H_
#define _THREAD_H_ 1
#if defined(__cplusplus)
extern "C" {
#endif
/*
* basic procs and threads
*/
int proccreate(void (*f)(void *arg), void *arg, unsigned int stacksize);
int threadcreate(void (*f)(void *arg), void *arg, unsigned int stacksize);
void threadexits(char *);
void threadexitsall(char *);
void threadsetname(char*, ...);
void threadsetstate(char*, ...);
void threadyield(void);
void _threadready(_Thread*);
void _threadswitch(void);
void _threadsetsysproc(void);
void _threadsleep(Rendez*);
_Thread *_threadwakeup(Rendez*);
#define yield threadyield
/*
* per proc and thread data
*/
void **procdata(void);
/*
* supplied by user instead of main.
* mainstacksize is size of stack allocated to run threadmain
*/
void threadmain(int argc, char *argv[]);
extern int mainstacksize;
/*
* channel communication
*/
typedef struct Alt Alt;
typedef struct _Altarray _Altarray;
typedef struct Channel Channel;
enum
{
CHANEND,
CHANSND,
CHANRCV,
CHANNOP,
CHANNOBLK,
};
struct Alt
{
void *v;
Channel *c;
uint op;
_Thread *thread;
Alt *xalt;
};
struct _Altarray
{
Alt **a;
uint n;
uint m;
};
struct Channel
{
uint bufsize;
uint elemsize;
uchar *buf;
uint nbuf;
uint off;
_Altarray asend;
_Altarray arecv;
char *name;
};
/* [Edit .+1,./^$/ |cfn -h $PLAN9/src/libthread/channel.c] */
int chanalt(Alt *alts);
Channel* chancreate(int elemsize, int elemcnt);
void chanfree(Channel *c);
int chaninit(Channel *c, int elemsize, int elemcnt);
int channbrecv(Channel *c, void *v);
void* channbrecvp(Channel *c);
ulong channbrecvul(Channel *c);
int channbsend(Channel *c, void *v);
int channbsendp(Channel *c, void *v);
int channbsendul(Channel *c, ulong v);
int chanrecv(Channel *c, void *v);
void* chanrecvp(Channel *c);
ulong chanrecvul(Channel *c);
int chansend(Channel *c, void *v);
int chansendp(Channel *c, void *v);
int chansendul(Channel *c, ulong v);
#define alt chanalt
#define nbrecv channbrecv
#define nbrecvp channbrecvp
#define nvrecvul channbrecvul
#define nbsend channbsend
#define nbsendp channbsendp
#define nbsendul channbsendul
#define recv chanrecv
#define recvp chanrecvp
#define recvul chanrecvul
#define send chansend
#define sendp chansendp
#define sendul chansendul
/*
* reference counts
*/
typedef struct Ref Ref;
struct Ref {
Lock lock;
long ref;
};
long decref(Ref *r);
long incref(Ref *r);
/*
* slave i/o processes
*/
typedef struct Ioproc Ioproc;
/* [Edit .+1,/^$/ |cfn -h $PLAN9/src/libthread/io*.c] */
void closeioproc(Ioproc *io);
long iocall(Ioproc *io, long (*op)(va_list*), ...);
int ioclose(Ioproc *io, int fd);
int iodial(Ioproc *io, char *addr, char *local, char *dir, int *cdfp);
void iointerrupt(Ioproc *io);
int ioopen(Ioproc *io, char *path, int mode);
Ioproc* ioproc(void);
long ioread(Ioproc *io, int fd, void *a, long n);
int ioread9pmsg(Ioproc*, int, void*, int);
long ioreadn(Ioproc *io, int fd, void *a, long n);
int iorecvfd(Ioproc *, int);
int iosendfd(Ioproc*, int, int);
int iosleep(Ioproc *io, long n);
long iowrite(Ioproc *io, int fd, void *a, long n);
/*
* exec external programs
*/
void threadexec(Channel*, int[3], char*, char *[]);
void threadexecl(Channel*, int[3], char*, ...);
int threadspawn(int[3], char*, char*[]);
Channel* threadwaitchan(void);
#if defined(__cplusplus)
}
#endif
#endif /* _THREADH_ */
|