//------------------------------------------------------- // // 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 imbox; uint32 intrval; // grabbing a Mbox should be an atomic operation intrval = DisableIntrs(); for(imbox = 0; imbox < MBOX_NUM_MBOXES; imbox++) { if(mboxes[imbox].inuse == false) { mboxes[imbox].inuse = true; break; } } RestoreIntrs(intrval); if(imbox == MAX_SEMS) return MBOX_FAIL; if ((mboxes[imbox].s_mbox_emptyslots = SemCreate(MBOX_MAX_BUFFERS_PER_MBOX - 1)) == SYNC_FAIL) { printf("Bad sem_create in MboxOpen"); exitsim(); } if ((mboxes[imbox].s_mbox_fillslots = SemCreate(0)) == SYNC_FAIL) { printf("Bad sem_create in MboxOpen"); exitsim(); } if((mboxes[imbox].l_mbox = LockCreate()) == SYNC_FAIL) { printf("Bad lock_create in MboxModInit"); exitsim(); } return imbox; }
SafeQueue* SafeQueueInit(size_t _size) { SafeQueue* safeQ = NULL; /* creating safe queue */ safeQ = malloc (sizeof(SafeQueue)); if (NULL == safeQ) { return NULL; } safeQ->m_queue = QueueCreate(_size); if (NULL == safeQ->m_queue) { return NULL; } /* initializing its semahores and mutex */ pthread_mutex_init(&safeQ->m_mutex, NULL); /* initially an empty queue, so full ability exists to insert all messages up to size */ if (ERR_OK != SemCreate(&safeQ->m_prodSem, _size)) { return NULL; } /* initially an empty queue, so consumer can't yet consume */ if (ERR_OK != SemCreate(&safeQ->m_consSem, 0)) { return NULL; } return safeQ; }
bool DevInit(void) { mux_load = SemCreate(1); sem_load = SemCreate(0); ThrCreateThread(&proc_idle, true, DevLoaderThread, false, NULL, 16, L"DevLoaderThread"); return true; }
void LmuxInit(lmutex_t *mux) { mux->locks = 0; mux->eip = 0; mux->owner = 0; #ifdef FAST mux->mutex = SemCreate(0); #else mux->mutex = SemCreate(1); #endif }
int start3(char *arg) { int result; int pid; int status; USLOSS_Console("start3(): started\n"); result = SemCreate(3, &sem1); SemP(sem1); USLOSS_Console("start3(): After P in the CS\n"); Spawn("Child1", Child1, "Child1", USLOSS_MIN_STACK, 2, &pid); USLOSS_Console("\nstart3(): spawn %d\n", pid); Spawn("Child2", Child2, "Child2", USLOSS_MIN_STACK, 3, &pid); USLOSS_Console("start3(): spawn %d\n", pid); SemV(sem1); USLOSS_Console("\nstart3(): After V -- may appear before: Child1(): After P attempt #3\n"); Wait(&pid, &status); USLOSS_Console("\nstart3(): status of quit child = %d\n",status); Wait(&pid, &status); USLOSS_Console("start3(): status of quit child = %d\n",status); USLOSS_Console("start3(): Parent done\n"); Terminate(8); return 0; } /* start3 */
//------------------------------------------------------- // // 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 i; int j; for (i = 0; i < MBOX_NUM_MBOXES; i++) { //modified (MBOX_NUM_BOXES) if (mbox_list[i].in_use == -1){ mbox_list[i].in_use = 0; mbox_list[i].msg_count = 0; mbox_list[i].empty = SemCreate(MBOX_MAX_BUFFERS_PER_MBOX); //modified (MBOX_MAX_BUFFERS) mbox_list[i].full = SemCreate(0); mbox_list[i].lock = LockCreate(); for(j = 0; j < MBOX_NUM_BUFFERS; j++) { mbox_list[i].users[j] = -1; } return mbox_list[i].handle; } } return MBOX_FAIL; }
//------------------------------------------------------- // // 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; uint32 intrval; //grabbing a mailbox should be an atomic operation intrval = DisableIntrs(); for(mbox=0; mbox<MBOX_NUM_MBOXES; mbox++){ if(mboxs[mbox].inuse == 0){ mboxs[mbox].inuse = 1; break; } } RestoreIntrs(intrval); if((mboxs[mbox].l = LockCreate()) == SYNC_FAIL){ printf("FATAL ERROR: Could not create lock for mbox\n"); exitsim(); } if((mboxs[mbox].s_msg_full = SemCreate(0)) == SYNC_FAIL) { printf("Bad sem create in mbox create\n "); exitsim(); } if((mboxs[mbox].s_msg_empty = SemCreate(MBOX_MAX_BUFFERS_PER_MBOX)) == SYNC_FAIL) { printf("Bad sem create in mbox create\n "); exitsim(); } if(mbox == MBOX_NUM_MBOXES) return MBOX_FAIL; if(AQueueInit(&mboxs[mbox].messages) != QUEUE_SUCCESS){ printf("FATAL ERROR: Could not initialize mbox messsage queue\n"); exitsim(); } if(AQueueInit(&mboxs[mbox].pids) != QUEUE_SUCCESS){ printf("FATAL ERROR: Could not initialize mbox pid queue\n"); exitsim(); } return mbox; }
int start3(char *arg) { int semaphore[MAXSEMS+1]; int sem_result; int i; printf("start3(): started. Calling SemCreate\n"); for (i = 0; i < MAXSEMS; i++) { sem_result = SemCreate(0, &semaphore[i]); if (sem_result == -1) printf("start3(): i = %3d, sem_result = %2d\n", i, sem_result); } sem_result = SemCreate(0, &semaphore[MAXSEMS]); if (sem_result != -1) printf("start3(): ERROR: sem_result should have been -1, but was not\n"); printf("start3(): freeing one semaphore\n"); sem_result = SemFree(semaphore[105]); if (sem_result != 0) printf("start3(): ERROR: SemFree should have returned -1, but did not\n"); sem_result = SemCreate(0, &semaphore[MAXSEMS]); if (sem_result == 0) printf("start3(): Correct result from last call to SemCreate()\n"); else { printf("start3(): ERROR: last call to SemCreate should have "); printf("returned 0, but did not\n"); } Terminate(8); return 0; } /* start3 */
int start5(char *arg) { int pid; int status; Tconsole("start5(): Running: %s\n", TEST); Tconsole("start5(): Pagers: %d\n", PAGERS); Tconsole(" Mappings: %d\n", MAPPINGS); Tconsole(" Pages: %d\n", PAGES); Tconsole(" Frames: %d\n", FRAMES); Tconsole(" Children: %d\n", CHILDREN); Tconsole(" Iterations: %d\n", ITERATIONS); Tconsole(" Priority: %d\n", PRIORITY); status = VmInit( MAPPINGS, PAGES, FRAMES, PAGERS, &vmRegion ); Tconsole("start5(): after call to VmInit, status = %d\n\n", status); assert(status == 0); assert(vmRegion != NULL); SemCreate(0, &sem); Spawn("Child", Child, NULL, USLOSS_MIN_STACK * 7, PRIORITY, &pid); SemP( sem); Wait(&pid, &status); assert(status == 117); Tconsole("start5(): done\n"); //PrintStats(); VmDestroy(); Terminate(1); return 0; } /* start5 */
//---------------------------------------------------------------------- // // 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 (); }
/** * @b Description * @n * The function creates a V6 Daemon. * * @param[in] Type * This is the type of socket being opened through the daemon. In * the case of IPv6 the following types are supported * - SOCK_STREAM * Use this for TCP Sockets. * - SOCK_DGRAM * Use this for UDP Sockets. * @param[in] LocalAddress * This is the Local Address to which the socket will be bound to. * In most cases this is typically passed as IPV6_UNSPECIFIED_ADDRESS * @param[in] LocalPort * This is the Local Port to serve (cannot be NULL) * @param[in] pCb * Call back function which is to be invoked. * @param[in] Priority * Priority of new task to create for callback function * @param[in] StackSize * Stack size of new task to create for callback function * @param[in] Argument * Argument (besides socket) to pass to callback function * @param[in] MaxSpawn * Maximum number of callback function instances (must be 1 for UDP) * * @retval * Success - Handle to the spawned Daemon. * @retval * Error - 0 */ HANDLE Daemon6New (uint Type, IP6N LocalAddress, uint LocalPort, int (*pCb)(SOCKET,UINT32), uint Priority, uint StackSize, UINT32 Argument, uint MaxSpawn ) { int i; DREC *pdr = 0; // Sanity check the arguments if( Type==SOCK_DGRAM ) MaxSpawn=1; else if( Type!=SOCK_STREAM) return(0); if( !LocalPort || !pCb || Priority<1 || Priority>15 || !StackSize || !MaxSpawn ) return(0); // We'll borrow the stack's kernel mode for a temp exclusion method llEnter(); if( !hDSem6 ) { hDSem6 = SemCreate( 1 ); bzero( drec6, sizeof(drec6) ); RequestedRecords6 = 0; } llExit(); // At this point we must have a semaphore if( !hDSem6 ) return(0); // Enter our own lock SemPend( hDSem6, SEM_FOREVER ); // Scan the list for a free slot for( i=0; i<DAEMON_MAXRECORD; i++ ) if( !drec6[i].Type && !drec6[i].TasksSpawned ) break; // Break out if no free records if(i==DAEMON_MAXRECORD) goto errorout; // Build the new record pdr = &drec6[i]; pdr->Type = Type; pdr->LocalV6Address = LocalAddress; pdr->LocalPort = LocalPort; pdr->pCb = pCb; pdr->Priority = Priority; pdr->StackSize = StackSize; pdr->Argument = Argument; pdr->MaxSpawn = MaxSpawn; pdr->s = INVALID_SOCKET; // If the Deamon task exists, ping it, otherwise create it if( hDTask6 ) fdSelectAbort( hDTask6 ); else { hDTask6 = TaskCreate(daemon6,"daemon6",OS_TASKPRINORM,OS_TASKSTKLOW,0,0,0); if( hDTask6 ) fdOpenSession(hDTask6); else { pdr->Type = 0; pdr = 0; goto errorout; } } RequestedRecords6++; errorout: // Exit our lock SemPost( hDSem6 ); return( pdr ); }