void c_entry(void) { int i = 0; task_count = 0; currentTask = 0; /* VIC Configuration */ VIC_INT_SELECT = 0; VIC_ENABLE_INT = 0x00000210; /* Enable Timer01 Interrupt and UART0 */ unsigned int user_stacks[TASK_LIMIT][STACK_SIZE]; /* Task initialization */ init_task(&task[0], user_stacks[0], &task1_func); task_count = task_count + 1; init_task(&task[1], user_stacks[1], &task2_func); task_count = task_count + 1; init_task(&task[2], user_stacks[2], &task3_func); task_count = task_count + 1; print_uart0("OS: Starting...\n"); print_uart0("OS: Scheduler implementation : round-robin\n"); /* Timer1 Configuration */ TIMER01_disable(); TIMER01_LOAD_VALUE = 65535; TIMER01_enable(); activate(task[currentTask].sp); while (i < 5) { TIMER01_disable(); print_uart0("Kernel gets back control ! \n"); print_uart0("Kernel can do some stuff...\n"); print_uart0("Load the next task ! \n"); /* Scheduler */ currentTask = currentTask + 1; if (currentTask >= 2) currentTask = 0; /* We only start the first and second task */ TIMER01_LOAD_VALUE = 65535; TIMER01_enable(); activate(task[currentTask].sp); TIMER01_disable(); i++; } print_uart0("Kernel is going to activate Task #3 " "which will call a syscall() to return back " "to kernel mode \n"); activate(task[2].sp); print_uart0("Kernel gets back control ! \n"); print_uart0("Now, the OS is about to shutdown."); while (1) /* wait */ ; }
/******************************************************** MAIN *********************************************************/ int main(void) { int map[XMAX][YMAX], bmap[XMAX][YMAX][2]; SPLAYER player; LPTCB task; floor_cnt = 1; init_genrand((unsigned long)time(NULL)); // 必ずmainに入れること init_task(); init_monster(); task = create_task(title_load, NULL, PRIO_00); task->p[0] = &player; task->p[1] = &floor_cnt; task = create_task(game_start, NULL, PRIO_00); task->p[0] = map; task->p[1] = &player; task->p[2] = bmap; loop_task(); // printf("taskcnt =%d\n", count_task()); return 0; }
void sched_init() { // Creamos la tarea ``init`` task_t *init = kmalloc(sizeof(task_t)); init->prog = kmalloc(sizeof(program_t)); init->prog->name = "init"; init->pd = kernel_pd; init->kernel_stack = KERNEL_STACK_TOP; init->kernel_stack_limit = KERNEL_STACK_BOTTOM; init->waiting = FALSE; init->waited = FALSE; init->parent = NULL; init->ticks = 0; init->quantum = SCHED_QUANTUM; restart_quantum(init); init->pid = get_next_pid(); // El stack de nivel 0 no interesa. Deberia sobreescribirse al cambiar de // tarea. Ademas, como estamos en espacio de kernel, no se deberia utilizar // el valor del stack de nivel 0 que esta en la TSS. init->kernel_stack_pointer = NULL; setup_tss(NULL); add_task(init); sti(); init_task(); }
/* init_itron --- ITRON の初期化を行う。 * */ static ER init_itron () { init_interrupt (); simple_init_console (); /* コンソールに文字を出力できるようにする */ pmem_init (); /* 物理メモリ管理機能の初期化 */ banner (); /* 立ち上げメッセージ出力 */ printf ("init_itron: start\n"); init_kalloc (); /* バイト単位のメモリ管理機能の初期化 */ init_semaphore (); /* セマフォの管理機能の初期化 */ init_msgbuf (); /* メッセージ管理機能の初期化 */ init_eventflag (); /* イベントフラグ管理機能の初期化 */ #ifdef notdef init_mpl (); /* メモリプール管理機能の初期化 */ simple_init_console (); /* コンソールに文字を出力できるようにする */ #endif init_task (); /* タスク管理機能の初期化 */ /* 1番目のタスクを初期化する。そしてそのタスクを以後の処 * 理で使用する。 */ init_task1 (); printf ("call init_timer\n"); init_timer (); /* インターバルタイマ機能の初期化 */ start_interval (); /* インターバルタイマの起動 */ init_io (); return (E_OK); }
/*======================================================================* kernel_main *======================================================================*/ PUBLIC int kernel_main() { clear_screen(); loadELF(); TASK* p_task = task_table; PROCESS* p_proc = proc_table; char* p_task_stack = task_stack + STACK_SIZE_TOTAL; u16 selector_ldt = SELECTOR_LDT_FIRST; int i,priority; proc_table[0].ticks = proc_table[0].pre_ticks=proc_table[0].priority = 20; proc_table[0].status = RUNNING; init_task(proc_table,task_table,SELECTOR_LDT_FIRST,p_task_stack,20,RUNNING); for (i=1; i<NR_TASKS; i++){ proc_table[i].pid=i+1; proc_table[i].status=STOPPED; task_table[i].stacksize=0x400; } control_ticks(); k_reenter=0; ticks=0; p_proc_ready=proc_table; init_clock(); init_keyboard(); restart(); while(1){} }
int lc_open_task(lua_State *L) { init_task(); if (luaL_newmetatable(L, CASTING_TASK) == 1) { luaL_register(L, NULL, task_meths); // [tbl][tbl] lua_setfield(L, -1, "__index"); } return 0; }
void setup() { Serial.begin(115200); fdevopen(&serial_putc, 0); fb_init(fb_default()); init_task(); vTaskStartScheduler(); }
static void mainproc(void *arg) { Dynamic *dynamicp; Gfx *glistp; Control cont; init_dma(); init_task(); init_framebuffer(); read_rom( _staticSegmentStart, _staticSegmentRomStart, _staticSegmentRomEnd ); read_rom( _dkSegmentStart, _dkSegmentRomStart, _dkSegmentRomEnd ); read_rom( _dk7SegmentStart, _dk7SegmentRomStart, _dk7SegmentRomEnd ); read_rom( _roadSegmentStart, _roadSegmentRomStart, _roadSegmentRomEnd ); read_rom( _l2_tvSegmentStart, _l2_tvSegmentRomStart, _l2_tvSegmentRomEnd ); init_controlers( &cont ); game_init(); while (1) { read_controler( &cont ); dynamicp = &dynamic; guOrtho( &dynamicp->projection, -(float) SCREEN_WD / 2.0F, (float) SCREEN_WD / 2.0F, -(float) SCREEN_HT / 2.0F, (float) SCREEN_HT / 2.0F, 1.0F, 10.0F, 1.0F ); guRotate( &dynamicp->modeling, 0.0F, 0.0F, 0.0F, 1.0F ); glistp = dynamicp->glist; /* rcp rdp & color frame buffer initialize */ glistp = init_rcprdp( glistp, (char *)_staticSegmentStart, draw_buffer ); glistp = clear_cfb( glistp ); /* game main */ glistp = game_main( glistp, &cont ); gDPFullSync(glistp++); gSPEndDisplayList(glistp++); assert((glistp - dynamicp->glist) < GLIST_LEN); start_task( glistp, dynamicp ); swap_framebuffer( draw_buffer ); draw_buffer ^= 1; } }
int start_program(char *process_name, void* initial_eip){ int i; for (i=1; i<NR_TASKS; i++) if (proc_table[i].status==STOPPED){ memcpy(task_table[i].name,process_name,sizeof(process_name)+1); task_table[i].initial_eip=initial_eip; char* stk=task_stack+STACK_SIZE_TOTAL-task_table[i].stacksize*i; init_task(proc_table+i,task_table+i,SELECTOR_LDT_FIRST+i*(1<<3),stk,4,RUNNING); return proc_table[i].pid; } return -1; }
int read_taskset(FILE *fp) { char line[MAX_BUF], s[MAX_BUF]; char props[NR_COLS][MAX_BUF]; ulong_t lcm; int tmp; int n; /* # of tasks */ int i, j; char *token; ulong_t C, T, D; /* skip comments and empty lines */ while(fgets(line, MAX_BUF, fp)) { if (line[0] != '\n' && line[0] != '#') break; } /* get the number of tasks */ n = atoi(line); /* allocate the memory for the tasks */ tasks = (task_t *) malloc(sizeof(task_t) * n); /* skip comments and empty lines */ while(fgets(line, MAX_BUF, fp)) { if (line[0] != '\n' && line[0] != '#') break; } for (i = 0; i < n; i++) { strcpy(s, line); token = strtok(s, ",\t "); /* get task name, exec. time, period, and relative deadline. */ for (j = 0; j < NR_COLS; j++) { if (!token) { printf("Error: invalid format: %s!\n", line); exit(1); } strncpy(props[j], token, MAX_BUF); token = strtok(NULL, ",\t "); } C = atoi(props[1]); T = atoi(props[2]); D = atoi(props[3]); init_task(&tasks[i], i, C, T, D); // printf("task%d: %d, %d, %d\n", i, C, T, D); /* get line for the next task. */ fgets(line, MAX_BUF, fp); } return n; }
/* kernel_main() * This is called by the low-level architecture startup routine. It sets up * the kernel proper and generally gets the operating system off the ground. */ void kernel_main(unsigned int initial_stack) { initial_esp = initial_stack; /* as given to us by multiboot */ /* Set up the default kernel flags. Change these by adding their * corresponding option when booting the kernel. */ kern.flags.preempt_kernel = TRUE; kern.flags.debug_sched = FALSE; kern.flags.debug_task = FALSE; kern.flags.debug_interrupt = FALSE; kern.flags.debug_ticks = FALSE; kern.flags.stats = FALSE; /* Before we do anything with the higher-level kernel, move the kernel * stack to a known location. This has to copy and remap all absolute * memory addresses. */ move_stack((void *)STACK_LOC, STACK_SIZE); /* Extract and set any options given to the kernel */ parse_cmdline(kern.cmdline); /* Now that all the lower-level startup has been done, we can set up * the higher-level kernel functions. */ init_vt(); print_startup(); setup_initrd(); load_kernel_symbols(); init_sched(); init_task(); create_init(); /* Start the kthread daemon going to set up other kernel threads */ kthread_create(kthreadd, "kthreadd"); /* And we're done */ kprintf("Kernel startup complete in %ldms\n\n", kern.current_time_offset.tv_msec); /* We need to wait a bit here for all the threads to settle themselves * before going away. */ sleep(100); /* The kernel task has finished the startup, so remove the task from the * system. This should never return, so panic if it does. */ task_exit(); panic("Kernel task did not die when it was supposed to :-("); }
int main() { init_task(&task); signal(SIGPIPE,SIG_IGN); signal(SIGINT,signal_quit); create_listen_thread(); create_worker_thread(); while(1) { } }
ERL_NIF_TERM snappy_decompress_impl(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ctx_t *ctx; task_t *task; ErlNifPid pid; if (argc != 4) { return enif_make_badarg(env); } if (!enif_get_resource(env, argv[0], res_type, reinterpret_cast<void**>(&ctx))) { return enif_make_badarg(env); } if (!enif_is_ref(env, argv[1])) { return enif_make_tuple2(env, atom_error, enif_make_string(env, "Second arg. is not a reference", ERL_NIF_LATIN1)); } if (!enif_get_local_pid(env, argv[2], &pid)) { return enif_make_tuple2(env, atom_error, enif_make_string(env, "Third arg. is not a pid of local process", ERL_NIF_LATIN1)); } if (!enif_is_binary(env, argv[3])) { return enif_make_tuple2(env, atom_error, enif_make_string(env, "Forth arg. is not a binary", ERL_NIF_LATIN1)); } task = init_task(DECOMPRESS, argv[1], pid, argv[3]); if (!task) { return enif_make_tuple2(env, atom_error, enif_make_string(env, "Failed to create a task", ERL_NIF_LATIN1)); } async_queue_push(ctx->queue, static_cast<void*>(task)); return atom_ok; }
coroutine_env_t::coroutine_env_t() { coroutine_env_t *self = this; self->main = new coroutine_t(); init_coroutine(self->main); self->main->is_main = 1; self->main->state = RUNNING; self->main->desc = "main"; INIT_LIST_HEAD(&self->main->wait_to); self->curr_co = self->main; INIT_LIST_HEAD(&self->run_queue); list_add_tail(&self->main->wait_to, &self->run_queue); INIT_LIST_HEAD(&self->tasks); self->spec_key_seed = 10000; this->pthread_mgr = NULL; // 初始化任务分发器 self->dispatch = new dispatch_mgr_t(this); INIT_LIST_HEAD(&this->delay_del_list); init_task(&delay_del_task, do_delay_del_co_task, this); // 初始化 epoll 环境 self->epoll_ctx = create_epoll_ctx(this, 100); // 添加到调度 self->dispatch->registry(&this->epoll_ctx->task); // 初始化定时器 self->tw = new timewheel_t(this, FLAGS_timewheel_slot_num); //后续才能启动, 因为全局变量为设置 // self->tw->start(); //堆栈设置为 64 字节对齐 this->default_stack_pool.init(FLAGS_stack_size, 100000, 64); this->co_struct_pool.init(sizeof(coroutine_t), 1000, __alignof__(coroutine_t)); }
void start(uint32_t* modulep, void* physbase, void* physfree) { clear_screen(); // printf("Pysfree in mainbefore:BASE:%x:%x", physfree, physbase); while(modulep[0] != 0x9001) modulep += modulep[1]+2; for(smap = (struct smap_t*)(modulep+2); smap < (struct smap_t*)((char*)modulep+modulep[1]+2*4); ++smap) { if (smap->type == 1 /* memory */ && smap->length != 0) { // printf("Available Physical Memory [%x-%x]\n", smap->base, smap->base + smap->length); free_page_list(smap, physbase, physfree); // Creates free page list (linked list implementation) } } // printf("tarfs in [%p:%p]\n", &_binary_tarfs_start, &_binary_tarfs_end); // kernel starts here physfree += 1048576; // increasing physfree by 1 MB accomodating free page list // uint64_t cur_VK = ((uint64_t )physfree + 0xffffffff80000000); // Free Virtual Memory above Kernel starts from here // uint64_t cur_PK = 0x2097152; // Starts at 2 MB mark (abhi confirm) // uint64_t pbase99 = (uint64_t)((uint64_t)physfree + 0xffffffff80000000); // uint64_t pid_bitmap[32]= {0}; // printf("PhysFREE in mainnow:%x", physfree); // printf("\nFREE_PAGE:%x:%x:%x", (uint64_t *) get_page()); // printf("\n VK:%x", cur_VK); kern_pt((void *) &kernmem, (uint64_t)physbase, (uint64_t)physfree); // Mapping Kernel to new Page Table init_VM((uint64_t) physfree); init_task(); init_fdtable(); clear_screen(); init_shell(); // uint64_t te = 0xFFFF00FF80000000; // *te = 1; // void *te = (void *) 0xFFFFFFFF80000000; // void *te = (void *) 0xFFFF000080000000; // uint64_t te =(uint64_t) (0xffffffff80000000 + physbase); // uint64_t te = 0xFFFFFEFF80000000; // self_refrence(te); // call_first(); //update physfree // printf("\n CHAR:%c:%s:%d:\n:%x:%p", 'A', "STONY !@#$ BROOK", 9999, 0xFFFF1B, &(stack)); // printf("\n STRING:%s","ABHIROOP DABRAL"); // printf("\n INT:%d", 0xFFC); // printf("\n HEX:%x", 510); // printf("\n PT:%p",(uint64_t *) te); while(1); }
int Downloader::run(void) { int ret; ret = init_task(); if(ret < 0){ cerr<<_("Can not get the info of the file ")<<endl; return ret; } if(task.isDirectory){ cerr<<_("This is a directory: ")<<task.url.get_url()<<endl; return directory_download(); } return file_download(); }; // end of run
static void start_kernel() { init_clock(); //clock interrupt init get_memsize(&main_memory_end); main_memory_end &= 0xfffff000; paging_init(); init_mem(); //memeory management init buffer_init(); /* scheduler init */ init_sched(); init_hd(); //hard disk init init_fs(); //filesystem init init_task(); /*init_sock();*/ }
int restart_process(char *name){ TASK* p_task = task_table; PROCESS* p_proc = proc_table; char* p_task_stack = task_stack + STACK_SIZE_TOTAL; u16 selector_ldt = SELECTOR_LDT_FIRST; int i,pid=-1; for (i = 0; i < NR_TASKS; i++) { if (strcmp(p_proc->p_name,name)==0){ pid=p_proc->pid; if (p_proc->status==SLEEPING){ p_proc->status=RUNNING; } else{ init_task(p_proc,p_task,selector_ldt,p_task_stack,4,RUNNING); } break; } p_task_stack -= p_task->stacksize; p_proc++; p_task++; selector_ldt += 1 << 3; } control_ticks(); return pid; }
int main(void) { unsigned int stacks[TASK_LIMIT][STACK_SIZE]; unsigned int *tasks[TASK_LIMIT]; struct pipe_ringbuffer pipes[PIPE_LIMIT]; size_t task_count = 0; size_t current_task = 0; size_t i; *(PIC + VIC_INTENABLE) = PIC_TIMER01; *TIMER0 = 10000; *(TIMER0 + TIMER_CONTROL) = TIMER_EN | TIMER_PERIODIC | TIMER_32BIT | TIMER_INTEN; tasks[task_count] = init_task(stacks[task_count], &first); task_count++; /* Initialize all pipes */ for(i = 0; i < PIPE_LIMIT; i++) { pipes[i].start = pipes[i].end = 0; } while(1) { tasks[current_task] = activate(tasks[current_task]); tasks[current_task][-1] = TASK_READY; switch(tasks[current_task][2+7]) { case 0x1: /* fork */ if(task_count == TASK_LIMIT) { /* Cannot create a new task, return error */ tasks[current_task][2+0] = -1; } else { /* Compute how much of the stack is used */ size_t used = stacks[current_task] + STACK_SIZE - tasks[current_task]; /* New stack is END - used */ tasks[task_count] = stacks[task_count] + STACK_SIZE - used; /* Copy only the used part of the stack */ memcpy(tasks[task_count], tasks[current_task], used*sizeof(*tasks[current_task])); /* Set return values in each process */ tasks[current_task][2+0] = task_count; tasks[task_count][2+0] = 0; /* There is now one more task */ task_count++; } break; case 0x2: /* getpid */ tasks[current_task][2+0] = current_task; break; case 0x3: /* write */ _write(tasks[current_task], tasks, task_count, pipes); break; case 0x4: /* read */ _read(tasks[current_task], tasks, task_count, pipes); break; case 0x5: /* interrupt_wait */ /* Enable interrupt */ *(PIC + VIC_INTENABLE) = tasks[current_task][2+0]; /* Block task waiting for interrupt to happen */ tasks[current_task][-1] = TASK_WAIT_INTR; break; default: /* Catch all interrupts */ if((int)tasks[current_task][2+7] < 0) { unsigned int intr = (1 << -tasks[current_task][2+7]); if(intr == PIC_TIMER01) { /* Never disable timer. We need it for pre-emption */ if(*(TIMER0 + TIMER_MIS)) { /* Timer0 went off */ *(TIMER0 + TIMER_INTCLR) = 1; /* Clear interrupt */ } } else { /* Disable interrupt, interrupt_wait re-enables */ *(PIC + VIC_INTENCLEAR) = intr; } /* Unblock any waiting tasks XXX: nondeterministic unblock order */ for(i = 0; i < task_count; i++) { if(tasks[i][-1] == TASK_WAIT_INTR && tasks[i][2+0] == intr) { tasks[i][-1] = TASK_READY; } } } } /* Select next TASK_READY task */ while(TASK_READY != tasks[current_task = (current_task + 1) % task_count][-1]); } return 0; }
/* This function is called whenever the port is written to. The port should be in binary mode, see open_port/2. The ErlIOVec contains both a SysIOVec, suitable for writev, and one or more binaries. If these binaries should be retained, when the driver returns from outputv, they can be queued (using driver_enq_bin for instance), or if they are kept in a static or global variable, the reference counter can be incremented. THIS IMPLEMENTATION of the callback unpacks a set of headers from the input binary and constructs a Command object which is then submitted to the XslEngine. When the emulator is running in SMP mode, the actual processing is done on an async thread (using the driver_async submission mechanism) and the apply_transform function is used to wrap the XslEngine callback functions. The results of processing are handled on a main emulator thread in the ready_async driver callback. */ static void outputv(ErlDrvData drv_data, ErlIOVec *ev) { // char *error_msg; char *xml; char *xsl; char *data; DriverHandle *d = (DriverHandle*)drv_data; ErlDrvPort port = (ErlDrvPort)d->port; InputSpec *hspec; PayloadSize *hsize; XslTask *job; DriverContext *ctx; AsyncState *asd; DriverState state; ErlDrvTermData callee_pid = driver_caller(port); UInt8 *type1; UInt64 *size; if ((hspec = ALLOC(sizeof(InputSpec))) == NULL) { FAIL(port, "system_limit"); return; } if ((hsize = (PayloadSize*)try_driver_alloc(port, sizeof(PayloadSize), hspec)) == NULL) return; DBG("sizeof(uint64_t): %lu \n", sizeof(UInt64)); DBG("ev->vsize: %i \n", ev->vsize); // the first 8bit chunk holds the number of parameters type1 = ((UInt8*)ev->binv[1]->orig_bytes); hspec->param_grp_arity = *type1; // next two 8bit chunks hold the type specs type1++; hspec->input_kind = *type1; type1++; hspec->xsl_kind = *type1; // next two 64bit chunks hold the type specs type1++; size = ((UInt64*)type1); hsize->input_size = *size; size++; hsize->xsl_size = *size; // next comes the xml and xslt binaries, which may be in one of three places: // 1. if the XML binary is heap allocated, it'll be in the binv entry // 2. if the XML binary is not heap allocated, it'll be in the next binv entry // 3. if the XSL binary is not heap allocated, it'll be in the next binv entry // otherwise it'll bin in the (following) SysIOVec // if there is enough space remaining in a binv entry for the input document, // we pull it from there. Otherwise, it'll be collapsed into the first binary. size_t pos = ((sizeof(UInt8) * NUM_TYPE_HEADERS) + (sizeof(UInt64) * NUM_SIZE_HEADERS)); // INFO("pos = %lu \n", pos); UInt8 bin_idx = FIRST_BINV_ENTRY; // first entry is reserved if ((pos + hsize->input_size) <= ev->binv[bin_idx]->orig_size) { data = (char*)(&ev->binv[bin_idx]->orig_bytes[pos]); } else { data = ev->binv[++bin_idx]->orig_bytes; } // FIXME: find a way around NULL terminated strings and we can share the binary! xml = ALLOC(hsize->input_size + 1); xml[hsize->input_size] = '\0'; strncpy(xml, data, hsize->input_size); if (hsize->xsl_size < 64) { data = &ev->iov[++bin_idx].iov_base[0]; } else { data = ev->binv[++bin_idx]->orig_bytes; } xsl = ALLOC(hsize->xsl_size + 1); xsl[hsize->xsl_size] = '\0'; strncpy(xsl, data, hsize->xsl_size); if ((job = (XslTask*)try_driver_alloc(port, sizeof(XslTask), xml, xsl, hsize, hspec)) == NULL) return; if ((ctx = (DriverContext*)try_driver_alloc(port, sizeof(DriverContext), xml, xsl, hsize, hspec, job)) == NULL) return; if ((asd = (AsyncState*)try_driver_alloc(port, sizeof(AsyncState), xml, xsl, hsize, hspec, job, ctx)) == NULL) return; ctx->port = port; ctx->caller_pid = callee_pid; asd->driver = d; if ((asd->command = init_command(transform_command, ctx, job, NULL)) == NULL) { free_async_state(asd); FAIL(port, "system_limit"); return; } fprintf(stderr, "xml[spec: %lu, len:%lu]\n", (long unsigned int)hsize->input_size, strlen(xml)); fprintf(stderr, "xsl[spec: %lu, len:%lu]\n", (long unsigned int)hsize->xsl_size, strlen(xsl)); state = init_task(job, hsize, hspec, xml, xsl); switch (state) { case OutOfMemoryError: free_async_state(asd); FAIL(port, "system_limit"); return; case Success: /* driver_async will call engine->transform passing command, then call ready_async followed by cleanup_task. The synchronous code works something like this: (*a->async_invoke)(a->async_data); if (async_ready(prt, a->async_data)) { if (a->async_free != NULL) (*a->async_free)(a->async_data); } */ INFO("provider handoff: transform\n"); driver_async(port, NULL, apply_transform, asd, NULL); //cleanup_task); break; default: // TODO: it would be better if we didn't do "everthing else is an error" here // TODO: error!? break; } };
int main() { unsigned int stacks[TASK_LIMIT][STACK_SIZE]; //struct task_control_block tasks[TASK_LIMIT]; struct pipe_ringbuffer pipes[PIPE_LIMIT]; struct task_control_block *ready_list[PRIORITY_LIMIT + 1]; /* [0 ... 39] */ struct task_control_block *wait_list = NULL; //size_t task_count = 0; size_t current_task = 0; size_t i; struct task_control_block *task; int timeup; unsigned int tick_count = 0; SysTick_Config(configCPU_CLOCK_HZ / configTICK_RATE_HZ); init_rs232(); __enable_irq(); tasks[task_count].stack = (void*)init_task(stacks[task_count], &first); tasks[task_count].pid = 0; tasks[task_count].priority = PRIORITY_DEFAULT; task_count++; /* Initialize all pipes */ for (i = 0; i < PIPE_LIMIT; i++) pipes[i].start = pipes[i].end = 0; /* Initialize fifos */ for (i = 0; i <= PATHSERVER_FD; i++) _mknod(&pipes[i], S_IFIFO); /* Initialize ready lists */ for (i = 0; i <= PRIORITY_LIMIT; i++) ready_list[i] = NULL; while (1) { tasks[current_task].stack = activate(tasks[current_task].stack); tasks[current_task].status = TASK_READY; timeup = 0; switch (tasks[current_task].stack->r8) { case 0x1: /* fork */ if (task_count == TASK_LIMIT) { /* Cannot create a new task, return error */ tasks[current_task].stack->r0 = -1; } else { /* Compute how much of the stack is used */ size_t used = stacks[current_task] + STACK_SIZE - (unsigned int*)tasks[current_task].stack; /* New stack is END - used */ tasks[task_count].stack = (void*)(stacks[task_count] + STACK_SIZE - used); /* Copy only the used part of the stack */ memcpy(tasks[task_count].stack, tasks[current_task].stack, used * sizeof(unsigned int)); /* Set PID */ tasks[task_count].pid = task_count; /* Set priority, inherited from forked task */ tasks[task_count].priority = tasks[current_task].priority; /* Set return values in each process */ tasks[current_task].stack->r0 = task_count; tasks[task_count].stack->r0 = 0; tasks[task_count].prev = NULL; tasks[task_count].next = NULL; task_push(&ready_list[tasks[task_count].priority], &tasks[task_count]); /* There is now one more task */ task_count++; } break; case 0x2: /* getpid */ tasks[current_task].stack->r0 = current_task; break; case 0x3: /* write */ _write(&tasks[current_task], tasks, task_count, pipes); break; case 0x4: /* read */ _read(&tasks[current_task], tasks, task_count, pipes); break; case 0x5: /* interrupt_wait */ /* Enable interrupt */ NVIC_EnableIRQ(tasks[current_task].stack->r0); /* Block task waiting for interrupt to happen */ tasks[current_task].status = TASK_WAIT_INTR; break; case 0x6: /* getpriority */ { int who = tasks[current_task].stack->r0; if (who > 0 && who < (int)task_count) tasks[current_task].stack->r0 = tasks[who].priority; else if (who == 0) tasks[current_task].stack->r0 = tasks[current_task].priority; else tasks[current_task].stack->r0 = -1; } break; case 0x7: /* setpriority */ { int who = tasks[current_task].stack->r0; int value = tasks[current_task].stack->r1; value = (value < 0) ? 0 : ((value > PRIORITY_LIMIT) ? PRIORITY_LIMIT : value); if (who > 0 && who < (int)task_count) tasks[who].priority = value; else if (who == 0) tasks[current_task].priority = value; else { tasks[current_task].stack->r0 = -1; break; } tasks[current_task].stack->r0 = 0; } break; case 0x8: /* mknod */ if (tasks[current_task].stack->r0 < PIPE_LIMIT) tasks[current_task].stack->r0 = _mknod(&pipes[tasks[current_task].stack->r0], tasks[current_task].stack->r2); else tasks[current_task].stack->r0 = -1; break; case 0x9: /* sleep */ if (tasks[current_task].stack->r0 != 0) { tasks[current_task].stack->r0 += tick_count; tasks[current_task].status = TASK_WAIT_TIME; } break; default: /* Catch all interrupts */ if ((int)tasks[current_task].stack->r8 < 0) { unsigned int intr = -tasks[current_task].stack->r8 - 16; if (intr == SysTick_IRQn) { /* Never disable timer. We need it for pre-emption */ timeup = 1; tick_count++; } else { /* Disable interrupt, interrupt_wait re-enables */ NVIC_DisableIRQ(intr); } /* Unblock any waiting tasks */ for (i = 0; i < task_count; i++) if ((tasks[i].status == TASK_WAIT_INTR && tasks[i].stack->r0 == intr) || (tasks[i].status == TASK_WAIT_TIME && tasks[i].stack->r0 == tick_count)) tasks[i].status = TASK_READY; } } /* Put waken tasks in ready list */ for (task = wait_list; task != NULL;) { struct task_control_block *next = task->next; if (task->status == TASK_READY) task_push(&ready_list[task->priority], task); task = next; } /* Select next TASK_READY task */ for (i = 0; i < (size_t)tasks[current_task].priority && ready_list[i] == NULL; i++); if (tasks[current_task].status == TASK_READY) { if (!timeup && i == (size_t)tasks[current_task].priority) /* Current task has highest priority and remains execution time */ continue; else task_push(&ready_list[tasks[current_task].priority], &tasks[current_task]); } else { task_push(&wait_list, &tasks[current_task]); } while (ready_list[i] == NULL) i++; current_task = task_pop(&ready_list[i])->pid; } return 0; }
int main() { int nf_sock; struct msghdr msg; struct nlmsghdr nlhdr; struct sockaddr_nl local_addr; struct sockaddr_nl kpeer_addr; char buf[MAX_BUF_SIZE]; int nres; int group_id = NETLINK_GROUP_ID; pid_t pid; int addr_len; nf_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_NFLOG); if(nf_sock < 0){ WRONG_MESSAGE_ERRNO("Create nf_sock error: %s", strerror(errno)); exit(EXIT_FAILURE); } bzero(&local_addr, sizeof(struct sockaddr_nl)); bzero(&kpeer_addr, sizeof(struct sockaddr_nl)); local_addr.nl_family = PF_NETLINK; local_addr.nl_pad = 0; local_addr.nl_pid = getpid(); local_addr.nl_groups = group_id; if(nres = bind(nf_sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_nl)) != 0){ WRONG_MESSAGE_ERRNO("Bind nf_sock error: %s", strerror(errno)); exit(EXIT_FAILURE); } nres = setsockopt( nf_sock, 270, NETLINK_ADD_MEMBERSHIP, &group_id, sizeof(group_id)); if(nres == -1){ WRONG_MESSAGE_ERRNO("Set nf_sock option error: %s", strerror(errno)); exit(EXIT_FAILURE); } //设置所有线程都阻塞信号,用单独的线程来处理所有的信号 sigset_t mask, oldmask; sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGUSR1); sigaddset(&mask, SIGUSR2); pthread_sigmask(SIG_BLOCK, &mask, &oldmask); //初始化任务队列 extern struct task_queue task_q; init_task(&task_q); //初始化发送任务队列 extern struct info_queue info_q; init_info_q(&info_q); //创建用于处理数据的线程组,线程从任务队列中获取任务 pthread_t tid; nres = pthread_create( &tid, NULL, worker_func, NULL); nres = pthread_create(&tid, NULL, hash_func, NULL); //创建一个task结构,用于接收新的task struct task *new_task; int test_index = 0; char buffer[MAX_BUF_SIZE]; while(1){ bzero(buffer, MAX_BUF_SIZE); nres = recvfrom(nf_sock, buffer, MAX_BUF_SIZE, 0, (struct sockaddr *)&kpeer_addr, &addr_len); if( nres < 0){ fprintf(stderr, "Recv data from kernel error: %s\n", strerror(errno)); continue; } #ifdef DEBUGMAIN printf("\n***************Main thread start\n"); #endif new_task = (struct task *)malloc(sizeof(struct task)); new_task->index = test_index++; memcpy(new_task->buffer, buffer, nres); new_task->buflen = nres; /* struct ulog_packet_msg *msghdr; struct nlmsghdr *nlhdr; nlhdr = (struct nlmsghdr * )new_task->buffer; nlhdr++; msghdr = (struct ulog_packet_msg *)nlhdr; */ //锁住互斥量 pthread_mutex_lock(&(task_q.task_mutex)); //将新接收到的任务加入队列 //list_add(&new_task->list, &task_q.queue_head); task_add(new_task, &task_q); #ifdef DEBUGMAIN printf("\nQueue Details:\n"); printf("Task in queue: %d\n", task_q.task_in_queue); printf("Thread waiting: %d\n",task_q.thread_waiting); #endif int flag = 0; //判断是否有线程在等待队列上加入任务 if(task_q.thread_waiting > 0) { flag = 1; task_q.thread_waiting--; } pthread_mutex_unlock(&(task_q.task_mutex)); //如果有线程在等待,则在该条件变量上发信号 // // // // if(flag == 1) { #ifdef DEBUGMAIN printf("Some thread are waiting task , now send signal...\n"); #endif pthread_cond_signal( &(task_q.task_cond)); } #ifdef DEBUGMAIN printf("****************Main thread end\n\n"); #endif } }