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

📄 threads.c

📁 专业汽车级嵌入式操作系统OSEK的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            currentThread = candidate;	// Its just easier this way.            init_sp_pv();            candidate->state = RUNNING;            if (candidate == bootThread)            {              MethodRecord *mRec;              ClassRecord *classRecord;              classRecord = get_class_record (get_entry_class (gProgramNumber));              // Initialize top word with fake parameter for main():              set_top_ref (JNULL);              // Push stack frame for main method:              mRec= find_method (classRecord, main_4_1Ljava_3lang_3String_2_5V);              dispatch_special (mRec, null);              // Push another if necessary for the static initializer:              dispatch_static_initializer (classRecord, pc);            }            else            {              set_top_ref (ptr2word (candidate));              dispatch_virtual ((Object *) candidate, run_4_5V, null);            }            // The following is needed because the current stack frame            // was just created            stackFrame = current_stackframe();            update_stack_frame (stackFrame);          }          break;        case RUNNING:          // Its running already        case DEAD:          // Dead threads should be handled earlier        default:          // ???          break;      }      // Do we now have a thread we want to run?      // Note we may later decide not to if all non-daemon threads have died              if (currentThread == null && candidate->state == RUNNING)      {        currentThread = candidate;        // Move thread to end of queue        *pThreadQ = candidate;      }            if (!candidate->daemon)      {      	// May or may not be running but it could do at some point#if DEBUG_THREADSprintf ("Found a non-daemon thread %d: %d(%d)\n", (int) candidate, (int)candidate->threadId, (int) candidate->state);#endif           nonDaemonRunnable = true;      }            #if DEBUG_THREADS      printf ("switch_thread: done processing thread %d: %d\n", (int) candidate,              (int) (candidate->state == RUNNING));      #endif      // Always use the first running thread as the thread      // Keep looping: cull dead threads, check there's at least one non-daemon thread      previousThread = candidate;    } while (candidate != anchorThread);  } // end for  #if DEBUG_THREADSprintf ("currentThread=%d, ndr=%d\n", (int) currentThread, (int)nonDaemonRunnable);#endif#if DEBUG_THREADS  printf ("Leaving switch_thread()\n");#endif  if (nonDaemonRunnable)  {    // There is at least one non-daemon thread left alive    if (currentThread != null)    {      // If we found a running thread and there is at least one      // non-daemon thread left somewhere in the queue...      #if DEBUG_THREADS      printf ("Current thread is %d: %d(%d)\n", (int) currentThread, (int)currentThread->threadId, (int) currentThread->state);      printf ("getting current stack frame...\n");      #endif          stackFrame = current_stackframe();          #if DEBUG_THREADS      printf ("updating registers...\n");      #endif          update_registers (stackFrame);          #if DEBUG_THREADS      printf ("done updating registers\n");      #endif          if (currentThread->interruptState == INTERRUPT_GRANTED)        throw_exception(interruptedException);    }          return true;  }  schedule_request(REQUEST_EXIT);  currentThread = null;    return false;}/* * Current thread owns object's monitor (we hope) and wishes to relinquish * it temporarily (by calling Object.wait()). */void monitor_wait(Object *obj, const FOURBYTES time){#if DEBUG_MONITOR  printf("monitor_wait of %d, thread %d(%d)\n",(int)obj, (int)currentThread, currentThread->threadId);#endif  if (currentThread->threadId != get_thread_id (obj))  {    throw_exception(illegalMonitorStateException);    return;  }    // Great. We own the monitor which means we can give it up, but  // indicate that we are listening for notify's.  currentThread->state = CONDVAR_WAITING;    // Save monitor depth  currentThread->monitorCount = get_monitor_count(obj);    // Save the object who's monitor we will want back  currentThread->waitingOn = ptr2word (obj);    // Might be an alarm set too.  if (time > 0)    currentThread->sleepUntil = get_sys_time() + time; 	  else    currentThread->sleepUntil = 0;  #if DEBUG_MONITOR  printf("monitor_wait of %d, thread %d(%d) until %ld\n",(int)obj, (int)currentThread, currentThread->threadId, time);#endif  // Indicate that the object's monitor is now free.  set_thread_id (obj, NO_OWNER);  set_monitor_count(obj, 0);    // Gotta yield  schedule_request( REQUEST_SWITCH_THREAD);}/* * Current thread owns object's monitor (we hope) and wishes to wake up * any other threads waiting on it. (by calling Object.notify()). */void monitor_notify(Object *obj, const boolean all){#if DEBUG_MONITOR  printf("monitor_notify of %d, thread %d(%d)\n",(int)obj, (int)currentThread, currentThread->threadId);#endif  if (currentThread->threadId != get_thread_id (obj))  {    throw_exception(illegalMonitorStateException);    return;  }    monitor_notify_unchecked(obj, all);}/* * wake up any objects waiting on the passed object. */void monitor_notify_unchecked(Object *obj, const boolean all){  short i;  Thread *pThread;  #if DEBUG_MONITOR  printf("monitor_notify_unchecked of %d, thread %d(%d)\n",(int)obj, (int)currentThread, currentThread->threadId);#endif  // Find a thread waiting on us and move to WAIT state.  for (i=MAX_PRIORITY-1; i >= 0; i--)  {    pThread = threadQ[i];    if (!pThread)      continue;          do {      // Remember threadQ[i] is the last thread on the queue      pThread = word2ptr(pThread->nextThread);      if (pThread->state == CONDVAR_WAITING && pThread->waitingOn == ptr2word (obj))      {        // might have been interrupted while waiting        if (pThread->interruptState != INTERRUPT_CLEARED)          pThread->interruptState = INTERRUPT_GRANTED;        pThread->state = MON_WAITING;        if (!all)          return;      }    } while (pThread != threadQ[i]);  }}/** * currentThread enters obj's monitor: * * if monitor is in use, save object in thread and re-schedule * else grab monitor and increment its count. *  * Note that this operation is atomic as far as the program is concerned. */void enter_monitor (Thread *pThread, Object* obj){#if DEBUG_MONITOR  printf("enter_monitor of %d\n",(int)obj);#endif  if (obj == JNULL)  {    throw_exception (nullPointerException);    return;  }  if (get_monitor_count (obj) != NO_OWNER && pThread->threadId != get_thread_id (obj))  {    // There is an owner, but its not us.    // Make thread wait until the monitor is relinquished.    pThread->state = MON_WAITING;    pThread->waitingOn = ptr2word (obj);    pThread->monitorCount = 1;    // Gotta yield    schedule_request (REQUEST_SWITCH_THREAD);        return;  }  set_thread_id (obj, pThread->threadId);  inc_monitor_count (obj);}/** * Decrement monitor count * Release monitor if count reaches zero */void exit_monitor (Thread *pThread, Object* obj){  byte newMonitorCount;#if DEBUG_MONITOR  printf("exit_monitor of %d\n",(int)obj);#endif  if (obj == JNULL)  {    // Exiting due to a NPE on monitor_enter [FIX THIS]    return;  }  #ifdef VERIFY  assert (get_thread_id(obj) == pThread->threadId, THREADS7);  assert (get_monitor_count(obj) > 0, THREADS8);  #endif  newMonitorCount = get_monitor_count(obj)-1;  if (newMonitorCount == 0)    set_thread_id (obj, NO_OWNER);  set_monitor_count (obj, newMonitorCount);}/** * Current thread waits for thread to die. * * throws InterruptedException */void join_thread(Thread *thread){}void dequeue_thread(Thread *thread){  // First take it out of its current queue  byte cIndex = thread->priority-1;  Thread **pThreadQ = &threadQ[cIndex];    // Find the previous thread at the old priority  Thread *previous = *pThreadQ;  #if DEBUG_THREADS  printf("Previous thread %ld\n", ptr2word(previous));  #endif  while (word2ptr(previous->nextThread) != thread)    previous = word2ptr(previous->nextThread);  #if DEBUG_THREADS  printf("Previous thread %ld\n", ptr2word(previous));  #endif  if (previous == thread)  {  #if DEBUG_THREADS  printf("No more threads of priority %d\n", thread->priority);  #endif    *pThreadQ = null;  }  else  {    previous->nextThread = thread->nextThread;    *pThreadQ = previous;  }  }void enqueue_thread(Thread *thread){  // Could insert it anywhere. Just insert it at the end.  byte cIndex = thread->priority-1;  Thread *previous = threadQ[cIndex];  threadQ[cIndex] = thread;  if (previous == null)    thread->nextThread = ptr2word(thread);  else {    Thread *pNext = word2ptr(previous->nextThread);    thread->nextThread = ptr2word(pNext);    previous->nextThread = ptr2word(thread);  }}/** * Set the priority of the passed thread. Insert into new queue, remove * from old queue. Overload to remove from all queues if passed priority * is zero. * * Returns the 'previous' thread. */void set_thread_priority(Thread *thread, const FOURBYTES priority){  #if DEBUG_THREADS  printf("Thread priority set to %ld was %d\n", priority, thread->priority);  #endif  if (thread->priority == priority)    return;  if (thread->state == NEW)  {  	// Not fully initialized  	thread->priority = priority;  	return;  }  dequeue_thread(thread);  thread->priority = priority;  enqueue_thread(thread);      }

⌨️ 快捷键说明

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