1*22ce4affSfengbojiang /*
2*22ce4affSfengbojiang * Copyright 2013-2015 Samy Al Bahra
3*22ce4affSfengbojiang * Copyright 2013-2014 AppNexus, Inc.
4*22ce4affSfengbojiang * All rights reserved.
5*22ce4affSfengbojiang *
6*22ce4affSfengbojiang * Redistribution and use in source and binary forms, with or without
7*22ce4affSfengbojiang * modification, are permitted provided that the following conditions
8*22ce4affSfengbojiang * are met:
9*22ce4affSfengbojiang * 1. Redistributions of source code must retain the above copyright
10*22ce4affSfengbojiang * notice, this list of conditions and the following disclaimer.
11*22ce4affSfengbojiang * 2. Redistributions in binary form must reproduce the above copyright
12*22ce4affSfengbojiang * notice, this list of conditions and the following disclaimer in the
13*22ce4affSfengbojiang * documentation and/or other materials provided with the distribution.
14*22ce4affSfengbojiang *
15*22ce4affSfengbojiang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*22ce4affSfengbojiang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*22ce4affSfengbojiang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*22ce4affSfengbojiang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19*22ce4affSfengbojiang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*22ce4affSfengbojiang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*22ce4affSfengbojiang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*22ce4affSfengbojiang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*22ce4affSfengbojiang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*22ce4affSfengbojiang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*22ce4affSfengbojiang * SUCH DAMAGE.
26*22ce4affSfengbojiang */
27*22ce4affSfengbojiang
28*22ce4affSfengbojiang #ifndef CK_ARRAY_H
29*22ce4affSfengbojiang #define CK_ARRAY_H
30*22ce4affSfengbojiang
31*22ce4affSfengbojiang #include <ck_cc.h>
32*22ce4affSfengbojiang #include <ck_malloc.h>
33*22ce4affSfengbojiang #include <ck_pr.h>
34*22ce4affSfengbojiang #include <ck_stdbool.h>
35*22ce4affSfengbojiang #include <ck_stddef.h>
36*22ce4affSfengbojiang
37*22ce4affSfengbojiang struct _ck_array {
38*22ce4affSfengbojiang unsigned int n_committed;
39*22ce4affSfengbojiang unsigned int length;
40*22ce4affSfengbojiang void *values[];
41*22ce4affSfengbojiang };
42*22ce4affSfengbojiang
43*22ce4affSfengbojiang struct ck_array {
44*22ce4affSfengbojiang struct ck_malloc *allocator;
45*22ce4affSfengbojiang struct _ck_array *active;
46*22ce4affSfengbojiang unsigned int n_entries;
47*22ce4affSfengbojiang struct _ck_array *transaction;
48*22ce4affSfengbojiang };
49*22ce4affSfengbojiang typedef struct ck_array ck_array_t;
50*22ce4affSfengbojiang
51*22ce4affSfengbojiang struct ck_array_iterator {
52*22ce4affSfengbojiang struct _ck_array *snapshot;
53*22ce4affSfengbojiang };
54*22ce4affSfengbojiang typedef struct ck_array_iterator ck_array_iterator_t;
55*22ce4affSfengbojiang
56*22ce4affSfengbojiang #define CK_ARRAY_MODE_SPMC 0U
57*22ce4affSfengbojiang #define CK_ARRAY_MODE_MPMC (void) /* Unsupported. */
58*22ce4affSfengbojiang
59*22ce4affSfengbojiang bool ck_array_init(ck_array_t *, unsigned int, struct ck_malloc *, unsigned int);
60*22ce4affSfengbojiang bool ck_array_commit(ck_array_t *);
61*22ce4affSfengbojiang bool ck_array_put(ck_array_t *, void *);
62*22ce4affSfengbojiang int ck_array_put_unique(ck_array_t *, void *);
63*22ce4affSfengbojiang bool ck_array_remove(ck_array_t *, void *);
64*22ce4affSfengbojiang void ck_array_deinit(ck_array_t *, bool);
65*22ce4affSfengbojiang
66*22ce4affSfengbojiang CK_CC_INLINE static unsigned int
ck_array_length(struct ck_array * array)67*22ce4affSfengbojiang ck_array_length(struct ck_array *array)
68*22ce4affSfengbojiang {
69*22ce4affSfengbojiang struct _ck_array *a = ck_pr_load_ptr(&array->active);
70*22ce4affSfengbojiang
71*22ce4affSfengbojiang ck_pr_fence_load();
72*22ce4affSfengbojiang return ck_pr_load_uint(&a->n_committed);
73*22ce4affSfengbojiang }
74*22ce4affSfengbojiang
75*22ce4affSfengbojiang CK_CC_INLINE static void *
ck_array_buffer(struct ck_array * array,unsigned int * length)76*22ce4affSfengbojiang ck_array_buffer(struct ck_array *array, unsigned int *length)
77*22ce4affSfengbojiang {
78*22ce4affSfengbojiang struct _ck_array *a = ck_pr_load_ptr(&array->active);
79*22ce4affSfengbojiang
80*22ce4affSfengbojiang ck_pr_fence_load();
81*22ce4affSfengbojiang *length = ck_pr_load_uint(&a->n_committed);
82*22ce4affSfengbojiang return a->values;
83*22ce4affSfengbojiang }
84*22ce4affSfengbojiang
85*22ce4affSfengbojiang CK_CC_INLINE static bool
ck_array_initialized(struct ck_array * array)86*22ce4affSfengbojiang ck_array_initialized(struct ck_array *array)
87*22ce4affSfengbojiang {
88*22ce4affSfengbojiang
89*22ce4affSfengbojiang return ck_pr_load_ptr(&array->active) != NULL;
90*22ce4affSfengbojiang }
91*22ce4affSfengbojiang
92*22ce4affSfengbojiang #define CK_ARRAY_FOREACH(a, i, b) \
93*22ce4affSfengbojiang (i)->snapshot = ck_pr_load_ptr(&(a)->active); \
94*22ce4affSfengbojiang ck_pr_fence_load(); \
95*22ce4affSfengbojiang for (unsigned int _ck_i = 0; \
96*22ce4affSfengbojiang _ck_i < (a)->active->n_committed && \
97*22ce4affSfengbojiang ((*b) = (a)->active->values[_ck_i], 1); \
98*22ce4affSfengbojiang _ck_i++)
99*22ce4affSfengbojiang
100*22ce4affSfengbojiang #endif /* CK_ARRAY_H */
101