Exemplo n.º 1
0
/*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;

};
Exemplo n.º 2
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;
}