int main(void) { pid_t pid; int i; int n = 2; char buf[BUFSIZ]; char *b; int size; char *p; #if DEBUG_MEM_POOL == 2 while (1) { b = fgets(buf, BUFSIZ, stdin); buf[strlen(b) - 1] = '\0'; if (strcmp(b, "q") == 0) break; size = atoi(buf); p = mem_pool(size); } mem_pool_free(); #endif #if DEBUG_MEM_POOL == 1 /* 匿名 内存 映射区, 用于有 父子,兄弟 关系的进程*/ int *p, *q; p = (int *) memory_pool(4084); *p = 100; for (i = 0; i < n; i++) if ((pid = fork()) == 0) break; if (i == n) { /* parent */ sleep(1); printf("*p = %d\n", *p); } else { /* child */ *p = 200; } mem_pool_free(); #endif return 0; }
Field ConstField::dup(const char* new_name, size_t new_name_length) const { return dup(memory_pool(), new_name, new_name_length); }
Field ConstField::dup() const { return dup(memory_pool()); }
int main() { GDT::init(); Console::init(); IDT::init(); ExceptionHandler::init_dispatcher(); IRQ::init(); InterruptHandler::init_dispatcher(); /* -- EXAMPLE OF AN EXCEPTION HANDLER -- */ class DBZ_Handler : public ExceptionHandler { public: virtual void handle_exception(REGS * _regs) { Console::puts("DIVISION BY ZERO!\n"); for(;;); } } dbz_handler; ExceptionHandler::register_handler(0, &dbz_handler); /* -- INITIALIZE MEMORY -- */ /* NOTE: We don't have paging enabled in this MP. */ /* NOTE2: This is not an exercise in memory management. The implementation of the memory management is accordingly *very* primitive! */ /* ---- Initialize a frame pool; details are in its implementation */ FramePool system_frame_pool; SYSTEM_FRAME_POOL = &system_frame_pool; /* ---- Create a memory pool of 256 frames. */ MemPool memory_pool(SYSTEM_FRAME_POOL, 256); MEMORY_POOL = &memory_pool; /* -- INITIALIZE THE TIMER (we use a very simple timer).-- */ /* Question: Why do we want a timer? We have it to make sure that we enable interrupts correctly. If we forget to do it, the timer "dies". */ SimpleTimer timer(100); /* timer ticks every 10ms. */ InterruptHandler::register_handler(0, &timer); /* The Timer is implemented as an interrupt handler. */ #ifdef _USES_SCHEDULER_ /* -- SCHEDULER -- IF YOU HAVE ONE -- */ Scheduler system_scheduler; SYSTEM_SCHEDULER = &system_scheduler; #endif #ifdef _USES_DISK_ /* -- DISK DEVICE -- IF YOU HAVE ONE -- */ BlockingDisk system_disk = BlockingDisk(MASTER, SYSTEM_DISK_SIZE); SYSTEM_DISK = &system_disk; #endif //#ifdef _USES_FILESYSTEM_ /* -- FILE SYSTEM -- IF YOU HAVE ONE -- */ FileSystem file_system= FileSystem(); FILE_SYSTEM = &file_system; //#endif /* NOTE: The timer chip starts periodically firing as soon as we enable interrupts. It is important to install a timer handler, as we would get a lot of uncaptured interrupts otherwise. */ /* -- ENABLE INTERRUPTS -- */ machine_enable_interrupts(); /* -- MOST OF WHAT WE NEED IS SETUP. THE KERNEL CAN START. */ Console::puts("Hello World!\n"); /* -- LET'S CREATE SOME THREADS... */ Console::puts("CREATING THREAD 1...\n"); char * stack1 = new char[1024]; thread1 = new Thread(fun1, stack1, 1024); Console::puts("DONE\n"); Console::puts("CREATING THREAD 2..."); char * stack2 = new char[1024*2];//allow for testing file system with larger buffers thread2 = new Thread(fun2, stack2, 1024); Console::puts("DONE\n"); Console::puts("CREATING THREAD 3..."); char * stack3 = new char[1024*10]; thread3 = new Thread(fun3, stack3, 1024); Console::puts("DONE\n"); Console::puts("CREATING THREAD 4..."); char * stack4 = new char[1024]; thread4 = new Thread(fun4, stack4, 1024); Console::puts("DONE\n"); #ifdef _USES_SCHEDULER_ /* WE ADD thread2 - thread4 TO THE READY QUEUE OF THE SCHEDULER. */ SYSTEM_SCHEDULER->add(thread2); SYSTEM_SCHEDULER->add(thread3); SYSTEM_SCHEDULER->add(thread4); #endif /* -- KICK-OFF THREAD1 ... */ Console::puts("STARTING THREAD 1 ...\n"); Thread::dispatch_to(thread1); /* -- AND ALL THE REST SHOULD FOLLOW ... */ assert(FALSE); /* WE SHOULD NEVER REACH THIS POINT. */ /* -- WE DO THE FOLLOWING TO KEEP THE COMPILER HAPPY. */ return 1; }