Kernel - Planning SMP fix with sleep edge case
authorJohn Hodge <[email protected]>
Sun, 11 Aug 2013 03:10:14 +0000 (11:10 +0800)
committerJohn Hodge <[email protected]>
Sun, 11 Aug 2013 03:10:14 +0000 (11:10 +0800)
KernelLand/Kernel/semaphore.c
KernelLand/Kernel/threads.c
KernelLand/Kernel/workqueue.c

index 1111967..e817574 100644 (file)
@@ -50,6 +50,11 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
        }
        else
        {
+               #if 0
+               Threads_int_Sleep(THREAD_STAT_SEMAPHORESLEEP,
+                       Sem, MaxToTake,
+                       &Sem->Waiting, &Sem->LastWaiting, &Sem->Protector);
+               #endif
                SHORTLOCK( &glThreadListLock );
                
                // - Remove from active list
@@ -75,9 +80,9 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                        us, us->TID, us->ThreadName,
                        Sem, Sem->ModName, Sem->Name);
                #endif
-               
-               SHORTREL( &Sem->Protector );    // Release first to make sure it is released
+               SHORTREL( &Sem->Protector );
                SHORTREL( &glThreadListLock );
+               // NOTE: This can break in SMP
                // Sleep until woken (either by getting what we need, or a timer event)
                Threads_int_WaitForStatusEnd( THREAD_STAT_SEMAPHORESLEEP );
                // We're only woken when there's something avaliable (or a signal arrives)
index 67a2f63..9f76070 100644 (file)
@@ -732,6 +732,39 @@ void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
        }
 }
 
+void Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **ListHead, tThread **ListTail, tShortSpinlock *Lock)
+{
+       SHORTLOCK( &glThreadListLock );
+       tThread *us = Threads_RemActive();
+       us->Next = NULL;
+       // - Mark as sleeping
+       us->Status = Status;
+       us->WaitPointer = Ptr;
+       us->RetStatus = Num;    // Use RetStatus as a temp variable
+               
+       // - Add to waiting
+       if( ListTail ) {
+               if(*ListTail) {
+                       (*ListTail)->Next = us;
+                       *ListTail = us;
+               }
+               else {
+                       *ListHead = us;
+                       *ListTail = us;
+               }
+       }
+       else {
+               *ListHead = us;
+       }
+       
+       //if( Proc_ThreadSync(us) )
+       //      return ;
+       SHORTREL( &glThreadListLock );
+       if( Lock )
+               SHORTLOCK( Lock );
+       Threads_int_WaitForStatusEnd(Status);
+}
+
 /**
  * \fn void Threads_Sleep(void)
  * \brief Take the current process off the run queue
index 2cd6a25..2083bde 100644 (file)
@@ -36,12 +36,18 @@ void *Workqueue_GetWork(tWorkqueue *Queue)
                        return ret;
                }
                
+               #if 0
+               Threads_int_Sleep(THREAD_STAT_QUEUESLEEP,
+                       Queue, 0,
+                       &Queue->Sleeper, NULL, &Queue->Protector);
+               #endif
                // Go to sleep
                SHORTLOCK(&glThreadListLock);
                us = Threads_RemActive();
                us->WaitPointer = Queue;
                us->Status = THREAD_STAT_QUEUESLEEP;
                Queue->Sleeper = us;
+               
                SHORTREL(&Queue->Protector);    
                SHORTREL(&glThreadListLock);
                

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