OS_Return _OS_SemAlloc(OS_Sem_t *sem, UINT32 value) { OS_Return status; if(!sem) { status = BAD_ARGUMENT; goto exit; } if(!g_current_process) { status = PROCESS_INVALID; goto exit; } // Get a free Semaphore resource from the pool *sem = (OS_Sem_t) GetFreeResIndex(g_semaphore_usage_mask, MAX_SEMAPHORE_COUNT); if(*sem < 0) { status = RESOURCE_EXHAUSTED; goto exit; } OS_SemaphoreCB *semobj = (OS_SemaphoreCB *)&g_semaphore_pool[*sem]; // Block the thread resource SetResourceStatus(g_semaphore_usage_mask, *sem, FALSE); semobj->count = value; semobj->owner = (OS_Process *) g_current_process; _OS_QueueInit(&semobj->periodic_task_queue); _OS_QueueInit(&semobj->aperiodic_task_queue); status = SUCCESS; exit: return status; }
OS_Return OS_CreateProcess( OS_Process_t *process, const INT8 *process_name, UINT16 attributes, void (*process_entry_function)(void *pdata), void *pdata) { OS_Process *pcb; if(!process) { FAULT("Invalid process"); return INVALID_ARG; } if(!process_entry_function || !process_name) { FAULT("OS_CreateProcess: invalid arguments"); return INVALID_ARG; } // Now get a free PCB resource from the pool *process = (OS_Process_t) GetFreeResIndex(g_process_usage_mask, MAX_PROCESS_COUNT); if(*process < 0) { FAULT("OS_CreateProcess failed for '%s': Exhausted all resources\n", g_current_process->name); return RESOURCE_EXHAUSTED; } KlogStr(KLOG_GENERAL_INFO, "Creating process - ", process_name); // Get a pointer to actual PCB pcb = &g_process_pool[*process]; // Clear the process structure memset(pcb, 0, sizeof(OS_Process)); // Copy process name strncpy(pcb->name, process_name, OS_PROCESS_NAME_SIZE - 1); pcb->name[OS_PROCESS_NAME_SIZE - 1] = '\0'; pcb->id = *process; // Assign a unique process id pcb->attributes = attributes; pcb->process_entry_function = process_entry_function; pcb->pdata = pdata; pcb->next = NULL; #if ENABLE_MMU pcb->ptable = _MMU_allocate_l1_page_table(); if(!pcb->ptable) { FAULT("OS_CreateProcess failed for '%s': No space in page table area\n", g_current_process->name); return RESOURCE_EXHAUSTED; } // Now create a memory map for the task for the kernel space. Every process is going to have map for // the whole kernel process. This makes it more efficient during system calls and interrupts // by eliminating the need to change the page table. // Note that this does not compromise the security as the user mode cannot read/write // anything in the kernel memory map _OS_create_kernel_memory_map(pcb->ptable); #endif // Block the process resource SetResourceStatus(g_process_usage_mask, *process, FALSE); // Add to the process list if(g_process_list_tail) { g_process_list_tail->next = pcb; g_process_list_tail = pcb; } else { g_process_list_head = g_process_list_tail = pcb; } return SUCCESS; }