-
Notifications
You must be signed in to change notification settings - Fork 14
/
ps_smr.c
109 lines (89 loc) · 2.23 KB
/
ps_smr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
57
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
100
101
102
103
104
105
106
107
108
109
/***
* Copyright 2014-2015 by Gabriel Parmer. All rights reserved.
* Redistribution of this file is permitted under the BSD 2 clause license.
*
* Authors: Qi Wang, interwq@gmail.com, Gabriel Parmer, gparmer@gwu.edu, 2015
*
* History:
* - Started as parsec.c and parsec.h by Qi.
*/
#include <ps_smr.h>
void __ps_timing_info_init(struct parsec *ps, ps_tsc_t now);
void __ps_smr_account_init(struct ps_smr_info *si);
int
__ps_smr_reclaim_batch(int batch, ps_tsc_t qsc, coreid_t curr, struct ps_qsc_list *ql,
struct ps_mem *m, ps_free_fn_t ffn)
{
int i;
struct ps_mheader *a;
/* Remove a batch worth of items from the qlist */
for (i = 0 ; i < batch ; i++) {
a = __ps_qsc_peek(ql);
if (!a || a->tsc_free > qsc) break;
a = __ps_qsc_dequeue(ql);
assert(a && __ps_mhead_isfree(a));
__ps_mhead_reset(a);
ffn(m, __ps_mhead_mem(a), 0, curr);
}
return i;
}
size_t
ps_smr_nqueued(struct ps_mem *m)
{ return m->percore[ps_coreid()].smr_info.account.qmemcnt; }
void
ps_init(struct parsec *ps)
{
ps_tsc_t now = ps_tsc();
int i;
assert(ps);
memset(ps, 0, sizeof(struct parsec));
ps->refcnt = 0;
for (i = 0 ; i < PS_NUMCORES ; i++) {
struct ps_quiescence_timing *t = &ps->timing_info[i].timing;
t->time_in = now;
t->time_out = t->time_in + 1;
}
__ps_timing_info_init(ps, now);
}
struct parsec *
ps_alloc(void)
{
struct parsec *ps = ps_plat_alloc(sizeof(struct parsec), ps_coreid());
if (!ps) return NULL;
ps_init(ps);
return ps;
}
int
ps_free(struct parsec *ps)
{
if (ps->refcnt > 0) return -1;
ps_plat_free(ps, sizeof(struct parsec), ps_coreid());
return 0;
}
void
__ps_memptr_init(struct ps_mem *m, struct parsec *ps)
{
struct ps_mem_percore *pc = &m->percore[0];
int i;
assert(m && ps);
for (i = 0 ; i < PS_NUMCORES ; i++) {
__ps_smr_account_init(&pc[i].smr_info);
pc[i].smr_info.ps = ps;
}
ps->refcnt++;
}
int
__ps_memptr_delete(struct ps_mem *m)
{
struct ps_mem_percore *pc = &m->percore[0];
struct parsec *ps = pc->smr_info.ps;
int i;
if (!ps) return 0;
if (!ps_slabptr_isempty(m)) return -1;
for (i = 0 ; i < PS_NUMCORES ; i++) {
if (__ps_qsc_peek(&pc[i].smr_info.qsc_list)) return -1;
}
ps->refcnt--;
/* TODO: actually delete it iff refcnt == 0 */
return 0;
}