for( ; gaSuperBitmap[a] == -1 && a >= 0; a-- );
if(a < 0) {
Mutex_Release( &glPhysAlloc );
- Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p)", __builtin_return_address(0));
+ Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p) - %lli/%lli used",
+ __builtin_return_address(0), giPhysAlloc, giPageCount);
LEAVE('i', 0);
return 0;
}
if( indx < 0 ) {
Mutex_Release( &glPhysAlloc );
- Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p)", __builtin_return_address(0));
+ Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p) - %lli/%lli used (indx = %x)",
+ __builtin_return_address(0), giPhysAlloc, giPageCount, indx);
+ Log_Debug("PMem", "giLastPossibleFree = %lli", giLastPossibleFree);
LEAVE('i', 0);
return 0;
}
// Create Initial Task
gActiveThreads = &gThreadZero;
gAllThreads = &gThreadZero;
- //giFreeTickets = gThreadZero.NumTickets;
+ //giFreeTickets = gThreadZero.NumTickets; // Not needed, as ThreadZero is running
giNumActiveThreads = 1;
Proc_Start();
tThread *prev;
tMsg *msg;
- // Kill all children
+ // TODO: Kill all children
#if 0
{
tThread *child;
prev = Threads_int_GetPrev( &gActiveThreads, Thread );
if(!prev) {
Warning("Proc_Exit - Current thread is not on the active queue");
- SHORTREL( &Thread->IsLocked );
SHORTREL( &glThreadListLock );
+ SHORTREL( &Thread->IsLocked );
return;
}
* \brief Wakes a sleeping/waiting thread up
* \param Thread Thread to wake
* \return Boolean Failure (Returns ERRNO)
- * \note Should be called with the scheduler lock held
+ * \warning This should ONLY be called with task switches disabled
*/
int Threads_Wake(tThread *Thread)
{
Log("Thread_Wake: Waking awake thread (%i)", Thread->TID);
return -EALREADY;
- case THREAD_STAT_SLEEPING: // TODO: Comment better
+ case THREAD_STAT_SLEEPING:
// Remove from sleeping queue
prev = Threads_int_GetPrev(&gSleepingThreads, Thread);
prev->Next = Thread->Next;
+
// Add to active queue
Thread->Next = gActiveThreads;
gActiveThreads = Thread;
+
// Update bookkeeping
giNumActiveThreads ++;
giFreeTickets += Thread->NumTickets;
#if DEBUG_TRACE_TICKETS
Log("Threads_Wake: new giFreeTickets = %i", giFreeTickets);
#endif
+
Thread->CurCPU = -1;
Thread->Status = THREAD_STAT_ACTIVE;
#if DEBUG_TRACE_STATE
SHORTLOCK( &glThreadListLock );
ret = Threads_Wake( thread );
SHORTREL( &glThreadListLock );
+ //Log_Debug("Threads", "TID %i woke %i (%p)", Threads_GetTID(), TID, thread);
return ret;
}
{
Log(" %i (%i) - %s (CPU %i)",
thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
- Log(" State: %i", thread->Status);
+ if(thread->Status != THREAD_STAT_ACTIVE)
+ Log(" ERROR State (%i) != THREAD_STAT_ACTIVE (%i)", thread->Status, THREAD_STAT_ACTIVE);
Log(" %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum);
Log(" KStack 0x%x", thread->KernelStack);
}
{
Log(" %i (%i) - %s (CPU %i)",
thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
- Log(" State: %i", thread->Status);
+ Log(" State %i", thread->Status);
Log(" %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum);
Log(" KStack 0x%x", thread->KernelStack);
}
SHORTLOCK( &glThreadListLock );
// Clear Delete Queue
+ // - I should probably put this in a worker thread to avoid calling free() in the scheduler
while(gDeleteThreads)
{
thread = gDeleteThreads->Next;
}
#if DEBUG_TRACE_TICKETS
else
- LogF(" %p (%s)->Status = %i\n", Last, Last->ThreadName, Last->Status);
+ LogF(" %p (%s)->Status = %i (Released)\n", Last, Last->ThreadName, Last->Status);
#endif
Last->CurCPU = -1;
}
#if 1
number = 0;
- for(thread=gActiveThreads;thread;thread=thread->Next) {
+ for(thread = gActiveThreads; thread; thread = thread->Next) {
if(thread->CurCPU >= 0) continue;
number += thread->NumTickets;
}
}
SHORTREL( &glThreadListLock );
SHORTREL( &Mutex->Protector );
- while(us->Status == THREAD_STAT_OFFSLEEP) HALT();
+ while(us->Status == THREAD_STAT_OFFSLEEP) Threads_Yield();
// We're only woken when we get the lock
}
// Ooh, let's take it!
// Read Data from DMA
LOG("Setting DMA for read");
- DMA_SetChannel(2, 512, !Write); // Read 512 Bytes from channel 2
+ DMA_SetChannel(2, 512, !Write); // Read/Write 512 Bytes from channel 2
LOG("Sending command");
st1 = FDD_int_GetByte(base);
st2 = FDD_int_GetByte(base);
- // Cylinder, Head and Sector (mutilated in some way
+ // Cylinder, Head and Sector (mutilated in some way)
rcy = FDD_int_GetByte(base);
rhe = FDD_int_GetByte(base);
rse = FDD_int_GetByte(base);
// Don't turn the motor off now, wait for a while
gFDD_Devices[Disk].timer = Time_CreateTimer(MOTOR_OFF_DELAY, FDD_int_StopMotor, (void*)(tVAddr)Disk);
+ // Error check
if( i < FDD_MAX_READWRITE_ATTEMPTS ) {
LEAVE('i', 0);
return 0;