Kernel - Implemented waking from semaphores
authorJohn Hodge <[email protected]>
Thu, 16 Jun 2011 11:01:51 +0000 (19:01 +0800)
committerJohn Hodge <[email protected]>
Thu, 16 Jun 2011 11:01:51 +0000 (19:01 +0800)
- Threads waiting on semaphores can now be woken by other threads
- Changed ping to not base its timestamp on after the packet is sent
 > Fixes extra-long timeouts

Kernel/debug.c
Kernel/drv/vterm.c
Kernel/include/semaphore.h
Kernel/messages.c
Kernel/threads.c
Kernel/vfs/select.c
Modules/IPStack/icmp.c
Modules/IPStack/link.c
Modules/Network/NE2000/ne2000.c
Modules/Network/RTL8139/rtl8139.c
Modules/Storage/ATA/io.c

index 76525bf..7915b86 100644 (file)
@@ -250,7 +250,7 @@ void Debug_Enter(const char *FuncName, const char *ArgTypes, ...)
 
        va_start(args, ArgTypes);
 
-       LogF("%012lli ", now());
+       LogF("%014lli ", now());
        while(i--)      Debug_Putchar(' ');
 
        Debug_Puts(1, FuncName);
@@ -308,7 +308,7 @@ void Debug_Log(const char *FuncName, const char *Fmt, ...)
 
        va_start(args, Fmt);
 
-       LogF("%012lli ", now());
+       LogF("%014lli ", now());
        while(i--)      Debug_Putchar(' ');
 
        Debug_Puts(1, FuncName);
@@ -343,7 +343,7 @@ void Debug_Leave(const char *FuncName, char RetType, ...)
                gDebug_Level = 0;
                i = 0;
        }
-       LogF("%012lli ", now());
+       LogF("%014lli ", now());
        // Indenting
        while(i--)      Debug_Putchar(' ');
 
@@ -387,6 +387,7 @@ void Debug_HexDump(const char *Header, const void *Data, Uint Length)
 {
        const Uint8     *cdat = Data;
        Uint    pos = 0;
+       LogF("%014lli ", now());
        Debug_Puts(1, Header);
        LogF(" (Hexdump of %p)\r\n", Data);
 
@@ -410,7 +411,7 @@ void Debug_HexDump(const char *Header, const void *Data, Uint Length)
 
        {
                 int    i ;
-               LogF("Log: %04x: ", pos);
+               LogF("%014lli Log: %04x: ", now(), pos);
                for(i = 0; i < Length; i ++)
                {
                        LogF("%02x ", cdat[i]);
index bead23c..2b9f656 100644 (file)
@@ -1047,6 +1047,57 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
                                                break;
                                        }
                                        break;
+                               
+                               // Erase in line
+                               case 'K':
+                                       switch(args[0])
+                                       {
+                                       case 0: // Erase to right
+                                               if( Term->Flags & VT_FLAG_ALTBUF )
+                                               {
+                                                        int    i, max;
+                                                       max = Term->Width - Term->AltWritePos % Term->Width;
+                                                       for( i = 0; i < max; i ++ )
+                                                               Term->AltBuf[Term->AltWritePos+i].Ch = 0;
+                                               }
+                                               else
+                                               {
+                                                        int    i, max;
+                                                       max = Term->Width - Term->WritePos % Term->Width;
+                                                       for( i = 0; i < max; i ++ )
+                                                               Term->Text[Term->WritePos+i].Ch = 0;
+                                               }
+                                               VT_int_UpdateScreen(Term, 0);
+                                               break;
+                                       case 1: // Erase to left
+                                               if( Term->Flags & VT_FLAG_ALTBUF )
+                                               {
+                                                        int    i = Term->AltWritePos % Term->Width;
+                                                       while( i -- )
+                                                               Term->AltBuf[Term->AltWritePos++].Ch = 0;
+                                               }
+                                               else
+                                               {
+                                                        int    i = Term->WritePos % Term->Width;
+                                                       while( i -- )
+                                                               Term->Text[Term->WritePos++].Ch = 0;
+                                               }
+                                               VT_int_UpdateScreen(Term, 0);
+                                               break;
+                                       case 2: // Erase all
+                                               if( Term->Flags & VT_FLAG_ALTBUF )
+                                               {
+                                                       VT_int_ClearLine(Term, Term->AltWritePos / Term->Width);
+                                               }
+                                               else
+                                               {
+                                                       VT_int_ClearLine(Term, Term->WritePos / Term->Width);
+                                               }
+                                               VT_int_UpdateScreen(Term, 0);
+                                               break;
+                                       }
+                                       break;
+                               
                                // Set cursor position
                                case 'H':
                                        if( Term->Flags & VT_FLAG_ALTBUF )
@@ -1582,6 +1633,7 @@ void VT_int_ToggleAltBuffer(tVTerm *Term, int Enabled)
                Term->Flags |= VT_FLAG_ALTBUF;
        else
                Term->Flags &= ~VT_FLAG_ALTBUF;
+       VT_int_UpdateScreen(Term, 1);
 }
 
 // ---
index 0cf4b21..f42da04 100644 (file)
@@ -46,7 +46,7 @@ extern void   Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const c
  * \param Semaphore    Semaphore structure to use
  * \param MaxToTake    Maximum number of items to take off the list (if zero, as much as possible is taken)
  * \return Number of items fetched
- * \retval 0   Semaphore interrupted
+ * \retval 0   Semaphore interrupted (signal/message)
  * \retval -1  Unspecified error
  */
 extern int     Semaphore_Wait(tSemaphore *Sem, int MaxToTake);
index 45b5dfa..ce23d6b 100644 (file)
@@ -2,6 +2,7 @@
  * AcessOS Microkernel Version
  * messages.c
  */
+#define DEBUG  1
 #include <acess.h>
 #include <threads.h>
 #include <threads_int.h>
@@ -24,18 +25,18 @@ int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
        tThread *thread;
        tMsg    *msg;
        
-       Log("Proc_SendMessage: (Err=%p, Dest=%i, Length=%i, Data=%p)", Err, Dest, Length, Data);
+       ENTER("pErr iDest iLength pData", Err, Dest, Length, Data);
        
        if(Length <= 0 || !Data) {
                *Err = -EINVAL;
-               return -1;
+               LEAVE_RET('i', -1);
        }
        
        // Get thread
        thread = Threads_GetThread( Dest );
        
        // Error check
-       if(!thread) {   return -1;      }
+       if(!thread)     LEAVE_RET('i', -1);
        
        // Get Spinlock
        SHORTLOCK( &thread->IsLocked );
@@ -43,7 +44,7 @@ int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
        // Check if thread is still alive
        if(thread->Status == THREAD_STAT_DEAD) {
                SHORTREL( &thread->IsLocked );
-               return -1;
+               LEAVE_RET('i', -1);
        }
        
        // Create message
@@ -68,7 +69,7 @@ int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
        Threads_Wake( thread );
        SHORTREL(&glThreadListLock);
        
-       return 0;
+       LEAVE_RET('i', 0);
 }
 
 /**
index 40e1729..bee332b 100644 (file)
@@ -755,6 +755,56 @@ int Threads_Wake(tThread *Thread)
                SHORTREL( &glThreadListLock );
                return -EOK;
        
+       case THREAD_STAT_SEMAPHORESLEEP: {
+               tSemaphore      *sem;
+               tThread *th, *prev=NULL;
+               
+               sem = Thread->WaitPointer;
+               
+               SHORTLOCK( &sem->Protector );
+               
+               // Remove from sleeping queue
+               for( th = sem->Waiting; th; prev = th, th = th->Next )
+                       if( th == Thread )      break;
+               if( th )
+               {
+                       if(prev)
+                               prev->Next = Thread->Next;
+                       else
+                               sem->Waiting = Thread->Next;
+                       if(sem->LastWaiting == Thread)
+                               sem->LastWaiting = prev;
+               }
+               else
+               {
+                       prev = NULL;
+                       for( th = sem->Signaling; th; prev = th, th = th->Next )
+                               if( th == Thread )      break;
+                       if( !th ) {
+                               Log_Warning("Threads", "Thread %p(%i %s) is not on semaphore %p(%s:%s)",
+                                       Thread, Thread->TID, Thread->ThreadName,
+                                       sem, sem->ModName, sem->Name);
+                               return -EINTERNAL;
+                       }
+                       
+                       if(prev)
+                               prev->Next = Thread->Next;
+                       else
+                               sem->Signaling = Thread->Next;
+                       if(sem->LastSignaling == Thread)
+                               sem->LastSignaling = prev;
+               }
+               
+               SHORTLOCK( &glThreadListLock );
+               Threads_AddActive( Thread );
+               SHORTREL( &glThreadListLock );
+               
+               #if DEBUG_TRACE_STATE
+               Log("Threads_Sleep: %p(%i %s) woken from semaphore", Thread, Thread->TID, Thread->ThreadName);
+               #endif
+               SHORTREL( &sem->Protector );
+               } return -EOK;
+       
        case THREAD_STAT_WAITING:
                Warning("Threads_Wake - Waiting threads are not currently supported");
                return -ENOTIMPL;
@@ -863,6 +913,9 @@ tThread *Threads_RemActive(void)
        #endif
        {
                SHORTREL( &glThreadListLock );
+               Log_Warning("Threads", "Current thread %p(%i %s) is not on active queue",
+                       ret, ret->TID, ret->ThreadName
+                       );
                return NULL;
        }
        
@@ -1456,7 +1509,7 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                SHORTREL( &Sem->Protector );    // Release first to make sure it is released
                SHORTREL( &glThreadListLock );  
                while(us->Status == THREAD_STAT_SEMAPHORESLEEP) Threads_Yield();
-               // We're only woken when there's something avaliable
+               // We're only woken when there's something avaliable (or a signal arrives)
                us->WaitPointer = NULL;
                
                taken = us->RetStatus;
index 22417c8..a092b07 100644 (file)
@@ -68,7 +68,7 @@ int VFS_SelectNode(tVFS_Node *Node, enum eVFS_SelectTypes Type, tTime *Timeout,
        }
        
        thread_info = malloc(sizeof(tVFS_SelectThread));
-       if(!thread_info)        return -1;
+       if(!thread_info)        LEAVE_RET('i', -1);
        
        Semaphore_Init(&thread_info->SleepHandle, 0, 0, "VFS_SelectNode()", Name);
        
@@ -148,7 +148,7 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set
        if( !Timeout || *Timeout > 0 )
        {
                ret = Semaphore_Wait(&thread_info->SleepHandle, 1);
-               // TODO: Do something with ret
+               // TODO: Do something with ret?
        }
        
        // Fill output (modify *Handles)
@@ -486,9 +486,9 @@ void VFS_int_Select_SignalAll(tVFS_SelectList *List)
        {
                for( i = 0; i < NUM_THREADS_PER_ALLOC; i ++ )
                {
-                       LOG("block->Threads[i] = %p", block->Threads[i]);
                        if( block->Threads[i]  )
                        {
+                               LOG("block(%p)->Threads[%i] = %p", block, i, block->Threads[i]);
                                Semaphore_Signal( &block->Threads[i]->SleepHandle, 1 );
                        }
                }
index de3a9db..969a1fa 100644 (file)
@@ -118,9 +118,11 @@ int ICMP_Ping(tInterface *Interface, tIPv4 Addr)
        hdr->ID = i;
        hdr->Sequence = ~i;
        hdr->Checksum = htons( IPv4_Checksum(hdr, sizeof(buf)) );
-       IPv4_SendPacket(Interface, Addr, 1, i, sizeof(buf), buf);
        
        ts = now();
+       
+       IPv4_SendPacket(Interface, Addr, 1, i, sizeof(buf), buf);
+       
        end = ts + Interface->TimeoutDelay;
        while( !gICMP_PingSlots[i].bArrived && now() < end)     Threads_Yield();
        
index fe08b8d..e5e789a 100644 (file)
@@ -129,8 +129,9 @@ void Link_WatchDevice(tAdapter *Adapter)
                ret = VFS_Read(Adapter->DeviceFD, MAX_PACKET_SIZE, buf);
                if(ret == -1)   break;
                
-               if(ret <= (int)sizeof(tEthernetHeader)) {
-                       Log_Log("Net Link", "Recieved an undersized packet");
+               if(ret < sizeof(tEthernetHeader)) {
+                       Log_Log("Net Link", "Recieved an undersized packet (%i < %i)",
+                               ret, sizeof(tEthernetHeader));
                        continue;
                }
                
index 53602e7..3fa85f4 100644 (file)
@@ -289,6 +289,8 @@ Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        
        ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
        
+       // TODO: Lock
+       
        // Sanity Check Length
        if(Length > TX_BUF_SIZE*256) {
                Log_Warning(
@@ -360,7 +362,11 @@ Uint64 Ne2k_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
        
        // Wait for packets
-       Semaphore_Wait( &Card->Semaphore, 1 );
+       if( Semaphore_Wait( &Card->Semaphore, 1 ) != 1 )
+       {
+               // Error or interrupted
+               LEAVE_RET('i', 0);
+       }
        
        outb(Card->IOBase, 0x22 | (1 << 6));    // Page 6
        LOG("CURR : 0x%02x", inb(Card->IOBase + CURR));
@@ -392,10 +398,7 @@ Uint64 Ne2k_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                
                LOG("pktHdr->Length (%i) > 256 - 4, allocated buffer %p", pktHdr->Length, buf);
                
-               if(!buf) {
-                       LEAVE('i', -1);
-                       return -1;
-               }
+               if(!buf)        LEAVE_RET('i', -1);
                
                // Copy the already read data
                memcpy(buf, data, 256);
@@ -523,7 +526,9 @@ void Ne2k_IRQHandler(int IntNum)
                        {
                                //if( gpNe2k_Cards[i].NumWaitingPackets > MAX_PACKET_QUEUE )
                                //      gpNe2k_Cards[i].NumWaitingPackets = MAX_PACKET_QUEUE;
-                               Semaphore_Signal( &gpNe2k_Cards[i].Semaphore, 1 );
+                               if( Semaphore_Signal( &gpNe2k_Cards[i].Semaphore, 1 ) != 1 ) {
+                                       // Oops?
+                               }
                        }
                        // 1: Packet sent (no error)
                        // 2: Recieved with error
index c63dfee..d77fe27 100644 (file)
@@ -255,7 +255,10 @@ Uint64 RTL8139_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
 
 retry:
-       Semaphore_Wait( &card->ReadSemaphore, 1 );
+       if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 )
+       {
+               LEAVE_RET('i', 0);
+       }
        
        Mutex_Acquire( &card->ReadMutex );
        
@@ -423,9 +426,13 @@ void RTL8139_IRQHandler(int Num)
                        
                        LOG("packet_count = %i, read_ofs = 0x%x", packet_count, read_ofs);
                        
-                       Semaphore_Signal( &card->ReadSemaphore, packet_count );
                        if( packet_count )
+                       {
+                               if( Semaphore_Signal( &card->ReadSemaphore, packet_count ) != packet_count ) {
+                                       // Oops?
+                               }
                                VFS_MarkAvaliable( &card->Node, 1 );
+                       }
                        
                        outw(card->IOBase + ISR, FLAG_ISR_ROK);
                }
index 6ed0409..73c33b2 100644 (file)
@@ -368,7 +368,6 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
        while( gaATA_IRQs[cont] == 0 && now() < timeoutTime)
        {
                HALT();
-//             Threads_Yield();
        }
 
        // Complete Transfer
@@ -471,7 +470,6 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer)
        timeoutTime = now() + ATA_TIMEOUT;
        while( gaATA_IRQs[cont] == 0 && now() < timeoutTime)
        {
-//             Threads_Yield();
                HALT();
        }
 

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