示例#1
0
文件: coat.c 项目: seL4/refos
void coat_release(coat_t *t) {
    assert(t);
    size_t count = cvector_count(&t->table);
    for (int i = 0; i < count; i++) {
        cvector_item_t obj = cvector_get(&t->table, i);
        if (!obj) continue;
        if (t->oat_delete) {
            t->oat_delete(t, obj);
        }
    }
    cvector_free(&t->table);
    cpool_release(&t->pool);
}
示例#2
0
文件: test.c 项目: Zolok/refos
static int
test_cvector(void)
{
    test_start("cvector");
    // Src: https://gist.github.com/EmilHernvall/953968
    cvector_t v;
    cvector_init(&v);
    cvector_add(&v, (cvector_item_t)1); cvector_add(&v, (cvector_item_t)2);
    cvector_add(&v, (cvector_item_t)3); cvector_add(&v, (cvector_item_t)4);
    cvector_add(&v, (cvector_item_t)5);
    test_assert(cvector_count(&v) == (int)5);
    test_assert(cvector_get(&v, 0) == (cvector_item_t)1);
    test_assert(cvector_get(&v, 1) == (cvector_item_t)2);
    test_assert(cvector_get(&v, 2) == (cvector_item_t)3);
    test_assert(cvector_get(&v, 3) == (cvector_item_t)4);
    test_assert(cvector_get(&v, 4) == (cvector_item_t)5);
    cvector_delete(&v, 1);
    cvector_delete(&v, 3);
    test_assert(cvector_count(&v) == (int)3);
    test_assert(cvector_get(&v, 0) == (cvector_item_t)1);
    test_assert(cvector_get(&v, 1) == (cvector_item_t)3);
    test_assert(cvector_get(&v, 2) == (cvector_item_t)4);
    cvector_free(&v);
    int vcStress = 10000;
    for (int i = 0; i < vcStress; i++) {
        int data = ((i << 2) * 0xcafebabe) ^ 0xdeadbeef;
        cvector_add(&v, (cvector_item_t)data);
        test_assert(cvector_count(&v) == (int)(i + 1));
        test_assert(cvector_get(&v, i) == (cvector_item_t)data);
        data = (data << 7) ^ 0xbaabaabb;
        cvector_set(&v, i, (cvector_item_t)data);
        test_assert(cvector_count(&v) == (int)(i + 1));
        test_assert(cvector_get(&v, i) == (cvector_item_t)data);
    }
    cvector_free(&v);
    return test_success();
}
示例#3
0
文件: cpool.c 项目: Zolok/refos
bool cpool_check(cpool_t *p, uint32_t obj) {
    if (obj < p->start || obj > p->end) {
        // Not free if out of range.
        return false;
    }
    if (obj > p->mx) {
        // Free if in the not-allocated-yet range.
        return true;
    }
    size_t sz = cvector_count(&p->freelist);
    for (int i = 0; i < sz; i++) {
        uint32_t x = (uint32_t)cvector_get(&p->freelist, i);
        if (x == obj) {
            return true;
        }
    }
    return false;
}
示例#4
0
文件: device_irq.c 项目: seL4/refos
int dev_dispatch_interrupt(dev_irq_state_t *irqState, srv_msg_t *m)
{
    assert(irqState && irqState->magic == DEVICE_IRQ_MAGIC);

    if ((m->badge & irqState->cfg.badgeMaskBits) == 0) {
        return DISPATCH_PASS;
    }

    /* Loop through every bit in the bitmask to determine which IRQs fired. */
    bool IRQFound = false;
    for (int i = 0; i <  irqState->cfg.numIRQChannels; i++) {
        if (m->badge & (1 << (irqState->cfg.badgeBaseBit + i))) {
            IRQFound = true;

            /* Go through every IRQ clash. If the server needs to handle a lot of different IRQs
               then this will lead to false positives. This seems to be a kernel API limitation 
               of a single threaded server design. More threads listening to multiple endpoints
               will avoid this problem of IRQ clash.

               Hopefully in practical environments, this won't be a problem since we probably won't
               have a small system that needs a lot of different interrupts.
            */
            int nIRQs = cvector_count(&irqState->channel[i]);
            for (int j = 0; j < nIRQs; j++) {
                uint32_t irq = (uint32_t) cvector_get(&irqState->channel[i], j);
                assert (irq < DEVICE_MAX_IRQ);

                if (irqState->handler[irq].callback) {
                    irqState->handler[irq].callback(irqState->handler[irq].cookie, irq);
                }
                if (irqState->handler[irq].handler) {
                    seL4_IRQHandler_Ack(irqState->handler[irq].handler);
                }
            }

        }
    }

    if (!IRQFound) {
        return DISPATCH_PASS;
    }

    return DISPATCH_SUCCESS;
}
示例#5
0
文件: coat.c 项目: seL4/refos
int coat_alloc(coat_t *t, uint32_t arg[COAT_ARGS], cvector_item_t *out_obj) {
    assert(t);

    // Allocate new ID.
    int id = cpool_alloc(&t->pool);
    if (!id || id == COAT_INVALID_ID) {
        goto error; 
    }

    // Potentially expand ID table vector.
    while (cvector_count(&t->table) <= id) {
        if (t->oat_expand) {
            t->oat_expand(&t->table);
            continue;
        }
        // Defaults to adding NULL pointers to fill ID table.
        cvector_add(&t->table, (cvector_item_t) NULL);
    }

    cvector_item_t obj = cvector_get(&t->table, id);
    if (!obj && t->oat_create) {
        // Create object structure and store it.
        obj = t->oat_create(t, id, arg);
        if (!obj) {
            goto error;
        }
        cvector_set(&t->table, id, obj);
    }

    if (out_obj) {
        (*out_obj) = obj;
    }

    return id;

error:
    if (id) cpool_free(&t->pool, id);
    return COAT_INVALID_ID; 
}
示例#6
0
文件: cpool.c 项目: Zolok/refos
uint32_t
cpool_alloc(cpool_t *p)
{
    assert(p);

    // First try to allocate from the free list.
    size_t fSz = cvector_count(&p->freelist);
    if (fSz > 0) {
        // Allocate the last item available on the free list.
        cvector_item_t obj = cvector_get(&p->freelist, fSz - 1);
        cvector_delete(&p->freelist, fSz - 1);
        return (uint32_t) obj;
    }

    // Free list exhausted, allocate by increasing max obj ID..
    if (p->mx <= p->end) {
        return (uint32_t) p->mx++;
    }

    // Out of object to allocate.
    return 0;
}
示例#7
0
文件: coat.c 项目: seL4/refos
cvector_item_t coat_get(coat_t *t, int id) {
    if (!t || id < t->pool.start || id >= t->pool.end || id >= cvector_count(&t->table)) {
        return (cvector_item_t) NULL;
    }
    return cvector_get(&t->table, id);
}