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

Method copyProcess

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

Source from the content-addressed store, hash-verified

377}
378
379bool ProgramManager::copyProcess(PCB *parent, PCB *child)
380{
381 // 复制进程0级栈
382 ProcessStartStack *childpss =
383 (ProcessStartStack *)((int)child + PAGE_SIZE - sizeof(ProcessStartStack));
384 ProcessStartStack *parentpss =
385 (ProcessStartStack *)((int)parent + PAGE_SIZE - sizeof(ProcessStartStack));
386 memcpy(parentpss, childpss, sizeof(ProcessStartStack));
387 // 设置子进程的返回值为0
388 childpss->eax = 0;
389
390 // 准备执行asm_switch_thread的栈的内容
391 child->stack = (int *)childpss - 7;
392 child->stack[0] = 0;
393 child->stack[1] = 0;
394 child->stack[2] = 0;
395 child->stack[3] = 0;
396 child->stack[4] = (int)asm_start_process;
397 child->stack[5] = 0; // asm_start_process 返回地址
398 child->stack[6] = (int)childpss; // asm_start_process 参数
399
400 // 设置子进程的PCB
401 child->status = ProgramStatus::READY;
402 child->parentPid = parent->pid;
403 child->priority = parent->priority;
404 child->ticks = parent->ticks;
405 child->ticksPassedBy = parent->ticksPassedBy;
406 strcpy(parent->name, child->name);
407
408 // 复制用户虚拟地址池
409 int bitmapLength = parent->userVirtual.resources.length;
410 int bitmapBytes = ceil(bitmapLength, 8);
411 memcpy(parent->userVirtual.resources.bitmap, child->userVirtual.resources.bitmap, bitmapBytes);
412
413 // 从内核中分配一页作为中转页
414 char *buffer = (char *)memoryManager.allocatePages(AddressPoolType::KERNEL, 1);
415 if (!buffer)
416 {
417 child->status = ProgramStatus::DEAD;
418 return false;
419 }
420
421 // 子进程页目录表物理地址
422 int childPageDirPaddr = memoryManager.vaddr2paddr(child->pageDirectoryAddress);
423 // 父进程页目录表物理地址
424 int parentPageDirPaddr = memoryManager.vaddr2paddr(parent->pageDirectoryAddress);
425 // 子进程页目录表指针(虚拟地址)
426 int *childPageDir = (int *)child->pageDirectoryAddress;
427 // 父进程页目录表指针(虚拟地址)
428 int *parentPageDir = (int *)parent->pageDirectoryAddress;
429
430 // 子进程页目录表初始化
431 memset((void *)child->pageDirectoryAddress, 0, 768 * 4);
432
433 // 复制页目录表
434 for (int i = 0; i < 768; ++i)
435 {
436 // 无对应页表

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