static void testConds() { { TCond stackCond; assert(CondCreate(&stackCond) == TRUE); assert(CondFree(&stackCond) == TRUE); } { TCond *heapCond = 0; assert(CondCreate(heapCond) == FALSE); assert(CondFree(heapCond) == FALSE); } { TCond *heapCond = (TCond *)malloc(sizeof(TCond)); assert(CondCreate(heapCond) == TRUE); assert(CondFree(heapCond) == TRUE); free(heapCond); heapCond = 0; } }
//------------------------------------------------------- // // mbox_t MboxCreate(); // // Allocate an available mailbox structure for use. // // Returns the mailbox handle on success // Returns MBOX_FAIL on error. // //------------------------------------------------------- mbox_t MboxCreate() { int ct; mbox_t mbox_ct; uint32 intrval; // grabbing a mbox should be an atomic operation intrval = DisableIntrs(); for(mbox_ct = 0; mbox_ct < MBOX_NUM_MBOXES; mbox_ct++){ // inuse = 0: the mbox is reserved, but not opened for any process yet if(system_mbox[mbox_ct].num_of_pid_inuse == -1 ){ system_mbox[mbox_ct].num_of_pid_inuse = 0; break; } } RestoreIntrs(intrval); if(mbox_ct == MBOX_NUM_MBOXES){ return MBOX_FAIL; } system_mbox[mbox_ct].mbox_buffer_head = 0; system_mbox[mbox_ct].mbox_buffer_tail = 0; system_mbox[mbox_ct].mbox_buffer_slot_used = 0; system_mbox[mbox_ct].mbox_buffer_lock = LockCreate(); system_mbox[mbox_ct].mbox_buffer_fill = CondCreate(system_mbox[mbox_ct].mbox_buffer_lock); system_mbox[mbox_ct].mbox_buffer_empty = CondCreate(system_mbox[mbox_ct].mbox_buffer_lock); for(ct = 0; ct < PROCESS_MAX_PROCS; ct++){ // No proc opens the mbox when it is created system_mbox[mbox_ct].mbox_pid_list[ct] = 0; } return mbox_ct; }
//------------------------------------------------------- // // mbox_t MboxCreate(); // // Allocate an available mailbox structure for use. // // Returns the mailbox handle on success // Returns MBOX_FAIL on error. // //------------------------------------------------------- mbox_t MboxCreate() { mbox_t mbox_no = MBOX_NUM_MBOXES; for(i = 0; i < MBOX_NUM_MBOXES;i++) { if(MailBox[i].inuse == false) { mbox_no = i; break; } } if(mbox_no == MBOX_NUM_MBOXES) { printf("MailBox cannot be assigned to the calling process : %d\n", GetCurrentPid()); return MBOX_FAIL; } MailBox[mbox_no].inuse = true; if((MailBox[mbox_no].lock = LockCreate()) == SYNC_FAIL) { printf("MailBox cannot associate a lock with itself for calling process : %d\n", GetCurrentPid()); return MBOX_FAIL; } if((MailBox[mbox_no].moreData = CondCreate(MailBox[mbox_no].lock)) == SYNC_FAIL) { printf("MailBox cannot associate a cond var for buffer emptiness calling process : %d\n", GetCurrentPid()); return MBOX_FAIL; } if((MailBox[mbox_no].moreSpace = CondCreate(MailBox[mbox_no].lock)) == SYNC_FAIL) { printf("MailBox cannot associate a cond var for buffer saturation for calling process : %d\n", GetCurrentPid()); return MBOX_FAIL; } if(AQueueInit(&MailBox[mbox_no].buffers) == QUEUE_FAIL) { printf("FATAL Error : Available mailbox : %d cannot have its buffer queue initialized for process : %d\n", mbox_no, GetCurrentPid()); return MBOX_FAIL; //exitsim(); } for(i = 0; i < PROCESS_MAX_PROCS; i++) { MailBox[mbox_no].procs_link[i] = 0; } //MailBox[mbox_no].tail = 0; //MailBox[mbox_no].head = 1; MailBox[mbox_no].process_count = 0; //printf("Created mailbox with handle : %d\n", mbox_no); return mbox_no; }
/** * Main function */ int main() { // We create a condition CondId cond = CondCreate("TableCondition"); // We create a thread to fill it and one to read it ThreadId thread_fill = newThread("FillThread", (int)fillThread, (int)cond); ThreadId thread_read = newThread("ReadThread", (int)readThread, (int)cond); // Wait the two threads before returning if (Join(thread_fill) < 0) n_printf("Error joining first thread"); n_printf("Thread fill just finished"); if (Join(thread_read) < 0) n_printf("Error joining second thread"); n_printf("Thread read just finished"); // Delete the condition if (CondDestroy(cond) < 0) n_printf("Error destroy lock"); // Exit the program return 0; }
int main() { cond = CondCreate("cond"); tid1 = threadCreate("test1", test1); tid2 = threadCreate("test2", test2); return 0; }
void MboxModuleInit() { int ct; system_mbox_message.system_buffer_slot_used = 0; system_mbox_message.system_buffer_lock = LockCreate(); system_mbox_message.system_buffer_empty = CondCreate(system_mbox_message.system_buffer_lock); // Initially, all system buffer slots are available for using for(ct = 0; ct < MBOX_NUM_BUFFERS; ct++){ system_mbox_message.system_buffer_index_array[ct] = 0; } // inuse = -1: not activated, inuse = 0: activated, ready to be opened, no process is using it now // inuse > 0: some processes are using it for(ct = 0; ct < MBOX_NUM_MBOXES; ct++){ system_mbox[ct].num_of_pid_inuse = -1; } }
//---------------------------------------------------------------------- // // doInterrupt // // Handle an interrupt or trap. // //---------------------------------------------------------------------- void dointerrupt (unsigned int cause, unsigned int iar, unsigned int isr, uint32 *trapArgs) { int result; int i; uint32 args[4]; int intrs; uint32 handle; int ihandle; dbprintf ('t',"Interrupt cause=0x%x iar=0x%x isr=0x%x args=0x%08x.\n", cause, iar, isr, (int)trapArgs); // If the TRAP_INSTR bit is set, this was from a trap instruction. // If the bit isn't set, this was a system interrupt. if (cause & TRAP_TRAP_INSTR) { cause &= ~TRAP_TRAP_INSTR; switch (cause) { case TRAP_CONTEXT_SWITCH: dbprintf ('t', "Got a context switch trap!\n"); ProcessSchedule (); ClkResetProcess(); break; case TRAP_EXIT: case TRAP_USER_EXIT: dbprintf ('t', "Got an exit trap!\n"); ProcessDestroy (currentPCB); ProcessSchedule (); ClkResetProcess(); break; case TRAP_PROCESS_FORK: dbprintf ('t', "Got a fork trap!\n"); break; case TRAP_PROCESS_SLEEP: dbprintf ('t', "Got a process sleep trap!\n"); ProcessSuspend (currentPCB); ProcessSchedule (); ClkResetProcess(); break; case TRAP_PRINTF: // Call the trap printf handler and pass the arguments and a flag // indicating whether the trap was called from system mode. dbprintf ('t', "Got a printf trap!\n"); TrapPrintfHandler (trapArgs, isr & DLX_STATUS_SYSMODE); break; case TRAP_OPEN: // Get the arguments to the trap handler. If this is a user mode trap, // copy them from user space. if (isr & DLX_STATUS_SYSMODE) { args[0] = trapArgs[0]; args[1] = trapArgs[1]; } else { char filename[32]; // trapArgs points to the trap arguments in user space. There are // two of them, so copy them to to system space. The first argument // is a string, so it has to be copied to system space and the // argument replaced with a pointer to the string in system space. MemoryCopyUserToSystem (currentPCB, (char *)trapArgs, (char *)args, sizeof(args[0])*2); MemoryCopyUserToSystem (currentPCB, (char *)(args[0]), (char *)filename, 31); // Null-terminate the string in case it's longer than 31 characters. filename[31] = '\0'; // Set the argument to be the filename args[0] = (uint32)filename; } // Allow Open() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, args[1] + 0x10000); printf ("Got an open with parameters ('%s',0x%x)\n", (char *)(args[0]), args[1]); RestoreIntrs (intrs); break; case TRAP_CLOSE: // Allow Close() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_READ: // Allow Read() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_WRITE: // Allow Write() calls to be interruptible! intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_DELETE: intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_SEEK: intrs = EnableIntrs (); ProcessSetResult (currentPCB, -1); RestoreIntrs (intrs); break; case TRAP_PROCESS_GETPID: ProcessSetResult(currentPCB, GetCurrentPid()); break; case TRAP_PROCESS_CREATE: TrapProcessCreateHandler(trapArgs, isr & DLX_STATUS_SYSMODE); break; case TRAP_SEM_CREATE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = SemCreate(ihandle); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_SEM_WAIT: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = SemHandleWait(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_SEM_SIGNAL: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = SemHandleSignal(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_MALLOC: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = (int)malloc(currentPCB, ihandle); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_MFREE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = mfree(currentPCB, (void*)ihandle); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_LOCK_CREATE: ihandle = LockCreate(); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_LOCK_ACQUIRE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = LockHandleAcquire(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_LOCK_RELEASE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); handle = LockHandleRelease(ihandle); ProcessSetResult(currentPCB, handle); //Return 1 or 0 break; case TRAP_COND_CREATE: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondCreate(ihandle); ProcessSetResult(currentPCB, ihandle); //Return handle break; case TRAP_COND_WAIT: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleWait(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; case TRAP_COND_SIGNAL: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleSignal(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; case TRAP_COND_BROADCAST: ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE); ihandle = CondHandleBroadcast(ihandle); ProcessSetResult(currentPCB, ihandle); //Return 1 or 0 break; default: printf ("Got an unrecognized trap (0x%x) - exiting!\n", cause); exitsim (); break; } } else { switch (cause) { case TRAP_TIMER: dbprintf ('t', "Got a timer interrupt!\n"); // ClkInterrupt returns 1 when 1 "process quantum" has passed, meaning // that it's time to call ProcessSchedule again. if (ClkInterrupt()) { ProcessSchedule (); } break; case TRAP_KBD: do { i = *((uint32 *)DLX_KBD_NCHARSIN); result = *((uint32 *)DLX_KBD_GETCHAR); printf ("Got a keyboard interrupt (char=0x%x(%c), nleft=%d)!\n", result, result, i); } while (i > 1); break; case TRAP_ACCESS: printf ("Exiting after illegal access at iar=0x%x, isr=0x%x\n", iar, isr); exitsim (); break; case TRAP_ADDRESS: printf ("Exiting after illegal address at iar=0x%x, isr=0x%x\n", iar, isr); exitsim (); break; case TRAP_ILLEGALINST: printf ("Exiting after illegal instruction at iar=0x%x, isr=0x%x\n", iar, isr); exitsim (); break; case TRAP_PAGEFAULT: MemoryPageFaultHandler(currentPCB); break; default: printf ("Got an unrecognized system interrupt (0x%x) - exiting!\n", cause); exitsim (); break; } } dbprintf ('t',"About to return from dointerrupt.\n"); // Note that this return may schedule a new process! intrreturn (); }