Kernel - Added 'Flags' param to VFS Read/Write/FindDir
[tpg/acess2.git] / KernelLand / Kernel / threads.c
index a86eba0..0961f8d 100644 (file)
@@ -66,6 +66,10 @@ tThread      *Threads_RemActive(void);
 void   Threads_ToggleTrace(int TID);
 void   Threads_Fault(int Num);
 void   Threads_SegFault(tVAddr Addr);
+void   Threads_PostSignal(int SignalNum);
+ int   Threads_GetPendingSignal(void);
+void   Threads_SetSignalHandler(int SignalNum, void *Handler);
+void   *Threads_GetSignalHandler(int SignalNum);
 #if 0
  int   Threads_GetPID(void);
  int   Threads_GetTID(void);
@@ -212,7 +216,7 @@ int Threads_SetName(const char *NewName)
        if( IsHeap(oldname) )   free( oldname );        
        cur->ThreadName = strdup(NewName);
 
-//     Log_Debug("Threads", "Thread renamed to '%s'", NewName);        
+       Log_Debug("Threads", "Thread renamed to '%s'", NewName);        
 
        return 0;
 }
@@ -712,6 +716,22 @@ void Threads_Yield(void)
        Proc_Reschedule();
 }
 
+/**
+ * \breif Wait for the thread status to not be a specified value
+ */
+void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
+{
+       tThread *us = Proc_GetCurThread();
+       ASSERT(Status != THREAD_STAT_ACTIVE);
+       ASSERT(Status != THREAD_STAT_DEAD);
+       while( us->Status == Status )
+       {
+               Proc_Reschedule();
+               if( us->Status == Status )
+                       Debug("Thread %p(%i %s) rescheduled while in %s state", casTHREAD_STAT[Status]);
+       }
+}
+
 /**
  * \fn void Threads_Sleep(void)
  * \brief Take the current process off the run queue
@@ -743,12 +763,7 @@ void Threads_Sleep(void)
        
        // Release Spinlock
        SHORTREL( &glThreadListLock );
-
-       while(cur->Status != THREAD_STAT_ACTIVE) {
-               Proc_Reschedule();
-               if( cur->Status != THREAD_STAT_ACTIVE )
-                       Log("%i - Huh? why am I up? zzzz...", cur->TID);
-       }
+       Threads_int_WaitForStatusEnd(THREAD_STAT_SLEEPING);
 }
 
 
@@ -993,6 +1008,62 @@ void Threads_SegFault(tVAddr Addr)
        //Threads_Exit( 0, -1 );
 }
 
+
+void Threads_PostSignal(int SignalNum)
+{
+       tThread *cur = Proc_GetCurThread();
+       cur->PendingSignal = SignalNum;
+       Threads_PostEvent(cur, THREAD_EVENT_SIGNAL);
+}
+
+/**
+ */
+int Threads_GetPendingSignal(void)
+{
+       tThread *cur = Proc_GetCurThread();
+       
+       // Atomic AND with 0 fetches and clears in one operation
+       return __sync_fetch_and_and( &cur->PendingSignal, 0 );
+}
+
+/*
+ * \brief Update the current thread's signal handler
+ */
+void Threads_SetSignalHandler(int SignalNum, void *Handler)
+{
+       if( SignalNum <= 0 || SignalNum >= NSIGNALS )
+               return ;
+       if( !MM_IsUser(Handler) )
+               return ;
+       Proc_GetCurThread()->Process->SignalHandlers[SignalNum] = Handler;
+}
+
+/**
+ * \return 0  Ignore
+ */
+void *Threads_GetSignalHandler(int SignalNum)
+{
+       if( SignalNum <= 0 || SignalNum >= NSIGNALS )
+               return NULL;
+       void *ret = Proc_GetCurThread()->Process->SignalHandlers[SignalNum];
+       if( !ret )
+       {
+               // Defaults
+               switch(SignalNum)
+               {
+               case SIGINT:
+               case SIGKILL:
+               case SIGSEGV:
+//                     ret = User_Signal_Kill;
+                       break;
+               default:
+                       ret = NULL;
+                       break;
+               }
+       }
+       return ret;
+}
+
 // --- Process Structure Access Functions ---
 tPGID Threads_GetPGID(void)
 {

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