MCPcopy Create free account
hub / github.com/YatSenOS/YatSenOS-Tutorial-Volume-1 / copyProcess

Method copyProcess

lab8/src/6/src/kernel/program.cpp:392–515  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

390}
391
392bool ProgramManager::copyProcess(PCB *parent, PCB *child)
393{
394 // 复制PCB
395 ProcessStartStack *childpps = (ProcessStartStack *)((int)child + PAGE_SIZE - sizeof(ProcessStartStack));
396 ProcessStartStack *parentpps = (ProcessStartStack *)((int)parent + PAGE_SIZE - sizeof(ProcessStartStack));
397 memcpy(parentpps, childpps, sizeof(ProcessStartStack));
398 childpps->eax = 0;
399
400 child->stack = (int *)childpps - 7;
401 child->stack[0] = 0;
402 child->stack[1] = 0;
403 child->stack[2] = 0;
404 child->stack[3] = 0;
405 child->stack[4] = (int)asm_start_process;
406 child->stack[5] = 0; // asm_start_process 返回地址
407 child->stack[6] = (int)childpps; // asm_start_process 参数
408
409 child->status = ProgramStatus::READY;
410 child->parentPid = parent->pid;
411 child->priority = parent->priority;
412 child->ticks = parent->ticks;
413 child->ticksPassedBy = parent->ticksPassedBy;
414 strcpy(parent->name, child->name);
415
416 // 复制用户虚拟地址池
417 int bitmapLength = parent->userVirtual.resources.length;
418 int bitmapBytes = ceil(bitmapLength, 8);
419 memcpy(parent->userVirtual.resources.bitmap, child->userVirtual.resources.bitmap, bitmapBytes);
420
421 char *buffer = (char *)memoryManager.allocatePages(AddressPoolType::KERNEL, 1);
422 if (!buffer)
423 {
424 child->status = ProgramStatus::DEAD;
425 return false;
426 }
427
428 // 子进程页目录表地址
429 int childPageDirPaddr = memoryManager.vaddr2paddr(child->pageDirectoryAddress);
430 // 父进程页目录表地址
431 int parentPageDirPaddr = memoryManager.vaddr2paddr(parent->pageDirectoryAddress);
432 // 子进程页目录表指针(虚拟地址)
433 int *childPageDir = (int *)child->pageDirectoryAddress;
434 // 父进程页目录表指针(虚拟地址)
435 int *parentPageDir = (int *)parent->pageDirectoryAddress;
436
437 //printf("%x %x\n", parent->pageDirectoryAddress, child->pageDirectoryAddress);
438
439 memset((void *)child->pageDirectoryAddress, 0, 768 * 4);
440
441 for (int i = 0; i < 768; ++i)
442 {
443 // 无对应页表
444 if (!(parentPageDir[i] & 0x1))
445 {
446 continue;
447 }
448
449 // 从用户物理地址池中分配一页,作为子进程的页目录项指向的页表

Callers

nothing calls this directly

Calls 8

memcpyFunction · 0.50
strcpyFunction · 0.50
ceilFunction · 0.50
memsetFunction · 0.50
allocatePagesMethod · 0.45
vaddr2paddrMethod · 0.45
allocatePhysicalPagesMethod · 0.45
releasePagesMethod · 0.45

Tested by

no test coverage detected