void decrement_task(task_id task) { task_t* current = &open_tasks[task]; while (current != 0) { if (!waiting_on_task) { evaluate_dependencies(); } task_t* deletion = current; int items = atomic_decrement(current->open_work_items); if (items == 0) { if (current->parent != kNullTask) { current = &open_tasks[current->parent]; } else { current = 0; } // remove the task from the open_list atomic_decrement(num_tasks); task_id deletedid = deletion->id; task_initialize(deletion); availableIds.push(deletedid); } else { current = 0; } } }
task_t *dummyParentTask(void *payload, task_t *task) { task_t *newTask = task_initialize(dummyChildTask, NULL); atomic_increment(&gParentWorkCount); task_setFinishes(newTask, task); tasks_schedule(newTask); return NULL; }
task_manager(size_t maxTasks, size_t numThreads = -1) : tasks(maxTasks), max_tasks(maxTasks), num_tasks(0), kill(false), waiting_on_task(false) { if (numThreads == -1) { numThreads = internal::number_of_cores() - 1; } open_tasks = new task_t[maxTasks]; for (int i = 0; i < maxTasks; ++i) { availableIds.push(i); task_initialize(&open_tasks[i]); } for (int i = 0; i < numThreads; ++i) { worker_thread_data worker; worker.thread_ = thread(worker_thread_func); worker.scheduler_ = this; workers_.push_back(worker); workers_[i].thread_.start(this); } }
void object_initialize( void ) { alarm_initialize(); resource_initialize(); task_initialize(); }
void object_initialize( void ) { task_initialize(); }
void start_kernel(struct multiboot *mbp, unsigned int magic,u32 esp) { u32 initrd_location = *((u32*)mbp->mods_addr); u32 initrd_end = *(u32*)(mbp->mods_addr+4); __asm__ __volatile__("cli"); cpu_init(); placement_pointer = initrd_end; vmmngr_initialize(mbp->mem_upper + mbp->mem_lower); kheap = _heapmngr_initialize(0x02000000, 0x20000000, 0x200000); con_init(); init_IRQ(); time_init(); _kbd_init_hook(); /*setup_irq(2, &irq2); setup_irq(3, &irq3 ); setup_irq(4, &irq4 ); setup_irq(5, &irq5 ); setup_irq(8, &irq8 ); */ //auto_fpu(); task_initialize(); syscalls_install(); fs_root_initrd = install_initrd(initrd_location); //pci_inst_check(); //enable_pci_master(0,3,0); //8139 need this struct request *info = 0; probe_ide(info); hd_init_hook_(); putch('P'); double test = 3.14444; printk("test ::: %d\n", test); //serial_install(); //unsigned long cpu_khz = init_tsc(); //u32 *pf = (u32 *)0xffff0000; //*pf = 10; ext2_read_superblock(); register_filesystem(); __asm__ __volatile__("sti"); //graphics_install_bochs(1024,768); //heaptest(); //create_thread(test_task,1); while(1) { if(getch_polling() == 'i') { const char *filename = "test__2"; //execve__((char*)filename,0,0); load_elf((char*)filename,0,0); //show_state(); } } }
void os_start(void) { int i; slldbg("Entry\n"); /* Initialize RTOS Data ***************************************************/ /* Initialize all task lists */ dq_init(&g_readytorun); dq_init(&g_pendingtasks); dq_init(&g_waitingforsemaphore); #ifndef CONFIG_DISABLE_SIGNALS dq_init(&g_waitingforsignal); #endif #ifndef CONFIG_DISABLE_MQUEUE dq_init(&g_waitingformqnotfull); dq_init(&g_waitingformqnotempty); #endif #ifdef CONFIG_PAGING dq_init(&g_waitingforfill); #endif dq_init(&g_inactivetasks); sq_init(&g_delayed_kufree); #if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \ defined(CONFIG_MM_KERNEL_HEAP) sq_init(&g_delayed_kfree); #endif /* Initialize the logic that determine unique process IDs. */ g_lastpid = 0; for (i = 0; i < CONFIG_MAX_TASKS; i++) { g_pidhash[i].tcb = NULL; g_pidhash[i].pid = INVALID_PROCESS_ID; } /* Assign the process ID of ZERO to the idle task */ g_pidhash[PIDHASH(0)].tcb = &g_idletcb.cmn; g_pidhash[PIDHASH(0)].pid = 0; /* Initialize the IDLE task TCB *******************************************/ /* Initialize a TCB for this thread of execution. NOTE: The default * value for most components of the g_idletcb are zero. The entire * structure is set to zero. Then only the (potentially) non-zero * elements are initialized. NOTE: The idle task is the only task in * that has pid == 0 and sched_priority == 0. */ bzero((void*)&g_idletcb, sizeof(struct task_tcb_s)); g_idletcb.cmn.task_state = TSTATE_TASK_RUNNING; g_idletcb.cmn.entry.main = (main_t)os_start; g_idletcb.cmn.flags = TCB_FLAG_TTYPE_KERNEL; /* Set the IDLE task name */ #if CONFIG_TASK_NAME_SIZE > 0 strncpy(g_idletcb.cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE); g_idletcb.cmn.name[CONFIG_TASK_NAME_SIZE] = '\0'; #endif /* CONFIG_TASK_NAME_SIZE */ /* Configure the task name in the argument list. The IDLE task does * not really have an argument list, but this name is still useful * for things like the NSH PS command. * * In the kernel mode build, the arguments are saved on the task's stack * and there is no support that yet. */ #if CONFIG_TASK_NAME_SIZE > 0 g_idleargv[0] = g_idletcb.cmn.name; #else g_idleargv[0] = (FAR char *)g_idlename; #endif /* CONFIG_TASK_NAME_SIZE */ g_idleargv[1] = NULL; g_idletcb.argv = g_idleargv; /* Then add the idle task's TCB to the head of the ready to run list */ dq_addfirst((FAR dq_entry_t*)&g_idletcb, (FAR dq_queue_t*)&g_readytorun); /* Initialize the processor-specific portion of the TCB */ up_initial_state(&g_idletcb.cmn); /* Initialize RTOS facilities *********************************************/ /* Initialize the semaphore facility. This has to be done very early * because many subsystems depend upon fully functional semaphores. */ sem_initialize(); #if defined(MM_KERNEL_USRHEAP_INIT) || defined(CONFIG_MM_KERNEL_HEAP) || defined(CONFIG_MM_PGALLOC) /* Initialize the memory manager */ { FAR void *heap_start; size_t heap_size; #ifdef MM_KERNEL_USRHEAP_INIT /* Get the user-mode heap from the platform specific code and configure * the user-mode memory allocator. */ up_allocate_heap(&heap_start, &heap_size); kumm_initialize(heap_start, heap_size); #endif #ifdef CONFIG_MM_KERNEL_HEAP /* Get the kernel-mode heap from the platform specific code and configure * the kernel-mode memory allocator. */ up_allocate_kheap(&heap_start, &heap_size); kmm_initialize(heap_start, heap_size); #endif #ifdef CONFIG_MM_PGALLOC /* If there is a page allocator in the configuration, then get the page * heap information from the platform-specific code and configure the * page allocator. */ up_allocate_pgheap(&heap_start, &heap_size); mm_pginitialize(heap_start, heap_size); #endif } #endif #if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) /* Initialize tasking data structures */ #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (task_initialize != NULL) #endif { task_initialize(); } #endif /* Initialize the interrupt handling subsystem (if included) */ #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (irq_initialize != NULL) #endif { irq_initialize(); } /* Initialize the watchdog facility (if included in the link) */ #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (wd_initialize != NULL) #endif { wd_initialize(); } /* Initialize the POSIX timer facility (if included in the link) */ #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (clock_initialize != NULL) #endif { clock_initialize(); } #ifndef CONFIG_DISABLE_POSIX_TIMERS #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (timer_initialize != NULL) #endif { timer_initialize(); } #endif #ifndef CONFIG_DISABLE_SIGNALS /* Initialize the signal facility (if in link) */ #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (sig_initialize != NULL) #endif { sig_initialize(); } #endif #ifndef CONFIG_DISABLE_MQUEUE /* Initialize the named message queue facility (if in link) */ #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (mq_initialize != NULL) #endif { mq_initialize(); } #endif #ifndef CONFIG_DISABLE_PTHREAD /* Initialize the thread-specific data facility (if in link) */ #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (pthread_initialize != NULL) #endif { pthread_initialize(); } #endif #if CONFIG_NFILE_DESCRIPTORS > 0 /* Initialize the file system (needed to support device drivers) */ fs_initialize(); #endif #ifdef CONFIG_NET /* Initialize the networking system. Network initialization is * performed in two steps: (1) net_setup() initializes static * configuration of the network support. This must be done prior * to registering network drivers by up_initialize(). This step * cannot require upon any hardware-depending features such as * timers or interrupts. */ net_setup(); #endif /* The processor specific details of running the operating system * will be handled here. Such things as setting up interrupt * service routines and starting the clock are some of the things * that are different for each processor and hardware platform. */ up_initialize(); #ifdef CONFIG_NET /* Complete initialization the networking system now that interrupts * and timers have been configured by up_initialize(). */ net_initialize(); #endif #ifdef CONFIG_MM_SHM /* Initialize shared memory support */ shm_initialize(); #endif /* Initialize the C libraries. This is done last because the libraries * may depend on the above. */ lib_initialize(); /* IDLE Group Initialization **********************************************/ #ifdef HAVE_TASK_GROUP /* Allocate the IDLE group */ DEBUGVERIFY(group_allocate(&g_idletcb, g_idletcb.cmn.flags)); #endif #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 /* Create stdout, stderr, stdin on the IDLE task. These will be * inherited by all of the threads created by the IDLE task. */ DEBUGVERIFY(group_setupidlefiles(&g_idletcb)); #endif #ifdef HAVE_TASK_GROUP /* Complete initialization of the IDLE group. Suppress retention * of child status in the IDLE group. */ DEBUGVERIFY(group_initialize(&g_idletcb)); g_idletcb.cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT; #endif /* Bring Up the System ****************************************************/ /* Create initial tasks and bring-up the system */ DEBUGVERIFY(os_bringup()); /* The IDLE Loop **********************************************************/ /* When control is return to this point, the system is idle. */ sdbg("Beginning Idle Loop\n"); for (;;) { /* Perform garbage collection (if it is not being done by the worker * thread). This cleans-up memory de-allocations that were queued * because they could not be freed in that execution context (for * example, if the memory was freed from an interrupt handler). */ #ifndef CONFIG_SCHED_WORKQUEUE /* We must have exclusive access to the memory manager to do this * BUT the idle task cannot wait on a semaphore. So we only do * the cleanup now if we can get the semaphore -- this should be * possible because if the IDLE thread is running, no other task is! * * WARNING: This logic could have undesirable side-effects if priority * inheritance is enabled. Imaginee the possible issues if the * priority of the IDLE thread were to get boosted! Moral: If you * use priority inheritance, then you should also enable the work * queue so that is done in a safer context. */ if (kmm_trysemaphore() == 0) { sched_garbagecollection(); kmm_givesemaphore(); } #endif /* Perform any processor-specific idle state operations */ up_idle(); } }
void kernel_main(unsigned long magic, unsigned long addr) { multiboot_info_t *mbi; if (magic != MULTIBOOT_BOOTLOADER_MAGIC) return; mbi = (multiboot_info_t*)addr; /* kernel init */ serial_init(DEBUG_SERIAL_PORT, DEBUG_SERIAL_SPEED, UART_8BITS_WORD, UART_NO_PARITY, UART_1_STOP_BIT); cls(); cpu_cli(); printf("[x] interrupts disabled\n"); gdt_initialize(); printf("[x] gdt initialized\n"); idt_initialize(); printf("[x] idt initialized\n"); breakpoint_initialize(); #if defined(USE_APIC) apic_initialize(); serial_printl("[x] apic initialized\n"); #else pic_initialize(); serial_printl("[x] pic initialized\n"); #endif /* USE_APIC */ /* initialize the kernel */ { kernel_init(mbi); } /* memory initialization */ { phys_init(mbi); phys_debug(); /* vm_init(); */ /* unit_test_vm(); */ /* cpu_hlt(); */ } #if defined(USE_PCI) pci_initialize(); pci_list(); #endif cpu_sti(); #if defined(USE_TASK) { /* subsystems */ event_initialize(); sched_initialize(); task_initialize(); /* tasks */ idle_initialize(); muksh_initialize(); net_initialize(); /* task_test(); */ /* start scheduling */ sched_start(); } #endif /* endless loop */ serial_printl("[?] kernel loop\n"); while (1) { serial_printl("k"); cpu_hlt(); } }