#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_ */
#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_ */