-
Notifications
You must be signed in to change notification settings - Fork 47
Expand file tree
/
Copy pathccsynch.h
More file actions
84 lines (64 loc) · 1.82 KB
/
ccsynch.h
File metadata and controls
84 lines (64 loc) · 1.82 KB
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
#ifndef _CCSYNCH_H_
#define _CCSYNCH_H_
#include <stdlib.h>
#include "align.h"
#include "primitives.h"
typedef struct _ccsynch_node_t {
struct _ccsynch_node_t * volatile next CACHE_ALIGNED;
void * volatile data;
int volatile status CACHE_ALIGNED;
} ccsynch_node_t;
typedef struct _ccsynch_handle_t {
struct _ccsynch_node_t * next;
} ccsynch_handle_t;
typedef struct _ccsynch_t {
struct _ccsynch_node_t * volatile tail DOUBLE_CACHE_ALIGNED;
} ccsynch_t;
#define CCSYNCH_WAIT 0x0
#define CCSYNCH_READY 0x1
#define CCSYNCH_DONE 0x3
static inline
void ccsynch_apply(ccsynch_t * synch, ccsynch_handle_t * handle,
void (*apply)(void *, void *), void * state, void * data)
{
ccsynch_node_t * next = handle->next;
next->next = NULL;
next->status = CCSYNCH_WAIT;
ccsynch_node_t * curr = SWAPra(&synch->tail, next);
handle->next = curr;
int status = ACQUIRE(&curr->status);
if (status == CCSYNCH_WAIT) {
curr->data = data;
RELEASE(&curr->next, next);
do {
PAUSE();
status = ACQUIRE(&curr->status);
} while (status == CCSYNCH_WAIT);
}
if (status != CCSYNCH_DONE) {
apply(state, data);
curr = next;
next = ACQUIRE(&curr->next);
int count = 0;
const int CCSYNCH_HELP_BOUND = 256;
while (next && count++ < CCSYNCH_HELP_BOUND) {
apply(state, curr->data);
RELEASE(&curr->status, CCSYNCH_DONE);
curr = next;
next = ACQUIRE(&curr->next);
}
RELEASE(&curr->status, CCSYNCH_READY);
}
}
static inline void ccsynch_init(ccsynch_t * synch)
{
ccsynch_node_t * node = align_malloc(CACHE_LINE_SIZE, sizeof(ccsynch_node_t));
node->next = NULL;
node->status = CCSYNCH_READY;
synch->tail = node;
}
static inline void ccsynch_handle_init(ccsynch_handle_t * handle)
{
handle->next = align_malloc(CACHE_LINE_SIZE, sizeof(ccsynch_node_t));
}
#endif