text: /* Copyright (c) 2005 Russ Cox, MIT; see COPYRIGHT */
  
  #ifndef _TASK_H_
  #define _TASK_H_ 1
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  #include <stdarg.h>
  #include <inttypes.h>
  
  /*
   * basic procs and threads
   */
  
  typedef struct Task Task;
  typedef struct Tasklist Tasklist;
  
  int		anyready(void);
  int		taskcreate(void (*f)(void *arg), void *arg, unsigned int stacksize);
  void		taskexit(int);
  void		taskexitall(int);
  void		taskmain(int argc, char *argv[]);
  int		taskyield(void);
  void**		taskdata(void);
  void		needstack(int);
  void		taskname(char*, ...);
  void		taskstate(char*, ...);
  char*		taskgetname(void);
  char*		taskgetstate(void);
  void		tasksystem(void);
  unsigned int	taskdelay(unsigned int);
  unsigned int	taskid(void);
  
  // 任务链表
  struct Tasklist	/* used internally */
  {
  	Task	*head;
  	Task	*tail;
  };
  
  /*
   * queuing locks
   */
  typedef struct QLock QLock;
  struct QLock
  {
  	Task	*owner;
  	Tasklist waiting;
  };
  
  void	qlock(QLock*);
  int	canqlock(QLock*);
  void	qunlock(QLock*);
  
  /*
   * reader-writer locks
   */
  typedef struct RWLock RWLock;
  struct RWLock
  {
  	int	readers;
  	Task	*writer;
  	Tasklist rwaiting;
  	Tasklist wwaiting;
  };
  
  void	rlock(RWLock*);
  int	canrlock(RWLock*);
  void	runlock(RWLock*);
  
  void	wlock(RWLock*);
  int	canwlock(RWLock*);
  void	wunlock(RWLock*);
  
  /*
   * sleep and wakeup (condition variables)
   */
  typedef struct Rendez Rendez;
  
  struct Rendez
  {
  	QLock	*l;
  	Tasklist waiting;
  };
  
  void	tasksleep(Rendez*);
  int	taskwakeup(Rendez*);
  int	taskwakeupall(Rendez*);
  
  /*
   * channel communication
   * Channel通信
   */
  typedef struct Alt Alt;
  typedef struct Altarray Altarray;
  typedef struct Channel Channel;
  
  enum
  {
  	CHANEND,
  	CHANSND,
  	CHANRCV,
  	CHANNOP,
  	CHANNOBLK,
  };
  
  /* Channel传输的时候使用 */
  struct Alt
  {
  	Channel		*c;			// Channel
  	void		*v;			// value
  	unsigned int	op;		// operation
  	Task		*task;		// 当前Task
  	Alt		*xalt;			// 属于哪一个Alt数组
  };
  
  struct Altarray
  {
  	Alt		**a;		// Alt容器
  	unsigned int	n;	// 当前数量
  	unsigned int	m;	// 最大容量
  };
  
  /* Channel结构体
   */
  struct Channel
  {
  	unsigned int	bufsize;	// buffer总共可以放多少元素
  	unsigned int	elemsize;	// 元素大小
  	unsigned char	*buf;	// 指向真正buffer的内存地址
  	unsigned int	nbuf;	// buffer 里面元素的个数
  	unsigned int	off;	// buffer 队列的头
  	Altarray	asend;		// 发送队列
  	Altarray	arecv;		// 接收队列
  	char		*name;
  };
  
  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);
  unsigned long	channbrecvul(Channel *c);
  int		channbsend(Channel *c, void *v);
  int		channbsendp(Channel *c, void *v);
  int		channbsendul(Channel *c, unsigned long v);
  int		chanrecv(Channel *c, void *v);
  void*		chanrecvp(Channel *c);
  unsigned long	chanrecvul(Channel *c);
  int		chansend(Channel *c, void *v);
  int		chansendp(Channel *c, void *v);
  int		chansendul(Channel *c, unsigned long v);
  
  /*
   * Threaded I/O.
   */
  int		fdread(int, void*, int);
  int		fdread1(int, void*, int);	/* always uses fdwait */
  int		fdwrite(int, void*, int);
  void		fdwait(int, int);
  int		fdnoblock(int);
  
  void		fdtask(void*);
  
  /*
   * Network dialing - sets non-blocking automatically
   */
  enum
  {
  	UDP = 0,
  	TCP = 1,
  };
  
  int		netannounce(int, char*, int);
  int		netaccept(int, char*, int*);
  int		netdial(int, char*, int);
  int		netlookup(char*, uint32_t*);	/* blocks entire program! */
  int		netdial(int, char*, int);
  
  #ifdef __cplusplus
  }
  #endif
  #endif
  
  