Skip to content

Commit dcdc13d

Browse files
committed
Backport simplifications from cdeque-c11 to cdeque-native
1 parent 9842026 commit dcdc13d

File tree

4 files changed

+56
-78
lines changed

4 files changed

+56
-78
lines changed

libworkstream_df/cbuffer-native.h

+27-28
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,19 @@ typedef struct cbuffer{
2727
static inline cbuffer_p
2828
cbuffer_alloc (size_t log_size)
2929
{
30+
void *p;
3031
cbuffer_p cbuffer;
31-
if (posix_memalign ((void **)&cbuffer, 64, sizeof (cbuffer_t)))
32+
33+
if (posix_memalign (&p, 64, sizeof *cbuffer))
3234
wstream_df_fatal ("Out of memory ...");
3335

36+
cbuffer = p;
3437
cbuffer->log_size = log_size;
3538
cbuffer->size = (1 << log_size);
3639
cbuffer->modulo_mask = cbuffer->size - 1;
37-
if (posix_memalign ((void **)&cbuffer->array, 64,
38-
sizeof (wstream_df_type) * cbuffer->size))
40+
if (posix_memalign (&p, 64, sizeof *cbuffer->array * cbuffer->size))
3941
wstream_df_fatal ("Out of memory ...");
42+
cbuffer->array = p;
4043

4144
return cbuffer;
4245
}
@@ -50,12 +53,6 @@ cbuffer_free (cbuffer_p cbuffer)
5053
free (cbuffer);
5154
}
5255

53-
static inline size_t
54-
cbuffer_size (cbuffer_p cbuffer)
55-
{
56-
return cbuffer->size;
57-
}
58-
5956
static inline wstream_df_type
6057
cbuffer_get (cbuffer_p cbuffer, size_t i)
6158
{
@@ -68,11 +65,11 @@ cbuffer_set (cbuffer_p cbuffer, size_t i, wstream_df_type elem)
6865
cbuffer->array[i & cbuffer->modulo_mask] = elem;
6966
}
7067

71-
static inline void
72-
cbuffer_grow (cbuffer_p volatile *cbuffer, size_t bottom, size_t top)
68+
static inline cbuffer_p
69+
cbuffer_grow (cbuffer_p old_cbuffer, size_t bottom, size_t top,
70+
cbuffer_p volatile *pnew)
7371
{
74-
cbuffer_p new_cbuffer = cbuffer_alloc ((*cbuffer)->log_size + 1);
75-
cbuffer_p old_cbuffer = *cbuffer;
72+
cbuffer_p new_cbuffer = cbuffer_alloc (old_cbuffer->log_size + 1);
7673

7774
size_t old_buffer_size = old_cbuffer->size;
7875
size_t old_top_pos = top & old_cbuffer->modulo_mask;
@@ -81,43 +78,45 @@ cbuffer_grow (cbuffer_p volatile *cbuffer, size_t bottom, size_t top)
8178
size_t new_top_pos = top & new_cbuffer->modulo_mask;
8279
size_t new_bot_pos = bottom & new_cbuffer->modulo_mask;
8380

84-
/* If no wrap-around for old buffer, new one can't have one if size
85-
is doubled. */
8681
if (old_top_pos < old_bot_pos)
87-
memcpy (&new_cbuffer->array[new_top_pos],
88-
&(*cbuffer)->array[old_top_pos],
89-
(old_bot_pos - old_top_pos) * sizeof (wstream_df_type));
90-
91-
/* If old buffer wraps around, then either new one wraps around at
92-
same place or it just doesn't. */
82+
{
83+
/* If no wrap-around for old buffer, new one can't have one if
84+
size is doubled. */
85+
memcpy (&new_cbuffer->array[new_top_pos],
86+
&old_cbuffer->array[old_top_pos],
87+
(old_bot_pos - old_top_pos) * sizeof (wstream_df_type));
88+
}
9389
else
9490
{
91+
/* If old buffer wraps around, then either new one wraps around
92+
at same place or it just doesn't. */
93+
9594
/* No wrap around in new buffer? */
96-
int no_wrap_around = (new_top_pos < new_bot_pos) ? 1 : 0;
95+
int no_wrap_around = new_top_pos < new_bot_pos;
9796

9897
memcpy (&new_cbuffer->array[new_top_pos],
99-
&(*cbuffer)->array[old_top_pos],
98+
&old_cbuffer->array[old_top_pos],
10099
(old_buffer_size - old_top_pos) * sizeof (wstream_df_type));
101100
memcpy (&new_cbuffer->array[no_wrap_around * old_buffer_size],
102-
(*cbuffer)->array,
101+
old_cbuffer->array,
103102
(old_bot_pos) * sizeof (wstream_df_type));
104103
}
105104

106105
store_store_fence ();
107-
108-
*cbuffer = new_cbuffer;
109-
106+
*pnew = new_cbuffer;
110107
store_store_fence ();
111108

112109
/* XXX(nhatle): Race condition with steal() on freed buffer? */
113110
cbuffer_free (old_cbuffer);
111+
112+
return new_cbuffer;
114113
}
115114

116115
static inline void
117116
print_cbuffer (cbuffer_p cbuffer)
118117
{
119118
size_t i;
120-
for (i = 0; i < cbuffer_size (cbuffer); i++)
119+
for (i = 0; i < cbuffer->size; i++)
121120
printf ("%p,", cbuffer_get (cbuffer, i));
122121
printf ("\n");
123122
}

libworkstream_df/cdeque-c11.c.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#include <stdatomic.h>
2+
#include <stddef.h>
3+
14
#include "papi-defs.h"
25
#include "wstream_df.h"
36
#include "error.h"
@@ -32,8 +35,8 @@ cdeque_take (cdeque_p cdeque)
3235
{
3336
_PAPI_P1B;
3437
size_t bottom, top;
35-
cbuffer_p buffer;
3638
wstream_df_type task;
39+
cbuffer_p buffer;
3740

3841
bottom = atomic_load_explicit (&cdeque->bottom, relaxed) - 1;
3942
buffer = atomic_load_explicit (&cdeque->cbuffer, relaxed);

libworkstream_df/cdeque-native.c.h

+20-16
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ cdeque_push_bottom (cdeque_p cdeque, wstream_df_type elem)
1313
size_t bottom = cdeque->bottom;
1414
size_t top = cdeque->top;
1515

16-
XLOG ("cdeque_push_bottom with elem: %d\n", elem);
17-
if (bottom >= top + cdeque_size (cdeque))
18-
cdeque_grow (cdeque, bottom, top);
16+
cbuffer_p buffer = cdeque->cbuffer;
1917

20-
cdeque_set (cdeque, bottom, elem);
18+
XLOG ("cdeque_push_bottom with elem: %d\n", elem);
19+
if (bottom >= top + buffer->size)
20+
buffer = cbuffer_grow (buffer, bottom, top, &cdeque->cbuffer);
2121

22+
cbuffer_set (buffer, bottom, elem);
2223
store_store_fence ();
23-
2424
cdeque->bottom = bottom + 1;
25+
2526
_PAPI_P0E;
2627
}
2728

@@ -32,13 +33,9 @@ cdeque_take (cdeque_p cdeque)
3233
_PAPI_P1B;
3334
size_t bottom, top;
3435
wstream_df_type task;
36+
cbuffer_p buffer;
3537

36-
if (cdeque->bottom == 0)
37-
{
38-
_PAPI_P1E;
39-
return NULL;
40-
}
41-
38+
buffer = cdeque->cbuffer;
4239
#if LLSC_OPTIMIZATION && defined(__arm__)
4340
do
4441
bottom = load_linked (&cdeque->bottom) - 1;
@@ -49,27 +46,29 @@ cdeque_take (cdeque_p cdeque)
4946
cdeque->bottom = bottom;
5047
store_load_fence ();
5148
#endif
49+
5250
top = cdeque->top;
5351

54-
if (bottom < top)
52+
if (bottom == (size_t) -1 || bottom < top)
5553
{
56-
cdeque->bottom = top;
54+
cdeque->bottom = bottom + 1;
5755
_PAPI_P1E;
5856
return NULL;
5957
}
6058

61-
task = cdeque_get (cdeque, bottom);
59+
task = cbuffer_get (buffer, bottom);
6260

6361
if (bottom > top)
6462
{
6563
_PAPI_P1E;
6664
return task;
6765
}
66+
6867
/* One compare and swap when the deque has one single element. */
6968
if (!compare_and_swap (&cdeque->top, top, top+1))
7069
task = NULL;
71-
7270
cdeque->bottom = top + 1;
71+
7372
_PAPI_P1E;
7473
return task;
7574
}
@@ -81,15 +80,18 @@ cdeque_steal (cdeque_p remote_cdeque)
8180
_PAPI_P2B;
8281
size_t bottom, top;
8382
wstream_df_type elem;
83+
cbuffer_p buffer;
8484

8585
top = remote_cdeque->top;
86+
8687
#if defined(__arm__)
8788
/* Block until the value read from top has been propagated to all
8889
other threads. */
8990
store_load_fence ();
9091
#else
9192
load_load_fence (top);
9293
#endif
94+
9395
#if LLSC_OPTIMIZATION && defined(__arm__)
9496
bottom = load_linked (&remote_cdeque->bottom);
9597
if (!store_conditional (&remote_cdeque->bottom, bottom))
@@ -98,6 +100,7 @@ cdeque_steal (cdeque_p remote_cdeque)
98100
#else
99101
bottom = remote_cdeque->bottom;
100102
#endif
103+
101104
load_load_fence (bottom);
102105

103106
XLOG ("cdeque_steal with bottom %d, top %d\n", bottom, top);
@@ -108,7 +111,8 @@ cdeque_steal (cdeque_p remote_cdeque)
108111
return NULL;
109112
}
110113

111-
elem = cdeque_get (remote_cdeque, top);
114+
buffer = remote_cdeque->cbuffer;
115+
elem = cbuffer_get (buffer, top);
112116
#if defined(__arm__)
113117
/* Do not reorder the previous load with the load from the CAS. */
114118
load_load_fence ((uintptr_t) elem);

libworkstream_df/cdeque-native.h

+5-33
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,6 @@ typedef struct cdeque {
2323
cbuffer_p volatile cbuffer __attribute__ ((aligned (64)));
2424
} cdeque_t, *cdeque_p;
2525

26-
/* Get the size/capacity of the deque CDEQUE. */
27-
static inline size_t
28-
cdeque_size (cdeque_p cdeque)
29-
{
30-
return cbuffer_size (cdeque->cbuffer);
31-
}
32-
33-
/* Extend the size of the deque CDEQUE, with bottom BOTTOM and top TOP. */
34-
static inline void
35-
cdeque_grow (cdeque_p cdeque, size_t bottom, size_t top)
36-
{
37-
cbuffer_grow (&cdeque->cbuffer, bottom, top);
38-
}
39-
40-
/* Set the deque at position POS with element ELEM. */
41-
static inline void
42-
cdeque_set (cdeque_p cdeque, size_t pos, wstream_df_type elem)
43-
{
44-
cbuffer_set (cdeque->cbuffer, pos, elem);
45-
}
46-
47-
/* Get the element from the deque CDEQUE at position POS. */
48-
static inline wstream_df_type
49-
cdeque_get (cdeque_p cdeque, size_t pos)
50-
{
51-
return cbuffer_get (cdeque->cbuffer, pos);
52-
}
53-
5426
static inline void
5527
cdeque_init (cdeque_p cdeque, size_t log_size)
5628
{
@@ -64,10 +36,9 @@ static inline cdeque_p
6436
cdeque_alloc (size_t log_size)
6537
{
6638
cdeque_p cdeque = (cdeque_p) malloc (sizeof (cdeque_t));
67-
cdeque->bottom = 0;
68-
cdeque->top = 0;
69-
cdeque->cbuffer = cbuffer_alloc (log_size);
70-
39+
if (cdeque == NULL)
40+
wstream_df_fatal ("Out of memory ...");
41+
cdeque_init (cdeque, log_size);
7142
return cdeque;
7243
}
7344

@@ -84,8 +55,9 @@ static inline void
8455
print_cdeque (cdeque_p cdeque)
8556
{
8657
size_t i;
58+
cbuffer_p buffer = cdeque->cbuffer;
8759
for (i = cdeque->top; i < cdeque->bottom; i++)
88-
printf ("%p,", cdeque_get (cdeque, i));
60+
printf ("%p,", cbuffer_get (buffer, i));
8961
printf ("\n");
9062
}
9163

0 commit comments

Comments
 (0)