示例#1
0
/** 
 * User should at least prepare this example function in order to use garbage collector:
 *
 * objectCFree
 * -----------
 * This function walks through all the pointers in the object struct that prepared by user
 *
 * return:
 *  obj   object that gone through
 */
void objectCFree(Object *obj) {
  ((ObjectC *)obj)->ptrC1 = _gc_free((Object *)((ObjectC *)obj)->ptrC1);
  ((ObjectC *)obj)->ptrC2 = _gc_free((Object *)((ObjectC *)obj)->ptrC2);
  ((ObjectC *)obj)->ptrC3 = _gc_free((Object *)((ObjectC *)obj)->ptrC3);
}
示例#2
0
文件: gc.c 项目: roby85/Viper
void gc_keep_root(void) {
    PObject *obj;
    int i;

    if (_vmpnt) {
        //get the root set
        obj = PNT(_vm.thlist);
        do {
            PThread *pth = (PThread *)obj;
            VThread vth = pth->th;
            debug( "Scanning thread %x %i\n", pth, pth->header.flags);
            if (vth && vosThGetStatus(vth) == VTHREAD_INACTIVE) {
                //terminated, remove from list...it will die if no references remain
                pth->prev->next = pth->next;
                pth->next->prev = pth->prev;
                GCH_FLAG_SET(pth, GC_USED);
                //free workspace
                //if PThread has references, it's ok. But it can't be restarted
                _gc_free(vth);
                pth->th = NULL;
            } else {
                GC_MARK(pth);
                if (pth->frame) GC_KEEP(pth->frame);
            }
            obj = PNT(pth->next);
        } while (obj != PNT(_vm.thlist));

        for (i = 0; i < _vm.nmodules; i++) {
            PModule *mod = VM_MODULE(i);
            GC_MARK(mod);
            if (PMODULE_IS_LOADED(mod)) {
                GC_KEEP_MANY(mod->globals, mod->nfo.nums.nglobals);
            } else {
                GC_KEEP(mod->nfo.frame);
            }
        }
        //-----> irqs could be modifing irq struct here: no worries
        SYSLOCK();
        //slots & irqstack
        for (i = 0; i < _vm.irqn; i++) {
            GC_KEEP(_vm.irqstack[i].fn);
            GC_KEEP_NOTNULL(_vm.irqstack[i].args);
        }

        for (i = 0; i < EXT_SLOTS; i++) {
            if (_vm.irqslots[0][i].fn) {
                GC_KEEP(_vm.irqslots[0][i].fn);
                GC_KEEP_NOTNULL(_vm.irqslots[0][i].args);
            }
            if (_vm.irqslots[1][i].fn) {
                GC_KEEP(_vm.irqslots[1][i].fn);
                GC_KEEP_NOTNULL(_vm.irqslots[1][i].args);
            }
        }
        if (_vm.irqcur) {
            GC_KEEP(_vm.irqcur->fn);
            GC_KEEP_NOTNULL(_vm.irqcur->args);
        }


        if (_vm.timers) {
            obj = _vm.timers;
            do {
                GC_KEEP(obj);
                obj = (PObject *)((PSysObject *)obj)->sys.timer.next;
            } while (obj != _vm.timers);
        }


        SYSUNLOCK();
        //-----> irq could be modifing irq struct here:
        //       - it can add something to irqslots: np, the objects added must be in an active frame (gc lock is on, no new frame can be created)
        //       - it can add something to irqstack from pin irq: np, the objects are sitting in irqslots
        //       - it can add something to irqstack from timers: that timer was in the timer list, so it is already kept
        //       - it can be the irqthread at 2 different times:
        //           - it modifies _vm.irqcur after putting it in a new frame: if happens up there, np. if happens now, already kept
        //           - it does _vm.irqn--: if happens up there, the removed irqfn is in irqcur. if happens here, already kept
    }

}
示例#3
0
文件: gc.c 项目: roby85/Viper
void gc_sweep(void) {
    PObject *start = (PObject *)hbase;
    PObject *cur = start;
    PObject *prev = (PObject *)hedge;
    uint32_t flags;
    uint32_t prev_is_free = 0;


    debug( "\n\n<<<<<<<SWEEP started\n");

    /*heapwalk and create free list */
    hblocks = 0;
    hfblocks = 0;
    hfreemem = 0;
    while (cur != (PObject *)hedge) {
        flags = GCH_FLAG(cur);
        //debug("cur is %x with flag %i\n", cur, flags);
        switch (flags) {
            case GC_FREE:
            /*case GC_USED_UNMARKED:*/
gc_sweep_free:            
                hfreemem += GCH_SIZE(cur);
                debug("sweeping %x\n", cur);
                //debug("found free block: %i (%i,%i) %i\n",cur,hblocks,hfblocks,GCH_FLAG(cur));
                if (prev_is_free && (GCH_SIZE(prev) + GCH_SIZE(cur) <= 0xffff)) {
                    /* coalesce */
                    GCH_SIZE_SET(prev, GCH_SIZE(prev) + GCH_SIZE(cur));
                    //debug("...coalesced with prev %i~%i size %i\n",prev,cur,GCH_SIZE(prev));
                    prev_is_free = (GCH_SIZE(prev) < 0xffff);
                } else {
                    prev_is_free = (GCH_SIZE(cur) < 0xffff);
                    GCH_NEXT_SET(prev, cur); /*unset mark flags. First time, sets hedge->next */
                    prev = cur;
                    hfblocks++;
                    //debug("...splitted prev %i~%i size %i (%i,%i)\n",prev,cur,GCH_SIZE(prev),hblocks,hfblocks);
                }
                break;
            case GC_USED_UNMARKED:
                if (PHEADERTYPE(cur) == PSYSOBJ) {
                    if (((PSysObject *)cur)->type == PSYS_TIMER) {
                        //if we are here, timer is not in timers and not reachable...free vos mem
                        _gc_free( ((PSysObject *)cur)->sys.timer.vtm);
                    } else if (((PSysObject *)cur)->type == PSYS_SEMAPHORE){
                        //if it's a lost semaphore, still active, anything can happen :-o
                        _gc_free( ((PSysObject *)cur)->sys.sem);
                    }
                }
                goto gc_sweep_free;
            case GC_USED_MARKED:
                prev_is_free = 0;
                GCH_FLAG_SET(cur, GC_USED);
                hblocks++;
                //debug("found marked block: %i (%i,%i) %i\n",cur,hblocks,hfblocks,GCH_FLAG(cur));
                break;
            case GC_STAGED:
                /* don't touch flags */
                prev_is_free = 0;
                hblocks++;
                //debug("found staged block: %i (%i,%i) %i\n",cur,hblocks,hfblocks,GCH_FLAG(cur));
                break;
        }
        /* skip current */
        cur = (PObject *)(((uint8_t *)(cur)) + GCH_SIZE(cur));
    }

    if (prev_is_free) {
        /* coalesce with hedge */
        hfreemem -= GCH_SIZE(prev);
        GCH_NEXT_SET(prev, GCH_NEXT(hedge));
        hedge = (uint8_t *)prev;
        //debug("coalesced with hedge\n");
    } else {
        GCH_NEXT_SET(prev, hedge);
        //debug("not coalesced with hedge\n");
        hfblocks++;
    }
    debug( "S%i\n", hfreemem);
    hfreemem += ((uint32_t)hend - (uint32_t)hedge);
    debug( "S%i\n", hfreemem);
    GCH_SIZE_SET(PNT(hedge), MIN(0xffff, hfreemem));
    gc_trace();
    debug( "<<<<<<<<SWEEP stopped (%i,%i)\n\n\n", hblocks, hfblocks);

}
示例#4
0
文件: gc.c 项目: roby85/Viper
void gc_free(void *pnt) {
    gc_wait();
    _gc_free(pnt);
    gc_signal();
}