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