- Mutex->LastWaiting was never reset to NULL, hence could point to
a thread on the active queue, causing corruption.
HEADDESK, HEADDESK, HEADDESK
- Also, fixed lack of LEAVE macros in some parts of binary.c
- Fixed a typo in EXT2 directory handling (write)
// Allow nested spinlocks?
#define STACKED_LOCKS 2 // 0: No, 1: Per-CPU, 2: Per-Thread
// Allow nested spinlocks?
#define STACKED_LOCKS 2 // 0: No, 1: Per-CPU, 2: Per-Thread
-#define LOCK_DISABLE_INTS 0
+#define LOCK_DISABLE_INTS 1
// - Processor/Machine Specific Features
#if ARCH != i386 && ARCH != i486 && ARCH != i586
// - Processor/Machine Specific Features
#if ARCH != i386 && ARCH != i486 && ARCH != i586
argenvBuf = malloc(argenvBytes);
if(argenvBuf == NULL) {
Log_Error("BIN", "Proc_Execve - What the hell? The kernel is out of heap space");
argenvBuf = malloc(argenvBytes);
if(argenvBuf == NULL) {
Log_Error("BIN", "Proc_Execve - What the hell? The kernel is out of heap space");
return 0;
}
strBuf = argenvBuf + (argc+1)*sizeof(void*) + (envc+1)*sizeof(void*);
return 0;
}
strBuf = argenvBuf + (argc+1)*sizeof(void*) + (envc+1)*sizeof(void*);
if(bases[0] == 0)
{
Log_Warning("BIN", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
if(bases[0] == 0)
{
Log_Warning("BIN", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
Threads_Exit(0, 0);
for(;;);
}
Threads_Exit(0, 0);
for(;;);
}
/**
* \fn Uint Binary_Load(char *file, Uint *entryPoint)
/**
* \fn Uint Binary_Load(char *file, Uint *entryPoint)
+ * \brief Load a binary into the current address space
+ * \param file Path to binary to load
+ * \param entryPoint Pointer for exectuable entry point
*/
Uint Binary_Load(char *file, Uint *entryPoint)
{
*/
Uint Binary_Load(char *file, Uint *entryPoint)
{
tBinary *pBinary;
Uint base = -1;
tBinary *pBinary;
Uint base = -1;
+ ENTER("sfile pentryPoint", file, entryPoint);
// Sanity Check Argument
if(file == NULL) {
// Sanity Check Argument
if(file == NULL) {
// Get True File Path
sTruePath = VFS_GetTruePath(file);
// Get True File Path
sTruePath = VFS_GetTruePath(file);
+ LOG("sTruePath = %p", sTruePath);
if(sTruePath == NULL) {
Log_Warning("BIN", "'%s' does not exist.", file);
if(sTruePath == NULL) {
Log_Warning("BIN", "'%s' does not exist.", file);
}
LOG("sTruePath = '%s'", sTruePath);
}
LOG("sTruePath = '%s'", sTruePath);
+
+ // TODO: Also get modifcation time
// Check if the binary has already been loaded
if( !(pBinary = Binary_GetInfo(sTruePath)) )
// Check if the binary has already been loaded
if( !(pBinary = Binary_GetInfo(sTruePath)) )
int Threads_WaitTID(int TID, int *status);
tThread *Threads_GetThread(Uint TID);
void Threads_AddToDelete(tThread *Thread);
int Threads_WaitTID(int TID, int *status);
tThread *Threads_GetThread(Uint TID);
void Threads_AddToDelete(tThread *Thread);
-tThread *Threads_int_GetPrev(tThread **List, tThread *Thread);
+tThread *Threads_int_DelFromQueue(tThread **List, tThread *Thread);
void Threads_Exit(int TID, int Status);
void Threads_Kill(tThread *Thread, int Status);
void Threads_Yield(void);
void Threads_Exit(int TID, int Status);
void Threads_Kill(tThread *Thread, int Status);
void Threads_Yield(void);
tGID Threads_GetGID(void);
int Threads_SetGID(Uint *Errno, tUID ID);
void Threads_Dump(void);
tGID Threads_GetGID(void);
int Threads_SetGID(Uint *Errno, tUID ID);
void Threads_Dump(void);
+void Threads_DumpActive(void);
void Mutex_Acquire(tMutex *Mutex);
void Mutex_Release(tMutex *Mutex);
int Mutex_IsLocked(tMutex *Mutex);
void Mutex_Acquire(tMutex *Mutex);
void Mutex_Release(tMutex *Mutex);
int Mutex_IsLocked(tMutex *Mutex);
- * \brief Gets the previous entry in a thead linked list
+ * \brief Deletes an entry from a list
* \param List Pointer to the list head
* \param Thread Thread to find
* \param List Pointer to the list head
* \param Thread Thread to find
- * \return Thread before \a Thread on \a List
- * \note This uses a massive hack of assuming that the first field in the
- * structure is the .Next pointer. By doing this, we can return \a List
- * as a (tThread*) and simplify other code.
-tThread *Threads_int_GetPrev(tThread **List, tThread *Thread)
+tThread *Threads_int_DelFromQueue(tThread **List, tThread *Thread)
- tThread *ret;
- // First Entry
- if(*List == Thread) {
- return (tThread*)List;
+ tThread *ret, *prev = NULL;
+
+ for(ret = *List;
+ ret && ret != Thread;
+ prev = ret, ret = ret->Next
+ );
+
+ // Is the thread on the list
+ if(!ret) {
+ //LogF("%p(%s) is not on list %p\n", Thread, Thread->ThreadName, List);
+ return NULL;
+ }
+
+ if( !prev ) {
+ *List = Thread->Next;
+ //LogF("%p(%s) removed from head of %p\n", Thread, Thread->ThreadName, List);
- for(ret = *List;
- ret->Next && ret->Next != Thread;
- ret = ret->Next
- );
- // Error if the thread is not on the list
- if(!ret->Next || ret->Next != Thread) {
- return NULL;
- }
+ prev->Next = Thread->Next;
+ //LogF("%p(%s) removed from %p (prev=%p)\n", Thread, Thread->ThreadName, List, prev);
*/
void Threads_Kill(tThread *Thread, int Status)
{
*/
void Threads_Kill(tThread *Thread, int Status)
{
tMsg *msg;
// TODO: Kill all children
tMsg *msg;
// TODO: Kill all children
// Lock thread list
SHORTLOCK( &glThreadListLock );
// Lock thread list
SHORTLOCK( &glThreadListLock );
- // Get previous thread on list
- prev = Threads_int_GetPrev( &gActiveThreads, Thread );
- if(!prev) {
+ // Delete from active list
+ if( !Threads_int_DelFromQueue( &gActiveThreads, Thread ) )
+ {
Warning("Proc_Exit - Current thread is not on the active queue");
SHORTREL( &glThreadListLock );
SHORTREL( &Thread->IsLocked );
Warning("Proc_Exit - Current thread is not on the active queue");
SHORTREL( &glThreadListLock );
SHORTREL( &Thread->IsLocked );
// Ensure that we are not rescheduled
Thread->Remaining = 0; // Clear Remaining Quantum
Thread->Quantum = 0; // Clear Quantum to indicate dead thread
// Ensure that we are not rescheduled
Thread->Remaining = 0; // Clear Remaining Quantum
Thread->Quantum = 0; // Clear Quantum to indicate dead thread
- prev->Next = Thread->Next; // Remove from active
// Update bookkeeping
giNumActiveThreads --;
// Update bookkeeping
giNumActiveThreads --;
*/
int Threads_Wake(tThread *Thread)
{
*/
int Threads_Wake(tThread *Thread)
{
if(!Thread)
return -EINVAL;
if(!Thread)
return -EINVAL;
case THREAD_STAT_SLEEPING:
SHORTLOCK( &glThreadListLock );
// Remove from sleeping queue
case THREAD_STAT_SLEEPING:
SHORTLOCK( &glThreadListLock );
// Remove from sleeping queue
- prev = Threads_int_GetPrev(&gSleepingThreads, Thread);
- prev->Next = Thread->Next;
+ Threads_int_DelFromQueue(&gSleepingThreads, Thread);
Threads_AddActive( Thread );
Threads_AddActive( Thread );
- // Add to active list
- Thread->Next = gActiveThreads;
- gActiveThreads = Thread;
// Set state
Thread->Status = THREAD_STAT_ACTIVE;
Thread->CurCPU = -1;
// Set state
Thread->Status = THREAD_STAT_ACTIVE;
Thread->CurCPU = -1;
+ // Add to active list
+ Thread->Next = gActiveThreads;
+ gActiveThreads = Thread;
// Update bookkeeping
giNumActiveThreads ++;
// Update bookkeeping
giNumActiveThreads ++;
tThread *Threads_RemActive(void)
{
tThread *ret = Proc_GetCurThread();
tThread *Threads_RemActive(void)
{
tThread *ret = Proc_GetCurThread();
SHORTLOCK( &glThreadListLock );
SHORTLOCK( &glThreadListLock );
- prev = Threads_int_GetPrev(&gActiveThreads, ret);
- if(!prev) {
+ // Delete from active queue
+ if( !Threads_int_DelFromQueue(&gActiveThreads, ret) ) {
SHORTREL( &glThreadListLock );
return NULL;
}
SHORTREL( &glThreadListLock );
return NULL;
}
ret->Remaining = 0;
ret->CurCPU = -1;
ret->Remaining = 0;
ret->CurCPU = -1;
- prev->Next = ret->Next;
giNumActiveThreads --;
// no need to decrement tickets, scheduler did it for us
giNumActiveThreads --;
// no need to decrement tickets, scheduler did it for us
if( CPU_HAS_LOCK( &glThreadListLock ) )
return Last;
if( CPU_HAS_LOCK( &glThreadListLock ) )
return Last;
- // Same if the current CPU has any lock
+ // Don't change threads if the current CPU has switches disabled
if( gaThreads_NoTaskSwitch[CPU] )
return Last;
if( gaThreads_NoTaskSwitch[CPU] )
return Last;
}
#if DEBUG_TRACE_TICKETS
else
}
#if DEBUG_TRACE_TICKETS
else
- LogF(" CPU %i released %p (%s)->Status = %i (Released)\n",
- CPU, Last, Last->ThreadName, Last->Status);
+ LogF(" CPU %i released %p (%i %s)->Status = %i (Released)\n",
+ CPU, Last, Last->TID, Last->ThreadName, Last->Status);
#endif
Last->CurCPU = -1;
}
#endif
Last->CurCPU = -1;
}
if( Mutex->Owner ) {
SHORTLOCK( &glThreadListLock );
// - Remove from active list
if( Mutex->Owner ) {
SHORTLOCK( &glThreadListLock );
// - Remove from active list
+ us = Threads_RemActive();
// - Mark as sleeping
us->Status = THREAD_STAT_OFFSLEEP;
// - Mark as sleeping
us->Status = THREAD_STAT_OFFSLEEP;
if( Mutex->Waiting ) {
Mutex->Owner = Mutex->Waiting; // Set owner
Mutex->Waiting = Mutex->Waiting->Next; // Next!
if( Mutex->Waiting ) {
Mutex->Owner = Mutex->Waiting; // Set owner
Mutex->Waiting = Mutex->Waiting->Next; // Next!
+ // Reset ->LastWaiting to NULL if we have just removed the last waiting thread
+ if( Mutex->LastWaiting == Mutex->Owner )
+ Mutex->LastWaiting = NULL;
// Wake new owner
SHORTLOCK( &glThreadListLock );
// Wake new owner
SHORTLOCK( &glThreadListLock );
// === EXPORTS ===
EXPORT(Threads_GetUID);
// === EXPORTS ===
EXPORT(Threads_GetUID);
EXPORT(Mutex_Acquire);
EXPORT(Mutex_Release);
EXPORT(Mutex_IsLocked);
EXPORT(Mutex_Acquire);
EXPORT(Mutex_Release);
EXPORT(Mutex_IsLocked);
BLOCK_DIR_OFS(Node->Data, block) = nEntries;
block ++;
ofs = 0;
BLOCK_DIR_OFS(Node->Data, block) = nEntries;
block ++;
ofs = 0;
- base = Ext2_int_GetBlockAddr(disk, inode.i_blocks, block);
+ base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
}
}
VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
}
}
// Check if a free slot was found
if( bestMatch >= 0 ) {
// Read-Modify-Write
// Check if a free slot was found
if( bestMatch >= 0 ) {
// Read-Modify-Write
- bestBlock = Ext2_int_GetBlockAddr(disk, inode.i_blocks, bestBlock);
+ bestBlock = Ext2_int_GetBlockAddr(disk, inode.i_block, bestBlock);
if( block > 0 )
bestMatch = BLOCK_DIR_OFS(Node->Data, bestBlock);
VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
if( block > 0 )
bestMatch = BLOCK_DIR_OFS(Node->Data, bestBlock);
VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );