-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpmcrcu.c
67 lines (53 loc) · 1.38 KB
/
pmcrcu.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
//#define AEM_PMCRCU_DLFCN
#ifdef AEM_PMCRCU_DLFCN
# define _GNU_SOURCE
# include <dlfcn.h>
#endif
#define AEM_INTERNAL
#include <aem/linked_list.h>
#include <aem/log.h>
#include "pmcrcu.h"
static struct aem_pmcrcu_rcu_head *aem_pmcrcu_head = NULL;
void aem_pmcrcu_call_rcu(struct aem_pmcrcu_rcu_head *head,
void (*func)(struct aem_pmcrcu_rcu_head *head))
{
aem_assert(head);
aem_assert(func);
head->func = func;
#ifdef AEM_DEBUG
// Make sure this rcu_head isn't already enqueued.
AEM_LL_FOR_RANGE(curr, aem_pmcrcu_head, NULL, next) {
aem_assert(curr != head);
}
#endif
head->next = aem_pmcrcu_head;
aem_pmcrcu_head = head;
}
static int aem_pmcrcu_process_one_callback(void)
{
struct aem_pmcrcu_rcu_head *head = aem_pmcrcu_head;
if (!head)
return -1;
aem_assert(head != head->next);
aem_pmcrcu_head = head->next;
#ifdef AEM_PMCRCU_DLFCN
{
Dl_info info;
if (dladdr(head->func, &info)) {
//aem_logf_ctx(AEM_LOG_DEBUG, "rcu callback: obj %p, method %s from %s", head, info.dli_sname, info.dli_fname);
aem_logf_ctx(AEM_LOG_DEBUG, "rcu callback: %s(%p)", info.dli_sname, head);
} else {
aem_logf_ctx(AEM_LOG_DEBUG, "rcu callback: ((void(*)(struct rcu_head*))%p)(%p)", head->func, head);
}
}
#endif
aem_assert(head->func);
head->func(head);
return 0;
}
void aem_pmcrcu_rcu_barrier(void)
{
while (aem_pmcrcu_head) {
aem_pmcrcu_process_one_callback();
}
}