OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [rtos.c] - Diff between revs 167 and 168

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 167 Rev 168
Line 50... Line 50...
   HeapNode_t base;
   HeapNode_t base;
   struct OS_Heap_s *alternate;
   struct OS_Heap_s *alternate;
};
};
//typedef struct OS_Heap_s OS_Heap_t;
//typedef struct OS_Heap_s OS_Heap_t;
 
 
 
typedef enum {
 
   THREAD_BLOCKED = 0,
 
   THREAD_READY   = 1,
 
   THREAD_RUNNING = 2
 
} OS_ThreadState_e;
 
 
struct OS_Thread_s {
struct OS_Thread_s {
   const char *name;
   const char *name;
 
   OS_ThreadState_e state;
   jmp_buf env;
   jmp_buf env;
   OS_FuncPtr_t funcPtr;
   OS_FuncPtr_t funcPtr;
   void *arg;
   void *arg;
   uint32 priority;
   uint32 priority;
   uint32 ticksTimeout;
   uint32 ticksTimeout;
Line 105... Line 112...
/*************** Globals ******************/
/*************** Globals ******************/
static OS_Heap_t *HeapArray[HEAP_COUNT];
static OS_Heap_t *HeapArray[HEAP_COUNT];
static OS_Semaphore_t *SemaphoreSleep;
static OS_Semaphore_t *SemaphoreSleep;
static OS_Semaphore_t *SemaphoreLock;
static OS_Semaphore_t *SemaphoreLock;
static int ThreadSwapEnabled;
static int ThreadSwapEnabled;
static int ThreadCurrentActive[OS_CPU_COUNT];
 
static int ThreadNeedReschedule;
static int ThreadNeedReschedule;
static uint32 ThreadTime;
static uint32 ThreadTime;
static OS_Thread_t *ThreadHead;   //Linked list of threads sorted by priority
static OS_Thread_t *ThreadHead;   //Linked list of threads sorted by priority
static OS_Thread_t *TimeoutHead;  //Linked list of threads sorted by timeout
static OS_Thread_t *TimeoutHead;  //Linked list of threads sorted by timeout
static OS_Thread_t *ThreadCurrent[OS_CPU_COUNT];
static OS_Thread_t *ThreadCurrent[OS_CPU_COUNT];
Line 278... Line 284...
      thread->next = prev->next;
      thread->next = prev->next;
      thread->prev = prev;
      thread->prev = prev;
      prev->next = thread;
      prev->next = thread;
   }
   }
   assert(ThreadHead);
   assert(ThreadHead);
 
   if(*head == ThreadHead)
 
      thread->state = THREAD_READY;
}
}
 
 
 
 
/******************************************/
/******************************************/
//Must be called with interrupts disabled
//Must be called with interrupts disabled
static void OS_ThreadPriorityRemove(OS_Thread_t **head, OS_Thread_t *thread)
static void OS_ThreadPriorityRemove(OS_Thread_t **head, OS_Thread_t *thread)
{
{
   uint32 cpuIndex = OS_CpuIndex();
 
   //printf("r(%d) ", thread->priority);
 
   assert(thread->magic[0] == THREAD_MAGIC);  //check stack overflow
   assert(thread->magic[0] == THREAD_MAGIC);  //check stack overflow
   if(thread->prev == NULL)
   if(thread->prev == NULL)
      *head = thread->next;
      *head = thread->next;
   else
   else
      thread->prev->next = thread->next;
      thread->prev->next = thread->next;
   if(thread->next)
   if(thread->next)
      thread->next->prev = thread->prev;
      thread->next->prev = thread->prev;
   thread->next = NULL;
   thread->next = NULL;
   thread->prev = NULL;
   thread->prev = NULL;
   if(head == &ThreadHead && ThreadCurrent[cpuIndex] == thread)
   thread->state = THREAD_BLOCKED;
      ThreadCurrentActive[cpuIndex] = 0;
 
}
}
 
 
 
 
/******************************************/
/******************************************/
//Linked list of threads sorted by timeout value
//Linked list of threads sorted by timeout value
Line 359... Line 364...
/******************************************/
/******************************************/
//Loads a new thread 
//Loads a new thread 
//Must be called with interrupts disabled
//Must be called with interrupts disabled
static void OS_ThreadReschedule(int RoundRobin)
static void OS_ThreadReschedule(int RoundRobin)
{
{
   OS_Thread_t *threadNext, *threadPrev, *threadCurrent;
   OS_Thread_t *threadNext, *threadCurrent, *threadBest, *threadTry;
   uint32 cpuIndex = OS_CpuIndex();
   uint32 cpuIndex = OS_CpuIndex();
   int rc;
   int rc;
 
 
   if(ThreadSwapEnabled == 0 || InterruptInside)
   if(ThreadSwapEnabled == 0 || InterruptInside)
   {
   {
Line 372... Line 377...
   }
   }
 
 
   //Determine which thread should run
   //Determine which thread should run
   threadCurrent = ThreadCurrent[cpuIndex];
   threadCurrent = ThreadCurrent[cpuIndex];
   threadNext = threadCurrent;
   threadNext = threadCurrent;
   assert(ThreadHead);
   for(threadBest = ThreadHead; threadBest; threadBest = threadBest->next)
   if(ThreadCurrentActive[cpuIndex] == 0 || threadCurrent == NULL)
   {
      threadNext = ThreadHead;
      if(threadBest->state == THREAD_READY)
   else if(threadCurrent->priority < ThreadHead->priority)
         break;
      threadNext = ThreadHead;
   }
 
   if(threadBest == NULL && threadCurrent && threadCurrent->state == THREAD_RUNNING)
 
      threadBest = threadCurrent;
 
   assert(threadBest);
 
   if(threadCurrent == NULL || threadCurrent->state == THREAD_BLOCKED)
 
      threadNext = threadBest;
 
   else if(threadCurrent->priority < threadBest->priority)
 
      threadNext = threadBest;
   else if(RoundRobin)
   else if(RoundRobin)
   {
   {
      if(threadCurrent->next &&
      for(threadTry = threadCurrent->next; threadTry; threadTry = threadTry->next)
         threadCurrent->next->priority == ThreadHead->priority)
      {
         threadNext = threadCurrent->next;
         if(threadTry->state == THREAD_READY)
      else
            break;
         threadNext = ThreadHead;
      }
 
      if(threadTry && threadTry->priority == threadCurrent->priority)
 
         threadNext = threadTry;
 
      else if(threadBest->priority == threadCurrent->priority)
 
         threadNext = threadBest;
   }
   }
 
 
   if(threadNext != threadCurrent)
   if(threadNext != threadCurrent)
   {
   {
      //Swap threads
      //Swap threads
      threadPrev = threadCurrent;
 
      ThreadCurrent[cpuIndex] = threadNext;
      ThreadCurrent[cpuIndex] = threadNext;
      assert(threadNext);
      assert(threadNext);
      if(threadPrev)
      if(threadCurrent)
      {
      {
         assert(threadPrev->magic[0] == THREAD_MAGIC); //check stack overflow
         assert(threadCurrent->magic[0] == THREAD_MAGIC); //check stack overflow
         threadPrev->spinLocks = OS_SpinLockGet();
         threadCurrent->state = THREAD_READY;
 
         threadCurrent->spinLocks = OS_SpinLockGet();
 
 
         //printf("OS_ThreadRescheduleSave(%s)\n", threadPrev->name);
         //printf("OS_ThreadRescheduleSave(%s)\n", threadPrev->name);
         rc = setjmp(threadPrev->env);  //ANSI C call to save registers
         rc = setjmp(threadCurrent->env);  //ANSI C call to save registers
         if(rc)
         if(rc)
         {
         {
            //Returned from longjmp()
            //Returned from longjmp()
            return;
            return;
         }
         }
      }
      }
 
 
      cpuIndex = OS_CpuIndex();             //removed warning
      cpuIndex = OS_CpuIndex();             //removed warning
      threadNext = ThreadCurrent[cpuIndex]; //removed warning
      threadNext = ThreadCurrent[cpuIndex]; //removed warning
      ThreadCurrentActive[cpuIndex] = 1;
 
      //printf("OS_ThreadRescheduleRestore(%s)\n", threadNext->name);
      //printf("OS_ThreadRescheduleRestore(%s)\n", threadNext->name);
 
      threadNext->state = THREAD_RUNNING;
      OS_SpinLockSet(threadNext->spinLocks);
      OS_SpinLockSet(threadNext->spinLocks);
      longjmp(threadNext->env, 1);      //ANSI C call to restore registers
      longjmp(threadNext->env, 1);      //ANSI C call to restore registers
   }
   }
}
}
 
 
Line 420... Line 438...
static void OS_ThreadInit(void *Arg)
static void OS_ThreadInit(void *Arg)
{
{
   uint32 cpuIndex = OS_CpuIndex();
   uint32 cpuIndex = OS_CpuIndex();
   (void)Arg;
   (void)Arg;
 
 
   OS_AsmInterruptEnable(1);
   OS_CriticalEnd(1);
   ThreadCurrent[cpuIndex]->funcPtr(ThreadCurrent[cpuIndex]->arg);
   ThreadCurrent[cpuIndex]->funcPtr(ThreadCurrent[cpuIndex]->arg);
   OS_ThreadExit();
   OS_ThreadExit();
}
}
 
 
 
 
Line 464... Line 482...
      return NULL;
      return NULL;
   stack = (uint8*)(thread + 1);
   stack = (uint8*)(thread + 1);
   memset(stack, 0xcd, StackSize);
   memset(stack, 0xcd, StackSize);
 
 
   thread->name = Name;
   thread->name = Name;
 
   thread->state = THREAD_READY;
   thread->funcPtr = FuncPtr;
   thread->funcPtr = FuncPtr;
   thread->arg = Arg;
   thread->arg = Arg;
   thread->priority = Priority;
   thread->priority = Priority;
   thread->info = NULL;
   thread->info = NULL;
   thread->semaphorePending = NULL;
   thread->semaphorePending = NULL;
Line 556... Line 575...
/******************************************/
/******************************************/
void OS_ThreadPrioritySet(OS_Thread_t *Thread, uint32 Priority)
void OS_ThreadPrioritySet(OS_Thread_t *Thread, uint32 Priority)
{
{
   uint32 state;
   uint32 state;
   state = OS_CriticalBegin();
   state = OS_CriticalBegin();
   OS_ThreadPriorityRemove(&ThreadHead, Thread);
 
   Thread->priority = Priority;
   Thread->priority = Priority;
 
   if(Thread->state != THREAD_BLOCKED)
 
   {
 
      OS_ThreadPriorityRemove(&ThreadHead, Thread);
   OS_ThreadPriorityInsert(&ThreadHead, Thread);
   OS_ThreadPriorityInsert(&ThreadHead, Thread);
   OS_ThreadReschedule(0);
   OS_ThreadReschedule(0);
 
   }
   OS_CriticalEnd(state);
   OS_CriticalEnd(state);
}
}
 
 
 
 
/******************************************/
/******************************************/
Line 631... Line 653...
{
{
   uint32 state, cpuIndex;
   uint32 state, cpuIndex;
   OS_Thread_t *thread;
   OS_Thread_t *thread;
   int returnCode=0;
   int returnCode=0;
 
 
 
   //assert(OS_SpinLockGet() == 0);
   assert(Semaphore);
   assert(Semaphore);
   assert(InterruptInside == 0);
   assert(InterruptInside == 0);
   state = OS_CriticalBegin();
   state = OS_CriticalBegin();
   if(--Semaphore->count < 0)
   if(--Semaphore->count < 0)
   {
   {
Line 651... Line 674...
      thread->ticksTimeout = Ticks + OS_ThreadTime();
      thread->ticksTimeout = Ticks + OS_ThreadTime();
      OS_ThreadPriorityRemove(&ThreadHead, thread);
      OS_ThreadPriorityRemove(&ThreadHead, thread);
      OS_ThreadPriorityInsert(&Semaphore->threadHead, thread);
      OS_ThreadPriorityInsert(&Semaphore->threadHead, thread);
      if(Ticks != OS_WAIT_FOREVER)
      if(Ticks != OS_WAIT_FOREVER)
         OS_ThreadTimeoutInsert(thread);
         OS_ThreadTimeoutInsert(thread);
      ThreadCurrentActive[cpuIndex] = 0;
 
      assert(ThreadHead);
      assert(ThreadHead);
      OS_ThreadReschedule(0);
      OS_ThreadReschedule(0);
      returnCode = thread->returnCode;
      returnCode = thread->returnCode;
   }
   }
   OS_CriticalEnd(state);
   OS_CriticalEnd(state);
 
   //assert(OS_SpinLockGet() == 0);
   return returnCode;
   return returnCode;
}
}
 
 
 
 
/******************************************/
/******************************************/
Line 1117... Line 1140...
 
 
 
 
/******************************************/
/******************************************/
void OS_Init(uint32 *HeapStorage, uint32 Bytes)
void OS_Init(uint32 *HeapStorage, uint32 Bytes)
{
{
 
   int i;
   OS_AsmInterruptInit();               //Patch interrupt vector
   OS_AsmInterruptInit();               //Patch interrupt vector
   OS_InterruptMaskClear(0xffffffff);   //Disable interrupts
   OS_InterruptMaskClear(0xffffffff);   //Disable interrupts
   HeapArray[0] = OS_HeapCreate("Default", HeapStorage, Bytes);
   HeapArray[0] = OS_HeapCreate("Default", HeapStorage, Bytes);
   SemaphoreSleep = OS_SemaphoreCreate("Sleep", 0);
   SemaphoreSleep = OS_SemaphoreCreate("Sleep", 0);
   SemaphoreLock = OS_SemaphoreCreate("Lock", 1);
   SemaphoreLock = OS_SemaphoreCreate("Lock", 1);
 
   for(i = 0; i < OS_CPU_COUNT; ++i)
   OS_ThreadCreate("Idle", OS_IdleThread, NULL, 0, 256);
   OS_ThreadCreate("Idle", OS_IdleThread, NULL, 0, 256);
#ifndef DISABLE_IRQ_SIM
#ifndef DISABLE_IRQ_SIM
   if((OS_InterruptStatus() & (IRQ_COUNTER18 | IRQ_COUNTER18_NOT)) == 0)
   if((OS_InterruptStatus() & (IRQ_COUNTER18 | IRQ_COUNTER18_NOT)) == 0)
   {
   {
      //Detected that running in simulator so create SimIsr thread
      //Detected that running in simulator so create SimIsr thread
Line 1167... Line 1192...
 
 
/******************************************/
/******************************************/
//Symmetric Multiprocessing Spin Lock Mutex
//Symmetric Multiprocessing Spin Lock Mutex
uint32 OS_SpinLock(void)
uint32 OS_SpinLock(void)
{
{
   uint32 state, cpu, i, j, ok;
   uint32 state, cpuIndex, i, j, ok, delay;
 
 
   cpu = OS_CpuIndex();
   cpuIndex = OS_CpuIndex();
 
   delay = cpuIndex + 8;
   state = OS_AsmInterruptEnable(0);
   state = OS_AsmInterruptEnable(0);
   do
   do
   {
   {
      ok = 1;
      ok = 1;
      if(++SpinLockArray[cpu] == 1)
      if(++SpinLockArray[cpuIndex] == 1)
      {
      {
         for(i = 0; i < OS_CPU_COUNT; ++i)
         for(i = 0; i < OS_CPU_COUNT; ++i)
         {
         {
            if(i != cpu && SpinLockArray[i])
            if(i != cpuIndex && SpinLockArray[i])
               ok = 0;
               ok = 0;
         }
         }
         if(ok == 0)
         if(ok == 0)
         {
         {
            SpinLockArray[cpu] = 0;
            SpinLockArray[cpuIndex] = 0;
            for(j = 0; j < 100*cpu; ++j)  //wait a bit
            for(j = 0; j < delay; ++j)  //wait a bit
               ++i;
               ++i;
 
            if(delay < 128)
 
               delay <<= 1;
         }
         }
      }
      }
   } while(ok == 0);
   } while(ok == 0);
   return state;
   return state;
}
}
 
 
 
 
/******************************************/
/******************************************/
void OS_SpinUnlock(uint32 state)
void OS_SpinUnlock(uint32 state)
{
{
   uint32 cpu;
   uint32 cpuIndex;
   cpu = OS_CpuIndex();
   cpuIndex = OS_CpuIndex();
   if(--SpinLockArray[cpu] == 0)
   if(--SpinLockArray[cpuIndex] == 0)
      OS_AsmInterruptEnable(state);
      OS_AsmInterruptEnable(state);
 
 
 
   assert(SpinLockArray[cpuIndex] < 10);
 
   assert(!(state && SpinLockArray[cpuIndex]));
}
}
 
 
 
 
/******************************************/
/******************************************/
//Must be called with interrupts disabled and spin locked
//Must be called with interrupts disabled and spin locked
uint32 OS_SpinLockGet(void)
uint32 OS_SpinLockGet(void)
{
{
   uint32 cpu, count;
   uint32 cpuIndex, count;
   cpu = OS_CpuIndex();
   cpuIndex = OS_CpuIndex();
   count = SpinLockArray[cpu];
   count = SpinLockArray[cpuIndex];
 
   //assert(count);
   return count;
   return count;
}
}
 
 
 
 
/******************************************/
/******************************************/
//Must be called with interrupts disabled and spin locked
//Must be called with interrupts disabled and spin locked
void OS_SpinLockSet(uint32 count)
void OS_SpinLockSet(uint32 count)
{
{
   uint32 cpu;
   uint32 cpuIndex;
   cpu = OS_CpuIndex();
   cpuIndex = OS_CpuIndex();
   SpinLockArray[cpu] = (uint8)count;
   SpinLockArray[cpuIndex] = (uint8)count;
 
   assert(count);
}
}
#endif
#endif
 
 
 
 
/************** WIN32 Support *************/
/************** WIN32 Support *************/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.