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

📄 stp.c

📁 system C源码 一种替代verilog的语言
💻 C
字号:
#include "copyright.h"#include "qt.h"#include "stp.h"#ifndef NULL#define NULL	0#endif#define STP_STKSIZE (0x1000)/* `alignment' must be a power of 2. */#define STP_STKALIGN(sp, alignment) \  ((void *)((((qt_word_t)(sp)) + (alignment) - 1) & ~((alignment)-1)))/* The notion of a thread is merged with the notion of a queue.   Thread stuff: thread status (sp) and stuff to use during   (re)initialization.  Queue stuff: next thread in the queue   (next). */struct stp_t {  qt_t *sp;              /* QuickThreads handle. */  void *sto;             /* `malloc'-allocated stack. */  struct stp_t *next;    /* Next thread in the queue. */};/* A queue is a circular list of threads.  The queue head is a   designated list element.  If this is a uniprocessor-only   implementation we can store the `main' thread in this, but in a   multiprocessor there are several `heavy' threads but only one run   queue.  A fancier implementation might have private run queues,   which would lead to a simpler (trivial) implementation */typedef struct stp_q_t {  stp_t t;  stp_t *tail;} stp_q_t;/* Helper functions. */extern void *malloc (unsigned size);extern void perror (char const *msg);extern void free (void *sto);  void *xmalloc (unsigned size){  void *sto;  sto = malloc (size);  if (!sto) {    perror ("malloc");    exit (1);  }  return (sto);}/* Queue access functions. */  static voidstp_qinit (stp_q_t *q){  q->t.next = q->tail = &q->t;}  static stp_t *stp_qget (stp_q_t *q){  stp_t *t;  t = q->t.next;  q->t.next = t->next;  if (t->next == &q->t) {    if (t == &q->t) {		/* If it was already empty .. */      return (NULL);		/* .. say so. */    }    q->tail = &q->t;		/* Else now it is empty. */  }  return (t);}  static voidstp_qput (stp_q_t *q, stp_t *t){  q->tail->next = t;  t->next = &q->t;  q->tail = t;}/* Thread routines. */static stp_q_t stp_global_runq;	/* A queue of runable threads. */static stp_t stp_global_main;   /* Thread for the process. */static stp_t *stp_global_curr;	/* Currently-executing thread. */static void *stp_starthelp (qt_t *old, void *ignore0, void *ignore1);static void stp_only (void *pu, void *pt, qt_userf_t *f);static void *stp_aborthelp (qt_t *sp, void *old, void *null);static void *stp_yieldhelp (qt_t *sp, void *old, void *blockq);  voidstp_init(){  stp_qinit (&stp_global_runq);}  voidstp_start(){  stp_t *next;  while ((next = stp_qget (&stp_global_runq)) != NULL) {    stp_global_curr = next;    QT_BLOCK (stp_starthelp, 0, 0, next->sp);  }}  static void *stp_starthelp (qt_t *old, void *ignore0, void *ignore1){  stp_global_main.sp = old;  stp_qput (&stp_global_runq, &stp_global_main);  /* return (garbage); */}  voidstp_create (stp_userf_t *f, void *pu){  stp_t *t;  void *sto;  t = xmalloc (sizeof(stp_t));  t->sto = xmalloc (STP_STKSIZE);  sto = STP_STKALIGN (t->sto, QT_STKALIGN);  t->sp = QT_SP (sto, STP_STKSIZE - QT_STKALIGN);  t->sp = QT_ARGS (t->sp, pu, t, (qt_userf_t *)f, stp_only);  stp_qput (&stp_global_runq, t);}  static voidstp_only (void *pu, void *pt, qt_userf_t *f){  stp_global_curr = (stp_t *)pt;  (*(stp_userf_t *)f)(pu);  stp_abort();  /* NOTREACHED */}  voidstp_abort (void){  stp_t *old, *newthread;  newthread = stp_qget (&stp_global_runq);  old = stp_global_curr;  stp_global_curr = newthread;  QT_ABORT (stp_aborthelp, old, (void *)NULL, newthread->sp);}  static void *stp_aborthelp (qt_t *sp, void *old, void *null){  free (((stp_t *)old)->sto);  free (old);  /* return (garbage); */}  voidstp_yield(){  stp_t *old, *newthread;  newthread = stp_qget (&stp_global_runq);  old = stp_global_curr;  stp_global_curr = newthread;  QT_BLOCK (stp_yieldhelp, old, &stp_global_runq, newthread->sp);}  static void *stp_yieldhelp (qt_t *sp, void *old, void *blockq){  ((stp_t *)old)->sp = sp;  stp_qput ((stp_q_t *)blockq, (stp_t *)old);  /* return (garbage); */}

⌨️ 快捷键说明

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