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){
Elsa Gonsiorowski (Uranus)'s avatar
Elsa Gonsiorowski (Uranus) committed
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){
Elsa Gonsiorowski (Uranus)'s avatar
Elsa Gonsiorowski (Uranus) committed
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
 */