mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-18 21:29:18 +02:00
230 lines
7.9 KiB
C
230 lines
7.9 KiB
C
#ifndef CYCLONE_CK_POLYFILL_H
|
|
#define CYCLONE_CK_POLYFILL_H
|
|
|
|
#include "cyclone/types.h"
|
|
#include "cyclone/hashset.h"
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
void ck_polyfill_init();
|
|
|
|
struct ck_malloc {
|
|
void *(*malloc)(size_t);
|
|
void *(*realloc)(void *, size_t, size_t, bool);
|
|
void (*free)(void *, size_t, bool);
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Simple hashset (hashset with string support)
|
|
/* hash function */
|
|
typedef size_t (*hash_func_t)(const char *, size_t);
|
|
|
|
struct simple_hashset_item_st {
|
|
size_t hash;
|
|
symbol_type *item;
|
|
};
|
|
|
|
struct simple_hashset_st {
|
|
size_t nbits;
|
|
size_t mask;
|
|
|
|
size_t capacity;
|
|
struct simple_hashset_item_st *items;
|
|
size_t nitems;
|
|
size_t n_deleted_items;
|
|
|
|
hash_func_t hash_func;
|
|
};
|
|
// struct simple_hashset_st;
|
|
typedef struct simple_hashset_st *simple_hashset_t;
|
|
|
|
struct hashmap_st;
|
|
typedef struct hashmap_st *hashmap_t;
|
|
|
|
/*
|
|
* HASHSET FUNCTIONS
|
|
*/
|
|
|
|
/* create hashset instance */
|
|
simple_hashset_t simple_hashset_create(void);
|
|
|
|
/* destroy hashset instance */
|
|
void simple_hashset_destroy(simple_hashset_t set);
|
|
|
|
/* set hash function */
|
|
void simple_hashset_set_hash_function(simple_hashset_t set, hash_func_t func);
|
|
|
|
/* add item into the hashset.
|
|
*
|
|
* @note 0 and 1 is special values, meaning nil and deleted items. the
|
|
* function will return -1 indicating error.
|
|
*
|
|
* returns zero if the item already in the set and non-zero otherwise
|
|
*/
|
|
int simple_hashset_add(simple_hashset_t set, symbol_type * key);
|
|
|
|
/* check if existence of the item
|
|
*
|
|
* returns non-zero if the item exists and zero otherwise
|
|
*/
|
|
int simple_hashset_is_member(simple_hashset_t set, symbol_type * key);
|
|
|
|
static inline uint64_t MurmurHash64A(const void *key, int len, uint64_t seed)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CK Hashset section
|
|
|
|
#define CK_HS_MODE_OBJECT 0
|
|
#define CK_HS_MODE_SPMC 0
|
|
|
|
struct ck_hs {
|
|
pthread_mutex_t lock;
|
|
simple_hashset_t hs;
|
|
};
|
|
|
|
typedef struct ck_hs ck_hs_t;
|
|
|
|
/*
|
|
* Hash callback function.
|
|
*/
|
|
typedef unsigned long ck_hs_hash_cb_t(const void *, unsigned long);
|
|
|
|
/*
|
|
* Returns pointer to object if objects are equivalent.
|
|
*/
|
|
typedef bool ck_hs_compare_cb_t(const void *, const void *);
|
|
|
|
#define CK_HS_HASH(hs, hs_hash, value) 0
|
|
|
|
bool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *,
|
|
ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long,
|
|
unsigned long);
|
|
|
|
void *ck_hs_get(ck_hs_t *, unsigned long, const void *);
|
|
bool ck_hs_put(ck_hs_t *, unsigned long, const void *);
|
|
|
|
/*
|
|
struct ck_hs {
|
|
struct ck_malloc *m;
|
|
struct ck_hs_map *map;
|
|
unsigned int mode;
|
|
unsigned long seed;
|
|
ck_hs_hash_cb_t *hf;
|
|
ck_hs_compare_cb_t *compare;
|
|
};
|
|
typedef struct ck_hs ck_hs_t;
|
|
|
|
|
|
*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CK Array section
|
|
struct ck_array {
|
|
pthread_mutex_t lock;
|
|
hashset_t hs;
|
|
};
|
|
typedef struct ck_array ck_array_t;
|
|
|
|
struct ck_array_iterator {
|
|
int unused;
|
|
};
|
|
typedef struct ck_array_iterator ck_array_iterator_t;
|
|
|
|
#define CK_ARRAY_MODE_SPMC 0
|
|
|
|
// DESCRIPTION
|
|
// The ck_array_init(3) function initializes the array pointed to by the
|
|
// argument array. The mode value must be CK_ARRAY_MODE_SPMC. The
|
|
// allocator argument must point to a ck_malloc data structure with valid
|
|
// non-NULL function pointers initialized for malloc, free and realloc. The
|
|
// initial_length specifies the initial length of the array. The value of
|
|
// initial_length must be greater than or equal to 2. An array allows for
|
|
// one concurrent put or remove operations in the presence of any number of
|
|
// concurrent CK_ARRAY_FOREACH operations.
|
|
//
|
|
// RETURN VALUES
|
|
// This function returns true if the array was successfully created. It
|
|
// returns false if the creation failed. Failure may occur due to internal
|
|
// memory allocation failures or invalid arguments.
|
|
bool
|
|
ck_array_init(ck_array_t * array, unsigned int mode,
|
|
struct ck_malloc *allocator, unsigned int initial_length);
|
|
|
|
// DESCRIPTION
|
|
// The ck_array_put_unique(3) function will attempt to insert the value of
|
|
// pointer into the array pointed to by array. This function may incur
|
|
// additional memory allocations if not enough memory has been allocated in
|
|
// the array for a new entry. The operation is also free to apply the opera-
|
|
// tion immediately if there is an opportunity for elimination with a pend-
|
|
// ing (uncommitted) remove operation. The function will not make any modi-
|
|
// fications if the pointer already exists in the array.
|
|
//
|
|
// RETURN VALUES
|
|
// This function returns 1 if the pointer already exists in the array. It
|
|
// returns 0 if the put operation succeeded. It returns -1 on error due to
|
|
// internal memory allocation failures.
|
|
int ck_array_put_unique(ck_array_t * array, void *pointer);
|
|
|
|
// DESCRIPTION
|
|
// The ck_array_remove(3) function will attempt to remove the value of
|
|
// pointer into the array pointed to by array. The operation is also free to
|
|
// apply the operation immediately if there is an opportunity for elimina-
|
|
// tion with a pending (uncommitted) put operation. If no elimination was
|
|
// possible, the function may require to allocate more memory.
|
|
//
|
|
// RETURN VALUES
|
|
// This function returns true if the remove operation succeeded. It will
|
|
// return false otherwise due to internal allocation failures or because the
|
|
// value did not exist.
|
|
bool ck_array_remove(ck_array_t * array, void *pointer);
|
|
|
|
// DESCRIPTION
|
|
// The ck_array_commit(3) function will commit any pending put or remove
|
|
// operations associated with the array. The function may end up requesting
|
|
// the safe reclamation of memory actively being iterated upon by other
|
|
// threads.
|
|
//
|
|
// RETURN VALUES
|
|
// This function returns true if the commit operation succeeded. It will
|
|
// return false otherwise, and pending operations will not be applied.
|
|
bool ck_array_commit(ck_array_t * array);
|
|
|
|
// TODO:
|
|
|
|
// Can we safely lock the array, make a copy, and interate over that????
|
|
#define CK_ARRAY_FOREACH(a, i, b) \
|
|
pthread_mutex_lock(&((a)->lock)); \
|
|
int tmpc = (a)->hs->nitems; \
|
|
void **tmp = alloca(sizeof(void *) * tmpc); \
|
|
hashset_to_array((a)->hs, tmp); \
|
|
pthread_mutex_unlock(&((a)->lock)); \
|
|
if (tmpc > 0) { (*b) = tmp[0]; } \
|
|
for (unsigned int _ck_i = 0; \
|
|
_ck_i < tmpc; \
|
|
_ck_i++, (*b) = tmp[_ck_i])
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CK PR section
|
|
bool ck_pr_cas_ptr(void *target, void *old_value, void *new_value);
|
|
|
|
bool ck_pr_cas_int(int *target, int old_value, int new_value);
|
|
|
|
bool ck_pr_cas_8(uint8_t * target, uint8_t old_value, uint8_t new_value);
|
|
|
|
void ck_pr_add_ptr(void *target, uintptr_t delta);
|
|
|
|
void ck_pr_add_int(int *target, int delta);
|
|
|
|
void ck_pr_add_8(uint8_t * target, uint8_t delta);
|
|
|
|
void *ck_pr_load_ptr(const void *target);
|
|
|
|
int ck_pr_load_int(const int *target);
|
|
|
|
uint8_t ck_pr_load_8(const uint8_t * target);
|
|
|
|
void ck_pr_store_ptr(void *target, void *value);
|
|
#endif /* CYCLONE_CK_POLYFILL_H */
|