#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 threadannounce(char*, char*); int threadlisten(char*, char*); int threadaccept(int, char*); int tprivalloc(void); void tprivfree(int); void **tprivaddr(int); int 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_ */