⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.c

📁 神经网络模拟系统和多任务应用系统开发的C语言源程序
💻 C
字号:
/*********** THREAD.C COPYRIGHT 1989 GREGORY COLVIN ************
This program may be distributed free with this copyright notice.
***************************************************************/
#include "thread.h"

       ThTabl Threads=0;        /* table of threads           */
       Thread ThCurr;           /* currently executing thread */
static int    N_Threads;        /* number of threads in table */
static Thread Free;             /* first thread on free list  */
static char  *Stack;            /* bottom of stack for init   */
static void (*Root)(Thread);    /* for temporary use for exec */

static void init(int n,int size)        /* recurse for ThInit */
{ Thread id;
  if (!Stack) {                         /* start new thread   */
    Stack= (char *)&size;               /* at top of stack    */
    if (id= setjmp(Threads[n].init)) {  /* set entry point    */
      (*Root)(id);                      /* call root function */
      ThExit(ThNext());                 /* fell off thread    */
    }
  }
  if (Stack - (char *)&size < size)     /* if not enough stack*/
    init(n,size);                       /* push more stack    */
  else {                                /* done with a thread */
    Threads[n].stack= (char *)&size;    /* save top of stack  */
    Stack= 0 ;                          /* flag for new thread*/
    if (n < N_Threads) {                /* if not done        */
      Threads[n].free= n+1;             /* link to free list  */
      init(++n,size);                   /* push more stack    */
    }
  }
  Threads[n].free = 0;                  /* end of free list   */
  longjmp(Threads[1].jump,1);           /* return to ThInit   */
}
int ThInit(int n,int size)      /* create n size byte threads */
{ assert (!Threads);                    /* must be free       */
  assert (n >= 2);                      /* must be plural     */
  Threads=                              /* create table       */
    (ThTabl)calloc(n,sizeof *Threads);
  if (!Threads)
    return 0;                           /* not enough memory  */
  Threads--;                            /* will index from 1  */
  if (setjmp(Threads[1].jump)){         /* become thread 1    */
    Threads[1].free= 0;                 /* take off free list */
    return n;                           /* return to thread 1 */
  }
  N_Threads= n, ThCurr= 1, Free= 2;     /* initialize globals */
  init(1,size);                         /* initialize stack   */
}

Thread ThNew(void(*f)(Thread))  /* fork and exec new thread   */
{ Thread parent, fork;
  ThProbe();                            /* stack probe        */
  assert(f);                            /* prevent crash      */
  fork= Free;                           /* fork to free thread*/
  if (fork == 0)
    return 0;                           /* error, none free   */
  Free= Threads[fork].free;             /* take off free list */
  Threads[fork].free= 0;
  parent= ThCurr;                       /* current is parent  */
  ThCurr= fork;                         /* will run fork next */
  if (setjmp(Threads[parent].jump))     /* put parent to sleep*/
    return fork;                        /* parent is awake    */
  Root= f;                              /* who to call        */
  longjmp(Threads[fork].init,parent);   /* exec root in init  */
}

Thread ThNext(void)             /* find next runnable thread  */
{ Thread id= ThCurr;                    /* start from self    */
  do id %= N_Threads;                   /* circle round table */
  while (Threads[++id].free);           /* until we find life */
  return id;                            /* next might be self */
}

Thread ThJump(Thread id)        /* jump to another thread     */
{ Thread jumper, caller;
  ThProbe();                            /* stack probe        */
  assert(id > 0 && id <= N_Threads);    /* prevent crash      */
  assert(ThLive(id) && id != ThCurr);   /* no go dead or self */
  caller= ThCurr;                       /* where we came from */
  ThCurr= id;                           /* where we are going */
  if (jumper=setjmp(Threads[caller].jump))
    return jumper;                      /* return who jumped  */
  longjmp(Threads[id].jump,caller);     /* context switch     */
}

void ThExit(Thread id)          /* exit to another thread     */
{ ThProbe();                            /* stack probe        */
  assert(id > 0 && id <= N_Threads);    /* prevent crash      */
  assert(ThLive(id) && id != ThCurr);   /* no go dead or self */
  Threads[ThCurr].free= Free;           /* put on free list   */
  Free= ThCurr;                         /* where we came from */
  ThCurr= id;                           /* where we are going */
  longjmp(Threads[id].jump,Free);       /* context switch     */
}

void ThFree()                   /* free the thread table      */
{   assert (Threads);                   /* prevent crash      */
    free(Threads+1);                    /* goodbye            */
    Threads= 0, N_Threads= 0;           /* can init again     */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -