Merge branch 'master' of git://localhost/acess2
authorJohn Hodge <[email protected]>
Sat, 2 Feb 2013 09:18:42 +0000 (17:18 +0800)
committerJohn Hodge <[email protected]>
Sat, 2 Feb 2013 09:18:42 +0000 (17:18 +0800)
22 files changed:
KernelLand/Kernel/events.c
KernelLand/Kernel/include/threads_int.h
KernelLand/Kernel/mutex.c
KernelLand/Kernel/rwlock.c
KernelLand/Kernel/semaphore.c
KernelLand/Kernel/threads.c
KernelLand/Kernel/workqueue.c
KernelLand/Modules/IPStack/routing.c
KernelLand/Modules/IPStack/tcp.c
KernelLand/Modules/IPStack/tcp.h
Tools/Makefile
Tools/NetTest/main.c
Tools/NetTest/vfs_shim.c
Tools/nativelib/Makefile
Tools/nativelib/include/acess.h
Tools/nativelib/include/shortlock.h [new file with mode: 0644]
Tools/nativelib/include/threads_int.h
Tools/nativelib/logging.c
Tools/nativelib/semaphore.c
Tools/nativelib/threads.c
Tools/nativelib/threads_int.c
Usermode/Applications/irc_src/main.c

index c3ab282..84a1b0a 100644 (file)
@@ -91,7 +91,7 @@ Uint32 Threads_WaitEvents(Uint32 EventMask)
                // Note stored anywhere because we're woken using other means
                SHORTREL( &glThreadListLock );
                SHORTREL( &us->IsLocked );
-               while(us->Status == THREAD_STAT_EVENTSLEEP)     Threads_Yield();
+               Threads_int_WaitForStatusEnd(THREAD_STAT_EVENTSLEEP);
                // Woken when lock is acquired
                SHORTLOCK( &us->IsLocked );
        }
index 642f6c3..09e58c1 100644 (file)
@@ -125,6 +125,7 @@ static const char * const casTHREAD_STAT[] = {
        "THREAD_STAT_ACTIVE",
        "THREAD_STAT_SLEEPING",
        "THREAD_STAT_MUTEXSLEEP",
+       "THREAD_STAT_RWLOCKSLEEP",
        "THREAD_STAT_SEMAPHORESLEEP",
        "THREAD_STAT_QUEUESLEEP",
        "THREAD_STAT_EVENTSLEEP",
@@ -152,6 +153,7 @@ extern tThread      *Threads_GetNextToRun(int CPU, tThread *Last);
 extern tThread *Threads_CloneTCB(Uint Flags);
 extern tThread *Threads_CloneThreadZero(void);
 
+extern void    Threads_int_WaitForStatusEnd(enum eThreadStatus Status);
 extern void    Semaphore_ForceWake(tThread *Thread);
 
 #endif
index 597242b..d74cde8 100644 (file)
@@ -66,7 +66,7 @@ int Mutex_Acquire(tMutex *Mutex)
                
                SHORTREL( &glThreadListLock );
                SHORTREL( &Mutex->Protector );
-               while(us->Status == THREAD_STAT_MUTEXSLEEP)     Threads_Yield();
+               Threads_int_WaitForStatusEnd(THREAD_STAT_MUTEXSLEEP);
                // We're only woken when we get the lock
                us->WaitPointer = NULL;
        }
index 979df4a..a6aeca8 100644 (file)
@@ -48,7 +48,7 @@ int RWLock_AcquireRead(tRWLock *Lock)
                
                SHORTREL( &glThreadListLock );
                SHORTREL( &Lock->Protector );
-               while(us->Status == THREAD_STAT_RWLOCKSLEEP)    Threads_Yield();
+               Threads_int_WaitForStatusEnd(THREAD_STAT_RWLOCKSLEEP);
                // We're only woken when we get the lock
                // TODO: Handle when this isn't the case
                us->WaitPointer = NULL;
@@ -90,7 +90,7 @@ int RWLock_AcquireWrite(tRWLock *Lock)
                SHORTREL( &glThreadListLock );
                SHORTREL( &Lock->Protector );
                
-               while(us->Status == THREAD_STAT_RWLOCKSLEEP)    Threads_Yield();
+               Threads_int_WaitForStatusEnd(THREAD_STAT_RWLOCKSLEEP);
                us->WaitPointer = NULL;
        }
        else
index ce7d4ba..2417473 100644 (file)
@@ -79,17 +79,11 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                SHORTREL( &Sem->Protector );    // Release first to make sure it is released
                SHORTREL( &glThreadListLock );
                // Sleep until woken (either by getting what we need, or a timer event)
-               while( us->Status == THREAD_STAT_SEMAPHORESLEEP )
-               {
-                       Threads_Yield();
-                       if(us->Status == THREAD_STAT_SEMAPHORESLEEP)
-                               Log_Warning("Threads", "Semaphore %p %s:%s re-schedulued while asleep",
-                                       Sem, Sem->ModName, Sem->Name);
-               }
+               Threads_int_WaitForStatusEnd( THREAD_STAT_SEMAPHORESLEEP );
+               // We're only woken when there's something avaliable (or a signal arrives)
                #if DEBUG_TRACE_STATE || SEMAPHORE_DEBUG
                Log("Semaphore %p %s:%s woken", Sem, Sem->ModName, Sem->Name);
                #endif
-               // We're only woken when there's something avaliable (or a signal arrives)
                us->WaitPointer = NULL;
                
                taken = us->RetStatus;
@@ -191,7 +185,7 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
                
                SHORTREL( &glThreadListLock );  
                SHORTREL( &Sem->Protector );
-               while(us->Status == THREAD_STAT_SEMAPHORESLEEP) Threads_Yield();
+               Threads_int_WaitForStatusEnd(THREAD_STAT_SEMAPHORESLEEP);
                // We're only woken when there's something avaliable
                us->WaitPointer = NULL;
                
index a86eba0..7dd9f6e 100644 (file)
@@ -712,6 +712,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 +759,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);
 }
 
 
index 9e2c6f6..2cd6a25 100644 (file)
@@ -46,10 +46,7 @@ void *Workqueue_GetWork(tWorkqueue *Queue)
                SHORTREL(&glThreadListLock);
                
                // Yield and sleep
-               Threads_Yield();
-               if(us->Status == THREAD_STAT_QUEUESLEEP) {
-                       // Why are we awake?!
-               }
+               Threads_int_WaitForStatusEnd(THREAD_STAT_QUEUESLEEP);
 
                us->WaitPointer = NULL;
        }
index d9efa99..e86f333 100644 (file)
@@ -115,12 +115,13 @@ tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name)
                {       
                        LOG("Why does this route not have a node? trying to find an iface for the next hop");
 
-                       rt = _Route_FindInterfaceRoute(type, rt->NextHop);
-                       if(!rt) {
+                       void *nextrt = _Route_FindInterfaceRoute(type, rt->NextHop);
+                       if(!nextrt) {
                                Log_Notice("Cannot find route to next hop '%s'",
                                        IPStack_PrintAddress(type, rt->NextHop));
                                return NULL;
                        }
+                       rt = nextrt;
                }
                if( !rt->Interface ) {
                        Log_Notice("Routes", "No interface for route %p, what the?", rt);
index 2bb90d1..f1eee65 100644 (file)
@@ -276,6 +276,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
                        srv->NewConnections = conn;
                VFS_MarkAvaliable( &srv->Node, 1 );
                SHORTREL(&srv->lConnections);
+               Semaphore_Signal(&srv->WaitingConnections, 1);
 
                // Send the SYN ACK
                hdr->Flags |= TCP_FLAG_ACK;
@@ -380,6 +381,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                        {       
                                Log_Log("TCP", "ACKing SYN-ACK");
                                Connection->State = TCP_ST_OPEN;
+                               VFS_MarkFull(&Connection->Node, 0);
                        }
                        else
                        {
@@ -394,8 +396,9 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                if( Header->Flags & TCP_FLAG_ACK )
                {
                        // TODO: Handle max half-open limit
-                       Connection->State = TCP_ST_OPEN;
                        Log_Log("TCP", "Connection fully opened");
+                       Connection->State = TCP_ST_OPEN;
+                       VFS_MarkFull(&Connection->Node, 0);
                }
                break;
                
@@ -915,15 +918,9 @@ int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
        ENTER("pNode iPos", Node, Pos);
 
        Log_Log("TCP", "Thread %i waiting for a connection", Threads_GetTID());
-       for(;;)
-       {
-               SHORTLOCK( &srv->lConnections );
-               if( srv->NewConnections != NULL )       break;
-               SHORTREL( &srv->lConnections );
-               Threads_Yield();        // TODO: Sleep until poked
-       }
+       Semaphore_Wait( &srv->WaitingConnections, 1 );
        
-
+       SHORTLOCK(&srv->lConnections);
        // Increment the new list (the current connection is still on the 
        // normal list)
        conn = srv->NewConnections;
@@ -1076,6 +1073,7 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface)
        conn->Node.NumACLs = 1;
        conn->Node.ACLs = &gVFS_ACL_EveryoneRW;
        conn->Node.Type = &gTCP_ClientNodeType;
+       conn->Node.BufferFull = 1;      // Cleared when connection opens
 
        conn->RecievedBuffer = RingBuffer_Create( TCP_RECIEVE_BUFFER_SIZE );
        #if 0
@@ -1112,14 +1110,9 @@ size_t TCP_Client_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffe
        ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
        LOG("conn = %p {State:%i}", conn, conn->State);
        
-       // Check if connection is estabilishing
-       // - TODO: Sleep instead (maybe using VFS_SelectNode to wait for the
-       //   data to be availiable
-       while( conn->State == TCP_ST_SYN_RCVD || conn->State == TCP_ST_SYN_SENT )
-               Threads_Yield();
-       
-       // If the conneciton is not open, then clean out the recieved buffer
-       if( conn->State != TCP_ST_OPEN )
+       // If the connection has been closed (state > ST_OPEN) then clear
+       // any stale data in the buffer (until it is empty (until it is empty))
+       if( conn->State > TCP_ST_OPEN )
        {
                Mutex_Acquire( &conn->lRecievedPackets );
                len = RingBuffer_Read( Buffer, conn->RecievedBuffer, Length );
@@ -1198,16 +1191,16 @@ size_t TCP_Client_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void
 //             Buffer, Length);
 //     #endif
        
-       // Check if connection is open
-       while( conn->State == TCP_ST_SYN_RCVD || conn->State == TCP_ST_SYN_SENT )
-               Threads_Yield();
-       
-       if( conn->State != TCP_ST_OPEN ) {
+       // Don't allow a write to a closed connection
+       if( conn->State > TCP_ST_OPEN ) {
                VFS_MarkError(Node, 1);
                LEAVE('i', -1);
                return -1;
        }
        
+       // Wait
+       VFS_SelectNode(Node, VFS_SELECT_WRITE|VFS_SELECT_ERROR, NULL, "TCP_Client_Write");
+       
        do
        {
                 int    len = (rem < TCP_MAX_PACKET_SIZE) ? rem : TCP_MAX_PACKET_SIZE;
@@ -1312,13 +1305,10 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        LEAVE_RET('i', 0);
 
                {
-                       tTime   timeout_end = now() + conn->Interface->TimeoutDelay;
+                       tTime   timeout = conn->Interface->TimeoutDelay;
        
                        TCP_StartConnection(conn);
-                       // TODO: Wait for connection to open
-                       while( conn->State == TCP_ST_SYN_SENT && timeout_end > now() ) {
-                               Threads_Yield();
-                       }
+                       VFS_SelectNode(&conn->Node, VFS_SELECT_WRITE, &timeout, "TCP Connection");
                        if( conn->State == TCP_ST_SYN_SENT )
                                LEAVE_RET('i', 0);
                }
@@ -1364,7 +1354,8 @@ void TCP_Client_Close(tVFS_Node *Node)
                while( conn->State == TCP_ST_FIN_WAIT1 )        Threads_Yield();
                break;
        default:
-               Log_Warning("TCP", "Unhandled connection state in TCP_Client_Close");
+               Log_Warning("TCP", "Unhandled connection state %i in TCP_Client_Close",
+                       conn->State);
                break;
        }
        
index 2247b90..42682ac 100644 (file)
@@ -8,6 +8,7 @@
 #include "ipstack.h"
 #include <adt.h>       // tRingBuffer
 #include <timers.h>    // tTimer
+#include <semaphore.h> // tSemaphore
 
 typedef struct sTCPHeader      tTCPHeader;
 typedef struct sTCPListener    tTCPListener;
@@ -69,6 +70,7 @@ struct sTCPListener
        tInterface      *Interface;     //!< Listening Interface
        tVFS_Node       Node;   //!< Server Directory node
         int    NextID;         //!< Name of the next connection
+       tSemaphore      WaitingConnections;
        tShortSpinlock  lConnections;   //!< Spinlock for connections
        tTCPConnection  *Connections;   //!< Connections (linked list)
        tTCPConnection  *volatile NewConnections;
index e10b765..52493d0 100644 (file)
@@ -1,13 +1,15 @@
 
-.PHONY: all clean nativelib DiskTool NetTest
+.PHONY: all clean
+.PHONY: nativelib DiskTool NetTest
+#.PHONY: nativelib-clean DiskTool-clean NetTest-clean
 
-all: DiskTool NetTest
+all clean: DiskTool NetTest
 
 img2sif: img2sif.c
        $(CC) -o $@ $< `sdl-config --libs --cflags` -lSDL_image -Wall
 
 nativelib:
-       $(MAKE) -C $@
+       $(MAKE) -C $@ $(MAKECMDGOALS)
 
 DiskTool NetTest: nativelib
-       $(MAKE) -C $@
+       $(MAKE) -C $@ $(MAKECMDGOALS)
index 9ce48a4..d3728c5 100644 (file)
@@ -55,6 +55,7 @@ int main(int argc, char *argv[])
                                if( argc-i != 3 ) {
                                        Log_Error("NetTest", "'netcat' <addr> <port>");
                                        PrintUsage(argv[0]);
+                                       return -1;
                                }
 
                                NetTest_Suite_Netcat(argv[i+1], strtol(argv[i+2], NULL, 0));
index 1b0c686..97ac4db 100644 (file)
 // === CODE ===
 int VFS_SelectNode(tVFS_Node *Node, int Type, tTime *Timeout, const char *Name)
 {
+       tThread *us = Proc_GetCurThread();
+
+        int    ret = 0;
+
+       Threads_ClearEvent(THREAD_EVENT_VFS);
+
+       if( Type & VFS_SELECT_READ ) {
+               Node->ReadThreads = (void*)us;
+               if(Node->DataAvaliable) ret |= VFS_SELECT_READ;
+       }
+       if( Type & VFS_SELECT_WRITE ) {
+               Node->WriteThreads = (void*)us;
+               if(!Node->BufferFull)   ret |= VFS_SELECT_WRITE;
+       }
+       if( Type & VFS_SELECT_ERROR ) {
+               Node->ErrorThreads = (void*)us;
+               if(Node->ErrorOccurred) ret |= VFS_SELECT_ERROR;
+       }
        
-       return 0;
+       if( !ret )
+       {
+               // TODO: Timeout
+               Threads_WaitEvents(THREAD_EVENT_VFS);
+       }
+
+       if( Type & VFS_SELECT_READ ) {
+               Node->ReadThreads = NULL;
+               if(Node->DataAvaliable) ret |= VFS_SELECT_READ;
+       }
+       if( Type & VFS_SELECT_WRITE ) {
+               Node->WriteThreads = NULL;
+               if(!Node->BufferFull)   ret |= VFS_SELECT_WRITE;
+       }
+       if( Type & VFS_SELECT_ERROR ) {
+               Node->ErrorThreads = NULL;
+               if(Node->ErrorOccurred) ret |= VFS_SELECT_ERROR;
+       }
+       return ret;
 }
 
 int VFS_MarkAvaliable(tVFS_Node *Node, BOOL bAvail)
@@ -32,6 +68,15 @@ int VFS_MarkError(tVFS_Node *Node, BOOL bError)
        return 0;
 }
 
+int VFS_MarkFull(tVFS_Node *Node, BOOL bError)
+{
+       Node->BufferFull = bError;
+       if( !Node->BufferFull && Node->WriteThreads )
+               Threads_PostEvent( (void*)Node->WriteThreads, THREAD_EVENT_VFS );
+       return 0;
+}
+
+
 #if 0
 int VFS_Open(const char *Path, Uint Flags)
 {
index e8e7f55..6b1957e 100644 (file)
@@ -3,12 +3,14 @@ KERNEL_DIR := ../../KernelLand/Kernel
 
 NOBJ := logging.o misc.o threads_int.o
 
-LOBJ := threads.o time.o mutex.o rwlock.o semaphore.o
+LOBJ := threads.o time.o
+# mutex.o rwlock.o semaphore.o
 
 KOBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o
 KOBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o # vfs/select.o
 KOBJ += vfs/fs/root.o vfs/fs/devfs.o
 KOBJ += drv/proc.o
+KOBJ += mutex.o rwlock.o semaphore.o
 
 NOBJ := $(NOBJ:%.o=obj/%.o)
 LOBJ := $(LOBJ:%.o=obj/%.o)
@@ -28,18 +30,20 @@ clean:
        $(RM) $(BIN) $(OBJ)
 
 $(BIN): $(OBJ)
-       ar cru $(BIN) $(OBJ)
+       ar cr $(BIN) $(OBJ)
 
-$(NOBJ): obj/%.o: %.c
+$(NOBJ): obj/%.o: %.c Makefile
        @echo [CC Native] $@
        @mkdir -p $(dir $@)
-       @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS)
-$(LOBJ): obj/%.o: %.c
+       @$(CC) -o $@ -c $< -MMD -MF [email protected] -MT $@ -MP $(CFLAGS) $(CPPFLAGS)
+$(LOBJ): obj/%.o: %.c Makefile
        @echo [CC Local] $@
        @mkdir -p $(dir $@)
-       @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
+       @$(CC) -o $@ -c $< -MMD -MF [email protected] -MT $@ -MP $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
 
-$(KOBJ): obj/_Kernel/%.o: $(KERNEL_DIR)/%.c
+$(KOBJ): obj/_Kernel/%.o: $(KERNEL_DIR)/%.c Makefile
        @echo [CC Kernel] $@
        @mkdir -p $(dir $@)
-       @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
+       @$(CC) -o $@ -c $< -MMD -MF [email protected] -MT $@ -MP $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
+
+-include $(OBJ:%=%.dep)
index 7198865..b83b977 100644 (file)
@@ -50,9 +50,6 @@ typedef uint32_t      tUID;
 typedef uint32_t       tGID;
 typedef uint32_t       tTID;
 
-// NOTE: Since this is single-threaded (for now) mutexes can be implimented as simple locks
-typedef char   tShortSpinlock;
-
 typedef int64_t        tTime;
 extern tTime   now(void);
 extern int64_t timestamp(int sec, int min, int hr, int day, int month, int year);
@@ -147,16 +144,7 @@ extern uint64_t    DivMod64U(uint64_t Num, uint64_t Den, uint64_t *Rem);
 static inline int MIN(int a, int b) { return a < b ? a : b; }
 static inline int MAX(int a, int b) { return a > b ? a : b; }
 
-#if USE_MULTITHREADING
-#error "TODO: Impliment multithreaded SHORTLOCK"
-#else
-static inline void SHORTLOCK(tShortSpinlock *Lock) {
-       if(*Lock)       Log_KernelPanic("---", "Double short lock");
-       *Lock = 1;
-}
-static inline void SHORTREL(tShortSpinlock *m) { *m = 0; }
-static inline int  CPU_HAS_LOCK(tShortSpinlock *m) { return *m; }
-#endif
+#include <shortlock.h>
 
 static inline intptr_t MM_GetPhysAddr(void *Ptr) { return 1; }
 static inline int      MM_IsUser(const void *Ptr) { return 1; }
diff --git a/Tools/nativelib/include/shortlock.h b/Tools/nativelib/include/shortlock.h
new file mode 100644 (file)
index 0000000..f050eb6
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Acess2 native library
+ * - By John Hodge (thePowersGang)
+ *
+ * shortlock.h
+ * - Short locks :)
+ */
+#ifndef _SHORTLOCK_H_
+#define _SHORTLOCK_H_
+
+typedef void   *tShortSpinlock;
+
+extern void    SHORTLOCK(tShortSpinlock *Lock);
+extern void    SHORTREL(tShortSpinlock *m);
+extern int     CPU_HAS_LOCK(tShortSpinlock *m);
+
+#endif
index 36e5aba..3e85232 100644 (file)
@@ -8,6 +8,10 @@
 #ifndef _THREADS_INT_H_
 #define _THREADS_INT_H_
 
+#include <shortlock.h>
+
+typedef struct sThread tThread;
+
 #define THREAD_EVENT_RWLOCK    (1 << 8)
 
 typedef struct sThreadIntMutex tThreadIntMutex;        // actually pthreads
@@ -39,24 +43,68 @@ struct sThread
        void    *ThreadHandle;
         int    TID;
 
-       tThreadIntMutex *Protector;
+        int    Status;
+
+       tShortSpinlock  IsLocked;
 
        uint32_t        PendingEvents;
        uint32_t        WaitingEvents;
        tThreadIntSem   *WaitSemaphore; // pthreads
 
-       char    *Name;
+       char    *ThreadName;
+
+        int    bInstrTrace;    // Used for semaphore tracing
+
+        int    RetStatus;
+       void    *WaitPointer;
 
        // Init Only
        void    (*SpawnFcn)(void*);
        void    *SpawnData;
 };
 
+enum eThreadStatus {
+       THREAD_STAT_NULL,       // Invalid process
+       THREAD_STAT_ACTIVE,     // Running and schedulable process
+       THREAD_STAT_SLEEPING,   // Message Sleep
+       THREAD_STAT_MUTEXSLEEP, // Mutex Sleep
+       THREAD_STAT_RWLOCKSLEEP,        // Read-Writer lock Sleep
+       THREAD_STAT_SEMAPHORESLEEP,     // Semaphore Sleep
+       THREAD_STAT_QUEUESLEEP, // Queue
+       THREAD_STAT_EVENTSLEEP, // Event sleep
+       THREAD_STAT_WAITING,    // ??? (Waiting for a thread)
+       THREAD_STAT_PREINIT,    // Being created
+       THREAD_STAT_ZOMBIE,     // Died/Killed, but parent not informed
+       THREAD_STAT_DEAD,       // Awaiting burial (free)
+       THREAD_STAT_BURIED      // If it's still on the list here, something's wrong
+};
+static const char * const casTHREAD_STAT[] = {
+       "THREAD_STAT_NULL",
+       "THREAD_STAT_ACTIVE",
+       "THREAD_STAT_SLEEPING",
+       "THREAD_STAT_MUTEXSLEEP",
+       "THREAD_STAT_RWLOCKSLEEP",
+       "THREAD_STAT_SEMAPHORESLEEP",
+       "THREAD_STAT_QUEUESLEEP",
+       "THREAD_STAT_EVENTSLEEP",
+       "THREAD_STAT_WAITING",
+       "THREAD_STAT_PREINIT",
+       "THREAD_STAT_ZOMBIE",
+       "THREAD_STAT_DEAD",
+       "THREAD_STAT_BURIED"
+};
+
 extern struct sThread __thread *lpThreads_This;
+extern tShortSpinlock  glThreadListLock;
 
 extern int     Threads_int_CreateThread(struct sThread *Thread);
 extern int     Threads_int_ThreadingEnabled(void);
 
+extern tThread *Proc_GetCurThread(void);
+extern tThread *Threads_RemActive(void);
+extern void    Threads_AddActive(tThread *Thread);
+extern void    Threads_int_WaitForStatusEnd(enum eThreadStatus Status);
+
 extern tThreadIntMutex *Threads_int_MutexCreate(void);
 extern void    Threads_int_MutexDestroy(tThreadIntMutex *Mutex);
 extern void    Threads_int_MutexLock(tThreadIntMutex *Mutex);
index 0cb3ed3..c2d8a76 100644 (file)
@@ -1,5 +1,9 @@
 /*
- * 
+ * Acess2 libnative (Kernel Simulation Library)
+ * - By John Hodge (thePowersGang)
+ *
+ * logging.c
+ * - Logging functions
  */
 #include <stdio.h>
 #include <stdarg.h>
 #include <acess_logging.h>
 #include <ctype.h>
 #include <inttypes.h>
+#include <shortlock.h>
 
-#define LOGHDR(col,type)       fprintf(stderr, "\e["col"m[%-8.8s]"type" ", Ident)
+extern int     Threads_GetTID();
+
+#define LOGHDR(col,type)       fprintf(stderr, "\e["col"m[%-8.8s]"type"%2i ", Ident, Threads_GetTID())
 #define LOGTAIL()      fprintf(stderr, "\e[0m\n")
 
 #define PUTERR(col,type)       {\
+       if(!gbThreadInLog)      SHORTLOCK(&glDebugLock); \
+       gbThreadInLog ++; \
        LOGHDR(col,type);\
        va_list args; va_start(args, Message);\
        vfprintf(stderr, Message, args);\
        va_end(args);\
        LOGTAIL();\
+       gbThreadInLog --; \
+       if(!gbThreadInLog)      SHORTREL(&glDebugLock); \
 }
 
+// === GLOBALS ===
+int __thread   gbThreadInLog;
+tShortSpinlock glDebugLock;
+
 // === CODE ===
 void Log_KernelPanic(const char *Ident, const char *Message, ...) {
        PUTERR("35", "k")
-       abort();
+       exit(-1);
 }
 void Log_Panic(const char *Ident, const char *Message, ...)
        PUTERR("34", "p")
index c1476f6..20c3293 100644 (file)
@@ -8,6 +8,11 @@
 #include <acess.h>
 #include <semaphore.h>
 
+#if 0
+TODO:: Rework kernel-land semaphore code to use events
+- Allows it to be used here and be tested easier
+#endif
+
 // === CODE ===
 void Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const char *Module, const char *Name)
 {
index 1231c43..b214f21 100644 (file)
@@ -16,6 +16,8 @@ tThread       *Threads_int_CreateTCB(tThread *Parent);
 // === GLOBALS ===
 tThread        *gThreads_List;
 tThread __thread       *lpThreads_This;
+ int   giThreads_NextTID = 1;
+tShortSpinlock glThreadListLock;
 
 // === CODE ===
 void Threads_int_Init(void)
@@ -34,16 +36,16 @@ void Threads_PostEvent(tThread *Thread, Uint32 Events)
                // nope.avi
                return ;
        }
-       Threads_int_MutexLock(Thread->Protector);
+       SHORTLOCK( &Thread->IsLocked );
        Thread->PendingEvents |= Events;
        if( Thread->WaitingEvents & Events )
                Threads_int_SemSignal(Thread->WaitSemaphore);
-       Threads_int_MutexRelease(Thread->Protector);
+       SHORTREL( &Thread->IsLocked );
 }
 
 Uint32 Threads_WaitEvents(Uint32 Events)
 {
-       if( Threads_int_ThreadingEnabled() ) {
+       if( !Threads_int_ThreadingEnabled() ) {
                Log_Notice("Threads", "_WaitEvents: Threading disabled");
                return 0;
        }
@@ -56,19 +58,19 @@ Uint32 Threads_WaitEvents(Uint32 Events)
 
 void Threads_ClearEvent(Uint32 Mask)
 {
-       if( Threads_int_ThreadingEnabled() ) {
+       if( !Threads_int_ThreadingEnabled() ) {
                Log_Notice("Threads", "_ClearEvent: Threading disabled");
                return ;
        }
-       Threads_int_MutexLock(lpThreads_This->Protector);
+       SHORTLOCK(&lpThreads_This->IsLocked);
        lpThreads_This->PendingEvents &= ~Mask;
-       Threads_int_MutexRelease(lpThreads_This->Protector);
+       SHORTREL(&lpThreads_This->IsLocked);
 }
 
 tUID Threads_GetUID(void) { return 0; }
 tGID Threads_GetGID(void) { return 0; }
 
-tTID Threads_GetTID(void) { return 0; }
+tTID Threads_GetTID(void) { return lpThreads_This->TID; }
 
 int *Threads_GetMaxFD(void)        { return &lpThreads_This->Process->MaxFDs;  }
 char **Threads_GetCWD(void)        { return &lpThreads_This->Process->CWD;     }
@@ -86,14 +88,20 @@ void Threads_Sleep(void)
        Log_Warning("Threads", "Threads_Sleep shouldn't be used");
 }
 
+void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
+{
+       while( lpThreads_This->Status != Status )
+               Threads_int_SemWaitAll(lpThreads_This->WaitSemaphore);
+}
+
 int Threads_SetName(const char *Name)
 {
        if( !lpThreads_This )
                return 0;
 
-       if( lpThreads_This->Name )
-               free(lpThreads_This->Name);
-       lpThreads_This->Name = strdup(Name);
+       if( lpThreads_This->ThreadName )
+               free(lpThreads_This->ThreadName);
+       lpThreads_This->ThreadName = strdup(Name);
 
        return 0;
 }
@@ -106,6 +114,18 @@ int *Threads_GetErrno(void)
        return &a_errno;
 }
 
+tThread *Threads_RemActive(void)
+{
+       return lpThreads_This;
+}
+
+void Threads_AddActive(tThread *Thread)
+{
+       Thread->Status = THREAD_STAT_ACTIVE;
+       // Increment state-change semaphore
+       Threads_int_SemSignal(Thread->WaitSemaphore);
+}
+
 struct sProcess *Threads_int_CreateProcess(void)
 {
        struct sProcess *ret = calloc(sizeof(struct sProcess), 1);
@@ -118,8 +138,9 @@ struct sProcess *Threads_int_CreateProcess(void)
 tThread *Threads_int_CreateTCB(tThread *Parent)
 {
        tThread *ret = calloc( sizeof(tThread), 1 );
+       ret->TID = giThreads_NextTID ++;
        ret->WaitSemaphore = Threads_int_SemCreate();
-       ret->Protector = Threads_int_MutexCreate();
+       //ret->Protector = Threads_int_MutexCreate();
 
        if( !Parent )
        {
index f25ab95..3b7b08a 100644 (file)
@@ -11,6 +11,7 @@
 #include <acess_logging.h>
 #include <threads_int.h>
 #include <pthread_weak.h>
+#include <shortlock.h>
 
 // === TYPES ===
 typedef struct sThread tThread;
@@ -22,7 +23,6 @@ struct sThreadIntSem { int val; };
 // === CODE ===
 int Threads_int_ThreadingEnabled(void)
 {
-       Log_Debug("Threads", "pthread_create = %p", pthread_create);
        return !!pthread_create;
 }
 
@@ -139,3 +139,38 @@ int Threads_int_CreateThread(tThread *Thread)
        }
 }
 
+void SHORTLOCK(tShortSpinlock *Lock)
+{
+       if( !pthread_mutex_init )
+       {
+               if(*Lock)       Log_KernelPanic("---", "Double short lock");
+               *Lock = (void*)1;
+       }
+       else
+       {
+               if( !*Lock ) {
+                       *Lock = malloc(sizeof(pthread_mutex_t));
+                       pthread_mutex_init(*Lock, NULL);
+               }
+               pthread_mutex_lock(*Lock);
+       }
+}
+
+void SHORTREL(tShortSpinlock *Lock)
+{
+       if( !pthread_mutex_init )
+       {
+               if(!*Lock)      Log_Notice("---", "Short release when not held");
+               *Lock = NULL;
+       }
+       else
+       {
+               pthread_mutex_unlock(*Lock);
+       }
+}
+
+int CPU_HAS_LOCK(tShortSpinlock *Lock)
+{
+       return 0;
+}
+
index 16eee39..3448dbd 100644 (file)
@@ -578,6 +578,7 @@ void ParseServerLine(tServer *Server, char *Line)
                                Message_Append(Server, MSG_TYPE_SERVER, user, user, message);\r
                                break;\r
                        case 372:       // MOTD Data\r
+                       case 375:       // MOTD Start\r
                        case 376:       // MOTD End\r
                                \r
                        default:\r

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