Пример #1
0
int ggc_barrier_wait_raw(ggc_barrier_t *barrier)
{
    ggc_mutex_lock_raw(&barrier->lock);

    /* if we're the last one, great */
    if (barrier->cur == barrier->ct - 1) {
        unsigned long i;

        /* signal all the others */
        for (i = 0; i < barrier->cur; i++) ggc_sem_post(&barrier->waiters);

        /* wait for them to wake up */
        for (i = 0; i < barrier->cur; i++) ggc_sem_wait_raw(&barrier->leader);

        /* and reset the barrier */
        barrier->cur = 0;
        ggc_mutex_unlock(&barrier->lock);
        return 0;
    }

    /* otherwise, wait on the others */
    barrier->cur++;
    ggc_mutex_unlock(&barrier->lock);
    ggc_sem_wait_raw(&barrier->waiters);
    ggc_sem_post(&barrier->leader);

    return 0;
}
Пример #2
0
/* allocate and initialize a pool */
static struct GGGGC_Pool *newPool(unsigned char gen, int mustSucceed)
{
    struct GGGGC_Pool *ret;
#ifdef GGGGC_DEBUG_TINY_HEAP
    static ggc_thread_local int allocationsLeft = GGGGC_GENERATIONS;

    if (allocationsLeft-- <= 0) {
        allocationsLeft = 0;
        if (mustSucceed) {
            fprintf(stderr, "GGGGC: exceeded tiny heap size\n");
            abort();
        }
        return NULL;
    }
#endif

    ret = NULL;

    /* try to reuse a pool */
    if (freePoolsHead) {
        ggc_mutex_lock_raw(&freePoolsLock);
        if (freePoolsHead) {
            ret = freePoolsHead;
            freePoolsHead = freePoolsHead->next;
            if (!freePoolsHead) freePoolsTail = NULL;
        }
        ggc_mutex_unlock(&freePoolsLock);
    }

    /* otherwise, allocate one */
    if (!ret) ret = (struct GGGGC_Pool *) allocPool(mustSucceed);

    if (!ret) return NULL;

    /* set it up */
    ret->next = NULL;
    ret->gen = gen;
    ret->free = ret->start;
    ret->end = (ggc_size_t *) ((unsigned char *) ret + GGGGC_POOL_BYTES);

#if GGGGC_GENERATIONS > 1
    /* clear the remembered set */
    if (gen > 0)
        memset(ret->remember, 0, GGGGC_CARDS_PER_POOL);

    /* the first object in the first usable card */
    ret->firstObject[GGGGC_CARD_OF(ret->start)] =
        (((ggc_size_t) ret->start) & GGGGC_CARD_INNER_MASK) / sizeof(ggc_size_t);
#endif

    return ret;
}
Пример #3
0
/* free a generation (used when a thread exits) */
void ggggc_freeGeneration(struct GGGGC_Pool *pool)
{
    if (!pool) return;
    ggc_mutex_lock_raw(&freePoolsLock);
    if (freePoolsHead) {
        freePoolsTail->next = pool;
    } else {
        freePoolsHead = pool;
    }
    while (pool->next) pool = pool->next;
    freePoolsTail = pool;
    ggc_mutex_unlock(&freePoolsLock);
}
Пример #4
0
/* allocate a descriptor from a descriptor slot */
struct GGGGC_Descriptor *ggggc_allocateDescriptorSlot(struct GGGGC_DescriptorSlot *slot)
{
    if (slot->descriptor) return slot->descriptor;
    ggc_mutex_lock_raw(&slot->lock);
    if (slot->descriptor) {
        ggc_mutex_unlock(&slot->lock);
        return slot->descriptor;
    }

    slot->descriptor = ggggc_allocateDescriptor(slot->size, slot->pointers);

    /* make the slot descriptor a root */
    GGC_PUSH_1(slot->descriptor);
    GGC_GLOBALIZE();

    ggc_mutex_unlock(&slot->lock);
    return slot->descriptor;
}
Пример #5
0
/* allocate a descriptor-descriptor for a descriptor of the given size */
struct GGGGC_Descriptor *ggggc_allocateDescriptorDescriptor(ggc_size_t size)
{
    struct GGGGC_Descriptor tmpDescriptor, *ret;
    ggc_size_t ddSize;

    /* need one description bit for every word in the object */
    ddSize = GGGGC_WORD_SIZEOF(struct GGGGC_Descriptor) + GGGGC_DESCRIPTOR_WORDS_REQ(size);

    /* check if we already have a descriptor */
    if (ggggc_descriptorDescriptors[size])
        return ggggc_descriptorDescriptors[size];

    /* otherwise, need to allocate one. First lock the space */
    ggc_mutex_lock_raw(&ggggc_descriptorDescriptorsLock);
    if (ggggc_descriptorDescriptors[size]) {
        ggc_mutex_unlock(&ggggc_descriptorDescriptorsLock);
        return ggggc_descriptorDescriptors[size];
    }

    /* now make a temporary descriptor to describe the descriptor descriptor */
    tmpDescriptor.header.descriptor__ptr = NULL;
    tmpDescriptor.size = ddSize;
    tmpDescriptor.pointers[0] = GGGGC_DESCRIPTOR_DESCRIPTION;

    /* allocate the descriptor descriptor */
    ret = (struct GGGGC_Descriptor *) ggggc_mallocGen0(&tmpDescriptor, 1);

    /* make it correct */
    ret->size = size;
    ret->pointers[0] = GGGGC_DESCRIPTOR_DESCRIPTION;

    /* put it in the list */
    ggggc_descriptorDescriptors[size] = ret;
    ggc_mutex_unlock(&ggggc_descriptorDescriptorsLock);
    GGC_PUSH_1(ggggc_descriptorDescriptors[size]);
    GGC_GLOBALIZE();

    /* and give it a proper descriptor */
    ret->header.descriptor__ptr = ggggc_allocateDescriptorDescriptor(ddSize);

    return ret;
}