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

Method copyProcess

lab8/src/7/src/kernel/program.cpp:388–511  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

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

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