taskqid_t taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) { task_t *t; if (taskq_now) { func(arg); return (1); } mutex_enter(&tq->tq_lock); ASSERT(tq->tq_flags & TASKQ_ACTIVE); if ((t = task_alloc(tq, tqflags)) == NULL) { mutex_exit(&tq->tq_lock); return (0); } t->task_next = &tq->tq_task; t->task_prev = tq->tq_task.task_prev; t->task_next->task_prev = t; t->task_prev->task_next = t; t->task_func = func; t->task_arg = arg; cv_signal(&tq->tq_dispatch_cv); mutex_exit(&tq->tq_lock); return (1); }
void testAllocHandlesOutOfMemory(void){ long i; int dealtWithOutOfMemory = 0; printf(" => testAllocHandlesOutOfMemory\n"); REAL_TASK_COUNT = 0; for(i = FAIR_TASK_COUNT; i <= MAX_TASK_COUNT && dealtWithOutOfMemory == 0; i++){ /* Point test slot i to the actual task_alloc() result. */ tasks[i] = NULL; tasks[i] = task_alloc(); if (tasks[i] != NULL){ /* Slots must be in the allocated space */ assert( (unsigned long)tasks[i] <= ( (unsigned long)get_MEM_BLOCK_START() + MEM_BLOCK_SIZE ) ); } else { /* If the allocation was out of memory, NULL may have been returned, which passes the test */ dealtWithOutOfMemory = 1; REAL_TASK_COUNT = i; } } assert(REAL_TASK_COUNT >= FAIR_TASK_COUNT); assert(REAL_TASK_COUNT <= MAX_TASK_COUNT); assert( dealtWithOutOfMemory ); }
/*ARGSUSED*/ taskq_t * taskq_create(const char *name, int nthreads, pri_t pri, int minalloc, int maxalloc, uint_t flags) { taskq_t *tq = kmem_zalloc(sizeof (taskq_t), KM_SLEEP); int t; rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL); mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL); cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL); cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL); tq->tq_flags = flags | TASKQ_ACTIVE; tq->tq_active = nthreads; tq->tq_nthreads = nthreads; tq->tq_minalloc = minalloc; tq->tq_maxalloc = maxalloc; tq->tq_task.task_next = &tq->tq_task; tq->tq_task.task_prev = &tq->tq_task; tq->tq_threadlist = kmem_alloc(nthreads * sizeof (pthread_t), KM_SLEEP); if (flags & TASKQ_PREPOPULATE) { mutex_enter(&tq->tq_lock); while (minalloc-- > 0) task_free(tq, task_alloc(tq, KM_SLEEP)); mutex_exit(&tq->tq_lock); } for (t = 0; t < nthreads; t++) pthread_create(&tq->tq_threadlist[t], NULL, taskq_thread, tq); return (tq); }
void testAllocUniqueFreeMemory(void){ int i; task_t *prev_task = NULL; printf(" => testAllocUniqueFreeMemory\n"); for(i = 0; i < FAIR_TASK_COUNT; i++){ /* Point test slot i to the actual task_alloc() result. */ tasks[i] = task_alloc(); /* Slots must be allocated */ assert(tasks[i] != NULL); /* Cannot assert: Slots must be in the allocated space */ /* Try and set some data */ tasks[i]->id = i; /* Compare and set prev_task */ if (prev_task != NULL){ /* Slots must be unique in pointer reference */ assert(tasks[i] != prev_task); /* Slots must thus be unique in value */ assert(tasks[i]->id != prev_task->id); } prev_task = tasks[i]; /* Keep track of the amount of tasks*/ } }
void testAllocUniqueFreeMemory(void){ int i; task_t *prev_task = NULL; printf(" => testAllocUniqueFreeMemory\n"); for(i = 0; i < FAIR_TASK_COUNT; i++){ /* Point test slot i to the actual task_alloc() result. */ tasks[i] = task_alloc(); /* Slots must be allocated */ assert(tasks[i] != NULL); /* Slots must be in the allocated space */ assert( (unsigned long)tasks[i] <= ( (unsigned long)get_MEM_BLOCK_START() + MEM_BLOCK_SIZE ) ); /* Try and set some data */ tasks[i]->id = i; /* Compare and set prev_task */ if (prev_task != NULL){ /* Slots must be unique in pointer reference */ assert(tasks[i] != prev_task); /* Slots must thus be unique in value */ assert(tasks[i]->id != prev_task->id); } prev_task = tasks[i]; } }
struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof(struct TASKCTL)); for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; task->priority = 2; task->level = 0; task_add(task); task_switchsub(); load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
static int spmd_add_resolver_task(struct resolver_sock *rshead) { struct task *t; struct resolver_sock *rs = NULL; if (!rshead) { SPMD_PLOG(SPMD_L_INTERR, "Argument rshead is NULL"); return -1; } rs = rshead; while (rs) { t = task_alloc(MAX_UDP_DNS_SIZE); t->fd = rs->s; t->flags = 0; t->sa = &rs->sock.sa; t->salen = sizeof(rs->sock);/* cant use SPMD_SALEN() */ t->func = query_recv; task_list_add(t, &spmd_task_root->read); rs = rs->next; } return 0; }
struct SHEET *open_console(struct SHTCTL *shtctl, unsigned int memtotal) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct SHEET *sht = sheet_alloc(shtctl); unsigned char *buf = (unsigned char *) memman_alloc_4k(memman, 256 * 165); struct TASK *task = task_alloc(); int *cons_fifo = (int *) memman_alloc_4k(memman, 128 * 4); sheet_setbuf(sht, buf, 256, 165, -1); /* 透明色なし */ make_window8(buf, 256, 165, "console", 0); make_textbox8(sht, 8, 28, 240, 128, COL8_000000); task->cons_stack = memman_alloc_4k(memman, 64 * 1024); task->tss.esp = task->cons_stack + 64 * 1024 - 12; task->tss.eip = (int) &console_task; task->tss.es = 1 * 8; task->tss.cs = 2 * 8; task->tss.ss = 1 * 8; task->tss.ds = 1 * 8; task->tss.fs = 1 * 8; task->tss.gs = 1 * 8; *((int *) (task->tss.esp + 4)) = (int) sht; *((int *) (task->tss.esp + 8)) = memtotal; task_run(task, 2, 2); /* level=2, priority=2 */ sht->task = task; sht->flags |= 0x20; /* カーソルあり */ fifo32_init(&task->fifo, 128, cons_fifo, task); return sht; }
//打开新的console的函数 LAYER *open_console(LAYER_MANAGE *layer_manage, unsigned int memory_total) { MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR; LAYER *layer_console = layer_alloc(layer_manage); unsigned char *buf_console = (unsigned char *)memmanage_alloc_4K(memmanage, 256 * 165); TASK *task_console = task_alloc(); int *console_fifo = (int *)memmanage_alloc_4K(memmanage, 128 * 4); layer_set(layer_console, buf_console, 256, 165, -1); create_window(buf_console, 256, 165, "console", INACTIVE); create_textbox(layer_console, 8, 28, 240, 128, COL8_000000); task_console->console_stack = memmanage_alloc_4K(memmanage, 64 * 1024) + 64 * 1024 - 12; //由于这里要传入两个参数,所以减去了12 task_console->tss.esp = task_console->console_stack; task_console->tss.eip = (int) &console_task; //eip指向的是运行console的函数首地址 task_console->tss.es = 1 * 8; task_console->tss.cs = 2 * 8; task_console->tss.ss = 1 * 8; task_console->tss.ds = 1 * 8; task_console->tss.fs = 1 * 8; task_console->tss.gs = 1 * 8; *((int *) (task_console->tss.esp + 4)) = (int) layer_console; *((int *) (task_console->tss.esp + 8)) = memory_total; task_run(task_console, 2, 2); /* level=2, priority=2 */ layer_console->task = task_console; layer_console->flags |= 0x20; //flags的0x20代表当前窗口的光标ON init_fifo(&task_console->fifo, 128, console_fifo, task_console); return layer_console; }
void taskq_destroy(taskq_t *tq) { int t; int nthreads = tq->tq_nthreads; taskq_wait(tq); mutex_enter(&tq->tq_lock); tq->tq_flags &= ~TASKQ_ACTIVE; cv_broadcast(&tq->tq_dispatch_cv); while (tq->tq_nthreads != 0) cv_wait(&tq->tq_wait_cv, &tq->tq_lock); tq->tq_minalloc = 0; while (tq->tq_nalloc != 0) { ASSERT(tq->tq_freelist != NULL); task_free(tq, task_alloc(tq, KM_SLEEP)); } mutex_exit(&tq->tq_lock); for (t = 0; t < nthreads; t++) (void) thr_join(tq->tq_threadlist[t], NULL, NULL); kmem_free(tq->tq_threadlist, nthreads * sizeof (thread_t)); rw_destroy(&tq->tq_threadlock); kmem_free(tq, sizeof (taskq_t)); }
void testFreeUsedMemory(void){ int i; printf(" => testFreeUsedMemory\n"); /* Also, if we first free FAIR_TASK_COUNT... */ for(i = 0; i < FAIR_TASK_COUNT; i++){ /* Skip the entry we used in the previous test. This prevents a double free. */ if(i==1) continue; /* All slots were allocated up to FAIR_TASK_COUNT. */ assert(tasks[i] != NULL); /* Free the task. */ task_free(tasks[i]); } /* ...and then alloc FAIR_TASK_COUNT, we should not go out of memory. */ for(i = 0; i < FAIR_TASK_COUNT; i++){ /* Allocate a slot */ tasks[i] = NULL; tasks[i] = task_alloc(); /* The allocation should have succeeded. */ assert(tasks[i] != NULL); } }
struct _task *task_init(struct _memman *memman) { int i; struct _task *task; struct _segmdes *gdt = (struct _segmdes *) ADR_GDT; taskctl = (struct _taskctl *) memman_alloc_4k(memman, sizeof (struct _taskctl)); taskctl->now_lv = 0; taskctl->lv_change = 0; for (i = 0; i < MAX_TASKS; i++) { /* Register all task slots on segment descriptor table */ taskctl->tasks0[i].flags = TASK_UNUSED; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; /* Setup selector (GDT segment) number */ set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } /* Allocate new task for task_init caller */ task = task_alloc(); task->flags = TASK_RUNNING; /* Priority and level */ task->priority = 2; /* Timeslice = 10ms * pri */ task->level = 0; /* Highest Level */ /* Add task to level control */ task_add(task); /* Recalebrate Running Level */ task_switchsub(); /* Activate Current Task */ load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
static int create_workqueue_thread(struct workqueue_struct *wq, const char *name) { task_t *task_wq; startup_t startup; int ret; sema_init(&wq->lock, 1); wq->task = NULL; wq->insert_sequence = 0; wq->remove_sequence = 0; INIT_LIST_HEAD(&wq->worklist); init_waitqueue_head(&wq->more_work); init_waitqueue_head(&wq->work_done); init_completion(&wq->exit); init_completion(&startup.done); startup.wq = wq; startup.name = name; task_wq = task_alloc("workqueue", WQ_STACK_SIZE, 1); if (NULL == task_wq) { return -1; } ret = task_create(task_wq, worker_thread, &startup); if (0 == ret) { wait_for_completion(&startup.done); } return ret; }
task_t* task_init(mem_mgr_t* mem_mgr) { int i; task_t* task; segment_descriptor_t* gdt = (segment_descriptor_t*)ADR_GDT; g_taskctrl = (task_ctrl_t*)mem_mgr_alloc_4k(mem_mgr, sizeof(task_ctrl_t)); for (i = 0; i < MAX_TASKS; ++i) { g_taskctrl->tasks[i].flags = 0; g_taskctrl->tasks[i].sel = (TASK_GDT0 + i) * 8; set_segment_descriptor(gdt + TASK_GDT0 + i, 103, (int)&g_taskctrl->tasks[i].tss, AR_TSS32); } task = task_alloc(); task->flags = 2; /* flags about activity */ g_taskctrl->running = 1; g_taskctrl->now = 0; g_taskctrl->tasks_map[0] = task; load_tr(task->sel); g_task_timer = timer_alloc(); timer_settimer(g_task_timer, 2); return task; }
taskqid_t taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, unsigned int tqflags) { taskq_ent_t *t; if (taskq_now) { func(arg); return (1); } mxlock(&tq->tq_lock); assert(tq->tq_flags & TASKQ_ACTIVE); if ((t = task_alloc(tq, tqflags)) == NULL) { mxunlock(&tq->tq_lock); return (0); } if (tqflags & TQ_FRONT) { t->tqent_next = tq->tq_task.tqent_next; t->tqent_prev = &tq->tq_task; } else { t->tqent_next = &tq->tq_task; t->tqent_prev = tq->tq_task.tqent_prev; } t->tqent_next->tqent_prev = t; t->tqent_prev->tqent_next = t; t->tqent_func = func; t->tqent_arg = arg; t->tqent_flags = 0; condsig(&tq->tq_dispatch_cv); mxunlock(&tq->tq_lock); return (1); }
/* init taskctl and allocate the first task to the thread that calls the init method we don't need to assign it a fifo because all it doesn't is to switch by calling farjmp() and doesn't need to put data to any buffer */ struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *)memman_alloc_4k(memman, sizeof(struct TASKCTL)); for(i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; taskctl->tasks0[i].flags = 0; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32); } /* initialize all levels */ for(i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } /* after initializaing all tasks in taskctl, we need to alloc the first task and assign it to the thread that calls init */ task = task_alloc(); task->flags = 2; /* running */ task->priority = 2; task->level = 0; /* the first task(for mouse/keyboard/timer interruption) should be in highest level */ task_add(task); task_switchsub(); /* update taskctl->now_lv */ /* set task register to current task */ load_tr(task->sel); idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8; idle->tss.eip = (int)&task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; /* the idle task will always be running at lowest level in case there's no when there's no active task to run and OS doesn't know where to jump */ task_run(idle, MAX_TASKLEVELS - 1, 1); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
//任务管理主体的初始化(并为调用这个函数的那个程序分配一个任务状态段) TASK *task_init(MEMMANAGE *memman) { int i; TASK *task, *idle; SEGMENT_DESCRIPTOR *gdt = (SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (TASKCTL *) memmanage_alloc_4K(memman, sizeof (TASKCTL)); //对taskctl进行初始化 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks[i].flags = UNUSED; taskctl->tasks[i].selector = (TASK_GDT0 + i) * 8; //为这个任务分配任务状态段所在的GDT描述符 set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->task_level[i].running_number = 0; taskctl->task_level[i].task_now = 0; } /*为调用这个初始化函数的程序分配一个属于它的任务*/ /*为调用这个初始化函数的程序分配一个属于它的任务*/ task = task_alloc(); task->flags = RUNNING; //这个任务当前正在运行中 task->priority = 2; //任务的优先级默认的都是2,即可以占用CPU0.02秒 task->level = 0; //调用这个函数的任务默认设定为最高级0级 task_add(task); //自动根据task的level添加到相应等级任务队列中 level_switch(); //由于有新任务添加进来,所以需要改变当前的lv_now load_tr(task->selector); //改写TR寄存器,让它存储当前这个任务的段偏移值 task_timer = timer_alloc(); //分配一个用于任务切换的计时器 timer_set(task_timer, task->priority); //0.02秒切换一次任务 /*给整个操作系统一个最低级的任务,这样当没有任务且键盘鼠标等任务休眠的时候就可以转到这个任务里 **,这个任务永远存在 */ idle = task_alloc(); idle->tss.esp = memmanage_alloc_4K(memman, 64 * 1024) + 64 * 1024; idle->tss.eip = (int) &task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
/** * @description 初始化 * @param menman:内存地址 */ struct TASK *task_init(struct MEMMAN *memman){ int i; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); //TODO 初始化所有任务 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } //TODO 初始化所有优先级层 for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; // task->priority = 2; //0.02秒 task->level = 0; //最高级别 task_add(task); task_switchsub(); //切换 load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); //TODO 初始化空闲进程 idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024; //X86的栈是向下增长的,所以需要+64*1024 idle->tss.eip = (int) &task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
/* 整个多任务系统的初始化初始化 */ struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); /* 初始化所有的任务的task结构 */ for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; /* 选择子初始化 */ /* 描述符初始化 */ set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } /* 初始化所有level结构 */ for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; /* 没有正在运行的任务 */ taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; /* 活动中标志 */ task->priority = 2; /* 0.02秒 */ task->level = 0; /* 最高LEVEL */ task_add(task); task_switchsub(); /* LEVEL设置 */ load_tr(task->sel); /* 修改tr寄存器 */ task_timer = timer_alloc(); /* 重头戏!!任务切换的定时器 */ timer_settime(task_timer, task->priority); /* 闲置任务的初始化 */ idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024; idle->tss.eip = (int) &task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
task_t* task_init(mem_mgr_t* mem_mgr) { int i; task_t* task; task_t* idle; segment_descriptor_t* gdt = (segment_descriptor_t*)ADR_GDT; g_taskctrl = (task_ctrl_t*)mem_mgr_alloc_4k(mem_mgr, sizeof(task_ctrl_t)); for (i = 0; i < MAX_TASKS; ++i) { g_taskctrl->tasks[i].flags = 0; g_taskctrl->tasks[i].sel = (TASK_GDT0 + i) * 8; set_segment_descriptor(gdt + TASK_GDT0 + i, 103, (int)&g_taskctrl->tasks[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; ++i) { g_taskctrl->levels[i].running = 0; g_taskctrl->levels[i].now = 0; } task = task_alloc(); task->flags = 2; /* flags about activity */ task->level = 0; /* top task level */ task->priority = 2; /* 0.02 s */ task_add(task); task_switch_sub(); /* setting level */ load_tr(task->sel); g_task_timer = timer_alloc(); timer_settimer(g_task_timer, task->priority); idle = task_alloc(); idle->tss.esp = mem_mgr_alloc_4k(mem_mgr, 64 * 1024) + 64 * 1024; idle->tss.eip = (int)&task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
/*ARGSUSED*/ taskq_t * taskq_create(const char *name, int nthreads, int minalloc, int maxalloc, unsigned int flags) { taskq_t *tq; int t; tq = umem_zalloc(sizeof(taskq_t), 0); if (!tq) return NULL; if (flags & TASKQ_THREADS_CPU_PCT) { int pct; assert(nthreads >= 0); assert(nthreads <= taskq_cpupct_max_percent); pct = MIN(nthreads, taskq_cpupct_max_percent); pct = MAX(pct, 0); nthreads = (sysconf(_SC_NPROCESSORS_ONLN) * pct) / 100; nthreads = MAX(nthreads, 1); /* need at least 1 thread */ } else { assert(nthreads >= 1); } rwinit(&tq->tq_threadlock); mxinit(&tq->tq_lock); condinit(&tq->tq_dispatch_cv); condinit(&tq->tq_wait_cv); condinit(&tq->tq_maxalloc_cv); (void) strncpy(tq->tq_name, name, TASKQ_NAMELEN + 1); tq->tq_flags = flags | TASKQ_ACTIVE; tq->tq_active = nthreads; tq->tq_nthreads = nthreads; tq->tq_minalloc = minalloc; tq->tq_maxalloc = maxalloc; tq->tq_task.tqent_next = &tq->tq_task; tq->tq_task.tqent_prev = &tq->tq_task; tq->tq_threadlist = umem_alloc(nthreads * sizeof (pthread_t), UMEM_NOFAIL); if (flags & TASKQ_PREPOPULATE) { mxlock(&tq->tq_lock); while (minalloc-- > 0) task_free(tq, task_alloc(tq, UMEM_NOFAIL)); mxunlock(&tq->tq_lock); } for (t = 0; t < nthreads; t++) pthread_create(&tq->tq_threadlist[t], NULL, taskq_thread, tq); return (tq); }
int main(int argc, char *argv[]) { TaskQueue *tq = taskqueue_alloc(); FuncArgs *fa = malloc(sizeof(FuncArgs)); fa->count = 5; Task *t = task_alloc(&func, fa); taskqueue_enqueue(tq, t); taskqueue_run(tq); return 0; }
void kmain(void) { task_t *task_shell; int ret; /*************** Init Arch ****************/ arch_early_init(); show_logo(); /*************** Init Platform ****************/ platform_init(); timer_init(); buses_init(); /*************** Init Task ****************/ task_init(); task_create_init(); /*************** Init Workqueu ****************/ init_workqueues(); /*************** Init File System ****************/ register_filesystem(&fat_fs); /*************** Creating Shell TASK ****************/ task_shell = task_alloc("shell", 0x2000, 5); if (NULL == task_shell) { return; } ret = task_create(task_shell, init_shell, 0); if (ret) { printk("Create init shell task failed\n"); } sema_init(&sem, 1); arch_enable_ints(); while(1) { enter_critical_section(); arch_idle(); task_schedule(); exit_critical_section(); } task_free(task_shell); }
static void task_pool_push( TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata, TaskPriority priority, int thread_id) { Task *task = task_alloc(pool, thread_id); task->run = run; task->taskdata = taskdata; task->free_taskdata = free_taskdata; task->freedata = freedata; task->pool = pool; task_scheduler_push(pool->scheduler, task, priority); }
TASK* task_init(MEMMAN* memman) { SEGMENT_DESCRIPTOR* gdt = (SEGMENT_DESCRIPTOR*)ADR_GDT; taskctl = (TASKCTL*)memman_alloc_4k(memman, sizeof(TASKCTL)); for (int i = 0; i < MAX_TASKS; ++i) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32); set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int)taskctl->tasks0[i].ldt, AR_LDT); } for (int i = 0; i < MAX_TASKLEVELS; ++i) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } TASK* task = task_alloc(); // Main task. task->flags = RUNNING; task->priority = 2; // 0.02 sec task->level = 0; // Max level. task_add(task); task_switchsub(); load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); TASK* idle = task_alloc(); idle->tss.esp = (int)memman_alloc_4k(memman, 256) + 256; idle->tss.eip = (int)&task_idle; idle->tss.es = idle->tss.ss = idle->tss.ds = idle->tss.fs = idle->tss.gs = 1 * 8; idle->tss.cs = 2 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); taskctl->task_fpu = NULL; return task; }
task_t* task_init(memman_t* memman) { int i; task_t *task, *idle; segment_descriptor* gdt = (segment_descriptor*)ADR_GDT; taskctl = (taskctl_t*)memman_alloc_4k(memman, sizeof(taskctl_t)); for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32); set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int)taskctl->tasks0[i].ldt, AR_LDT); } task = task_alloc(); task->flags = 2; /* 活动中标志 */ task->priority = 2; /* 0.02s */ task->level = 0; /* 最高等级 */ task_add(task); task_switchsub(); /* 设置等级 */ load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024; idle->tss.eip = (int)&task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
void testReuseFreedMemory(void){ task_t* task; printf(" => testReuseFreedMemory\n"); /* Integrity check of the test. */ assert(tasks[1] != NULL); /* All slots are taken (due to testAllocHandlesOutOfMemory). So we free one and allocate one, which should be identical to that slot. */ task_free(tasks[1]); task = task_alloc(); /* Freed and reassigned slot identical in pointer. */ assert(task == tasks[1]); /* Freed and reassigned slot identical in value. */ assert(task->id == tasks[1]->id); }
void runTests(void) { void *task_a; void *task_b; void *task_c; void *task_d; void *task_e; void *task_f; void *task_g; printf("Testing task_alloc and task_free\n"); /* Allocate 4 task_t's */ printf("- Allocate 4 task_t's\n"); task_a = task_alloc(); assert(0 < (int)task_a); task_b = task_alloc(); assert((int)task_a < (int)task_b); task_c = task_alloc(); assert((int)task_b < (int)task_c); task_d = task_alloc(); assert((int)task_c < (int)task_d); /* Free task a, b and c (in order a, c, b) */ printf("- Free task a, b and c (in order a, c, b)\n"); task_free(task_a); task_free(task_c); task_free(task_b); /* Reallocate slot a, b and c */ printf("- Reallocate slot a, b and c\n"); task_e = task_alloc(); assert(task_e == task_a); task_f = task_alloc(); assert(task_f == task_c); task_g = task_alloc(); assert(task_g == task_b); /* Free task g twice */ printf("- Free task g twice\n"); task_free(task_g); task_free(task_g); printf("All tests have succeeded.\n"); }
//启动一个命令行窗口任务 TASK *open_console_task(LAYER *layer, unsigned int mem_total) { MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR; TASK *task_console = task_alloc(); int *console_fifo = (int *)memmanage_alloc_4K(memmanage, 128 * 4); task_console->console_stack = memmanage_alloc_4K(memmanage, 64 * 1024); //由于这里要传入两个参数,所以减去了12 task_console->tss.esp = task_console->console_stack + 64 * 1024 - 12; task_console->tss.eip = (int) &console_task; //eip指向的是运行console的函数首地址 task_console->tss.es = 1 * 8; task_console->tss.cs = 2 * 8; task_console->tss.ss = 1 * 8; task_console->tss.ds = 1 * 8; task_console->tss.fs = 1 * 8; task_console->tss.gs = 1 * 8; *((int *) (task_console->tss.esp + 4)) = (int) layer; *((int *) (task_console->tss.esp + 8)) = mem_total; task_run(task_console, 2, 2); /* level=2, priority=2 */ init_fifo(&task_console->fifo, 128, console_fifo, task_console); return task_console; }
struct TASK *open_constask(struct SHEET *sht, unsigned int memtotal) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct TASK *task = task_alloc(); int *cons_fifo = (int *) memman_alloc_4k(memman, 128 * 4); task->cons_stack = memman_alloc_4k(memman, 64 * 1024); task->tss.esp = task->cons_stack + 64 * 1024 - 12; task->tss.eip = (int) &console_task; task->tss.es = 1 * 8; task->tss.cs = 2 * 8; task->tss.ss = 1 * 8; task->tss.ds = 1 * 8; task->tss.fs = 1 * 8; task->tss.gs = 1 * 8; *((int *) (task->tss.esp + 4)) = (int) sht; *((int *) (task->tss.esp + 8)) = memtotal; task_run(task, 2, 2); /* level=2, priority=2 */ fifo32_init(&task->fifo, 128, cons_fifo, task); return task; }