Cleaning up and Debugging (Exposed by AcessNative mostly)
authorJohn Hodge <[email protected]>
Sat, 7 May 2011 13:29:33 +0000 (21:29 +0800)
committerJohn Hodge <[email protected]>
Sat, 7 May 2011 13:29:33 +0000 (21:29 +0800)
- Removed x86 specific code form debug.c (now in arch/x86/lib.c)
- Fixed some bugs in vterm / drvutil that caused some graphical glitches
- Added improved process state logging (for user state)
- Added instruction tracing (via x86 EFLAGS.TF)
- Fixed some possible bugs in the x86 task switch code (DR0 may not be set correctly)
- Cleaned up keyboard driver a bit
- Fixed some bugs shown by clang's static analyser
- Changed how VTerm determines IO devices (now with fallbacks)
- Fixed bug in VTerm with line not updating when text wraps
- Moved mutex.h to its own header
- Moved strdup to heap.h (makes AcessNative easier)
- Better debug and handling of errors in threads.c

19 files changed:
Kernel/arch/x86/include/arch.h
Kernel/arch/x86/include/proc.h
Kernel/arch/x86/lib.c
Kernel/arch/x86/proc.asm
Kernel/arch/x86/proc.c
Kernel/arch/x86_64/lib.c
Kernel/debug.c
Kernel/drv/kb.c
Kernel/drv/proc.c
Kernel/drv/vterm.c
Kernel/drvutil.c
Kernel/heap.c
Kernel/include/acess.h
Kernel/include/heap.h
Kernel/include/mutex.h [new file with mode: 0644]
Kernel/threads.c
Kernel/vfs/fs/root.c
Kernel/vfs/open.c
Kernel/vfs/select.c

index 8d8a14a..66d7a79 100644 (file)
@@ -123,9 +123,13 @@ typedef struct {
 
 typedef struct {
        Uint    EIP, ESP, EBP;
+       Uint32  UserCS, UserEIP;
 } tTaskState;
 
 // === FUNCTIONS ===
+extern void    Debug_PutCharDebug(char ch);
+extern void    Debug_PutStringDebug(const char *String);
+
 extern int     IS_LOCKED(struct sShortSpinlock *Lock);
 extern int     CPU_HAS_LOCK(struct sShortSpinlock *Lock);
 extern void    SHORTLOCK(struct sShortSpinlock *Lock);
index 2b04b75..e31c76d 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef _PROC_H
 #define _PROC_H
 
-#include <threads.h>
+#include <threads_int.h>
 
 // === TYPES ==
 typedef struct sTSS {
index 5fa9d12..969332b 100644 (file)
@@ -3,21 +3,29 @@
  * lib.c
  */
 #include <acess.h>
-#include <threads.h>
+#include <threads_int.h>
 
 #define TRACE_LOCKS    0
 
+#define DEBUG_TO_E9    1
+#define DEBUG_TO_SERIAL        1
+#define        SERIAL_PORT     0x3F8
+#define        GDB_SERIAL_PORT 0x2F8
+
+// === IMPRORTS ===
 #if TRACE_LOCKS
 extern struct sShortSpinlock   glDebug_Lock;
 #endif
-
-// === IMPRORTS ===
 extern int     GetCPUNum(void);
 
 // === PROTOTYPES ==
 Uint64 __udivdi3(Uint64 Num, Uint64 Den);
 Uint64 __umoddi3(Uint64 Num, Uint64 Den);
 
+// === GLOBALS ===
+ int   gbDebug_SerialSetup = 0;
+ int   gbGDB_SerialSetup = 0;
+
 // === CODE ===
 /**
  * \brief Determine if a short spinlock is locked
@@ -158,6 +166,69 @@ void SHORTREL(struct sShortSpinlock *Lock)
        #endif
 }
 
+// === DEBUG IO ===
+#if USE_GDB_STUB
+int putDebugChar(char ch)
+{
+       if(!gbGDB_SerialSetup) {
+               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(GDB_SERIAL_PORT + 1, 0x00);    //  (base is         (hi byte)
+               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit (8N1)
+               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(GDB_SERIAL_PORT + 5) & 0x20) == 0 );
+       outb(GDB_SERIAL_PORT, ch);
+       return 0;
+}
+int getDebugChar(void)
+{
+       if(!gbGDB_SerialSetup) {
+               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(GDB_SERIAL_PORT + 1, 0x00);    //                   (hi byte)
+               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(GDB_SERIAL_PORT + 5) & 1) == 0)     ;
+       return inb(GDB_SERIAL_PORT);
+}
+#endif /* USE_GDB_STUB */
+
+void Debug_PutCharDebug(char ch)
+{
+       #if DEBUG_TO_E9
+       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
+       #endif
+       
+       #if DEBUG_TO_SERIAL
+       if(!gbDebug_SerialSetup) {
+               outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(SERIAL_PORT + 1, 0x00);    //                   (hi byte)
+               outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
+       outb(SERIAL_PORT, ch);
+       #endif
+}
+
+void Debug_PutStringDebug(const char *String)
+{
+       while(*String)
+               Debug_PutCharDebug(*String++);
+}
+
 // === IO Commands ===
 void outb(Uint16 Port, Uint8 Data)
 {
index 87dcd61..944b24d 100644 (file)
@@ -74,6 +74,10 @@ SchedulerBase:
        push fs
        push gs
        
+       pushf
+       and BYTE [esp+1], 0xFE  ; Clear Trap Flag
+       popf
+       
        mov eax, dr0
        push eax        ; Debug Register 0, Current Thread
        
@@ -121,7 +125,7 @@ scheduler_return:   ; Used by some hackery in Proc_DumpThreadCPUState
        pop ds
        
        popa
-       add esp, 4      ; CPU ID
+       add esp, 4*2    ; CPU ID + Dummy error code
        ; No Error code / int num
        iret
 
@@ -142,9 +146,10 @@ SpawnTask:
        ; In child, so now set up stack frame
        mov ebx, [esp+4]        ; Child Function
        mov edx, [esp+8]        ; Argument
-       ; Child
+       ; Child Function
        push edx        ; Argument
        call ebx        ; Function
+       ; Kill thread once done
        push eax        ; Exit Code
        push   0        ; Kill this thread
        call Threads_Exit       ; Kill Thread
@@ -237,7 +242,7 @@ Proc_ReturnToUser:
 .justKillIt:
        xor eax, eax
        xor ebx, ebx
-       dec ebx
+       dec ebx ; EBX = -1
        int 0xAC
 
 [global GetCPUNum]
@@ -249,6 +254,15 @@ GetCPUNum: ; TODO: Store in debug registers
        mov eax, dr1
        ret
 
+[extern GetEIP]
+[global GetEIP_Sched]
+[global GetEIP_Sched_ret]
+GetEIP_Sched_ret equ GetEIP_Sched.ret
+GetEIP_Sched:
+       call GetEIP
+GetEIP_Sched.ret:
+       ret
+
 ; Usermode code exported by the kernel
 [section .usertext]
 ; Export a place for the user to jump to to call a syscall
index a85b0ca..ea8f8ad 100644 (file)
@@ -13,7 +13,7 @@
 #endif
 
 // === FLAGS ===
-#define DEBUG_TRACE_SWITCH     0
+#define DEBUG_TRACE_SWITCH     1
 #define DEBUG_DISABLE_DOUBLEFAULT      1
 
 // === CONSTANTS ===
@@ -40,6 +40,7 @@ extern tIDT   gIDT[];
 extern void APWait(void);      // 16-bit AP pause code
 extern void APStartup(void);   // 16-bit AP startup code
 extern Uint    GetEIP(void);   // start.asm
+extern Uint    GetEIP_Sched(void);     // proc.asm
 extern int     GetCPUNum(void);        // start.asm
 extern Uint32  gaInitPageDir[1024];    // start.asm
 extern char    Kernel_Stack_Top[];
@@ -51,6 +52,8 @@ extern void   Isr8(void);     // Double Fault
 extern void    Proc_ReturnToUser(tVAddr Handler, Uint Argument, tVAddr KernelStack);
 extern void    scheduler_return;       // Return address in SchedulerBase
 extern void    IRQCommon;      // Common IRQ handler code
+extern void    IRQCommon_handled;      // IRQCommon call return location
+extern void    GetEIP_Sched_ret;       // GetEIP call return location
 
 // === PROTOTYPES ===
 void   ArchThreads_Init(void);
@@ -289,7 +292,6 @@ void ArchThreads_Init(void)
        #else
        giNumCPUs = 1;
        gTSSs = &gTSS0;
-       MM_FinishVirtualInit();
        #endif
        
        #if !DEBUG_DISABLE_DOUBLEFAULT
@@ -621,7 +623,7 @@ int Proc_Clone(Uint *Err, Uint Flags)
        newThread->SavedState.EBP = ebp;
        eip = GetEIP();
        if(eip == SWITCH_MAGIC) {
-               __asm__ __volatile__ ("mov %0, %%db0" : : "r" (newThread) );
+               //__asm__ __volatile__ ("mov %0, %%db0" : : "r" (newThread) );
                #if USE_MP
                // ACK the interrupt
                if( GetCPUNum() )
@@ -674,7 +676,7 @@ int Proc_SpawnWorker(void)
        new->SavedState.EBP = ebp;
        eip = GetEIP();
        if(eip == SWITCH_MAGIC) {
-               __asm__ __volatile__ ("mov %0, %%db0" : : "r"(new));
+               //__asm__ __volatile__ ("mov %0, %%db0" : : "r"(new));
                #if USE_MP
                // ACK the interrupt
                if(GetCPUNum())
@@ -855,11 +857,40 @@ void Proc_CallFaultHandler(tThread *Thread)
 
 void Proc_DumpThreadCPUState(tThread *Thread)
 {
-       Uint32  *stack = (void *)Thread->SavedState.EBP;        // EBP = ESP after call and PUSH
-       
        if( Thread->CurCPU > -1 )
        {
-               Log("  Currently running");
+                int    maxBacktraceDistance = 6;
+               tRegs   *regs = NULL;
+               Uint32  *stack;
+               
+               if( Thread->CurCPU != GetCPUNum() ) {
+                       Log("  Currently running");
+                       return ;
+               }
+               
+               // Backtrace to find the IRQ entrypoint
+               // - This will usually only be called by an IRQ, so this should
+               //   work
+               __asm__ __volatile__ ("mov %%ebp, %0" : "=r" (stack));
+               while( maxBacktraceDistance -- )
+               {
+                       // [ebp] = oldEbp
+                       // [ebp+4] = retaddr
+                       
+                       if( stack[1] == (tVAddr)&IRQCommon_handled ) {
+                               regs = (void*)stack[2];
+                               break;
+                       }
+                       
+                       stack = (void*)stack[0];
+               }
+               
+               if( !regs ) {
+                       Log("  Unable to find IRQ Entry");
+                       return ;
+               }
+               
+               Log("  at %04x:%08x", regs->cs, regs->eip);
                return ;
        }
        
@@ -870,25 +901,25 @@ void Proc_DumpThreadCPUState(tThread *Thread)
        
        if( diffFromClone > 0 && diffFromClone < 512 )  // When I last checked, GetEIP was at .+0x183
        {
-               // Just spawned full thread
                Log("  Creating full thread");
                return ;
        }
        
        if( diffFromSpawn > 0 && diffFromSpawn < 512 )  // When I last checked, GetEIP was at .+0x99
        {
-               // Just spawned worker thread
                Log("  Creating worker thread");
                return ;
        }
        
        if( diffFromScheduler > 0 && diffFromScheduler < 256 )  // When I last checked, GetEIP was at .+0x60
        #else
-       if( stack[1] == (Uint32)&IRQCommon + 25 )
+       Uint32  data[3];
+       MM_ReadFromAddrSpace(Thread->MemState.CR3, Thread->SavedState.EBP, data, 12);
+       if( data[1] == (Uint32)&IRQCommon + 25 )
        {
-               tRegs   *regs = (void *) stack[2];
+               tRegs   *regs = (void *) data[2];
                Log("  oldebp = 0x%08x, ret = 0x%08x, regs = 0x%x",
-                       stack[0], stack[1], stack[2]
+                       data[0], data[1], data[2]
                        );
                // [EBP] = old EBP
                // [EBP+0x04] = Return Addr
@@ -901,19 +932,11 @@ void Proc_DumpThreadCPUState(tThread *Thread)
        #endif
        {
                // Scheduled out
-               tRegs   *regs = (void *) &stack[4];
-               Log("  oldebp = 0x%08x, ret = 0x%08x, cpu = %i, thread = 0x%x",
-                       stack[0], stack[1], stack[2], stack[3]);
-               // [EBP] = old EBP
-               // [EBP+0x04] = Return Addr
-               // [EBP+0x08] = Arg 1 (CPU Number)
-               // [EBP+0x0C] = Arg 2 (Thread)
-               // [EBP+0x10] = GS (start of tRegs)
-               Log("  At %02x:%08x", regs->cs, regs->eip);
+               Log("  At %04x:%08x", Thread->SavedState.UserCS, Thread->SavedState.UserEIP);
                return ;
        }
        
-       Log("  Just created");
+       Log("  Just created (unknow %p)", Thread->SavedState.EIP);
 }
 
 /**
@@ -935,8 +958,13 @@ void Proc_Scheduler(int CPU)
        thread = gCurrentThread;
        #endif
        
+       // NOTE:
+       // 2011-04-05
+       // Bug may be caused by DR0 not being maintained somewhere, hence 
+       // login is getting loaded with the idle state.
        if( thread )
        {
+               tRegs   *regs;
                // Reduce remaining quantum and continue timeslice if non-zero
                if( thread->Remaining-- )
                        return;
@@ -953,6 +981,18 @@ void Proc_Scheduler(int CPU)
                thread->SavedState.ESP = esp;
                thread->SavedState.EBP = ebp;
                thread->SavedState.EIP = eip;
+               
+               // TODO: Make this more stable somehow
+               regs = (tRegs*)(ebp+(2+2)*4);   // EBP,Ret + CPU,CurThread
+               thread->SavedState.UserCS = regs->cs;
+               thread->SavedState.UserEIP = regs->eip;
+               
+               if(thread->bInstrTrace) {
+                       regs->eflags |= 0x100;  // Set TF
+                       Log("%p De-scheduled", thread);
+               }
+               else
+                       regs->eflags &= ~0x100; // Clear TF
        }
        
        // Get next thread to run
@@ -997,18 +1037,26 @@ void Proc_Scheduler(int CPU)
        }
        #endif
        
+       if( thread->bInstrTrace ) {
+               Log("%p Scheduled", thread);
+       }
+       
        #if USE_PAE
        # error "Todo: Implement PAE Address space switching"
        #else
+       // Set thread pointer
+       __asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(thread) );
        // Switch threads
        __asm__ __volatile__ (
                "mov %4, %%cr3\n\t"     // Set address space
                "mov %1, %%esp\n\t"     // Restore ESP
                "mov %2, %%ebp\n\t"     // and EBP
+               "or %5, 72(%%ebp)\n\t"  // or trace flag to eflags (2+2+4+8+2)*4
                "jmp *%3" : :   // And return to where we saved state (Proc_Clone or Proc_Scheduler)
                "a"(SWITCH_MAGIC), "b"(thread->SavedState.ESP),
                "d"(thread->SavedState.EBP), "c"(thread->SavedState.EIP),
-               "r"(thread->MemState.CR3)
+               "r"(thread->MemState.CR3),
+               "r"(thread->bInstrTrace&&thread->SavedState.EIP==(Uint)&GetEIP_Sched_ret?0x100:0)
                );
        #endif
        for(;;);        // Shouldn't reach here
index da9955c..7402bda 100644 (file)
@@ -3,10 +3,19 @@
 #include <acess.h>
 #include <arch.h>
 
+#define DEBUG_TO_E9    1
+#define DEBUG_TO_SERIAL        1
+#define        SERIAL_PORT     0x3F8
+#define        GDB_SERIAL_PORT 0x2F8
+
 // === IMPORTS ===
 extern int     GetCPUNum(void);
 extern void    *Proc_GetCurThread(void);
 
+// === GLOBALS ===
+ int   gbDebug_SerialSetup = 0;
+ int   gbGDB_SerialSetup = 0;
+
 // === CODE ===
 /**
  * \brief Determine if a short spinlock is locked
@@ -131,6 +140,62 @@ void SHORTREL(struct sShortSpinlock *Lock)
        #endif
 }
 
+// === DEBUG IO ===
+int putDebugChar(char ch)
+{
+       if(!gbGDB_SerialSetup) {
+               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(GDB_SERIAL_PORT + 1, 0x00);    //  (base is         (hi byte)
+               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit (8N1)
+               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(GDB_SERIAL_PORT + 5) & 0x20) == 0 );
+       outb(GDB_SERIAL_PORT, ch);
+       return 0;
+}
+int getDebugChar(void)
+{
+       if(!gbGDB_SerialSetup) {
+               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(GDB_SERIAL_PORT + 1, 0x00);    //                   (hi byte)
+               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(GDB_SERIAL_PORT + 5) & 1) == 0)     ;
+       return inb(GDB_SERIAL_PORT);
+}
+
+void Debug_PutCharDebug(char ch)
+{
+       #if DEBUG_TO_E9
+       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
+       #endif
+       
+       #if DEBUG_TO_SERIAL
+       if(!gbDebug_SerialSetup) {
+               outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
+               outb(SERIAL_PORT + 1, 0x00);    //                   (hi byte)
+               outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               gbDebug_SerialSetup = 1;
+       }
+       while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
+       outb(SERIAL_PORT, ch);
+       #endif
+}
+
+// === PORT IO ===
 void outb(Uint16 Port, Uint8 Data)
 {
        __asm__ __volatile__ ("outb %%al, %%dx"::"d"(Port),"a"(Data));
index f59704a..57964bd 100644 (file)
@@ -7,10 +7,6 @@
 #include <acess.h>
 #include <stdarg.h>
 
-#define DEBUG_TO_E9    1
-#define DEBUG_TO_SERIAL        1
-#define        SERIAL_PORT     0x3F8
-#define        GDB_SERIAL_PORT 0x2F8
 #define        DEBUG_MAX_LINE_LEN      256
 
 #define        LOCK_DEBUG_OUTPUT       1
@@ -21,8 +17,6 @@ extern void   KernelPanic_SetMode(void);
 extern void    KernelPanic_PutChar(char Ch);
 
 // === PROTOTYPES ===
- int   putDebugChar(char ch);
- int   getDebugChar(void);
 static void    Debug_Putchar(char ch);
 static void    Debug_Puts(int DbgOnly, const char *Str);
 void   Debug_DbgOnlyFmt(const char *format, va_list args);
@@ -33,8 +27,6 @@ void  Debug_SetKTerminal(const char *File);
 // === GLOBALS ===
  int   gDebug_Level = 0;
  int   giDebug_KTerm = -1;
- int   gbDebug_SerialSetup = 0;
- int   gbGDB_SerialSetup = 0;
  int   gbDebug_IsKPanic = 0;
 volatile int   gbInPutChar = 0;
 #if LOCK_DEBUG_OUTPUT
@@ -42,60 +34,6 @@ tShortSpinlock       glDebug_Lock;
 #endif
 
 // === CODE ===
-int putDebugChar(char ch)
-{
-       if(!gbGDB_SerialSetup) {
-               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
-               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
-               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
-               outb(GDB_SERIAL_PORT + 1, 0x00);    //  (base is         (hi byte)
-               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit (8N1)
-               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
-               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
-               gbDebug_SerialSetup = 1;
-       }
-       while( (inb(GDB_SERIAL_PORT + 5) & 0x20) == 0 );
-       outb(GDB_SERIAL_PORT, ch);
-       return 0;
-}
-int getDebugChar(void)
-{
-       if(!gbGDB_SerialSetup) {
-               outb(GDB_SERIAL_PORT + 1, 0x00);    // Disable all interrupts
-               outb(GDB_SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
-               outb(GDB_SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
-               outb(GDB_SERIAL_PORT + 1, 0x00);    //                   (hi byte)
-               outb(GDB_SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
-               outb(GDB_SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
-               outb(GDB_SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
-               gbDebug_SerialSetup = 1;
-       }
-       while( (inb(GDB_SERIAL_PORT + 5) & 1) == 0)     ;
-       return inb(GDB_SERIAL_PORT);
-}
-
-static void Debug_PutCharDebug(char ch)
-{
-       #if DEBUG_TO_E9
-       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
-       #endif
-       
-       #if DEBUG_TO_SERIAL
-       if(!gbDebug_SerialSetup) {
-               outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
-               outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
-               outb(SERIAL_PORT + 0, 0x0C);    // Set divisor to 12 (lo byte) 9600 baud
-               outb(SERIAL_PORT + 1, 0x00);    //                   (hi byte)
-               outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
-               outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
-               outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
-               gbDebug_SerialSetup = 1;
-       }
-       while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
-       outb(SERIAL_PORT, ch);
-       #endif
-}
-
 static void Debug_Putchar(char ch)
 {      
        Debug_PutCharDebug(ch);
@@ -114,18 +52,18 @@ static void Debug_Putchar(char ch)
 static void Debug_Puts(int UseKTerm, const char *Str)
 {
         int    len = 0;
-       while( *Str )
-       {
-               Debug_PutCharDebug( *Str );
-               
-               if( gbDebug_IsKPanic )
-                       KernelPanic_PutChar(*Str);
-               len ++;
-               Str ++;
-       }
        
-       Str -= len;
+       Debug_PutStringDebug(Str);
+       
+       if( gbDebug_IsKPanic )
+       {               
+               for( len = 0; Str[len]; len ++ )
+                       KernelPanic_PutChar( Str[len] );
+       }
+       else
+               for( len = 0; Str[len]; len ++ );
        
+       // Output to the kernel terminal
        if( UseKTerm && !gbDebug_IsKPanic && giDebug_KTerm != -1)
        {
                if(gbInPutChar) return ;
@@ -196,7 +134,7 @@ void LogF(const char *Fmt, ...)
 }
 /**
  * \fn void Debug(const char *Msg, ...)
- * \brief Print only to the debug channel
+ * \brief Print only to the debug channel (not KTerm)
  */
 void Debug(const char *Fmt, ...)
 {
index 07e07f5..b67c8e3 100644 (file)
@@ -14,8 +14,9 @@
 #define        USE_KERNEL_MAGIC        1
 
 // === IMPORTS ===
-void   Threads_Dump(void);
-void   Heap_Stats(void);
+extern void    Threads_ToggleTrace(int TID);
+extern void    Threads_Dump(void);
+extern void    Heap_Stats(void);
 
 // === PROTOTYPES ===
  int   KB_Install(char **Arguments);
@@ -191,12 +192,19 @@ void KB_IRQHandler(int IRQNum)
                case '8':       case '9':       case 'a':       case 'b':
                case 'c':       case 'd':       case 'e':       case 'f':
                        {
-                       char    str[2] = {ch,0};
-                       if(giKB_MagicAddressPos == BITS/4)      break;
+                       char    str[4] = {'0', 'x', ch, 0};
+                       if(giKB_MagicAddressPos == BITS/4)      return;
                        giKB_MagicAddress |= atoi(str) << giKB_MagicAddressPos;
                        giKB_MagicAddressPos ++;
                        }
-                       break;
+                       return;
+               
+               // Instruction Tracing
+               case 't':
+                       Log("Toggle instruction tracing on %i\n", giKB_MagicAddress);
+                       Threads_ToggleTrace( giKB_MagicAddress );
+                       giKB_MagicAddress = 0;  giKB_MagicAddressPos = 0;
+                       return;
                
                // Thread List Dump
                case 'p':       Threads_Dump(); return;
@@ -208,10 +216,10 @@ void KB_IRQHandler(int IRQNum)
        }
        #endif
 
-       // Is shift pressed
-       // - Darn ugly hacks !!x means (bool)x
-       if( !!gbKB_ShiftState ^ gbKB_CapsState)
+       // Capitals required?
+       if( (gbKB_ShiftState != 0) != (gbKB_CapsState != 0))
        {
+               // TODO: Move this to the keyboard map header
                switch(ch)
                {
                case 0: break;
index c0ce6ed..0d1ae52 100644 (file)
@@ -155,10 +155,10 @@ int SysFS_RegisterFile(const char *Path, const char *Data, int Length)
                        child->Node.ReadDir = SysFS_Comm_ReadDir;
                        child->Node.FindDir = SysFS_Comm_FindDir;
                        if( !prev ) {
-                               //if(ent)
+                               if(ent)
                                        ent->Node.ImplPtr = child;
-                               //else
-                               //      gSysFS_DriverInfo.RootNode.ImplPtr = child;
+                               else
+                                       gSysFS_DriverInfo.RootNode.ImplPtr = child;
                                // ^^^ Impossible (There is already /Version)
                        }
                        else
@@ -184,7 +184,7 @@ int SysFS_RegisterFile(const char *Path, const char *Data, int Length)
                child = ent->Node.ImplPtr;
        else
                child = gSysFS_DriverInfo.RootNode.ImplPtr;
-       for( child = ent->Node.ImplPtr; child; prev = child, child = child->Next )
+       for( ; child; child = child->Next )
        {
                if( strcmp( &Path[start], child->Name ) == 0 )
                        break;
@@ -283,7 +283,10 @@ int SysFS_RemoveFile(int ID)
        parent = file->Parent;
        
        // Remove from file list
-       prev->ListNext = file->ListNext;
+       if(prev)
+               prev->ListNext = file->ListNext;
+       else
+               gSysFS_FileList = file->ListNext;
        file->Node.Size = 0;
        file->Node.ImplPtr = NULL;
        
index 31e7a50..ec5c1f5 100644 (file)
@@ -11,7 +11,7 @@
 #include <errno.h>
 #include <semaphore.h>
 
-#define        USE_CTRL_ALT    0
+#define        USE_CTRL_ALT    1
 
 // === CONSTANTS ===
 #define VERSION        ((0<<8)|(50))
@@ -57,7 +57,7 @@ typedef struct {
         int    InputRead;      //!< Input buffer read position
         int    InputWrite;     //!< Input buffer write position
        char    InputBuffer[MAX_INPUT_CHARS8];
-       tSemaphore      InputSemaphore;
+//     tSemaphore      InputSemaphore;
        
        tVT_Char        *Text;
        Uint32          *Buffer;
@@ -160,10 +160,12 @@ int VT_Install(char **Arguments)
                        Log_Debug("VTerm", "Argument '%s'", arg);
                        
                        if( strcmp(opt, "Video") == 0 ) {
-                               gsVT_OutputDevice = strdup(val);
+                               if( !gsVT_OutputDevice && Modules_InitialiseBuiltin( val ) == 0 )
+                                       gsVT_OutputDevice = strdup(val);
                        }
                        else if( strcmp(opt, "Input") == 0 ) {
-                               gsVT_InputDevice = strdup(val);
+                               if( !gsVT_InputDevice && Modules_InitialiseBuiltin( val ) == 0 )
+                                       gsVT_InputDevice = strdup(val);
                        }
                        else if( strcmp(opt, "Width") == 0 ) {
                                giVT_RealWidth = atoi( val );
@@ -177,9 +179,6 @@ int VT_Install(char **Arguments)
                }
        }
        
-       if(gsVT_OutputDevice)   Modules_InitialiseBuiltin( gsVT_OutputDevice );
-       if(gsVT_InputDevice)    Modules_InitialiseBuiltin( gsVT_InputDevice );
-       
        // Apply Defaults
        if(!gsVT_OutputDevice)  gsVT_OutputDevice = strdup(DEFAULT_OUTPUT);
        if(!gsVT_InputDevice)   gsVT_InputDevice = strdup(DEFAULT_INPUT);
@@ -223,7 +222,7 @@ int VT_Install(char **Arguments)
                gVT_Terminals[i].Node.Read = VT_Read;
                gVT_Terminals[i].Node.Write = VT_Write;
                gVT_Terminals[i].Node.IOCtl = VT_Terminal_IOCtl;
-               Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name);
+//             Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name);
        }
        
        // Add to DevFS
@@ -313,6 +312,9 @@ void VT_SetResolution(int Width, int Height)
                {
                        if( gVT_Terminals[i].Mode != TERM_MODE_TEXT )   continue;
                        
+                       gVT_Terminals[i].TextWidth = giVT_RealWidth/giVT_CharWidth;
+                       gVT_Terminals[i].TextHeight = giVT_RealHeight/giVT_CharHeight;
+                       
                        gVT_Terminals[i].Text = realloc(
                                gVT_Terminals[i].Text,
                                newBufSize*sizeof(tVT_Char)
@@ -735,7 +737,7 @@ void VT_KBCallBack(Uint32 Codepoint)
                #else
                case KEY_LALT:  gbVT_AltDown &= ~1;     break;
                case KEY_RALT:  gbVT_AltDown &= ~2;     break;
-               case KEY_LCTRL: gbVT_CtrlDown &= ~1     break;
+               case KEY_LCTRL: gbVT_CtrlDown &= ~1;    break;
                case KEY_RCTRL: gbVT_CtrlDown &= ~2;    break;
                #endif
                }
@@ -1101,6 +1103,9 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
        default:
                Term->Text[ Term->WritePos ].Ch = Ch;
                Term->Text[ Term->WritePos ].Colour = Term->CurColour;
+               // Update the line before wrapping
+               if( (Term->WritePos + 1) % Term->TextWidth == 0 )
+                       VT_int_UpdateScreen( Term, 0 );
                Term->WritePos ++;
                break;
        }
@@ -1146,7 +1151,7 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
        {
                //Debug("Term->WritePos (%i) >= %i",
                //      Term->WritePos,
-               //      Term->ViewPos + Term->Width*Term->Height
+               //      Term->ViewPos + Term->TextWidth*Term->TextHeight
                //      );
                //Debug("Scrolling screen only");
                
@@ -1161,6 +1166,8 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
                //Debug("Term->ViewPos = %i", Term->ViewPos);
                VT_int_ScrollFramebuffer( Term );
                VT_int_UpdateScreen( Term, 0 );
+               
+               //VT_int_UpdateScreen( Term, 1 );       // HACK!
        }
        
        //LEAVE('-');
index bac7894..a96e222 100644 (file)
@@ -57,7 +57,7 @@ Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
                        break;
                
                case VIDEO_2DOP_BLIT:
-                       if(rem < 16)    return Length-rem;
+                       if(rem < 12)    return Length-rem;
                        
                        if(!Handlers->Blit) {
                                Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
@@ -73,7 +73,7 @@ Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
                                );
                        
                        rem -= 16;
-                       stream = (void*)((tVAddr)stream + 16);
+                       stream = (void*)((tVAddr)stream + 12);
                        break;
                
                }
index c440b18..07a3aad 100644 (file)
@@ -664,8 +664,8 @@ void Heap_Stats(void)
                
                // Print the block info?
                #if 1
-               Log_Debug("Heap", "%p - 0x%x (%i) Owned by %s:%i",
-                       head, head->Size, head->ValidSize, head->File, head->Line);
+               Log_Debug("Heap", "%p (0x%x) - 0x%x (%i) Owned by %s:%i",
+                       head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size, head->ValidSize, head->File, head->Line);
                #endif
        }
 
index a2d406b..79c5062 100644 (file)
@@ -22,15 +22,6 @@ typedef Uint tGID;
 typedef Sint64 tTimestamp;
 typedef Sint64 tTime;
 typedef struct sShortSpinlock  tShortSpinlock;
-typedef struct sMutex  tMutex;
-
-struct sMutex {
-       tShortSpinlock  Protector;      //!< Protector for the lock strucure
-       const char      *Name;  //!< Human-readable name
-       struct sThread  *volatile Owner;        //!< Owner of the lock (set upon getting the lock)
-       struct sThread  *Waiting;       //!< Waiting threads
-       struct sThread  *LastWaiting;   //!< Waiting threads
-};
 
 // --- Helper Macros ---
 /**
@@ -337,8 +328,7 @@ extern char *strncpy(char *__dest, const char *__src, size_t max);
 extern int     strcmp(const char *__str1, const char *__str2);
 extern int     strncmp(const char *Str1, const char *Str2, size_t num);
 extern int     strucmp(const char *Str1, const char *Str2);
-//extern char  *strdup(const char *Str);
-#define strdup(Str)    _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str))
+// strdup macro is defined in heap.h
 extern char    *_strdup(const char *File, int Line, const char *Str);
 extern char    **str_split(const char *__str, char __ch);
 extern char    *strchr(const char *__s, int __c);
@@ -428,9 +418,6 @@ extern tGID Threads_GetGID(void);
 extern int     SpawnTask(tThreadFunction Function, void *Arg);
 extern Uint    *Threads_GetCfgPtr(int Id);
 extern int     Threads_SetName(const char *NewName);
-extern int     Mutex_Acquire(tMutex *Mutex);
-extern void    Mutex_Release(tMutex *Mutex);
-extern int     Mutex_IsLocked(tMutex *Mutex);
 /**
  * \}
  */
@@ -441,5 +428,6 @@ extern int  DivUp(int num, int dem);
 #include <binary_ext.h>
 #include <vfs_ext.h>
 #include <adt.h>
+#include <mutex.h>
 
 #endif
index 28d33c0..b058e8b 100644 (file)
@@ -20,4 +20,6 @@ extern void   Heap_Validate(void);
 #define        free(ptr)       Heap_Deallocate((ptr))
 #define IsHeap(ptr)    Heap_IsHeapAddr((ptr))
 
+#define strdup(Str)    _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str))
+
 #endif
diff --git a/Kernel/include/mutex.h b/Kernel/include/mutex.h
new file mode 100644 (file)
index 0000000..326dbd2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Acess2 Kernel
+ * mutex.h
+ * - Mutual Exclusion syncronisation primitive
+ */
+#ifndef _MUTEX_H
+#define _MUTEX_H
+
+#include <acess.h>
+
+typedef struct sMutex  tMutex;
+
+struct sMutex
+{
+       tShortSpinlock  Protector;      //!< Protector for the lock strucure
+       const char      *Name;  //!< Human-readable name
+       struct sThread  *volatile Owner;        //!< Owner of the lock (set upon getting the lock)
+       struct sThread  *Waiting;       //!< Waiting threads
+       struct sThread  *LastWaiting;   //!< Waiting threads
+};
+
+/**
+ * \brief Acquire a heavy mutex
+ * \param Mutex        Mutex to acquire
+ * \return zero on success, -1 if terminated
+ * 
+ * This type of mutex checks if the mutex is avaliable, and acquires it
+ * if it is. Otherwise, the current thread is added to the mutex's wait
+ * queue and the thread suspends. When the holder of the mutex completes,
+ * the oldest thread (top thread) on the queue is given the lock and
+ * restarted.
+ */
+extern int     Mutex_Acquire(tMutex *Mutex);
+
+/**
+ * \brief Release a held mutex
+ * \param Mutex        Mutex to release
+ * \note Releasing a non-held mutex has no effect
+ */
+extern void    Mutex_Release(tMutex *Mutex);
+
+/**
+ * \brief Is this mutex locked?
+ * \param Mutex        Mutex pointer
+ */
+extern int     Mutex_IsLocked(tMutex *Mutex);
+
+#endif
index b483830..7a8cbde 100644 (file)
@@ -59,6 +59,7 @@ void  Threads_Sleep(void);
 void   Threads_AddActive(tThread *Thread);
 tThread        *Threads_RemActive(void);
 #endif
+void   Threads_ToggleTrace(int TID);
 void   Threads_Fault(int Num);
 void   Threads_SegFault(tVAddr Addr);
 #if 0
@@ -71,7 +72,6 @@ tGID  Threads_GetGID(void);
 #endif
 void   Threads_Dump(void);
 void   Threads_DumpActive(void);
-
 #if 0
  int   Mutex_Acquire(tMutex *Mutex);
 void   Mutex_Release(tMutex *Mutex);
@@ -122,6 +122,9 @@ void Threads_Init(void)
 {
        ArchThreads_Init();
        
+       Log_Debug("Threads", "Offsets of tThread");
+       Log_Debug("Threads", ".Priority = %i", offsetof(tThread, Priority));
+       
        // Create Initial Task
        #if SCHEDULER_TYPE == SCHED_RR_PRI
        gaActiveThreads[gThreadZero.Priority] = &gThreadZero;
@@ -184,6 +187,7 @@ void Threads_SetPriority(tThread *Thread, int Pri)
        if(Thread == NULL)      Thread = Proc_GetCurThread();
        // Bounds checking
        // - If < 0, set to lowest priority
+       // - Minumum priority is actualy a high number, 0 is highest
        if(Pri < 0)     Pri = MIN_PRIORITY;
        if(Pri > MIN_PRIORITY)  Pri = MIN_PRIORITY;
        
@@ -208,7 +212,9 @@ void Threads_SetPriority(tThread *Thread, int Pri)
                #if SCHEDULER_TYPE == SCHED_LOTTERY
                giFreeTickets -= caiTICKET_COUNTS[Thread->Priority] - caiTICKET_COUNTS[Pri];
                # if DEBUG_TRACE_TICKETS
-               Log("Threads_SetTickets: new giFreeTickets = %i", giFreeTickets);
+               Log("Threads_SetTickets: new giFreeTickets = %i [-%i+%i]",
+                       giFreeTickets,
+                       caiTICKET_COUNTS[Thread->Priority], caiTICKET_COUNTS[Pri]);
                # endif
                #endif
                Thread->Priority = Pri;
@@ -217,6 +223,12 @@ void Threads_SetPriority(tThread *Thread, int Pri)
        else
                Thread->Priority = Pri;
        #endif
+       
+       #if DEBUG_TRACE_STATE
+       Log("Threads_SetPriority: %p(%i %s) pri set %i",
+               Thread, Thread->TID, Thread->ThreadName,
+               Pri);
+       #endif
 }
 
 /**
@@ -233,10 +245,7 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
        
        // Allocate and duplicate
        new = malloc(sizeof(tThread));
-       if(new == NULL) {
-               *Err = -ENOMEM;
-               return NULL;
-       }
+       if(new == NULL) { *Err = -ENOMEM; return NULL; }
        memcpy(new, cur, sizeof(tThread));
        
        new->CurCPU = -1;
@@ -248,6 +257,7 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
        // Get Thread ID
        new->TID = giNextTID++;
        new->Parent = cur;
+       new->bInstrTrace = 0;
        
        // Clone Name
        new->ThreadName = strdup(cur->ThreadName);
@@ -334,6 +344,7 @@ tThread *Threads_CloneThreadZero(void)
        // Set State
        new->Remaining = new->Quantum = cur->Quantum;
        new->Priority = cur->Priority;
+       new->bInstrTrace = 0;
        
        // Set Signal Handlers
        new->CurFaultNum = 0;
@@ -772,6 +783,13 @@ int Threads_WakeTID(tTID TID)
        return ret;
 }
 
+void Threads_ToggleTrace(int TID)
+{
+       tThread *thread = Threads_GetThread(TID);
+       if(!thread)     return ;
+       thread->bInstrTrace = !thread->bInstrTrace;
+}
+
 /**
  * \brief Adds a thread to the active queue
  */
@@ -987,6 +1005,8 @@ void Threads_DumpActive(void)
                                Log("  ERROR State (%i) != THREAD_STAT_ACTIVE (%i)", thread->Status, THREAD_STAT_ACTIVE);
                        Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
                        Log("  KStack 0x%x", thread->KernelStack);
+                       if( thread->bInstrTrace )
+                               Log("  Tracing Enabled");
                        Proc_DumpThreadCPUState(thread);
                }
        
@@ -1031,6 +1051,9 @@ void Threads_Dump(void)
                }
                Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
                Log("  KStack 0x%x", thread->KernelStack);
+               if( thread->bInstrTrace )
+                       Log("  Tracing Enabled");
+               Proc_DumpThreadCPUState(thread);
        }
 }
 
@@ -1117,7 +1140,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
                }
                #if SCHEDULER_TYPE == SCHED_LOTTERY && DEBUG_TRACE_TICKETS
                else
-                       LogF("Log: CPU%i released %p (%i %s)->Status = %i (Released)\n",
+                       LogF("Log: CPU%i released %p (%i %s)->Status = %i (Released,not in pool)\n",
                                CPU, Last, Last->TID, Last->ThreadName, Last->Status);
                #endif
                Last->CurCPU = -1;
@@ -1255,16 +1278,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
        return thread;
 }
 
-/**
- * \brief Acquire a heavy mutex
- * \param Mutex        Mutex to acquire
- * 
- * This type of mutex checks if the mutex is avaliable, and acquires it
- * if it is. Otherwise, the current thread is added to the mutex's wait
- * queue and the thread suspends. When the holder of the mutex completes,
- * the oldest thread (top thread) on the queue is given the lock and
- * restarted.
- */
+// Acquire mutex (see mutex.h for documentation)
 int Mutex_Acquire(tMutex *Mutex)
 {
        tThread *us = Proc_GetCurThread();
@@ -1293,6 +1307,12 @@ int Mutex_Acquire(tMutex *Mutex)
                        Mutex->Waiting = us;
                        Mutex->LastWaiting = us;
                }
+               
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) waiting on mutex %p",
+                       us, us->TID, us->ThreadName, Mutex);
+               #endif
+               
                #if 0
                {
                         int    i = 0;
@@ -1324,11 +1344,7 @@ int Mutex_Acquire(tMutex *Mutex)
        return 0;
 }
 
-/**
- * \brief Release a held mutex
- * \param Mutex        Mutex to release
- * \note Releasing a non-held mutex has no effect
- */
+// Release a mutex
 void Mutex_Release(tMutex *Mutex)
 {
        SHORTLOCK( &Mutex->Protector );
@@ -1361,10 +1377,7 @@ void Mutex_Release(tMutex *Mutex)
        #endif
 }
 
-/**
- * \brief Is this mutex locked?
- * \param Mutex        Mutex pointer
- */
+// Check if a mutex is locked
 int Mutex_IsLocked(tMutex *Mutex)
 {
        return Mutex->Owner != NULL;
@@ -1427,6 +1440,12 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                        Sem->LastWaiting = us;
                }
                
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) waiting on semaphore %p %s:%s",
+                       us, us->TID, us->ThreadName,
+                       Sem, Sem->ModName, Sem->Name);
+               #endif
+               
                SHORTREL( &glThreadListLock );  
                SHORTREL( &Sem->Protector );
                while(us->Status == THREAD_STAT_SEMAPHORESLEEP) Threads_Yield();
@@ -1458,6 +1477,13 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                        given = Sem->MaxValue - Sem->Value;
                Sem->Value -= given;
                
+               
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) woken by wait on %p %s:%s",
+                       toWake, toWake->TID, toWake->ThreadName,
+                       Sem, Sem->ModName, Sem->Name);
+               #endif
+               
                // Save the number we gave to the thread's status
                toWake->RetStatus = given;
                
@@ -1514,6 +1540,12 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
                        Sem->LastSignaling = us;
                }
                
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) signaling semaphore %p %s:%s",
+                       us, us->TID, us->ThreadName,
+                       Sem, Sem->ModName, Sem->Name);
+               #endif
+               
                SHORTREL( &glThreadListLock );  
                SHORTREL( &Sem->Protector );
                while(us->Status == THREAD_STAT_SEMAPHORESLEEP) Threads_Yield();
@@ -1542,12 +1574,13 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
        {
                tThread *toWake = Sem->Waiting;
                
+               // Remove thread from list (double ended, so clear LastWaiting if needed)
                Sem->Waiting = Sem->Waiting->Next;
-               // Reset ->LastWaiting to NULL if we have just removed the last waiting thread
                if( Sem->Waiting == NULL )
                        Sem->LastWaiting = NULL;
                
-               // Figure out how much to give
+               // Figure out how much to give to woken thread
+               // - Requested count is stored in ->RetStatus
                if( toWake->RetStatus && Sem->Value > toWake->RetStatus )
                        given = toWake->RetStatus;
                else
@@ -1557,6 +1590,14 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
                // Save the number we gave to the thread's status
                toWake->RetStatus = given;
                
+               if(toWake->bInstrTrace)
+                       Log("%s(%i) given %i from %p", toWake->ThreadName, toWake->TID, given, Sem);
+               #if DEBUG_TRACE_STATE
+               Log("%p (%i %s) woken by signal on %p %s:%s",
+                       toWake, toWake->TID, toWake->ThreadName,
+                       Sem, Sem->ModName, Sem->Name);
+               #endif
+               
                // Wake the sleeper
                SHORTLOCK( &glThreadListLock );
                if( toWake->Status != THREAD_STAT_ACTIVE )
index e9c9f09..4c3c6a2 100644 (file)
@@ -155,7 +155,7 @@ char *Root_ReadDir(tVFS_Node *Node, int Pos)
        
        for( ; child && Pos--; child = child->Next ) ;
        
-       if(Pos) return strdup(child->Name);
+       if(child)       return strdup(child->Name);
        
        return NULL;
 }
index 0820102..600cedc 100644 (file)
@@ -78,7 +78,7 @@ char *VFS_GetAbsPath(const char *Path)
                strcpy(ret, cwd);
                ret[cwdLen] = '/';
                strcpy(&ret[cwdLen+1], Path);
-               //Log("ret = '%s'\n", ret);
+               //Log("ret = '%s'", ret);
        }
        
        // Parse Path
@@ -590,7 +590,7 @@ void VFS_Close(int FD)
        // Get handle
        h = VFS_GetHandle(FD);
        if(h == NULL) {
-               Log_Warning("VFS", "Invalid file handle passed to VFS_Close, 0x%x\n", FD);
+               Log_Warning("VFS", "Invalid file handle passed to VFS_Close, 0x%x", FD);
                return;
        }
        
index 85c7d62..22417c8 100644 (file)
@@ -148,6 +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
        }
        
        // Fill output (modify *Handles)

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