Fixed compile errors, added Semaphore code
[tpg/acess2.git] / Kernel / threads.c
index b76fe59..8700154 100644 (file)
@@ -35,10 +35,11 @@ extern void Proc_Start(void);
 extern tThread *Proc_GetCurThread(void);
 extern int     Proc_Clone(Uint *Err, Uint Flags);
 extern void    Proc_CallFaultHandler(tThread *Thread);
+extern int     GetCPUNum(void);
 
 // === PROTOTYPES ===
 void   Threads_Init(void);
- int   Threads_SetName(char *NewName);
+ int   Threads_SetName(const char *NewName);
 char   *Threads_GetName(int ID);
 void   Threads_SetPriority(tThread *Thread, int Pri);
 tThread        *Threads_CloneTCB(Uint *Err, Uint Flags);
@@ -61,6 +62,7 @@ tGID  Threads_GetGID(void);
  int   Threads_SetGID(Uint *Errno, tUID ID);
 void   Threads_Dump(void);
 void   Threads_DumpActive(void);
+
 void   Mutex_Acquire(tMutex *Mutex);
 void   Mutex_Release(tMutex *Mutex);
  int   Mutex_IsLocked(tMutex *Mutex);
@@ -123,12 +125,12 @@ void Threads_Init(void)
 }
 
 /**
- * \fn void Threads_SetName(char *NewName)
+ * \fn void Threads_SetName(const char *NewName)
  * \brief Sets the current thread's name
  * \param NewName      New name for the thread
  * \return Boolean Failure
  */
-int Threads_SetName(char *NewName)
+int Threads_SetName(const char *NewName)
 {
        tThread *cur = Proc_GetCurThread();
        char    *oldname = cur->ThreadName;
@@ -662,6 +664,12 @@ void Threads_AddActive(tThread *Thread)
 {
        SHORTLOCK( &glThreadListLock );
        
+       if( Thread->Status == THREAD_STAT_ACTIVE ) {
+               tThread *cur = Proc_GetCurThread();
+               Warning("WTF, CPU%i %p (%i %s) is adding %p (%i %s) when it is active",
+                       GetCPUNum(), cur, cur->TID, cur->ThreadName, Thread, Thread->TID, Thread->ThreadName);
+       }
+       
        // Set state
        Thread->Status = THREAD_STAT_ACTIVE;
        Thread->CurCPU = -1;
@@ -680,8 +688,8 @@ void Threads_AddActive(tThread *Thread)
        #if SCHEDULER_TYPE == SCHED_LOTTERY
        giFreeTickets += caiTICKET_COUNTS[ Thread->Priority ];
        # if DEBUG_TRACE_TICKETS
-       Log("Threads_AddActive: %p %i (%s) added, new giFreeTickets = %i",
-               Thread, Thread->TID, Thread->ThreadName, giFreeTickets);
+       Log("Threads_AddActive: CPU%i %p %i (%s) added, new giFreeTickets = %i",
+               GetCPUNum(), Thread, Thread->TID, Thread->ThreadName, giFreeTickets);
        # endif
        #endif
        
@@ -718,8 +726,8 @@ tThread *Threads_RemActive(void)
        // no need to decrement tickets, scheduler did it for us
        
        #if SCHEDULER_TYPE == SCHED_LOTTERY && DEBUG_TRACE_TICKETS
-       Log("Threads_RemActive: %p %i (%s) removed, giFreeTickets = %i",
-               ret, ret->TID, ret->ThreadName, giFreeTickets);
+       Log("Threads_RemActive: CPU%i %p %i (%s) removed, giFreeTickets = %i",
+               GetCPUNum(), ret, ret->TID, ret->ThreadName, giFreeTickets);
        #endif
        
        SHORTREL( &glThreadListLock );
@@ -836,8 +844,8 @@ void Threads_DumpActive(void)
                for(thread=gActiveThreads;thread;thread=thread->Next)
        #endif
                {
-                       Log(" %i (%i) - %s (CPU %i)",
-                               thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
+                       Log(" %p %i (%i) - %s (CPU %i)",
+                               thread, thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
                        if(thread->Status != THREAD_STAT_ACTIVE)
                                Log("  ERROR State (%i) != THREAD_STAT_ACTIVE (%i)", thread->Status, THREAD_STAT_ACTIVE);
                        Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
@@ -863,8 +871,8 @@ void Threads_Dump(void)
        Log("All Threads:");
        for(thread=gAllThreads;thread;thread=thread->GlobalNext)
        {
-               Log(" %i (%i) - %s (CPU %i)",
-                       thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
+               Log(" %p %i (%i) - %s (CPU %i)",
+                       thread, thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
                Log("  State %i (%s)", thread->Status, casTHREAD_STAT[thread->Status]);
                switch(thread->Status)
                {
@@ -1167,6 +1175,12 @@ void Mutex_Acquire(tMutex *Mutex)
                Mutex->Owner = us;
                SHORTREL( &Mutex->Protector );
        }
+       
+       #if 0
+       extern tMutex   glPhysAlloc;
+       if( Mutex != &glPhysAlloc )
+               LogF("Mutex %p taken by %i %p\n", Mutex, us->TID, __builtin_return_address(0));
+       #endif
 }
 
 /**
@@ -1197,6 +1211,12 @@ void Mutex_Release(tMutex *Mutex)
                Mutex->Owner = NULL;
        }
        SHORTREL( &Mutex->Protector );
+       
+       #if 0
+       extern tMutex   glPhysAlloc;
+       if( Mutex != &glPhysAlloc )
+               LogF("Mutex %p released by %i %p\n", Mutex, Threads_GetTID(), __builtin_return_address(0));
+       #endif
 }
 
 /**
@@ -1208,6 +1228,86 @@ int Mutex_IsLocked(tMutex *Mutex)
        return Mutex->Owner != NULL;
 }
 
+/**
+ * \brief Initialise the semaphore
+ * \param Value        Initial value of the semaphore
+ * \param Label        Symbolic name
+ */
+void Semaphore_Init(tSemaphore *Sem, int Value, const char *Label)
+{
+       Sem->Value = Value;
+       Sem->Name = Label;
+}
+
+/**
+ * \brief Acquire a "item" from the semaphore
+ */
+void Semaphore_Wait(tSemaphore *Sem)
+{
+       tThread *us;
+       
+       SHORTLOCK( &Sem->Protector );
+       if( Sem->Value > 0 ) {
+               Sem->Value --;
+               SHORTREL( &Sem->Protector );
+               return ;
+       }
+       
+       SHORTLOCK( &glThreadListLock );
+       
+       // - Remove from active list
+       us = Threads_RemActive();
+       us->Next = NULL;
+       // - Mark as sleeping
+       us->Status = THREAD_STAT_SEMAPHORESLEEP;
+       us->WaitPointer = Sem;
+       
+       // - Add to waiting
+       if(Sem->LastWaiting) {
+               Sem->LastWaiting->Next = us;
+               Sem->LastWaiting = us;
+       }
+       else {
+               Sem->Waiting = us;
+               Sem->LastWaiting = us;
+       }
+       
+       SHORTREL( &glThreadListLock );
+       SHORTREL( &Sem->Protector );
+       while(us->Status == THREAD_STAT_MUTEXSLEEP)     Threads_Yield();
+       // We're only woken when there's something avaliable
+       us->WaitPointer = NULL;
+}
+
+/**
+ * \brief Add an "item" to the semaphore
+ */
+void Semaphore_Signal(tSemaphore *Sem)
+{
+       SHORTLOCK( &Sem->Protector );
+       Sem->Value ++;
+       
+       if( Sem->Waiting )
+       {
+               tThread *toWake = Sem->Waiting;
+               
+               Sem->Waiting = Sem->Waiting->Next;      // Next!
+               // Reset ->LastWaiting to NULL if we have just removed the last waiting thread
+               if( Sem->Waiting == NULL )
+                       Sem->LastWaiting = NULL;
+               
+               // Wake new owner
+               SHORTLOCK( &glThreadListLock );
+               if( toWake->Status != THREAD_STAT_ACTIVE )
+                       Threads_AddActive(toWake);
+               SHORTREL( &glThreadListLock );
+               
+               // Decrement (the value is now "owned" by `toWake`)
+               Sem->Value --;
+       }
+       SHORTREL( &Sem->Protector );
+}
+
 // === EXPORTS ===
 EXPORT(Threads_GetUID);
 EXPORT(Threads_GetGID);

UCC git Repository :: git.ucc.asn.au