rc-stack.c 1.98 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * 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;
15
    void (*free_fn)(void*);
16 17 18 19 20 21 22 23 24
    struct qlist_head ql;
} rc_entry;

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

void rc_stack_create(struct rc_stack **s){
25
    struct rc_stack *ss = (struct rc_stack*)malloc(sizeof(*ss));
26 27 28 29 30 31 32
    if (ss) {
        INIT_QLIST_HEAD(&ss->head);
        ss->count = 0;
    }
    *s = ss;
}

33 34
void rc_stack_destroy(struct rc_stack *s) {
    rc_stack_gc(NULL, s);
35 36 37 38
    free(s);
}

void rc_stack_push(
39
        tw_lp const *lp,
40
        void * data,
41
        void (*free_fn)(void*),
42
        struct rc_stack *s){
43
    rc_entry * ent = (rc_entry*)malloc(sizeof(*ent));
44 45 46
    assert(ent);
    ent->time = tw_now(lp);
    ent->data = data;
47
    ent->free_fn = free_fn;
48 49 50 51 52
    qlist_add_tail(&ent->ql, &s->head);
    s->count++;
}

void* rc_stack_pop(struct rc_stack *s){
Jonathan Jenkins's avatar
Jonathan Jenkins committed
53 54
    void * ret = NULL;
    rc_entry *ent = NULL;
55 56 57 58 59
    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--;
Jonathan Jenkins's avatar
Jonathan Jenkins committed
60 61 62 63
    ent = qlist_entry(item, rc_entry, ql);
    ret = ent->data;
    free(ent);
    return ret;
64 65
}

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

68
void rc_stack_gc(tw_lp const *lp, struct rc_stack *s) {
69 70 71
    struct qlist_head *ent = s->head.next;
    while (ent != &s->head) {
        rc_entry *r = qlist_entry(ent, rc_entry, ql);
72
        if (lp == NULL || r->time < lp->pe->GVT){
73
            qlist_del(ent);
74
            if (r->free_fn) r->free_fn(r->data);
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
            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
 */