/*called when another process wants to kill another. Also performs garbage collection (reclaims memory used by the application).*/ DWORD kill_process(DWORD processid) { PCB386 *ptr,*parentptr=0; sync_entercrit(&processmgr_busy); ptr = bridges_ps_findprocess(processid); if (ptr!=-1) { if (! (ptr->status&PS_ATTB_UNLOADABLE) ) { PCB386 *parent; kill_children(processid); //kill child processes first if (ptr->accesslevel == ACCESS_SYS) //a kernel thread? { dex32_killkthread(ptr); sync_leavecrit(&processmgr_busy); return 1; }; if ( ptr->status&PS_ATTB_THREAD ) //a thread process? If yes then redirect to another procedure { kill_thread(ptr); sync_leavecrit(&processmgr_busy); return 1; }; while (closeallfiles(ptr->processid)==1); parent=ps_findprocess(ptr->owner); if (parent!=-1) { parent->childwait=0; }; //locate the parent process and decrement its waiting //status...important for the dex32_wait() function if (ptr->accesslevel == ACCESS_SYS) free(ptr->stackptr); /*Perform memory garbage collection if necessary*/ if (ptr->meminfo!=0) freeprocessmemory(ptr->meminfo,(DWORD*)ptr->pagedirloc); if (!(ptr->status&PS_ATTB_THREAD) && (ptr->accesslevel != ACCESS_SYS) ) { //free the page tables used by the application dex32_freeuserpagetable((DWORD*)ptr->pagedirloc); #ifdef MEM_LEAK_CHECK printf("1 page freed (page directory).\n"); #endif mempush(ptr->pagedirloc); }; if (ptr->parameters!=0) free(ptr->parameters); if (ptr->stdout!=0) { free(ptr->stdout); }; //Tell the scheduler to remove this process from the queue ps_dequeue(ptr); free(ptr); sync_leavecrit(&processmgr_busy); return 1; }; }; sync_leavecrit(&processmgr_busy); return 0; };
/* TODO: deal with unmapping/freeing physical memory */ void kfree(void *ptr) { struct mempool *physpool = &memphyspool; struct mempool *virtpool = &memvirtpool; struct memmag *mag = memgetmag(ptr, virtpool); unsigned long bkt = (mag) ? mag->bkt : 0; #if defined(MEMPARANOIA) unsigned long ndx; unsigned long *bmap; #endif struct membkt *hdr = &virtpool->tab[bkt]; struct memmag *list = hdr->list; if (!ptr || !mag) { return; } mtxlk(&hdr->lk); #if defined(MEMPARANOIA) ndx = ((uintptr_t)ptr - mag->base) >> bkt; #if ((MEMSLABMINLOG2 - MEMMINLOG2) < (LONGSIZELOG2 + 3)) bmap = &mag->bmap; #else bmap = mag->bmap; #endif if (!bitset(bmap, ndx)) { kprintf("invalid free: %p (%ld/%ld)\n", ptr, ndx, mag->n); panic(k_curproc->pid, TRAPNONE, -EINVAL); } #endif mempush(mag, ptr); if (memmagfull(mag)) { if (gtpow2(mag->n, 1)) { if ((mag->prev) && (mag->next)) { mag->prev->next = mag->next; mag->next->prev = mag->prev; } else if (mag->prev) { mag->prev->next = NULL; } else if (mag->next) { mag->next->prev = NULL; hdr->list = mag->next; } else { hdr->list = NULL; } } slabfree(physpool, ptr); mag->base = 0; } else if (mag->ndx == mag->n - 1) { mag->prev = NULL; if (list) { list->prev = mag; } mag->next = list; hdr->list = mag; } #if defined(MEMPARANOIA) clrbit(bmap, ndx); #endif mtxunlk(&hdr->lk); return; }