rc-stack.c 2.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * Copyright (C) 2014 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
 */

#include <assert.h>
#include <ross.h>
#include "codes/rc-stack.h"
#include "codes/quicklist.h"

typedef struct rc_entry_s {
    tw_stime time;
    void * data;
    struct qlist_head ql;
} rc_entry;

struct rc_stack {
    int count;
    struct qlist_head head;
};

void rc_stack_create(struct rc_stack **s){
Elsa Gonsiorowski (Uranus)'s avatar
Elsa Gonsiorowski (Uranus) committed
24
    struct rc_stack *ss = (struct rc_stack*)malloc(sizeof(*ss));
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    if (ss) {
        INIT_QLIST_HEAD(&ss->head);
        ss->count = 0;
    }
    *s = ss;
}

void rc_stack_destroy(int free_data, struct rc_stack *s) {
#define FREE_ENTRY(_e, _free_data)\
    do { \
        if (_e != NULL){\
            rc_entry *r = qlist_entry(_e, rc_entry, ql);\
            if (_free_data) free(r->data);\
            free(r);\
        } \
    } while(0)

    struct qlist_head *ent, *ent_prev = NULL;
    qlist_for_each(ent, &s->head) {
        FREE_ENTRY(ent_prev, free_data);
        ent_prev = ent;
    }
    FREE_ENTRY(ent_prev, free_data);
    free(s);

#undef FREE_ENTRY
}

void rc_stack_push(
        tw_lp *lp,
        void * data,
        struct rc_stack *s){
Elsa Gonsiorowski (Uranus)'s avatar
Elsa Gonsiorowski (Uranus) committed
57
    rc_entry * ent = (rc_entry*)malloc(sizeof(*ent));
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
    assert(ent);
    ent->time = tw_now(lp);
    ent->data = data;
    qlist_add_tail(&ent->ql, &s->head);
    s->count++;
}

void* rc_stack_pop(struct rc_stack *s){
    struct qlist_head *item = qlist_pop_back(&s->head);
    if (item == NULL)
        tw_error(TW_LOC,
                "could not pop item from rc stack (stack likely empty)\n");
    s->count--;
    return qlist_entry(item, rc_entry, ql)->data;
}

int rc_stack_count(struct rc_stack *s) { return s->count; }

void rc_stack_gc(tw_lp *lp, int free_data, struct rc_stack *s) {
    struct qlist_head *ent = s->head.next;
    while (ent != &s->head) {
        rc_entry *r = qlist_entry(ent, rc_entry, ql);
        if (r->time < lp->pe->GVT){
            qlist_del(ent);
            if (free_data) free(r->data);
            free(r);
            s->count--;
            ent = s->head.next;
        }
        else
            break;
    }
}

/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */