BOOT_CODE void configureIdleThread(tcb_t *tcb) { Arch_configureIdleThread(tcb); setThreadState(tcb, ThreadState_IdleThreadState); }
BOOT_CODE bool_t create_initial_thread( cap_t root_cnode_cap, cap_t it_pd_cap, vptr_t ui_v_entry, vptr_t bi_frame_vptr, vptr_t ipcbuf_vptr, cap_t ipcbuf_cap ) { pptr_t pptr; cap_t cap; tcb_t* tcb; deriveCap_ret_t dc_ret; /* allocate TCB */ pptr = alloc_region(TCB_BLOCK_SIZE_BITS); if (!pptr) { printf("Kernel init failed: Unable to allocate tcb for initial thread\n"); return false; } memzero((void*)pptr, 1 << TCB_BLOCK_SIZE_BITS); tcb = TCB_PTR(pptr + TCB_OFFSET); tcb->tcbTimeSlice = CONFIG_TIME_SLICE; Arch_initContext(&tcb->tcbContext); /* derive a copy of the IPC buffer cap for inserting */ dc_ret = deriveCap(SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IT_IPCBUF), ipcbuf_cap); if (dc_ret.status != EXCEPTION_NONE) { printf("Failed to derive copy of IPC Buffer\n"); return false; } /* initialise TCB (corresponds directly to abstract specification) */ cteInsert( root_cnode_cap, SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IT_CNODE), SLOT_PTR(pptr, tcbCTable) ); cteInsert( it_pd_cap, SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IT_VSPACE), SLOT_PTR(pptr, tcbVTable) ); cteInsert( dc_ret.cap, SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IT_IPCBUF), SLOT_PTR(pptr, tcbBuffer) ); tcb->tcbIPCBuffer = ipcbuf_vptr; setRegister(tcb, capRegister, bi_frame_vptr); setNextPC(tcb, ui_v_entry); /* initialise TCB */ tcb->tcbPriority = seL4_MaxPrio; setupReplyMaster(tcb); setThreadState(tcb, ThreadState_Running); ksSchedulerAction = SchedulerAction_ResumeCurrentThread; ksCurThread = ksIdleThread; ksCurDomain = ksDomSchedule[ksDomScheduleIdx].domain; ksDomainTime = ksDomSchedule[ksDomScheduleIdx].length; assert(ksCurDomain < CONFIG_NUM_DOMAINS && ksDomainTime > 0); /* initialise current thread pointer */ switchToThread(tcb); /* initialises ksCurThread */ /* create initial thread's TCB cap */ cap = cap_thread_cap_new(TCB_REF(tcb)); write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IT_TCB), cap); #ifdef DEBUG setThreadName(tcb, "rootserver"); #endif return true; }
void mulMatrix(matrix_data_t *m) { int i, j, k; for(i=0; i< m->A.rows; i++) { for(j=0; j< m->B.colums; j++) { int ret; int thID = getFreeThread(); thread_data_t *threadData = malloc(sizeof(thread_data_t)); threadData->i = i; threadData->j = j; threadData->threadID = thID; threadData->m = m; if(activeThreads[thID] == 2) //juz raz uzylismy... { /* VERBOSE fprintf(stderr, "Reusing thread... securing with pthread_join just in case\n"); */ int *val; ret = pthread_join(threads[thID], (void **)&val); fprintf(stderr, "Thread %d exit status %d\n", thID, val); if( ret != 0) { fprintf(stderr, "%s:%d pthread_join fail %d\n", __FILE__, __LINE__, ret); exit(EXIT_FAILURE); } else { /* VERBOSE fprintf(stderr, "%s:%d pthread_join OK\n", __FILE__, __LINE__); */ activeThreads[thID] = 1; } } setThreadState(thID, 0);// Busy //raise(SIGINT); /* VERBOSE fprintf(stderr, "Thread %d\n", thID); */ ret = pthread_create( &threads[thID], NULL, mulThread, (void*) threadData); if( ret != 0) { fprintf(stderr, "%s:%d pthread_create fail %d\n", __FILE__, __LINE__, ret); exit(EXIT_FAILURE); } } } for (i = 0; i < MAX_THREADS;i++) { if(getThreadState(i) == 2 || getThreadState(i) == 0) { int *val; int ret = pthread_join(threads[i], (void **)&val); fprintf(stderr, "Thread %d exit status %d\n", i, val); if( ret != 0) { fprintf(stderr, "%s:%d pthread_join fail %d\n", __FILE__, __LINE__, ret); exit(EXIT_FAILURE); } else { /* VERBOSE fprintf(stderr, "%s:%d pthread_join OK\n", __FILE__, __LINE__); */ activeThreads[i] = 1; } } } }
static exception_t handleInvocation(bool_t isCall, bool_t isBlocking) { message_info_t info; cptr_t cptr; lookupCapAndSlot_ret_t lu_ret; word_t *buffer; exception_t status; word_t length; tcb_t *thread; thread = ksCurThread; info = messageInfoFromWord(getRegister(thread, msgInfoRegister)); cptr = getRegister(thread, capRegister); /* faulting section */ lu_ret = lookupCapAndSlot(thread, cptr); if (unlikely(lu_ret.status != EXCEPTION_NONE)) { userError("Invocation of invalid cap #%d.", (int)cptr); current_fault = fault_cap_fault_new(cptr, false); if (isBlocking) { handleFault(thread); } return EXCEPTION_NONE; } buffer = lookupIPCBuffer(false, thread); status = lookupExtraCaps(thread, buffer, info); if (unlikely(status != EXCEPTION_NONE)) { userError("Lookup of extra caps failed."); if (isBlocking) { handleFault(thread); } return EXCEPTION_NONE; } /* Syscall error/Preemptible section */ length = message_info_get_msgLength(info); if (unlikely(length > n_msgRegisters && !buffer)) { length = n_msgRegisters; } status = decodeInvocation(message_info_get_msgLabel(info), length, cptr, lu_ret.slot, lu_ret.cap, current_extra_caps, isBlocking, isCall, buffer); if (unlikely(status == EXCEPTION_PREEMPTED)) { return status; } if (unlikely(status == EXCEPTION_SYSCALL_ERROR)) { if (isCall) { replyFromKernel_error(thread); } return EXCEPTION_NONE; } if (unlikely( thread_state_get_tsType(thread->tcbState) == ThreadState_Restart)) { if (isCall) { replyFromKernel_success_empty(thread); } setThreadState(thread, ThreadState_Running); } return EXCEPTION_NONE; }
exception_t Arch_decodeIRQControlInvocation(word_t invLabel, word_t length, cte_t *srcSlot, extra_caps_t excaps, word_t *buffer) { word_t index, depth; cte_t *destSlot; cap_t cnodeCap; lookupSlot_ret_t lu_ret; exception_t status; irq_t irq; word_t vector; if (!config_set(CONFIG_IRQ_IOAPIC)) { userError("IRQControl: Illegal operation."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } /* check the common parameters */ if (length < 7 || excaps.excaprefs[0] == NULL) { userError("IRQControl: Truncated message"); current_syscall_error.type = seL4_TruncatedMessage; return EXCEPTION_SYSCALL_ERROR; } index = getSyscallArg(0, buffer); depth = getSyscallArg(1, buffer); cnodeCap = excaps.excaprefs[0]->cap; irq = getSyscallArg(6, buffer); if (irq > irq_user_max - irq_user_min) { userError("IRQControl: Invalid irq %ld should be between 0-%ld", (long)irq, (long)(irq_user_max - irq_user_min - 1)); current_syscall_error.type = seL4_RangeError; current_syscall_error.rangeErrorMin = 0; current_syscall_error.rangeErrorMax = irq_user_max - irq_user_min; return EXCEPTION_SYSCALL_ERROR; } irq += irq_user_min; vector = (word_t)irq + IRQ_INT_OFFSET; lu_ret = lookupTargetSlot(cnodeCap, index, depth); if (lu_ret.status != EXCEPTION_NONE) { return lu_ret.status; } destSlot = lu_ret.slot; status = ensureEmptySlot(destSlot); if (status != EXCEPTION_NONE) { return status; } switch (invLabel) { case X86IRQIssueIRQHandlerIOAPIC: { word_t ioapic = getSyscallArg(2, buffer); word_t pin = getSyscallArg(3, buffer); word_t level = getSyscallArg(4, buffer); word_t polarity = getSyscallArg(5, buffer); if (isIRQActive(irq)) { userError("IOAPICGet: IRQ %d is already active.", (int)irq); current_syscall_error.type = seL4_RevokeFirst; return EXCEPTION_SYSCALL_ERROR; } status = ioapic_decode_map_pin_to_vector(ioapic, pin, level, polarity, vector); if (status != EXCEPTION_NONE) { return status; } setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart); return invokeIssueIRQHandlerIOAPIC(irq, ioapic, pin, level, polarity, vector, destSlot, srcSlot); } break; case X86IRQIssueIRQHandlerMSI: { word_t pci_bus = getSyscallArg(2, buffer); word_t pci_dev = getSyscallArg(3, buffer); word_t pci_func = getSyscallArg(4, buffer); word_t handle = getSyscallArg(5, buffer); x86_irq_state_t irqState; /* until we support msi interrupt remaping through vt-d we ignore the * vector and trust the user */ (void)vector; if (isIRQActive(irq)) { current_syscall_error.type = seL4_RevokeFirst; return EXCEPTION_SYSCALL_ERROR; } if (pci_bus > PCI_BUS_MAX) { current_syscall_error.type = seL4_RangeError; current_syscall_error.rangeErrorMin = 0; current_syscall_error.rangeErrorMax = PCI_BUS_MAX; return EXCEPTION_SYSCALL_ERROR; } if (pci_dev > PCI_DEV_MAX) { current_syscall_error.type = seL4_RangeError; current_syscall_error.rangeErrorMin = 0; current_syscall_error.rangeErrorMax = PCI_DEV_MAX; return EXCEPTION_SYSCALL_ERROR; } if (pci_func > PCI_FUNC_MAX) { current_syscall_error.type = seL4_RangeError; current_syscall_error.rangeErrorMin = 0; current_syscall_error.rangeErrorMax = PCI_FUNC_MAX; return EXCEPTION_SYSCALL_ERROR; } irqState = x86_irq_state_irq_msi_new(pci_bus, pci_dev, pci_func, handle); setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart); return Arch_invokeIRQControl(irq, destSlot, srcSlot, irqState); } break; default: userError("IRQControl: Illegal operation."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } }