COUNT SerialRead(char * buf, COUNT len) { COUNT read = 0; COUNT readGeneration; BOOL wasFull = FALSE; do { IsrDisable(IRQ_LEVEL_SERIAL_READ); if ( RingBufferIsFull( &SerialInputRing ) ) { wasFull = TRUE; } read = RingBufferRead(buf, len, &SerialInputRing); readGeneration = ReadGenerationCount; IsrEnable(IRQ_LEVEL_SERIAL_READ); if (read == 0) { GenerationWait(&ReadGeneration, readGeneration, NULL); } } while (read == 0); // We were full, so lets make sure there wasn't any data buffered // in the hal. if ( wasFull ) { HalRaiseInterrupt( IRQ_LEVEL_SERIAL_READ ); } return read; }
/* * Performs a context switch from one MACHINE_CONTEXT (thread) to another. */ void ContextSwitch(struct CONTEXT * oldStack, struct CONTEXT * newStack) { #ifdef DEBUG TIME time = TimeGet(); #endif if( oldStack != newStack ) { //The NextStack is set, so we need to context switch. #ifdef DEBUG CounterAdd(&newStack->TimesSwitched, 1); CounterAdd(&newStack->TimesRun, 1); newStack->LastRanTime = time; newStack->LastSelectedTime = time; #endif //The Hal requires that no interrupts fire during the switch. IsrDisable(IRQ_LEVEL_MAX); //now that the system looks like the switch has //happened, go ahead and do the switch. //NOTE: If you change anything below here, you have to update ContextBootstrap. HalContextSwitch(&oldStack->MachineState, &newStack->MachineState); IsrEnable(IRQ_LEVEL_MAX); } else { //we are critical but the thread was the same, //so dont bother doing context switch. #ifdef DEBUG CounterAdd(&newStack->TimesRun, 1); newStack->LastRanTime = time; #endif } }
void TimerRegister( struct HANDLER_OBJECT * newTimer, TIME wait, HANDLER_FUNCTION * handler, void * context ) { TIME time = TimeGet(); TIME timerTime = time + wait; IsrDisable(IRQ_LEVEL_MAX); //Construct timer HandlerRegister( newTimer ); newTimer->Function = handler; newTimer->Context = context; //Add to heap if ( timerTime >= time ) { HeapAdd(timerTime, &newTimer->Link.WeightedLink, Timers ); } else { //Overflow ocurred HeapAdd(timerTime, &newTimer->Link.WeightedLink, TimersOverflow); } IsrEnable(IRQ_LEVEL_MAX); //Because we added a new timer, we may want to wait //a different amount of time than previously thought. //Lets update the hardware countdown. TimerSetNextTimer(time); }
/* * WorkerItemIsFinished should be used by creator of a work item * to see if his work item structure is free for use. If * WorkerItemIsFinished returns TRUE, then it is safe to use * the work item. * * If it returns FALSE, then the work item is still either * queued, or currently running. * * USAGE: * Only the work item's owner should call WorkerItemIsFinished. * It is the caller's responsibility to avoid racing to reclaim * work items. */ BOOL WorkerItemIsFinished( struct WORKER_ITEM * item ) { BOOL result; IsrDisable(IRQ_LEVEL_MAX); result = item->Finished; IsrEnable(IRQ_LEVEL_MAX); return result; }
COUNT SerialWrite(char * buf, COUNT len) { COUNT write; IsrDisable(IRQ_LEVEL_SERIAL_WRITE); write = RingBufferWrite(buf, len, &SerialOutputRing); IsrEnable(IRQ_LEVEL_SERIAL_WRITE); HalRaiseInterrupt(IRQ_LEVEL_SERIAL_WRITE); return write; }
void WatchdogAddFlag( INDEX index ) { FLAG flag = FLAG_NONE; ASSERT( index <= FLAG_MAX_INDEX ); flag = FlagGetBit( index ); IsrDisable(IRQ_LEVEL_WATCHDOG); FlagOn( WatchdogDesiredMask, flag ); IsrEnable(IRQ_LEVEL_WATCHDOG); }
/* * Call this routine to tell the watchdog that the flag * owner has run. */ void WatchdogNotify( INDEX index ) { FLAG flag; #ifdef DEBUG TIME time; #endif //Ensure that we are using a valid flag. ASSERT( index <= FLAG_MAX_INDEX ); //find the bit we want to flip. flag = FlagGetBit( index ); IsrDisable(IRQ_LEVEL_WATCHDOG); //Assert that this flag is present in the desired mask. ASSERT(FlagGet(flag, WatchdogDesiredMask)); #ifdef DEBUG time = TimeGet(); WatchdogLastUpdatedTime = time; #endif FlagOn( WatchdogCurMask, flag ); //check to see if all of the players have shown up. if ( FlagsEqual(WatchdogCurMask, WatchdogDesiredMask) ) { //We have flipped all the flags required. //So lets pet the watchdog. HalPetWatchdog(Timeout); //Now lets clear the mask because we need to //restart our checking. WatchdogCurMask = FLAG_NONE; #ifdef DEBUG WatchdogLastClearedTime = time; #endif } IsrEnable(IRQ_LEVEL_WATCHDOG); }