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

📄 sched.c

📁 快速开发
💻 C
📖 第 1 页 / 共 2 页
字号:
 */static _st_thread_t **heap_insert(_st_thread_t *thread) {  int target = thread->heap_index;  int s = target;  _st_thread_t **p = &_ST_SLEEPQ;  int bits = 0;  int bit;  int index = 1;  while (s) {    s >>= 1;    bits++;  }  for (bit = bits - 2; bit >= 0; bit--) {    if (thread->due < (*p)->due) {      _st_thread_t *t = *p;      thread->left = t->left;      thread->right = t->right;      *p = thread;      thread->heap_index = index;      thread = t;    }    index <<= 1;    if (target & (1 << bit)) {      p = &((*p)->right);      index |= 1;    } else {      p = &((*p)->left);    }  }  thread->heap_index = index;  *p = thread;  thread->left = thread->right = NULL;  return p;}/* * Delete "thread" from the timeout heap. */static void heap_delete(_st_thread_t *thread) {  _st_thread_t *t, **p;  int bits = 0;  int s, bit;  /* First find and unlink the last heap element */  p = &_ST_SLEEPQ;  s = _ST_SLEEPQ_SIZE;  while (s) {    s >>= 1;    bits++;  }  for (bit = bits - 2; bit >= 0; bit--) {    if (_ST_SLEEPQ_SIZE & (1 << bit)) {      p = &((*p)->right);    } else {      p = &((*p)->left);    }  }  t = *p;  *p = NULL;  --_ST_SLEEPQ_SIZE;  if (t != thread) {    /*     * Insert the unlinked last element in place of the element we are deleting     */    t->heap_index = thread->heap_index;    p = heap_insert(t);    t = *p;    t->left = thread->left;    t->right = thread->right;    /*     * Reestablish the heap invariant.     */    for (;;) {      _st_thread_t *y; /* The younger child */      int index_tmp;      if (t->left == NULL)	break;      else if (t->right == NULL)	y = t->left;      else if (t->left->due < t->right->due)	y = t->left;      else	y = t->right;      if (t->due > y->due) {	_st_thread_t *tl = y->left;	_st_thread_t *tr = y->right;	*p = y;	if (y == t->left) {	  y->left = t;	  y->right = t->right;	  p = &y->left;	} else {	  y->left = t->left;	  y->right = t;	  p = &y->right;	}	t->left = tl;	t->right = tr;	index_tmp = t->heap_index;	t->heap_index = y->heap_index;	y->heap_index = index_tmp;      } else {	break;      }    }  }  thread->left = thread->right = NULL;}void _st_add_sleep_q(_st_thread_t *thread, st_utime_t timeout){  thread->due = _ST_LAST_CLOCK + timeout;  thread->flags |= _ST_FL_ON_SLEEPQ;  thread->heap_index = ++_ST_SLEEPQ_SIZE;  heap_insert(thread);}void _st_del_sleep_q(_st_thread_t *thread){  heap_delete(thread);  thread->flags &= ~_ST_FL_ON_SLEEPQ;}void _st_vp_check_clock(void){  _st_thread_t *thread;  st_utime_t elapsed, now;   now = st_utime();  elapsed = now - _ST_LAST_CLOCK;  _ST_LAST_CLOCK = now;  if (_st_curr_time && now - _st_last_tset > 999000) {    _st_curr_time = time(NULL);    _st_last_tset = now;  }  while (_ST_SLEEPQ != NULL) {    thread = _ST_SLEEPQ;    ST_ASSERT(thread->flags & _ST_FL_ON_SLEEPQ);    if (thread->due > now)      break;    _ST_DEL_SLEEPQ(thread);    /* If thread is waiting on condition variable, set the time out flag */    if (thread->state == _ST_ST_COND_WAIT)      thread->flags |= _ST_FL_TIMEDOUT;    /* Make thread runnable */    ST_ASSERT(!(thread->flags & _ST_FL_IDLE_THREAD));    thread->state = _ST_ST_RUNNABLE;    _ST_ADD_RUNQ(thread);  }}void st_thread_interrupt(_st_thread_t *thread){  /* If thread is already dead */  if (thread->state == _ST_ST_ZOMBIE)    return;  thread->flags |= _ST_FL_INTERRUPT;  if (thread->state == _ST_ST_RUNNING || thread->state == _ST_ST_RUNNABLE)    return;  if (thread->flags & _ST_FL_ON_SLEEPQ)    _ST_DEL_SLEEPQ(thread);  /* Make thread runnable */  thread->state = _ST_ST_RUNNABLE;  _ST_ADD_RUNQ(thread);}_st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg,			       int joinable, int stk_size){  _st_thread_t *thread;  _st_stack_t *stack;  void **ptds;  char *sp;#ifdef __ia64__  char *bsp;#endif  /* Adjust stack size */  if (stk_size == 0)    stk_size = ST_DEFAULT_STACK_SIZE;  stk_size = ((stk_size + _ST_PAGE_SIZE - 1) / _ST_PAGE_SIZE) * _ST_PAGE_SIZE;  stack = _st_stack_new(stk_size);  if (!stack)    return NULL;  /* Allocate thread object and per-thread data off the stack */#if defined (MD_STACK_GROWS_DOWN)  sp = stack->stk_top;#ifdef __ia64__  /*   * The stack segment is split in the middle. The upper half is used   * as backing store for the register stack which grows upward.   * The lower half is used for the traditional memory stack which   * grows downward. Both stacks start in the middle and grow outward   * from each other.   */  sp -= (stk_size >> 1);  bsp = sp;  /* Make register stack 64-byte aligned */  if ((unsigned long)bsp & 0x3f)    bsp = bsp + (0x40 - ((unsigned long)bsp & 0x3f));  stack->bsp = bsp + _ST_STACK_PAD_SIZE;#endif  sp = sp - (ST_KEYS_MAX * sizeof(void *));  ptds = (void **) sp;  sp = sp - sizeof(_st_thread_t);  thread = (_st_thread_t *) sp;  /* Make stack 64-byte aligned */  if ((unsigned long)sp & 0x3f)    sp = sp - ((unsigned long)sp & 0x3f);  stack->sp = sp - _ST_STACK_PAD_SIZE;#elif defined (MD_STACK_GROWS_UP)  sp = stack->stk_bottom;  thread = (_st_thread_t *) sp;  sp = sp + sizeof(_st_thread_t);  ptds = (void **) sp;  sp = sp + (ST_KEYS_MAX * sizeof(void *));  /* Make stack 64-byte aligned */  if ((unsigned long)sp & 0x3f)    sp = sp + (0x40 - ((unsigned long)sp & 0x3f));  stack->sp = sp + _ST_STACK_PAD_SIZE;#else#error Unknown OS#endif  memset(thread, 0, sizeof(_st_thread_t));  memset(ptds, 0, ST_KEYS_MAX * sizeof(void *));  /* Initialize thread */  thread->private_data = ptds;  thread->stack = stack;  thread->start = start;  thread->arg = arg;#ifndef __ia64__  _ST_INIT_CONTEXT(thread, stack->sp, _st_thread_main);#else  _ST_INIT_CONTEXT(thread, stack->sp, stack->bsp, _st_thread_main);#endif  /* If thread is joinable, allocate a termination condition variable */  if (joinable) {    thread->term = st_cond_new();    if (thread->term == NULL) {      _st_stack_free(thread->stack);      return NULL;    }  }  /* Make thread runnable */  thread->state = _ST_ST_RUNNABLE;  _st_active_count++;  _ST_ADD_RUNQ(thread);#ifdef DEBUG  _ST_ADD_THREADQ(thread);#endif  return thread;}_st_thread_t *st_thread_self(void){  return _ST_CURRENT_THREAD();}#ifdef DEBUG/* ARGSUSED */void _st_show_thread_stack(_st_thread_t *thread, const char *messg){}/* To be set from debugger */int _st_iterate_threads_flag = 0;void _st_iterate_threads(void){  static _st_thread_t *thread = NULL;  static jmp_buf orig_jb, save_jb;  _st_clist_t *q;  if (!_st_iterate_threads_flag) {    if (thread) {      memcpy(thread->context, save_jb, sizeof(jmp_buf));      MD_LONGJMP(orig_jb, 1);    }    return;  }  if (thread) {    memcpy(thread->context, save_jb, sizeof(jmp_buf));    _st_show_thread_stack(thread, NULL);  } else {    if (MD_SETJMP(orig_jb)) {      _st_iterate_threads_flag = 0;      thread = NULL;      _st_show_thread_stack(thread, "Iteration completed");      return;    }    thread = _ST_CURRENT_THREAD();    _st_show_thread_stack(thread, "Iteration started");  }  q = thread->tlink.next;  if (q == &_ST_THREADQ)    q = q->next;  ST_ASSERT(q != &_ST_THREADQ);  thread = _ST_THREAD_THREADQ_PTR(q);  if (thread == _ST_CURRENT_THREAD())    MD_LONGJMP(orig_jb, 1);  memcpy(save_jb, thread->context, sizeof(jmp_buf));  MD_LONGJMP(thread->context, 1);}#endif /* DEBUG */

⌨️ 快捷键说明

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