mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-18 21:29:18 +02:00
Re-format code
This commit is contained in:
parent
b44198744b
commit
3b921e7389
12 changed files with 2586 additions and 2357 deletions
241
ck-polyfill.c
241
ck-polyfill.c
|
@ -27,8 +27,9 @@ void ck_polyfill_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CK Hashset section
|
// CK Hashset section
|
||||||
bool ck_hs_init(ck_hs_t *hs, unsigned int mode, ck_hs_hash_cb_t *hash_func,
|
bool ck_hs_init(ck_hs_t * hs, unsigned int mode, ck_hs_hash_cb_t * hash_func,
|
||||||
ck_hs_compare_cb_t *cmp, struct ck_malloc *alloc, unsigned long capacity, unsigned long seed)
|
ck_hs_compare_cb_t * cmp, struct ck_malloc *alloc,
|
||||||
|
unsigned long capacity, unsigned long seed)
|
||||||
{
|
{
|
||||||
(*hs).hs = simple_hashset_create();
|
(*hs).hs = simple_hashset_create();
|
||||||
if (pthread_mutex_init(&((*hs).lock), NULL) != 0) {
|
if (pthread_mutex_init(&((*hs).lock), NULL) != 0) {
|
||||||
|
@ -38,7 +39,7 @@ bool ck_hs_init(ck_hs_t *hs, unsigned int mode, ck_hs_hash_cb_t *hash_func,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ck_hs_get(ck_hs_t *_hs, unsigned long hash, const void *key)
|
void *ck_hs_get(ck_hs_t * _hs, unsigned long hash, const void *key)
|
||||||
{
|
{
|
||||||
void *result = NULL;
|
void *result = NULL;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
|
@ -46,7 +47,7 @@ void *ck_hs_get(ck_hs_t *_hs, unsigned long hash, const void *key)
|
||||||
|
|
||||||
pthread_mutex_lock(&((*_hs).lock));
|
pthread_mutex_lock(&((*_hs).lock));
|
||||||
|
|
||||||
index = simple_hashset_is_member(set, (symbol_type *)key);
|
index = simple_hashset_is_member(set, (symbol_type *) key);
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
result = (void *)(set->items[index].item);
|
result = (void *)(set->items[index].item);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +56,7 @@ void *ck_hs_get(ck_hs_t *_hs, unsigned long hash, const void *key)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ck_hs_put(ck_hs_t *_hs, unsigned long hash, const void *key)
|
bool ck_hs_put(ck_hs_t * _hs, unsigned long hash, const void *key)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
int rv, index;
|
int rv, index;
|
||||||
|
@ -65,10 +66,10 @@ bool ck_hs_put(ck_hs_t *_hs, unsigned long hash, const void *key)
|
||||||
|
|
||||||
//index = simple_hashset_is_member(hs, (symbol_type *)key);
|
//index = simple_hashset_is_member(hs, (symbol_type *)key);
|
||||||
//if (index == 0) {
|
//if (index == 0) {
|
||||||
rv = simple_hashset_add(hs, (symbol_type *)key);
|
rv = simple_hashset_add(hs, (symbol_type *) key);
|
||||||
if (rv >= 0) {
|
if (rv >= 0) {
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
|
|
||||||
pthread_mutex_unlock(&((*_hs).lock));
|
pthread_mutex_unlock(&((*_hs).lock));
|
||||||
|
@ -77,8 +78,8 @@ bool ck_hs_put(ck_hs_t *_hs, unsigned long hash, const void *key)
|
||||||
|
|
||||||
// CK Array section
|
// CK Array section
|
||||||
bool
|
bool
|
||||||
ck_array_init(ck_array_t *array, unsigned int mode,
|
ck_array_init(ck_array_t * array, unsigned int mode,
|
||||||
struct ck_malloc *allocator, unsigned int initial_length)
|
struct ck_malloc *allocator, unsigned int initial_length)
|
||||||
{
|
{
|
||||||
(*array).hs = hashset_create();
|
(*array).hs = hashset_create();
|
||||||
if (pthread_mutex_init(&((*array).lock), NULL) != 0) {
|
if (pthread_mutex_init(&((*array).lock), NULL) != 0) {
|
||||||
|
@ -101,8 +102,7 @@ ck_array_init(ck_array_t *array, unsigned int mode,
|
||||||
// This function returns 1 if the pointer already exists in the array. It
|
// 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
|
// returns 0 if the put operation succeeded. It returns -1 on error due to
|
||||||
// internal memory allocation failures.
|
// internal memory allocation failures.
|
||||||
int
|
int ck_array_put_unique(ck_array_t * array, void *pointer)
|
||||||
ck_array_put_unique(ck_array_t *array, void *pointer)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&(array->lock));
|
pthread_mutex_lock(&(array->lock));
|
||||||
hashset_add(array->hs, pointer);
|
hashset_add(array->hs, pointer);
|
||||||
|
@ -121,8 +121,8 @@ ck_array_put_unique(ck_array_t *array, void *pointer)
|
||||||
// This function returns true if the remove operation succeeded. It will
|
// This function returns true if the remove operation succeeded. It will
|
||||||
// return false otherwise due to internal allocation failures or because the
|
// return false otherwise due to internal allocation failures or because the
|
||||||
// value did not exist.
|
// value did not exist.
|
||||||
bool
|
bool ck_array_remove(ck_array_t * array, void *pointer)
|
||||||
ck_array_remove(ck_array_t *array, void *pointer){
|
{
|
||||||
pthread_mutex_lock(&(array->lock));
|
pthread_mutex_lock(&(array->lock));
|
||||||
hashset_remove(array->hs, pointer);
|
hashset_remove(array->hs, pointer);
|
||||||
pthread_mutex_unlock(&(array->lock));
|
pthread_mutex_unlock(&(array->lock));
|
||||||
|
@ -138,12 +138,12 @@ ck_array_remove(ck_array_t *array, void *pointer){
|
||||||
// RETURN VALUES
|
// RETURN VALUES
|
||||||
// This function returns true if the commit operation succeeded. It will
|
// This function returns true if the commit operation succeeded. It will
|
||||||
// return false otherwise, and pending operations will not be applied.
|
// return false otherwise, and pending operations will not be applied.
|
||||||
bool ck_array_commit(ck_array_t *array) {
|
bool ck_array_commit(ck_array_t * array)
|
||||||
|
{
|
||||||
// Nothing to do in this polyfill
|
// Nothing to do in this polyfill
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: global pthread mutex lock for this? obviously not ideal but the
|
// TODO: global pthread mutex lock for this? obviously not ideal but the
|
||||||
// whole purpose of this module is a minimal interface for compatibility
|
// whole purpose of this module is a minimal interface for compatibility
|
||||||
// not speed
|
// not speed
|
||||||
|
@ -164,7 +164,7 @@ bool ck_pr_cas_ptr(void *target, void *old_value, void *new_value)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
pthread_mutex_lock(&glock);
|
pthread_mutex_lock(&glock);
|
||||||
if ( *(void **)target == old_value ) {
|
if (*(void **)target == old_value) {
|
||||||
*(void **)target = new_value;
|
*(void **)target = new_value;
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ bool ck_pr_cas_ptr(void *target, void *old_value, void *new_value)
|
||||||
// *(void **)v = set;
|
// *(void **)v = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ck_pr_cas_8(uint8_t *target, uint8_t old_value, uint8_t new_value)
|
bool ck_pr_cas_8(uint8_t * target, uint8_t old_value, uint8_t new_value)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
pthread_mutex_lock(&glock);
|
pthread_mutex_lock(&glock);
|
||||||
|
@ -185,36 +185,32 @@ bool ck_pr_cas_8(uint8_t *target, uint8_t old_value, uint8_t new_value)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ck_pr_add_ptr(void *target, uintptr_t delta)
|
||||||
ck_pr_add_ptr(void *target, uintptr_t delta)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&glock);
|
pthread_mutex_lock(&glock);
|
||||||
size_t value = (size_t) target;
|
size_t value = (size_t)target;
|
||||||
size_t d = (size_t) delta;
|
size_t d = (size_t)delta;
|
||||||
size_t result = value + d;
|
size_t result = value + d;
|
||||||
*(void **)target = (void *)result;
|
*(void **)target = (void *)result;
|
||||||
// *(void **)v = set;
|
// *(void **)v = set;
|
||||||
pthread_mutex_unlock(&glock);
|
pthread_mutex_unlock(&glock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ck_pr_add_int(int *target, int delta)
|
||||||
ck_pr_add_int(int *target, int delta)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&glock);
|
pthread_mutex_lock(&glock);
|
||||||
(*target) += delta;
|
(*target) += delta;
|
||||||
pthread_mutex_unlock(&glock);
|
pthread_mutex_unlock(&glock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ck_pr_add_8(uint8_t * target, uint8_t delta)
|
||||||
ck_pr_add_8(uint8_t *target, uint8_t delta)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&glock);
|
pthread_mutex_lock(&glock);
|
||||||
(*target) += delta;
|
(*target) += delta;
|
||||||
pthread_mutex_unlock(&glock);
|
pthread_mutex_unlock(&glock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *ck_pr_load_ptr(const void *target)
|
||||||
ck_pr_load_ptr(const void *target)
|
|
||||||
{
|
{
|
||||||
void *result;
|
void *result;
|
||||||
pthread_mutex_lock(&glock);
|
pthread_mutex_lock(&glock);
|
||||||
|
@ -223,8 +219,7 @@ ck_pr_load_ptr(const void *target)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ck_pr_load_int(const int *target)
|
||||||
ck_pr_load_int(const int *target)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
pthread_mutex_lock(&glock);
|
pthread_mutex_lock(&glock);
|
||||||
|
@ -233,8 +228,7 @@ ck_pr_load_int(const int *target)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t ck_pr_load_8(const uint8_t * target)
|
||||||
ck_pr_load_8(const uint8_t *target)
|
|
||||||
{
|
{
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
pthread_mutex_lock(&glock);
|
pthread_mutex_lock(&glock);
|
||||||
|
@ -250,134 +244,139 @@ void ck_pr_store_ptr(void *target, void *value)
|
||||||
pthread_mutex_unlock(&glock);
|
pthread_mutex_unlock(&glock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Simple hashset
|
// Simple hashset
|
||||||
|
|
||||||
static const size_t prime_1 = 73;
|
static const size_t prime_1 = 73;
|
||||||
static const size_t prime_2 = 5009;
|
static const size_t prime_2 = 5009;
|
||||||
|
|
||||||
size_t hash_function(const char* str, size_t len) {
|
size_t hash_function(const char *str, size_t len)
|
||||||
unsigned long hash = 5381;
|
{
|
||||||
int c;
|
unsigned long hash = 5381;
|
||||||
|
int c;
|
||||||
|
|
||||||
while (c = *str++) {
|
while (c = *str++) {
|
||||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
simple_hashset_t simple_hashset_create()
|
simple_hashset_t simple_hashset_create()
|
||||||
{
|
{
|
||||||
simple_hashset_t set = (simple_hashset_t)calloc(1, sizeof(struct simple_hashset_st));
|
simple_hashset_t set =
|
||||||
|
(simple_hashset_t) calloc(1, sizeof(struct simple_hashset_st));
|
||||||
|
|
||||||
if (set == NULL) {
|
if (set == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
set->hash_func = hash_function;
|
set->hash_func = hash_function;
|
||||||
set->nbits = 3;
|
set->nbits = 3;
|
||||||
set->capacity = (size_t)(1 << set->nbits);
|
set->capacity = (size_t)(1 << set->nbits);
|
||||||
set->mask = set->capacity - 1;
|
set->mask = set->capacity - 1;
|
||||||
set->items = (struct simple_hashset_item_st*)calloc(set->capacity, sizeof(struct simple_hashset_item_st));
|
set->items =
|
||||||
if (set->items == NULL) {
|
(struct simple_hashset_item_st *)calloc(set->capacity,
|
||||||
simple_hashset_destroy(set);
|
sizeof(struct
|
||||||
return NULL;
|
simple_hashset_item_st));
|
||||||
}
|
if (set->items == NULL) {
|
||||||
set->nitems = 0;
|
simple_hashset_destroy(set);
|
||||||
set->n_deleted_items = 0;
|
return NULL;
|
||||||
return set;
|
}
|
||||||
|
set->nitems = 0;
|
||||||
|
set->n_deleted_items = 0;
|
||||||
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
void simple_hashset_destroy(simple_hashset_t set)
|
void simple_hashset_destroy(simple_hashset_t set)
|
||||||
{
|
{
|
||||||
if (set) {
|
if (set) {
|
||||||
free(set->items);
|
free(set->items);
|
||||||
}
|
}
|
||||||
free(set);
|
free(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
void simple_hashset_set_hash_function(simple_hashset_t set, hash_func_t func)
|
void simple_hashset_set_hash_function(simple_hashset_t set, hash_func_t func)
|
||||||
{
|
{
|
||||||
set->hash_func = func;
|
set->hash_func = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int simple_hashset_add_member(simple_hashset_t set, symbol_type* key, size_t hash)
|
static int simple_hashset_add_member(simple_hashset_t set, symbol_type * key,
|
||||||
|
size_t hash)
|
||||||
{
|
{
|
||||||
size_t index;
|
size_t index;
|
||||||
|
|
||||||
if (hash < 2) {
|
if (hash < 2) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = set->mask & (prime_1 * hash);
|
||||||
|
|
||||||
|
while (set->items[index].hash != 0 && set->items[index].hash != 1) {
|
||||||
|
if (set->items[index].hash == hash) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* search free slot */
|
||||||
|
index = set->mask & (index + prime_2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
index = set->mask & (prime_1 * hash);
|
++set->nitems;
|
||||||
|
if (set->items[index].hash == 1) {
|
||||||
|
--set->n_deleted_items;
|
||||||
|
}
|
||||||
|
|
||||||
while (set->items[index].hash != 0 && set->items[index].hash != 1) {
|
set->items[index].hash = hash;
|
||||||
if (set->items[index].hash == hash) {
|
set->items[index].item = key;
|
||||||
return 0;
|
return 1;
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* search free slot */
|
|
||||||
index = set->mask & (index + prime_2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++set->nitems;
|
|
||||||
if (set->items[index].hash == 1) {
|
|
||||||
--set->n_deleted_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
set->items[index].hash = hash;
|
|
||||||
set->items[index].item = key;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_maybe_rehash(simple_hashset_t set)
|
static void set_maybe_rehash(simple_hashset_t set)
|
||||||
{
|
{
|
||||||
struct simple_hashset_item_st *old_items;
|
struct simple_hashset_item_st *old_items;
|
||||||
size_t old_capacity, index;
|
size_t old_capacity, index;
|
||||||
|
|
||||||
|
if (set->nitems + set->n_deleted_items >= (double)set->capacity * 0.85) {
|
||||||
if (set->nitems + set->n_deleted_items >= (double)set->capacity * 0.85) {
|
old_items = set->items;
|
||||||
old_items = set->items;
|
old_capacity = set->capacity;
|
||||||
old_capacity = set->capacity;
|
++set->nbits;
|
||||||
++set->nbits;
|
set->capacity = (size_t)(1 << set->nbits);
|
||||||
set->capacity = (size_t)(1 << set->nbits);
|
set->mask = set->capacity - 1;
|
||||||
set->mask = set->capacity - 1;
|
set->items =
|
||||||
set->items = (struct simple_hashset_item_st*)calloc(set->capacity, sizeof(struct simple_hashset_item_st));
|
(struct simple_hashset_item_st *)calloc(set->capacity,
|
||||||
set->nitems = 0;
|
sizeof(struct
|
||||||
set->n_deleted_items = 0;
|
simple_hashset_item_st));
|
||||||
//assert(set->items);
|
set->nitems = 0;
|
||||||
for (index = 0; index < old_capacity; ++index) {
|
set->n_deleted_items = 0;
|
||||||
simple_hashset_add_member(set, old_items[index].item, old_items[index].hash);
|
//assert(set->items);
|
||||||
}
|
for (index = 0; index < old_capacity; ++index) {
|
||||||
free(old_items);
|
simple_hashset_add_member(set, old_items[index].item,
|
||||||
|
old_items[index].hash);
|
||||||
}
|
}
|
||||||
|
free(old_items);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int simple_hashset_add(simple_hashset_t set, symbol_type* key)
|
int simple_hashset_add(simple_hashset_t set, symbol_type * key)
|
||||||
{
|
{
|
||||||
size_t key_len = strlen(key->desc);
|
size_t key_len = strlen(key->desc);
|
||||||
size_t hash = set->hash_func(key->desc, key_len);
|
size_t hash = set->hash_func(key->desc, key_len);
|
||||||
int rv = simple_hashset_add_member(set, key, hash);
|
int rv = simple_hashset_add_member(set, key, hash);
|
||||||
set_maybe_rehash(set);
|
set_maybe_rehash(set);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int simple_hashset_is_member(simple_hashset_t set, symbol_type* key)
|
int simple_hashset_is_member(simple_hashset_t set, symbol_type * key)
|
||||||
{
|
{
|
||||||
size_t key_len = strlen(key->desc);
|
size_t key_len = strlen(key->desc);
|
||||||
size_t hash = set->hash_func(key->desc, key_len);
|
size_t hash = set->hash_func(key->desc, key_len);
|
||||||
size_t index = set->mask & (prime_1 * hash);
|
size_t index = set->mask & (prime_1 * hash);
|
||||||
|
|
||||||
while (set->items[index].hash != 0) {
|
while (set->items[index].hash != 0) {
|
||||||
if (set->items[index].hash == hash) {
|
if (set->items[index].hash == hash) {
|
||||||
return index;
|
return index;
|
||||||
} else {
|
} else {
|
||||||
index = set->mask & (index + prime_2);
|
index = set->mask & (index + prime_2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
139
ck-polyfill.h
139
ck-polyfill.h
|
@ -8,53 +8,52 @@
|
||||||
|
|
||||||
void ck_polyfill_init();
|
void ck_polyfill_init();
|
||||||
|
|
||||||
struct ck_malloc {
|
struct ck_malloc {
|
||||||
void *(*malloc)(size_t);
|
void *(*malloc)(size_t);
|
||||||
void *(*realloc)(void *, size_t, size_t, bool);
|
void *(*realloc)(void *, size_t, size_t, bool);
|
||||||
void (*free)(void *, size_t, bool);
|
void (*free)(void *, size_t, bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Simple hashset (hashset with string support)
|
// Simple hashset (hashset with string support)
|
||||||
/* hash function */
|
/* hash function */
|
||||||
typedef size_t(*hash_func_t)(const char*, size_t);
|
typedef size_t (*hash_func_t)(const char *, size_t);
|
||||||
|
|
||||||
struct simple_hashset_item_st {
|
struct simple_hashset_item_st {
|
||||||
size_t hash;
|
size_t hash;
|
||||||
symbol_type* item;
|
symbol_type *item;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct simple_hashset_st {
|
struct simple_hashset_st {
|
||||||
size_t nbits;
|
size_t nbits;
|
||||||
size_t mask;
|
size_t mask;
|
||||||
|
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
struct simple_hashset_item_st *items;
|
struct simple_hashset_item_st *items;
|
||||||
size_t nitems;
|
size_t nitems;
|
||||||
size_t n_deleted_items;
|
size_t n_deleted_items;
|
||||||
|
|
||||||
hash_func_t hash_func;
|
hash_func_t hash_func;
|
||||||
};
|
};
|
||||||
// struct simple_hashset_st;
|
// struct simple_hashset_st;
|
||||||
typedef struct simple_hashset_st *simple_hashset_t;
|
typedef struct simple_hashset_st *simple_hashset_t;
|
||||||
|
|
||||||
|
struct hashmap_st;
|
||||||
struct hashmap_st;
|
typedef struct hashmap_st *hashmap_t;
|
||||||
typedef struct hashmap_st *hashmap_t;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HASHSET FUNCTIONS
|
* HASHSET FUNCTIONS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* create hashset instance */
|
/* create hashset instance */
|
||||||
simple_hashset_t simple_hashset_create(void);
|
simple_hashset_t simple_hashset_create(void);
|
||||||
|
|
||||||
/* destroy hashset instance */
|
/* destroy hashset instance */
|
||||||
void simple_hashset_destroy(simple_hashset_t set);
|
void simple_hashset_destroy(simple_hashset_t set);
|
||||||
|
|
||||||
/* set hash function */
|
/* set hash function */
|
||||||
void simple_hashset_set_hash_function(simple_hashset_t set, hash_func_t func);
|
void simple_hashset_set_hash_function(simple_hashset_t set, hash_func_t func);
|
||||||
|
|
||||||
/* add item into the hashset.
|
/* add item into the hashset.
|
||||||
*
|
*
|
||||||
* @note 0 and 1 is special values, meaning nil and deleted items. the
|
* @note 0 and 1 is special values, meaning nil and deleted items. the
|
||||||
|
@ -62,17 +61,17 @@ struct ck_malloc {
|
||||||
*
|
*
|
||||||
* returns zero if the item already in the set and non-zero otherwise
|
* returns zero if the item already in the set and non-zero otherwise
|
||||||
*/
|
*/
|
||||||
int simple_hashset_add(simple_hashset_t set, symbol_type* key);
|
int simple_hashset_add(simple_hashset_t set, symbol_type * key);
|
||||||
|
|
||||||
/* check if existence of the item
|
/* check if existence of the item
|
||||||
*
|
*
|
||||||
* returns non-zero if the item exists and zero otherwise
|
* returns non-zero if the item exists and zero otherwise
|
||||||
*/
|
*/
|
||||||
int simple_hashset_is_member(simple_hashset_t set, symbol_type* key);
|
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)
|
static inline uint64_t MurmurHash64A(const void *key, int len, uint64_t seed)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -81,30 +80,31 @@ static inline uint64_t MurmurHash64A(const void *key, int len, uint64_t seed)
|
||||||
#define CK_HS_MODE_OBJECT 0
|
#define CK_HS_MODE_OBJECT 0
|
||||||
#define CK_HS_MODE_SPMC 0
|
#define CK_HS_MODE_SPMC 0
|
||||||
|
|
||||||
struct ck_hs {
|
struct ck_hs {
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
simple_hashset_t hs;
|
simple_hashset_t hs;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ck_hs ck_hs_t;
|
typedef struct ck_hs ck_hs_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hash callback function.
|
* Hash callback function.
|
||||||
*/
|
*/
|
||||||
typedef unsigned long ck_hs_hash_cb_t(const void *, unsigned long);
|
typedef unsigned long ck_hs_hash_cb_t(const void *, unsigned long);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns pointer to object if objects are equivalent.
|
* Returns pointer to object if objects are equivalent.
|
||||||
*/
|
*/
|
||||||
typedef bool ck_hs_compare_cb_t(const void *, const void *);
|
typedef bool ck_hs_compare_cb_t(const void *, const void *);
|
||||||
|
|
||||||
#define CK_HS_HASH(hs, hs_hash, value) 0
|
#define CK_HS_HASH(hs, hs_hash, value) 0
|
||||||
|
|
||||||
bool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *,
|
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);
|
ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long,
|
||||||
|
unsigned long);
|
||||||
|
|
||||||
void *ck_hs_get(ck_hs_t *, unsigned long, const void *);
|
void *ck_hs_get(ck_hs_t *, unsigned long, const void *);
|
||||||
bool ck_hs_put(ck_hs_t *, unsigned long, const void *);
|
bool ck_hs_put(ck_hs_t *, unsigned long, const void *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct ck_hs {
|
struct ck_hs {
|
||||||
|
@ -150,8 +150,8 @@ typedef struct ck_array_iterator ck_array_iterator_t;
|
||||||
// returns false if the creation failed. Failure may occur due to internal
|
// returns false if the creation failed. Failure may occur due to internal
|
||||||
// memory allocation failures or invalid arguments.
|
// memory allocation failures or invalid arguments.
|
||||||
bool
|
bool
|
||||||
ck_array_init(ck_array_t *array, unsigned int mode,
|
ck_array_init(ck_array_t * array, unsigned int mode,
|
||||||
struct ck_malloc *allocator, unsigned int initial_length);
|
struct ck_malloc *allocator, unsigned int initial_length);
|
||||||
|
|
||||||
// DESCRIPTION
|
// DESCRIPTION
|
||||||
// The ck_array_put_unique(3) function will attempt to insert the value of
|
// The ck_array_put_unique(3) function will attempt to insert the value of
|
||||||
|
@ -166,8 +166,7 @@ ck_array_init(ck_array_t *array, unsigned int mode,
|
||||||
// This function returns 1 if the pointer already exists in the array. It
|
// 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
|
// returns 0 if the put operation succeeded. It returns -1 on error due to
|
||||||
// internal memory allocation failures.
|
// internal memory allocation failures.
|
||||||
int
|
int ck_array_put_unique(ck_array_t * array, void *pointer);
|
||||||
ck_array_put_unique(ck_array_t *array, void *pointer);
|
|
||||||
|
|
||||||
// DESCRIPTION
|
// DESCRIPTION
|
||||||
// The ck_array_remove(3) function will attempt to remove the value of
|
// The ck_array_remove(3) function will attempt to remove the value of
|
||||||
|
@ -180,9 +179,7 @@ ck_array_put_unique(ck_array_t *array, void *pointer);
|
||||||
// This function returns true if the remove operation succeeded. It will
|
// This function returns true if the remove operation succeeded. It will
|
||||||
// return false otherwise due to internal allocation failures or because the
|
// return false otherwise due to internal allocation failures or because the
|
||||||
// value did not exist.
|
// value did not exist.
|
||||||
bool
|
bool ck_array_remove(ck_array_t * array, void *pointer);
|
||||||
ck_array_remove(ck_array_t *array, void *pointer);
|
|
||||||
|
|
||||||
|
|
||||||
// DESCRIPTION
|
// DESCRIPTION
|
||||||
// The ck_array_commit(3) function will commit any pending put or remove
|
// The ck_array_commit(3) function will commit any pending put or remove
|
||||||
|
@ -193,9 +190,7 @@ ck_array_remove(ck_array_t *array, void *pointer);
|
||||||
// RETURN VALUES
|
// RETURN VALUES
|
||||||
// This function returns true if the commit operation succeeded. It will
|
// This function returns true if the commit operation succeeded. It will
|
||||||
// return false otherwise, and pending operations will not be applied.
|
// return false otherwise, and pending operations will not be applied.
|
||||||
bool
|
bool ck_array_commit(ck_array_t * array);
|
||||||
ck_array_commit(ck_array_t *array);
|
|
||||||
|
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
||||||
|
@ -209,37 +204,27 @@ ck_array_commit(ck_array_t *array);
|
||||||
if (tmpc > 0) { (*b) = tmp[0]; } \
|
if (tmpc > 0) { (*b) = tmp[0]; } \
|
||||||
for (unsigned int _ck_i = 0; \
|
for (unsigned int _ck_i = 0; \
|
||||||
_ck_i < tmpc; \
|
_ck_i < tmpc; \
|
||||||
_ck_i++, (*b) = tmp[_ck_i])
|
_ck_i++, (*b) = tmp[_ck_i])
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// CK PR section
|
// CK PR section
|
||||||
bool
|
bool ck_pr_cas_ptr(void *target, void *old_value, void *new_value);
|
||||||
ck_pr_cas_ptr(void *target, void *old_value, void *new_value);
|
|
||||||
|
|
||||||
bool
|
bool ck_pr_cas_int(int *target, int old_value, int new_value);
|
||||||
ck_pr_cas_int(int *target, int old_value, int new_value);
|
|
||||||
|
|
||||||
bool
|
bool ck_pr_cas_8(uint8_t * target, uint8_t old_value, uint8_t new_value);
|
||||||
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
|
void ck_pr_add_int(int *target, int delta);
|
||||||
ck_pr_add_ptr(void *target, uintptr_t delta);
|
|
||||||
|
|
||||||
void
|
void ck_pr_add_8(uint8_t * target, uint8_t delta);
|
||||||
ck_pr_add_int(int *target, int delta);
|
|
||||||
|
|
||||||
void
|
void *ck_pr_load_ptr(const void *target);
|
||||||
ck_pr_add_8(uint8_t *target, uint8_t delta);
|
|
||||||
|
|
||||||
void *
|
int ck_pr_load_int(const int *target);
|
||||||
ck_pr_load_ptr(const void *target);
|
|
||||||
|
|
||||||
int
|
uint8_t ck_pr_load_8(const uint8_t * target);
|
||||||
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);
|
void ck_pr_store_ptr(void *target, void *value);
|
||||||
#endif /* CYCLONE_CK_POLYFILL_H */
|
#endif /* CYCLONE_CK_POLYFILL_H */
|
||||||
|
|
40
ffi.c
40
ffi.c
|
@ -13,14 +13,15 @@
|
||||||
#include <ck_pr.h>
|
#include <ck_pr.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
void *Cyc_init_thread(object thread_and_thunk, int argc, object *args);
|
void *Cyc_init_thread(object thread_and_thunk, int argc, object * args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After the Scheme call finishes, we wind down the GC / Heap used
|
* After the Scheme call finishes, we wind down the GC / Heap used
|
||||||
* for the call and perform a minor GC to ensure any returned object
|
* for the call and perform a minor GC to ensure any returned object
|
||||||
* is on the heap and safe to use.
|
* is on the heap and safe to use.
|
||||||
*/
|
*/
|
||||||
static void Cyc_return_from_scm_call(void *data, object _, int argc, object *args)
|
static void Cyc_return_from_scm_call(void *data, object _, int argc,
|
||||||
|
object * args)
|
||||||
{
|
{
|
||||||
gc_thread_data *thd = data;
|
gc_thread_data *thd = data;
|
||||||
object result = args[0];
|
object result = args[0];
|
||||||
|
@ -41,12 +42,13 @@ static void Cyc_return_from_scm_call(void *data, object _, int argc, object *arg
|
||||||
* We store results and longjmp back to where we started, at the
|
* We store results and longjmp back to where we started, at the
|
||||||
* bottom of the trampoline (we only jump once).
|
* bottom of the trampoline (we only jump once).
|
||||||
*/
|
*/
|
||||||
static void Cyc_after_scm_call(void *data, object _, int argc, object *args)
|
static void Cyc_after_scm_call(void *data, object _, int argc, object * args)
|
||||||
{
|
{
|
||||||
gc_thread_data *thd = data;
|
gc_thread_data *thd = data;
|
||||||
object result = args[0];
|
object result = args[0];
|
||||||
mclosure0(clo, Cyc_return_from_scm_call);
|
mclosure0(clo, Cyc_return_from_scm_call);
|
||||||
object buf[1]; buf[0] = result;
|
object buf[1];
|
||||||
|
buf[0] = result;
|
||||||
GC(thd, &clo, buf, 1);
|
GC(thd, &clo, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +60,8 @@ static void Cyc_after_scm_call(void *data, object _, int argc, object *args)
|
||||||
* can do anything "normal" Scheme code does, and any returned
|
* can do anything "normal" Scheme code does, and any returned
|
||||||
* objects will be on the heap and available for use by the caller.
|
* objects will be on the heap and available for use by the caller.
|
||||||
*/
|
*/
|
||||||
object Cyc_scm_call(gc_thread_data *parent_thd, object fnc, int argc, object *args)
|
object Cyc_scm_call(gc_thread_data * parent_thd, object fnc, int argc,
|
||||||
|
object * args)
|
||||||
{
|
{
|
||||||
jmp_buf l;
|
jmp_buf l;
|
||||||
gc_thread_data local;
|
gc_thread_data local;
|
||||||
|
@ -66,13 +69,13 @@ object Cyc_scm_call(gc_thread_data *parent_thd, object fnc, int argc, object *ar
|
||||||
local.jmp_start = &l;
|
local.jmp_start = &l;
|
||||||
|
|
||||||
gc_thread_data *td = malloc(sizeof(gc_thread_data));
|
gc_thread_data *td = malloc(sizeof(gc_thread_data));
|
||||||
gc_add_new_unrunning_mutator(td); /* Register this thread */
|
gc_add_new_unrunning_mutator(td); /* Register this thread */
|
||||||
make_c_opaque(co, td);
|
make_c_opaque(co, td);
|
||||||
make_utf8_string(NULL, name_str, "");
|
make_utf8_string(NULL, name_str, "");
|
||||||
|
|
||||||
make_c_opaque(co_parent_thd, parent_thd);
|
make_c_opaque(co_parent_thd, parent_thd);
|
||||||
make_c_opaque(co_this_thd, &local);
|
make_c_opaque(co_this_thd, &local);
|
||||||
mclosure0(after, (function_type)Cyc_after_scm_call);
|
mclosure0(after, (function_type) Cyc_after_scm_call);
|
||||||
|
|
||||||
make_empty_vector(vec);
|
make_empty_vector(vec);
|
||||||
vec.num_elements = 7;
|
vec.num_elements = 7;
|
||||||
|
@ -81,11 +84,11 @@ object Cyc_scm_call(gc_thread_data *parent_thd, object fnc, int argc, object *ar
|
||||||
vec.elements[1] = fnc;
|
vec.elements[1] = fnc;
|
||||||
vec.elements[2] = &co;
|
vec.elements[2] = &co;
|
||||||
vec.elements[3] = &name_str;
|
vec.elements[3] = &name_str;
|
||||||
vec.elements[4] = &co_this_thd; //boolean_f;
|
vec.elements[4] = &co_this_thd; //boolean_f;
|
||||||
vec.elements[5] = &co_parent_thd;
|
vec.elements[5] = &co_parent_thd;
|
||||||
vec.elements[6] = &after;
|
vec.elements[6] = &after;
|
||||||
|
|
||||||
make_pair(thread_and_thunk, &vec, fnc); // TODO: OK we are not clearing vec[5]? I think so...
|
make_pair(thread_and_thunk, &vec, fnc); // TODO: OK we are not clearing vec[5]? I think so...
|
||||||
|
|
||||||
if (!setjmp(*(local.jmp_start))) {
|
if (!setjmp(*(local.jmp_start))) {
|
||||||
Cyc_init_thread(&thread_and_thunk, argc, args);
|
Cyc_init_thread(&thread_and_thunk, argc, args);
|
||||||
|
@ -105,7 +108,8 @@ object Cyc_scm_call(gc_thread_data *parent_thd, object fnc, int argc, object *ar
|
||||||
* We store results and longjmp back to where we started, at the
|
* We store results and longjmp back to where we started, at the
|
||||||
* bottom of the trampoline (we only jump once).
|
* bottom of the trampoline (we only jump once).
|
||||||
*/
|
*/
|
||||||
static void no_gc_after_call_scm(gc_thread_data *thd, object _, int argc, object *args)
|
static void no_gc_after_call_scm(gc_thread_data * thd, object _, int argc,
|
||||||
|
object * args)
|
||||||
{
|
{
|
||||||
object result = args[0];
|
object result = args[0];
|
||||||
thd->gc_cont = result;
|
thd->gc_cont = result;
|
||||||
|
@ -115,11 +119,11 @@ static void no_gc_after_call_scm(gc_thread_data *thd, object _, int argc, object
|
||||||
/**
|
/**
|
||||||
* Call into Scheme function
|
* Call into Scheme function
|
||||||
*/
|
*/
|
||||||
static void no_gc_call_scm(gc_thread_data *thd, object fnc, object obj)
|
static void no_gc_call_scm(gc_thread_data * thd, object fnc, object obj)
|
||||||
{
|
{
|
||||||
mclosure0(after, (function_type)no_gc_after_call_scm);
|
mclosure0(after, (function_type) no_gc_after_call_scm);
|
||||||
object buf[2] = {&after, obj};
|
object buf[2] = { &after, obj };
|
||||||
((closure)fnc)->fn(thd, fnc, 2, buf);
|
((closure) fnc)->fn(thd, fnc, 2, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,12 +138,12 @@ static void no_gc_call_scm(gc_thread_data *thd, object fnc, object obj)
|
||||||
* or re-allocated (EG: malloc) before returning it
|
* or re-allocated (EG: malloc) before returning it
|
||||||
* to the C layer.
|
* to the C layer.
|
||||||
*/
|
*/
|
||||||
object Cyc_scm_call_no_gc(gc_thread_data *parent_thd, object fnc, object arg)
|
object Cyc_scm_call_no_gc(gc_thread_data * parent_thd, object fnc, object arg)
|
||||||
{
|
{
|
||||||
long stack_size = 100000;
|
long stack_size = 100000;
|
||||||
char *stack_base = (char *)&stack_size;
|
char *stack_base = (char *)&stack_size;
|
||||||
char *stack_traces[MAX_STACK_TRACES];
|
char *stack_traces[MAX_STACK_TRACES];
|
||||||
gc_thread_data thd = {0};
|
gc_thread_data thd = { 0 };
|
||||||
jmp_buf jmp;
|
jmp_buf jmp;
|
||||||
thd.jmp_start = &jmp;
|
thd.jmp_start = &jmp;
|
||||||
thd.stack_start = stack_base;
|
thd.stack_start = stack_base;
|
||||||
|
@ -154,7 +158,7 @@ object Cyc_scm_call_no_gc(gc_thread_data *parent_thd, object fnc, object arg)
|
||||||
thd.thread_state = CYC_THREAD_STATE_RUNNABLE;
|
thd.thread_state = CYC_THREAD_STATE_RUNNABLE;
|
||||||
|
|
||||||
// Copy parameter objects from the calling thread
|
// Copy parameter objects from the calling thread
|
||||||
object parent = parent_thd->param_objs; // Unbox parent thread's data
|
object parent = parent_thd->param_objs; // Unbox parent thread's data
|
||||||
object child = NULL;
|
object child = NULL;
|
||||||
while (parent) {
|
while (parent) {
|
||||||
if (thd.param_objs == NULL) {
|
if (thd.param_objs == NULL) {
|
||||||
|
@ -184,5 +188,5 @@ object Cyc_scm_call_no_gc(gc_thread_data *parent_thd, object fnc, object arg)
|
||||||
no_gc_call_scm(&thd, fnc, arg);
|
no_gc_call_scm(&thd, fnc, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(thd.gc_cont);
|
return (thd.gc_cont);
|
||||||
}
|
}
|
||||||
|
|
160
hashset.c
160
hashset.c
|
@ -23,125 +23,124 @@ static const unsigned int prime_2 = 5009;
|
||||||
|
|
||||||
hashset_t hashset_create()
|
hashset_t hashset_create()
|
||||||
{
|
{
|
||||||
hashset_t set = calloc(1, sizeof(struct hashset_st));
|
hashset_t set = calloc(1, sizeof(struct hashset_st));
|
||||||
|
|
||||||
if (set == NULL) {
|
if (set == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
set->nbits = 3;
|
set->nbits = 3;
|
||||||
set->capacity = (size_t)(1 << set->nbits);
|
set->capacity = (size_t)(1 << set->nbits);
|
||||||
set->mask = set->capacity - 1;
|
set->mask = set->capacity - 1;
|
||||||
set->items = calloc(set->capacity, sizeof(size_t));
|
set->items = calloc(set->capacity, sizeof(size_t));
|
||||||
if (set->items == NULL) {
|
if (set->items == NULL) {
|
||||||
hashset_destroy(set);
|
hashset_destroy(set);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
set->nitems = 0;
|
set->nitems = 0;
|
||||||
set->n_deleted_items = 0;
|
set->n_deleted_items = 0;
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t hashset_num_items(hashset_t set)
|
size_t hashset_num_items(hashset_t set)
|
||||||
{
|
{
|
||||||
return set->nitems;
|
return set->nitems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashset_destroy(hashset_t set)
|
void hashset_destroy(hashset_t set)
|
||||||
{
|
{
|
||||||
if (set) {
|
if (set) {
|
||||||
free(set->items);
|
free(set->items);
|
||||||
}
|
}
|
||||||
free(set);
|
free(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hashset_add_member(hashset_t set, void *item)
|
static int hashset_add_member(hashset_t set, void *item)
|
||||||
{
|
{
|
||||||
size_t value = (size_t)item;
|
size_t value = (size_t)item;
|
||||||
size_t ii;
|
size_t ii;
|
||||||
|
|
||||||
if (value == 0 || value == 1) {
|
if (value == 0 || value == 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ii = set->mask & (prime_1 * value);
|
ii = set->mask & (prime_1 * value);
|
||||||
|
|
||||||
while (set->items[ii] != 0 && set->items[ii] != 1) {
|
while (set->items[ii] != 0 && set->items[ii] != 1) {
|
||||||
if (set->items[ii] == value) {
|
if (set->items[ii] == value) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
/* search free slot */
|
/* search free slot */
|
||||||
ii = set->mask & (ii + prime_2);
|
ii = set->mask & (ii + prime_2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
set->nitems++;
|
}
|
||||||
if (set->items[ii] == 1) {
|
set->nitems++;
|
||||||
set->n_deleted_items--;
|
if (set->items[ii] == 1) {
|
||||||
}
|
set->n_deleted_items--;
|
||||||
set->items[ii] = value;
|
}
|
||||||
return 1;
|
set->items[ii] = value;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void maybe_rehash(hashset_t set)
|
static void maybe_rehash(hashset_t set)
|
||||||
{
|
{
|
||||||
size_t *old_items;
|
size_t *old_items;
|
||||||
size_t old_capacity, ii;
|
size_t old_capacity, ii;
|
||||||
|
|
||||||
|
if (set->nitems + set->n_deleted_items >= (double)set->capacity * 0.85) {
|
||||||
if (set->nitems + set->n_deleted_items >= (double)set->capacity * 0.85) {
|
old_items = set->items;
|
||||||
old_items = set->items;
|
old_capacity = set->capacity;
|
||||||
old_capacity = set->capacity;
|
set->nbits++;
|
||||||
set->nbits++;
|
set->capacity = (size_t)(1 << set->nbits);
|
||||||
set->capacity = (size_t)(1 << set->nbits);
|
set->mask = set->capacity - 1;
|
||||||
set->mask = set->capacity - 1;
|
set->items = calloc(set->capacity, sizeof(size_t));
|
||||||
set->items = calloc(set->capacity, sizeof(size_t));
|
set->nitems = 0;
|
||||||
set->nitems = 0;
|
set->n_deleted_items = 0;
|
||||||
set->n_deleted_items = 0;
|
assert(set->items);
|
||||||
assert(set->items);
|
for (ii = 0; ii < old_capacity; ii++) {
|
||||||
for (ii = 0; ii < old_capacity; ii++) {
|
hashset_add_member(set, (void *)old_items[ii]);
|
||||||
hashset_add_member(set, (void *)old_items[ii]);
|
|
||||||
}
|
|
||||||
free(old_items);
|
|
||||||
}
|
}
|
||||||
|
free(old_items);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashset_add(hashset_t set, void *item)
|
int hashset_add(hashset_t set, void *item)
|
||||||
{
|
{
|
||||||
int rv = hashset_add_member(set, item);
|
int rv = hashset_add_member(set, item);
|
||||||
maybe_rehash(set);
|
maybe_rehash(set);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashset_remove(hashset_t set, void *item)
|
int hashset_remove(hashset_t set, void *item)
|
||||||
{
|
{
|
||||||
size_t value = (size_t)item;
|
size_t value = (size_t)item;
|
||||||
size_t ii = set->mask & (prime_1 * value);
|
size_t ii = set->mask & (prime_1 * value);
|
||||||
|
|
||||||
while (set->items[ii] != 0) {
|
while (set->items[ii] != 0) {
|
||||||
if (set->items[ii] == value) {
|
if (set->items[ii] == value) {
|
||||||
set->items[ii] = 1;
|
set->items[ii] = 1;
|
||||||
set->nitems--;
|
set->nitems--;
|
||||||
set->n_deleted_items++;
|
set->n_deleted_items++;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
ii = set->mask & (ii + prime_2);
|
ii = set->mask & (ii + prime_2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashset_is_member(hashset_t set, void *item)
|
int hashset_is_member(hashset_t set, void *item)
|
||||||
{
|
{
|
||||||
size_t value = (size_t)item;
|
size_t value = (size_t)item;
|
||||||
size_t ii = set->mask & (prime_1 * value);
|
size_t ii = set->mask & (prime_1 * value);
|
||||||
|
|
||||||
while (set->items[ii] != 0) {
|
while (set->items[ii] != 0) {
|
||||||
if (set->items[ii] == value) {
|
if (set->items[ii] == value) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
ii = set->mask & (ii + prime_2);
|
ii = set->mask & (ii + prime_2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashset_to_array(hashset_t set, void **items)
|
void hashset_to_array(hashset_t set, void **items)
|
||||||
|
@ -154,4 +153,3 @@ void hashset_to_array(hashset_t set, void **items)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,52 +24,51 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct hashset_st {
|
struct hashset_st {
|
||||||
size_t nbits;
|
size_t nbits;
|
||||||
size_t mask;
|
size_t mask;
|
||||||
|
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
size_t *items;
|
size_t *items;
|
||||||
size_t nitems;
|
size_t nitems;
|
||||||
size_t n_deleted_items;
|
size_t n_deleted_items;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct hashset_st *hashset_t;
|
typedef struct hashset_st *hashset_t;
|
||||||
|
|
||||||
/* create hashset instance */
|
/* create hashset instance */
|
||||||
hashset_t hashset_create(void);
|
hashset_t hashset_create(void);
|
||||||
|
|
||||||
/* destroy hashset instance */
|
/* destroy hashset instance */
|
||||||
void hashset_destroy(hashset_t set);
|
void hashset_destroy(hashset_t set);
|
||||||
|
|
||||||
size_t hashset_num_items(hashset_t set);
|
size_t hashset_num_items(hashset_t set);
|
||||||
|
|
||||||
/* add item into the hashset.
|
/* add item into the hashset.
|
||||||
*
|
*
|
||||||
* @note 0 and 1 is special values, meaning nil and deleted items. the
|
* @note 0 and 1 is special values, meaning nil and deleted items. the
|
||||||
* function will return -1 indicating error.
|
* function will return -1 indicating error.
|
||||||
*
|
*
|
||||||
* returns zero if the item already in the set and non-zero otherwise
|
* returns zero if the item already in the set and non-zero otherwise
|
||||||
*/
|
*/
|
||||||
int hashset_add(hashset_t set, void *item);
|
int hashset_add(hashset_t set, void *item);
|
||||||
|
|
||||||
/* remove item from the hashset
|
/* remove item from the hashset
|
||||||
*
|
*
|
||||||
* returns non-zero if the item was removed and zero if the item wasn't
|
* returns non-zero if the item was removed and zero if the item wasn't
|
||||||
* exist
|
* exist
|
||||||
*/
|
*/
|
||||||
int hashset_remove(hashset_t set, void *item);
|
int hashset_remove(hashset_t set, void *item);
|
||||||
|
|
||||||
/* check if existence of the item
|
/* check if existence of the item
|
||||||
*
|
*
|
||||||
* returns non-zero if the item exists and zero otherwise
|
* returns non-zero if the item exists and zero otherwise
|
||||||
*/
|
*/
|
||||||
int hashset_is_member(hashset_t set, void *item);
|
int hashset_is_member(hashset_t set, void *item);
|
||||||
|
|
||||||
void hashset_to_array(hashset_t set, void **items);
|
void hashset_to_array(hashset_t set, void **items);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
long global_stack_size = 0;
|
long global_stack_size = 0;
|
||||||
long global_heap_size = 0;
|
long global_heap_size = 0;
|
||||||
|
|
||||||
static void c_entry_pt(void *data, object clo, int argc, object *args);
|
static void c_entry_pt(void *data, object clo, int argc, object * args);
|
||||||
static void Cyc_heap_init(long heap_size);
|
static void Cyc_heap_init(long heap_size);
|
||||||
|
|
||||||
static void Cyc_heap_init(long heap_size)
|
static void Cyc_heap_init(long heap_size)
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#ifndef CYCLONE_RUNTIME_H
|
#ifndef CYCLONE_RUNTIME_H
|
||||||
#define CYCLONE_RUNTIME_H
|
#define CYCLONE_RUNTIME_H
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The boolean True value.
|
* The boolean True value.
|
||||||
* \ingroup objects
|
* \ingroup objects
|
||||||
|
@ -231,7 +230,8 @@ object Cyc_global_set(void *thd, object sym, object * glo, object value);
|
||||||
|
|
||||||
#define global_set_cps(thd,k,glo,value) Cyc_global_set_cps(thd, k, NULL, (object *)&glo, value)
|
#define global_set_cps(thd,k,glo,value) Cyc_global_set_cps(thd, k, NULL, (object *)&glo, value)
|
||||||
#define global_set_cps_id(thd,k,id,glo,value) Cyc_global_set_cps(thd, k, id, (object *)&glo, value)
|
#define global_set_cps_id(thd,k,id,glo,value) Cyc_global_set_cps(thd, k, id, (object *)&glo, value)
|
||||||
object Cyc_global_set_cps(void *thd, object cont, object sym, object * glo, object value);
|
object Cyc_global_set_cps(void *thd, object cont, object sym, object * glo,
|
||||||
|
object value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable argument count support
|
* Variable argument count support
|
||||||
|
@ -274,8 +274,8 @@ object Cyc_global_set_cps(void *thd, object cont, object sym, object * glo, obje
|
||||||
|
|
||||||
/**@{*/
|
/**@{*/
|
||||||
object apply(void *data, object cont, object func, object args);
|
object apply(void *data, object cont, object func, object args);
|
||||||
void Cyc_apply(void *data, object cont, int argc, object *args);
|
void Cyc_apply(void *data, object cont, int argc, object * args);
|
||||||
void dispatch_apply_va(void *data, object clo, int argc, object *args);
|
void dispatch_apply_va(void *data, object clo, int argc, object * args);
|
||||||
object apply_va(void *data, object cont, int argc, object func, ...);
|
object apply_va(void *data, object cont, int argc, object func, ...);
|
||||||
void dispatch(void *data, int argc, function_type func, object clo, object cont,
|
void dispatch(void *data, int argc, function_type func, object clo, object cont,
|
||||||
object args);
|
object args);
|
||||||
|
@ -288,7 +288,7 @@ void dispatch(void *data, int argc, function_type func, object clo, object cont,
|
||||||
*/
|
*/
|
||||||
/**@{*/
|
/**@{*/
|
||||||
object Cyc_string_cmp(void *data, object str1, object str2);
|
object Cyc_string_cmp(void *data, object str1, object str2);
|
||||||
void dispatch_string_91append(void *data, object clo, int _argc, object *args);
|
void dispatch_string_91append(void *data, object clo, int _argc, object * args);
|
||||||
object Cyc_string2number_(void *d, object cont, object str);
|
object Cyc_string2number_(void *d, object cont, object str);
|
||||||
object Cyc_string2number2_(void *data, object cont, int argc, object str, ...);
|
object Cyc_string2number2_(void *data, object cont, int argc, object str, ...);
|
||||||
int binstr2int(const char *str);
|
int binstr2int(const char *str);
|
||||||
|
@ -342,12 +342,12 @@ object Cyc_set_cvar(object var, object value);
|
||||||
*/
|
*/
|
||||||
/**@{*/
|
/**@{*/
|
||||||
object Cyc_display(void *data, object, FILE * port);
|
object Cyc_display(void *data, object, FILE * port);
|
||||||
void dispatch_display_va(void *data, object clo, int argc, object *args);
|
void dispatch_display_va(void *data, object clo, int argc, object * args);
|
||||||
object Cyc_display_va(void *data, int argc, object x, ...);
|
object Cyc_display_va(void *data, int argc, object x, ...);
|
||||||
object Cyc_display_va_list(void *data, object x, object opts);
|
object Cyc_display_va_list(void *data, object x, object opts);
|
||||||
object Cyc_write_char(void *data, object c, object port);
|
object Cyc_write_char(void *data, object c, object port);
|
||||||
object Cyc_write(void *data, object, FILE * port);
|
object Cyc_write(void *data, object, FILE * port);
|
||||||
void dispatch_write_va(void *data, object clo, int argc, object *args);
|
void dispatch_write_va(void *data, object clo, int argc, object * args);
|
||||||
object Cyc_write_va(void *data, int argc, object x, ...);
|
object Cyc_write_va(void *data, int argc, object x, ...);
|
||||||
object Cyc_write_va_list(void *data, object x, object opts);
|
object Cyc_write_va_list(void *data, object x, object opts);
|
||||||
port_type Cyc_stdout(void);
|
port_type Cyc_stdout(void);
|
||||||
|
@ -372,13 +372,13 @@ object Cyc_io_char_ready(void *data, object port);
|
||||||
object Cyc_write_u8(void *data, object c, object port);
|
object Cyc_write_u8(void *data, object c, object port);
|
||||||
object Cyc_io_read_u8(void *data, object cont, object port);
|
object Cyc_io_read_u8(void *data, object cont, object port);
|
||||||
object Cyc_io_peek_u8(void *data, object cont, object port);
|
object Cyc_io_peek_u8(void *data, object cont, object port);
|
||||||
object Cyc_write_bytevector(void *data, object bvec, object port, object start, object end);
|
object Cyc_write_bytevector(void *data, object bvec, object port, object start,
|
||||||
|
object end);
|
||||||
object Cyc_io_read_line(void *data, object cont, object port);
|
object Cyc_io_read_line(void *data, object cont, object port);
|
||||||
void Cyc_io_read_token(void *data, object cont, object port);
|
void Cyc_io_read_token(void *data, object cont, object port);
|
||||||
int Cyc_have_mstreams();
|
int Cyc_have_mstreams();
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup prim_num Numbers
|
* \defgroup prim_num Numbers
|
||||||
* @brief Number functions
|
* @brief Number functions
|
||||||
|
@ -558,9 +558,11 @@ object Cyc_fast_list_3(object ptr, object a1, object a2, object a3);
|
||||||
object Cyc_fast_list_4(object ptr, object a1, object a2, object a3, object a4);
|
object Cyc_fast_list_4(object ptr, object a1, object a2, object a3, object a4);
|
||||||
object Cyc_fast_vector_2(object ptr, object a1, object a2);
|
object Cyc_fast_vector_2(object ptr, object a1, object a2);
|
||||||
object Cyc_fast_vector_3(object ptr, object a1, object a2, object a3);
|
object Cyc_fast_vector_3(object ptr, object a1, object a2, object a3);
|
||||||
object Cyc_fast_vector_4(object ptr, object a1, object a2, object a3, object a4);
|
object Cyc_fast_vector_4(object ptr, object a1, object a2, object a3,
|
||||||
object Cyc_fast_vector_5(object ptr, object a1, object a2, object a3, object a4, object a5);
|
object a4);
|
||||||
object Cyc_bit_unset(void *data, object n1, object n2);
|
object Cyc_fast_vector_5(object ptr, object a1, object a2, object a3, object a4,
|
||||||
|
object a5);
|
||||||
|
object Cyc_bit_unset(void *data, object n1, object n2);
|
||||||
object Cyc_bit_set(void *data, object n1, object n2);
|
object Cyc_bit_set(void *data, object n1, object n2);
|
||||||
object Cyc_num_op_va_list(void *data, int argc,
|
object Cyc_num_op_va_list(void *data, int argc,
|
||||||
object(fn_op(void *, common_type *, object)),
|
object(fn_op(void *, common_type *, object)),
|
||||||
|
@ -568,14 +570,13 @@ object Cyc_num_op_va_list(void *data, int argc,
|
||||||
va_list ns, common_type * buf);
|
va_list ns, common_type * buf);
|
||||||
object Cyc_num_op_args(void *data, int argc,
|
object Cyc_num_op_args(void *data, int argc,
|
||||||
object(fn_op(void *, common_type *, object)),
|
object(fn_op(void *, common_type *, object)),
|
||||||
int default_no_args, int default_one_arg,
|
int default_no_args, int default_one_arg,
|
||||||
object *args,
|
object * args, common_type * buf);
|
||||||
common_type * buf);
|
void Cyc_int2bignum(int n, mp_int * bn);
|
||||||
void Cyc_int2bignum(int n, mp_int *bn);
|
|
||||||
object Cyc_bignum_normalize(void *data, object n);
|
object Cyc_bignum_normalize(void *data, object n);
|
||||||
int Cyc_bignum_cmp(bn_cmp_type type, object x, int tx, object y, int ty);
|
int Cyc_bignum_cmp(bn_cmp_type type, object x, int tx, object y, int ty);
|
||||||
void Cyc_make_rectangular(void *data, object k, object r, object i);
|
void Cyc_make_rectangular(void *data, object k, object r, object i);
|
||||||
double MRG32k3a (double seed);
|
double MRG32k3a(double seed);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
/**
|
/**
|
||||||
* \defgroup prim_eq Equality and type predicates
|
* \defgroup prim_eq Equality and type predicates
|
||||||
|
@ -651,7 +652,8 @@ object Cyc_vector_ref(void *d, object v, object k);
|
||||||
object Cyc_vector_set(void *d, object v, object k, object obj);
|
object Cyc_vector_set(void *d, object v, object k, object obj);
|
||||||
object Cyc_vector_set_unsafe(void *d, object v, object k, object obj);
|
object Cyc_vector_set_unsafe(void *d, object v, object k, object obj);
|
||||||
object Cyc_vector_set_cps(void *d, object cont, object v, object k, object obj);
|
object Cyc_vector_set_cps(void *d, object cont, object v, object k, object obj);
|
||||||
object Cyc_vector_set_unsafe_cps(void *d, object cont, object v, object k, object obj);
|
object Cyc_vector_set_unsafe_cps(void *d, object cont, object v, object k,
|
||||||
|
object obj);
|
||||||
object Cyc_make_vector(void *data, object cont, int argc, object len, ...);
|
object Cyc_make_vector(void *data, object cont, int argc, object len, ...);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
@ -686,7 +688,7 @@ object Cyc_installation_dir(void *data, object cont, object type);
|
||||||
object Cyc_compilation_environment(void *data, object cont, object var);
|
object Cyc_compilation_environment(void *data, object cont, object var);
|
||||||
object Cyc_command_line_arguments(void *data, object cont);
|
object Cyc_command_line_arguments(void *data, object cont);
|
||||||
object Cyc_system(object cmd);
|
object Cyc_system(object cmd);
|
||||||
void Cyc_halt(void *data, object clo, int argc, object *args);
|
void Cyc_halt(void *data, object clo, int argc, object * args);
|
||||||
object __halt(object obj);
|
object __halt(object obj);
|
||||||
object Cyc_io_delete_file(void *data, object filename);
|
object Cyc_io_delete_file(void *data, object filename);
|
||||||
object Cyc_io_file_exists(void *data, object filename);
|
object Cyc_io_file_exists(void *data, object filename);
|
||||||
|
@ -704,7 +706,7 @@ time_t Cyc_file_last_modified_time(char *path);
|
||||||
object Cyc_spawn_thread(object thunk);
|
object Cyc_spawn_thread(object thunk);
|
||||||
void Cyc_start_trampoline(gc_thread_data * thd);
|
void Cyc_start_trampoline(gc_thread_data * thd);
|
||||||
void Cyc_end_thread(gc_thread_data * thd);
|
void Cyc_end_thread(gc_thread_data * thd);
|
||||||
void Cyc_exit_thread(void *data, object _, int argc, object *args);
|
void Cyc_exit_thread(void *data, object _, int argc, object * args);
|
||||||
object Cyc_thread_sleep(void *data, object timeout);
|
object Cyc_thread_sleep(void *data, object timeout);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
@ -907,7 +909,8 @@ extern object Cyc_glo_call_cc;
|
||||||
* @brief Raise and handle Scheme exceptions
|
* @brief Raise and handle Scheme exceptions
|
||||||
*/
|
*/
|
||||||
/**@{*/
|
/**@{*/
|
||||||
object Cyc_default_exception_handler(void *data, object _, int argc, object *args);
|
object Cyc_default_exception_handler(void *data, object _, int argc,
|
||||||
|
object * args);
|
||||||
|
|
||||||
object Cyc_current_exception_handler(void *data);
|
object Cyc_current_exception_handler(void *data);
|
||||||
void Cyc_rt_raise(void *data, object err);
|
void Cyc_rt_raise(void *data, object err);
|
||||||
|
@ -948,7 +951,7 @@ object register_library(const char *name);
|
||||||
/**@{*/
|
/**@{*/
|
||||||
extern list global_table;
|
extern list global_table;
|
||||||
void add_global(const char *identifier, object * glo);
|
void add_global(const char *identifier, object * glo);
|
||||||
void Cyc_set_globals_changed(gc_thread_data *thd);
|
void Cyc_set_globals_changed(gc_thread_data * thd);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -970,9 +973,9 @@ void Cyc_set_globals_changed(gc_thread_data *thd);
|
||||||
#define Cyc_utf8_encode_char(dest, dest_size, char_value) \
|
#define Cyc_utf8_encode_char(dest, dest_size, char_value) \
|
||||||
Cyc_utf8_encode(dest, dest_size, &char_value, 1)
|
Cyc_utf8_encode(dest, dest_size, &char_value, 1)
|
||||||
|
|
||||||
int Cyc_utf8_encode(char *dest, int sz, uint32_t *src, int srcsz);
|
int Cyc_utf8_encode(char *dest, int sz, uint32_t * src, int srcsz);
|
||||||
int Cyc_utf8_count_code_points(uint8_t* s);
|
int Cyc_utf8_count_code_points(uint8_t * s);
|
||||||
uint32_t Cyc_utf8_validate_stream(uint32_t *state, char *str, size_t len);
|
uint32_t Cyc_utf8_validate_stream(uint32_t * state, char *str, size_t len);
|
||||||
uint32_t Cyc_utf8_validate(char *str, size_t len);
|
uint32_t Cyc_utf8_validate(char *str, size_t len);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
@ -994,6 +997,7 @@ static inline object Cyc_cdr(void *data, object lis)
|
||||||
Cyc_check_pair(data, lis);
|
Cyc_check_pair(data, lis);
|
||||||
return cdr(lis);
|
return cdr(lis);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsafe car/cdr
|
// Unsafe car/cdr
|
||||||
#define Cyc_car_unsafe(d, lis) car(lis)
|
#define Cyc_car_unsafe(d, lis) car(lis)
|
||||||
#define Cyc_cdr_unsafe(d, lis) cdr(lis)
|
#define Cyc_cdr_unsafe(d, lis) cdr(lis)
|
||||||
|
|
|
@ -46,31 +46,13 @@ typedef void *object;
|
||||||
*\ingroup objects
|
*\ingroup objects
|
||||||
*/
|
*/
|
||||||
enum object_tag {
|
enum object_tag {
|
||||||
closure0_tag = 0
|
closure0_tag = 0, closure1_tag = 1, closureN_tag = 2, macro_tag = 3 // Keep closures here for quick type checking
|
||||||
, closure1_tag = 1
|
, boolean_tag = 4, bytevector_tag = 5, c_opaque_tag = 6, cond_var_tag =
|
||||||
, closureN_tag = 2
|
7, cvar_tag = 8, double_tag = 9, eof_tag = 10, forward_tag =
|
||||||
, macro_tag = 3 // Keep closures here for quick type checking
|
11, integer_tag = 12, bignum_tag = 13, mutex_tag = 14, pair_tag =
|
||||||
, boolean_tag = 4
|
15, port_tag = 16, primitive_tag = 17, string_tag = 18, symbol_tag =
|
||||||
, bytevector_tag = 5
|
19, vector_tag = 20, complex_num_tag = 21, atomic_tag = 22, void_tag =
|
||||||
, c_opaque_tag = 6
|
23, record_tag = 24
|
||||||
, cond_var_tag = 7
|
|
||||||
, cvar_tag = 8
|
|
||||||
, double_tag = 9
|
|
||||||
, eof_tag = 10
|
|
||||||
, forward_tag = 11
|
|
||||||
, integer_tag = 12
|
|
||||||
, bignum_tag = 13
|
|
||||||
, mutex_tag = 14
|
|
||||||
, pair_tag = 15
|
|
||||||
, port_tag = 16
|
|
||||||
, primitive_tag = 17
|
|
||||||
, string_tag = 18
|
|
||||||
, symbol_tag = 19
|
|
||||||
, vector_tag = 20
|
|
||||||
, complex_num_tag = 21
|
|
||||||
, atomic_tag = 22
|
|
||||||
, void_tag = 23
|
|
||||||
, record_tag = 24
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,13 +95,13 @@ typedef unsigned char tag_type;
|
||||||
// Parameters for size of a "page" on the heap (the second generation GC), in bytes.
|
// Parameters for size of a "page" on the heap (the second generation GC), in bytes.
|
||||||
|
|
||||||
/** Grow first page by adding this amount to it */
|
/** Grow first page by adding this amount to it */
|
||||||
#define GROW_HEAP_BY_SIZE (2 * 1024 * 1024)
|
#define GROW_HEAP_BY_SIZE (2 * 1024 * 1024)
|
||||||
|
|
||||||
/** Size of the first page */
|
/** Size of the first page */
|
||||||
#define INITIAL_HEAP_SIZE (3 * 1024 * 1024)
|
#define INITIAL_HEAP_SIZE (3 * 1024 * 1024)
|
||||||
|
|
||||||
/** Normal size of a heap page */
|
/** Normal size of a heap page */
|
||||||
#define HEAP_SIZE (8 * 1024 * 1024)
|
#define HEAP_SIZE (8 * 1024 * 1024)
|
||||||
|
|
||||||
// End heap page size parameters
|
// End heap page size parameters
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
@ -128,7 +110,7 @@ typedef unsigned char tag_type;
|
||||||
// Major GC tuning parameters
|
// Major GC tuning parameters
|
||||||
|
|
||||||
/** Start GC cycle if % heap space free below this percentage */
|
/** Start GC cycle if % heap space free below this percentage */
|
||||||
#define GC_COLLECTION_THRESHOLD 0.0125 //0.05
|
#define GC_COLLECTION_THRESHOLD 0.0125 //0.05
|
||||||
|
|
||||||
/** Start GC cycle if fewer than this many heap pages are unswept */
|
/** Start GC cycle if fewer than this many heap pages are unswept */
|
||||||
#define GC_COLLECT_UNDER_UNSWEPT_HEAP_COUNT 3
|
#define GC_COLLECT_UNDER_UNSWEPT_HEAP_COUNT 3
|
||||||
|
@ -221,15 +203,15 @@ struct gc_heap_t {
|
||||||
/** Size of the heap page in bytes */
|
/** Size of the heap page in bytes */
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
/** Keep empty page alive this many times before freeing */
|
/** Keep empty page alive this many times before freeing */
|
||||||
unsigned char ttl;
|
unsigned char ttl;
|
||||||
/** Bump: Track remaining space; this is useful for bump&pop style allocation */
|
/** Bump: Track remaining space; this is useful for bump&pop style allocation */
|
||||||
unsigned int remaining;
|
unsigned int remaining;
|
||||||
/** For fixed-size heaps, only allocate blocks of this size */
|
/** For fixed-size heaps, only allocate blocks of this size */
|
||||||
unsigned block_size;
|
unsigned block_size;
|
||||||
/** Lazy-sweep: Amount of heap data that is free */
|
/** Lazy-sweep: Amount of heap data that is free */
|
||||||
unsigned int free_size;
|
unsigned int free_size;
|
||||||
/** Lazy-sweep: Determine if the heap is full */
|
/** Lazy-sweep: Determine if the heap is full */
|
||||||
unsigned char is_full;
|
unsigned char is_full;
|
||||||
/** Lazy-sweep: Determine if the heap has been swept */
|
/** Lazy-sweep: Determine if the heap has been swept */
|
||||||
unsigned char is_unswept;
|
unsigned char is_unswept;
|
||||||
/** Lazy-sweep: Start GC cycle if fewer than this many heap pages are unswept */
|
/** Lazy-sweep: Start GC cycle if fewer than this many heap pages are unswept */
|
||||||
|
@ -261,9 +243,9 @@ struct gc_heap_root_t {
|
||||||
*/
|
*/
|
||||||
typedef struct gc_header_type_t gc_header_type;
|
typedef struct gc_header_type_t gc_header_type;
|
||||||
struct gc_header_type_t {
|
struct gc_header_type_t {
|
||||||
unsigned char mark; // mark bits
|
unsigned char mark; // mark bits
|
||||||
unsigned char grayed:1; // stack object to be grayed when moved to heap
|
unsigned char grayed:1; // stack object to be grayed when moved to heap
|
||||||
unsigned char immutable:1; // Flag normally mutable obj (EG: pair) as read-only
|
unsigned char immutable:1; // Flag normally mutable obj (EG: pair) as read-only
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Get an object's `mark` value */
|
/** Get an object's `mark` value */
|
||||||
|
@ -290,10 +272,10 @@ typedef enum { STAGE_CLEAR_OR_MARKING, STAGE_TRACING
|
||||||
// the collector swaps their values as an optimization.
|
// the collector swaps their values as an optimization.
|
||||||
|
|
||||||
/** Memory not to be collected by major GC, such as on the stack */
|
/** Memory not to be collected by major GC, such as on the stack */
|
||||||
#define gc_color_red 0
|
#define gc_color_red 0
|
||||||
|
|
||||||
/** Unallocated memory */
|
/** Unallocated memory */
|
||||||
#define gc_color_blue 2
|
#define gc_color_blue 2
|
||||||
|
|
||||||
/** Mark buffers */
|
/** Mark buffers */
|
||||||
typedef struct mark_buffer_t mark_buffer;
|
typedef struct mark_buffer_t mark_buffer;
|
||||||
|
@ -398,29 +380,31 @@ void gc_initialize(void);
|
||||||
void gc_add_new_unrunning_mutator(gc_thread_data * thd);
|
void gc_add_new_unrunning_mutator(gc_thread_data * thd);
|
||||||
void gc_add_mutator(gc_thread_data * thd);
|
void gc_add_mutator(gc_thread_data * thd);
|
||||||
void gc_remove_mutator(gc_thread_data * thd);
|
void gc_remove_mutator(gc_thread_data * thd);
|
||||||
int gc_is_mutator_active(gc_thread_data *thd);
|
int gc_is_mutator_active(gc_thread_data * thd);
|
||||||
int gc_is_mutator_new(gc_thread_data *thd);
|
int gc_is_mutator_new(gc_thread_data * thd);
|
||||||
void gc_sleep_ms(int ms);
|
void gc_sleep_ms(int ms);
|
||||||
gc_heap *gc_heap_create(int heap_type, size_t size, gc_thread_data *thd);
|
gc_heap *gc_heap_create(int heap_type, size_t size, gc_thread_data * thd);
|
||||||
gc_heap *gc_heap_free(gc_heap *page, gc_heap *prev_page);
|
gc_heap *gc_heap_free(gc_heap * page, gc_heap * prev_page);
|
||||||
void gc_heap_merge(gc_heap *hdest, gc_heap *hsrc);
|
void gc_heap_merge(gc_heap * hdest, gc_heap * hsrc);
|
||||||
void gc_merge_all_heaps(gc_thread_data *dest, gc_thread_data *src);
|
void gc_merge_all_heaps(gc_thread_data * dest, gc_thread_data * src);
|
||||||
void gc_print_stats(gc_heap * h);
|
void gc_print_stats(gc_heap * h);
|
||||||
gc_heap *gc_grow_heap(gc_heap * h, size_t size, gc_thread_data *thd);
|
gc_heap *gc_grow_heap(gc_heap * h, size_t size, gc_thread_data * thd);
|
||||||
char *gc_copy_obj(object hp, char *obj, gc_thread_data * thd);
|
char *gc_copy_obj(object hp, char *obj, gc_thread_data * thd);
|
||||||
void *gc_try_alloc(gc_heap * h, size_t size, char *obj,
|
void *gc_try_alloc(gc_heap * h, size_t size, char *obj, gc_thread_data * thd);
|
||||||
gc_thread_data * thd);
|
void *gc_try_alloc_slow(gc_heap * h_passed, gc_heap * h, size_t size, char *obj,
|
||||||
void *gc_try_alloc_slow(gc_heap *h_passed, gc_heap *h, size_t size, char *obj, gc_thread_data *thd);
|
gc_thread_data * thd);
|
||||||
void *gc_alloc(gc_heap_root * h, size_t size, char *obj, gc_thread_data * thd,
|
void *gc_alloc(gc_heap_root * h, size_t size, char *obj, gc_thread_data * thd,
|
||||||
int *heap_grown);
|
int *heap_grown);
|
||||||
void *gc_alloc_bignum(gc_thread_data *data);
|
void *gc_alloc_bignum(gc_thread_data * data);
|
||||||
size_t gc_allocated_bytes(object obj, gc_free_list * q, gc_free_list * r);
|
size_t gc_allocated_bytes(object obj, gc_free_list * q, gc_free_list * r);
|
||||||
gc_heap *gc_heap_last(gc_heap * h);
|
gc_heap *gc_heap_last(gc_heap * h);
|
||||||
|
|
||||||
void gc_heap_create_rest(gc_heap *h, gc_thread_data *thd);
|
void gc_heap_create_rest(gc_heap * h, gc_thread_data * thd);
|
||||||
void *gc_try_alloc_rest(gc_heap * h, size_t size, char *obj, gc_thread_data * thd);
|
void *gc_try_alloc_rest(gc_heap * h, size_t size, char *obj,
|
||||||
void *gc_alloc_rest(gc_heap_root * hrt, size_t size, char *obj, gc_thread_data * thd, int *heap_grown);
|
gc_thread_data * thd);
|
||||||
void gc_init_fixed_size_free_list(gc_heap *h);
|
void *gc_alloc_rest(gc_heap_root * hrt, size_t size, char *obj,
|
||||||
|
gc_thread_data * thd, int *heap_grown);
|
||||||
|
void gc_init_fixed_size_free_list(gc_heap * h);
|
||||||
|
|
||||||
//size_t gc_heap_total_size(gc_heap * h);
|
//size_t gc_heap_total_size(gc_heap * h);
|
||||||
//size_t gc_heap_total_free_size(gc_heap *h);
|
//size_t gc_heap_total_free_size(gc_heap *h);
|
||||||
|
@ -429,7 +413,7 @@ void gc_init_fixed_size_free_list(gc_heap *h);
|
||||||
void gc_request_mark_globals(void);
|
void gc_request_mark_globals(void);
|
||||||
void gc_mark_globals(object globals, object global_table);
|
void gc_mark_globals(object globals, object global_table);
|
||||||
//size_t gc_sweep(gc_heap * h, size_t * sum_freed_ptr, gc_thread_data *thd);
|
//size_t gc_sweep(gc_heap * h, size_t * sum_freed_ptr, gc_thread_data *thd);
|
||||||
gc_heap *gc_sweep(gc_heap * h, gc_thread_data *thd);
|
gc_heap *gc_sweep(gc_heap * h, gc_thread_data * thd);
|
||||||
void gc_thr_grow_move_buffer(gc_thread_data * d);
|
void gc_thr_grow_move_buffer(gc_thread_data * d);
|
||||||
void gc_thread_data_init(gc_thread_data * thd, int mut_num, char *stack_base,
|
void gc_thread_data_init(gc_thread_data * thd, int mut_num, char *stack_base,
|
||||||
long stack_size);
|
long stack_size);
|
||||||
|
@ -456,7 +440,8 @@ void gc_post_handshake(gc_status_type s);
|
||||||
void gc_wait_handshake();
|
void gc_wait_handshake();
|
||||||
void gc_start_collector();
|
void gc_start_collector();
|
||||||
void gc_mutator_thread_blocked(gc_thread_data * thd, object cont);
|
void gc_mutator_thread_blocked(gc_thread_data * thd, object cont);
|
||||||
void gc_mutator_thread_runnable(gc_thread_data * thd, object result, object maybe_copied);
|
void gc_mutator_thread_runnable(gc_thread_data * thd, object result,
|
||||||
|
object maybe_copied);
|
||||||
void Cyc_make_shared_object(void *data, object k, object obj);
|
void Cyc_make_shared_object(void *data, object k, object obj);
|
||||||
#define set_thread_blocked(d, c) \
|
#define set_thread_blocked(d, c) \
|
||||||
gc_mutator_thread_blocked(((gc_thread_data *)d), (c))
|
gc_mutator_thread_blocked(((gc_thread_data *)d), (c))
|
||||||
|
@ -523,7 +508,6 @@ void Cyc_make_shared_object(void *data, object k, object obj);
|
||||||
*/
|
*/
|
||||||
#define forward(obj) (((pair_type *) obj)->pair_car)
|
#define forward(obj) (((pair_type *) obj)->pair_car)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup gc_minor_mut Mutation table
|
* \defgroup gc_minor_mut Mutation table
|
||||||
* @brief Mutation table to support the minor GC write barrier
|
* @brief Mutation table to support the minor GC write barrier
|
||||||
|
@ -538,7 +522,8 @@ void clear_mutations(void *data);
|
||||||
* @brief Minor GC write barrier to ensure there are no references to stack objects from the heap.
|
* @brief Minor GC write barrier to ensure there are no references to stack objects from the heap.
|
||||||
*/
|
*/
|
||||||
/**@{*/
|
/**@{*/
|
||||||
object transport_stack_value(gc_thread_data *data, object var, object value, int *run_gc);
|
object transport_stack_value(gc_thread_data * data, object var, object value,
|
||||||
|
int *run_gc);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
@ -550,8 +535,9 @@ object transport_stack_value(gc_thread_data *data, object var, object value, int
|
||||||
* \defgroup ffi Foreign Function Interface
|
* \defgroup ffi Foreign Function Interface
|
||||||
*/
|
*/
|
||||||
/**@{*/
|
/**@{*/
|
||||||
object Cyc_scm_call(gc_thread_data *parent_thd, object fnc, int argc, object *args);
|
object Cyc_scm_call(gc_thread_data * parent_thd, object fnc, int argc,
|
||||||
object Cyc_scm_call_no_gc(gc_thread_data *parent_thd, object fnc, object arg);
|
object * args);
|
||||||
|
object Cyc_scm_call_no_gc(gc_thread_data * parent_thd, object fnc, object arg);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -659,10 +645,10 @@ typedef uint32_t char_type;
|
||||||
/**@{*/
|
/**@{*/
|
||||||
|
|
||||||
/** Function type */
|
/** Function type */
|
||||||
typedef void (*function_type) (void *data, object clo, int argc, object *args);
|
typedef void (*function_type)(void *data, object clo, int argc, object * args);
|
||||||
|
|
||||||
/** Non-CPS function type */
|
/** Non-CPS function type */
|
||||||
typedef object (*inline_function_type) ();
|
typedef object(*inline_function_type) ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief C-variable integration type - wrapper around a Cyclone object pointer
|
* @brief C-variable integration type - wrapper around a Cyclone object pointer
|
||||||
|
@ -913,11 +899,8 @@ typedef struct {
|
||||||
* and provides constants for each of the comparison operators.
|
* and provides constants for each of the comparison operators.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CYC_BN_LTE = -2
|
CYC_BN_LTE = -2, CYC_BN_LT = MP_LT, CYC_BN_EQ = MP_EQ, CYC_BN_GT =
|
||||||
, CYC_BN_LT = MP_LT
|
MP_GT, CYC_BN_GTE = 2
|
||||||
, CYC_BN_EQ = MP_EQ
|
|
||||||
, CYC_BN_GT = MP_GT
|
|
||||||
, CYC_BN_GTE = 2
|
|
||||||
} bn_cmp_type;
|
} bn_cmp_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1089,17 +1072,17 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gc_header_type hdr;
|
gc_header_type hdr;
|
||||||
tag_type tag;
|
tag_type tag;
|
||||||
void *unused; // Protect against forwarding pointer, ideally would not be needed.
|
void *unused; // Protect against forwarding pointer, ideally would not be needed.
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int mode;
|
int mode;
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
unsigned int line_num;
|
unsigned int line_num;
|
||||||
unsigned int col_num;
|
unsigned int col_num;
|
||||||
unsigned int buf_idx;
|
unsigned int buf_idx;
|
||||||
unsigned int tok_start; // Start of token in mem_buf (end is unknown yet)
|
unsigned int tok_start; // Start of token in mem_buf (end is unknown yet)
|
||||||
unsigned int tok_end; // End of token in tok_buf (start is tok_buf[0])
|
unsigned int tok_end; // End of token in tok_buf (start is tok_buf[0])
|
||||||
char *tok_buf; // Alternative buffer for tokens
|
char *tok_buf; // Alternative buffer for tokens
|
||||||
size_t tok_buf_len;
|
size_t tok_buf_len;
|
||||||
char *mem_buf;
|
char *mem_buf;
|
||||||
size_t mem_buf_len;
|
size_t mem_buf_len;
|
||||||
unsigned short read_len;
|
unsigned short read_len;
|
||||||
|
@ -1168,10 +1151,22 @@ typedef struct {
|
||||||
} vector_type;
|
} vector_type;
|
||||||
typedef vector_type *vector;
|
typedef vector_type *vector;
|
||||||
|
|
||||||
typedef struct { vector_type v; object arr[2]; } vector_2_type;
|
typedef struct {
|
||||||
typedef struct { vector_type v; object arr[3]; } vector_3_type;
|
vector_type v;
|
||||||
typedef struct { vector_type v; object arr[4]; } vector_4_type;
|
object arr[2];
|
||||||
typedef struct { vector_type v; object arr[5]; } vector_5_type;
|
} vector_2_type;
|
||||||
|
typedef struct {
|
||||||
|
vector_type v;
|
||||||
|
object arr[3];
|
||||||
|
} vector_3_type;
|
||||||
|
typedef struct {
|
||||||
|
vector_type v;
|
||||||
|
object arr[4];
|
||||||
|
} vector_4_type;
|
||||||
|
typedef struct {
|
||||||
|
vector_type v;
|
||||||
|
object arr[5];
|
||||||
|
} vector_5_type;
|
||||||
|
|
||||||
/** Create a new vector in the nursery */
|
/** Create a new vector in the nursery */
|
||||||
#define make_empty_vector(v) \
|
#define make_empty_vector(v) \
|
||||||
|
@ -1296,9 +1291,21 @@ typedef pair_type *pair;
|
||||||
(n))
|
(n))
|
||||||
|
|
||||||
//typedef list_1_type pair_type;
|
//typedef list_1_type pair_type;
|
||||||
typedef struct { pair_type a; pair_type b; } list_2_type;
|
typedef struct {
|
||||||
typedef struct { pair_type a; pair_type b; pair_type c;} list_3_type;
|
pair_type a;
|
||||||
typedef struct { pair_type a; pair_type b; pair_type c; pair_type d;} list_4_type;
|
pair_type b;
|
||||||
|
} list_2_type;
|
||||||
|
typedef struct {
|
||||||
|
pair_type a;
|
||||||
|
pair_type b;
|
||||||
|
pair_type c;
|
||||||
|
} list_3_type;
|
||||||
|
typedef struct {
|
||||||
|
pair_type a;
|
||||||
|
pair_type b;
|
||||||
|
pair_type c;
|
||||||
|
pair_type d;
|
||||||
|
} list_4_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a pair with a single value.
|
* Create a pair with a single value.
|
||||||
|
@ -1438,7 +1445,7 @@ typedef closure0_type *macro;
|
||||||
* These objects are special and can be statically allocated as an optimization
|
* These objects are special and can be statically allocated as an optimization
|
||||||
*/
|
*/
|
||||||
#define mclosure0(c, f) \
|
#define mclosure0(c, f) \
|
||||||
static closure0_type c = { .hdr.mark = gc_color_red, .hdr.grayed = 0, .tag = closure0_tag, .fn = f, .num_args = -1 }; /* TODO: need a new macro that initializes num_args */
|
static closure0_type c = { .hdr.mark = gc_color_red, .hdr.grayed = 0, .tag = closure0_tag, .fn = f, .num_args = -1 }; /* TODO: need a new macro that initializes num_args */
|
||||||
|
|
||||||
#define maclosure0(c,f,na) \
|
#define maclosure0(c,f,na) \
|
||||||
closure0_type c; \
|
closure0_type c; \
|
||||||
|
@ -1527,7 +1534,7 @@ struct vpbuffer_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
vpbuffer *vp_create(void);
|
vpbuffer *vp_create(void);
|
||||||
void vp_add(vpbuffer *v, void *obj);
|
void vp_add(vpbuffer * v, void *obj);
|
||||||
|
|
||||||
/* Utility functions */
|
/* Utility functions */
|
||||||
void **vpbuffer_realloc(void **buf, int *len);
|
void **vpbuffer_realloc(void **buf, int *len);
|
||||||
|
@ -1536,10 +1543,10 @@ void vpbuffer_free(void **buf);
|
||||||
|
|
||||||
/* Bignum utility functions */
|
/* Bignum utility functions */
|
||||||
int Cyc_bignum_cmp(bn_cmp_type type, object x, int tx, object y, int ty);
|
int Cyc_bignum_cmp(bn_cmp_type type, object x, int tx, object y, int ty);
|
||||||
void Cyc_int2bignum(int n, mp_int *bn);
|
void Cyc_int2bignum(int n, mp_int * bn);
|
||||||
|
|
||||||
/* Remaining GC prototypes that require objects to be defined */
|
/* Remaining GC prototypes that require objects to be defined */
|
||||||
void *gc_alloc_from_bignum(gc_thread_data *data, bignum_type *src);
|
void *gc_alloc_from_bignum(gc_thread_data * data, bignum_type * src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do a minor GC
|
* Do a minor GC
|
||||||
|
@ -1548,5 +1555,6 @@ void *gc_alloc_from_bignum(gc_thread_data *data, bignum_type *src);
|
||||||
int gc_minor(void *data, object low_limit, object high_limit, closure cont,
|
int gc_minor(void *data, object low_limit, object high_limit, closure cont,
|
||||||
object * args, int num_args);
|
object * args, int num_args);
|
||||||
|
|
||||||
void Cyc_import_shared_object(void *data, object cont, object filename, object entry_pt_fnc);
|
void Cyc_import_shared_object(void *data, object cont, object filename,
|
||||||
|
object entry_pt_fnc);
|
||||||
#endif /* CYCLONE_TYPES_H */
|
#endif /* CYCLONE_TYPES_H */
|
||||||
|
|
41
mstreams.c
41
mstreams.c
|
@ -41,7 +41,7 @@ int Cyc_have_mstreams()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
object Cyc_heap_alloc_port(void *data, port_type *p);
|
object Cyc_heap_alloc_port(void *data, port_type * p);
|
||||||
port_type *Cyc_io_open_input_string(void *data, object str)
|
port_type *Cyc_io_open_input_string(void *data, object str)
|
||||||
{
|
{
|
||||||
// Allocate port on the heap so the location of mem_buf does not change
|
// Allocate port on the heap so the location of mem_buf does not change
|
||||||
|
@ -49,7 +49,7 @@ port_type *Cyc_io_open_input_string(void *data, object str)
|
||||||
make_input_port(sp, NULL, CYC_IO_BUF_LEN);
|
make_input_port(sp, NULL, CYC_IO_BUF_LEN);
|
||||||
|
|
||||||
Cyc_check_str(data, str);
|
Cyc_check_str(data, str);
|
||||||
p = (port_type *)Cyc_heap_alloc_port(data, &sp);
|
p = (port_type *) Cyc_heap_alloc_port(data, &sp);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
#if CYC_HAVE_FMEMOPEN
|
#if CYC_HAVE_FMEMOPEN
|
||||||
p->str_bv_in_mem_buf = malloc(sizeof(char) * (string_len(str) + 1));
|
p->str_bv_in_mem_buf = malloc(sizeof(char) * (string_len(str) + 1));
|
||||||
|
@ -57,8 +57,9 @@ port_type *Cyc_io_open_input_string(void *data, object str)
|
||||||
memcpy(p->str_bv_in_mem_buf, string_str(str), string_len(str));
|
memcpy(p->str_bv_in_mem_buf, string_str(str), string_len(str));
|
||||||
p->fp = fmemopen(p->str_bv_in_mem_buf, string_len(str), "r");
|
p->fp = fmemopen(p->str_bv_in_mem_buf, string_len(str), "r");
|
||||||
#endif
|
#endif
|
||||||
if (p->fp == NULL){
|
if (p->fp == NULL) {
|
||||||
Cyc_rt_raise2(data, "Unable to open input memory stream", obj_int2obj(errno));
|
Cyc_rt_raise2(data, "Unable to open input memory stream",
|
||||||
|
obj_int2obj(errno));
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -70,16 +71,17 @@ port_type *Cyc_io_open_input_bytevector(void *data, object bv)
|
||||||
make_input_port(sp, NULL, CYC_IO_BUF_LEN);
|
make_input_port(sp, NULL, CYC_IO_BUF_LEN);
|
||||||
|
|
||||||
Cyc_check_bvec(data, bv);
|
Cyc_check_bvec(data, bv);
|
||||||
p = (port_type *)Cyc_heap_alloc_port(data, &sp);
|
p = (port_type *) Cyc_heap_alloc_port(data, &sp);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
#if CYC_HAVE_FMEMOPEN
|
#if CYC_HAVE_FMEMOPEN
|
||||||
p->str_bv_in_mem_buf = malloc(sizeof(char) * ((bytevector)bv)->len);
|
p->str_bv_in_mem_buf = malloc(sizeof(char) * ((bytevector) bv)->len);
|
||||||
p->str_bv_in_mem_buf_len = ((bytevector)bv)->len;
|
p->str_bv_in_mem_buf_len = ((bytevector) bv)->len;
|
||||||
memcpy(p->str_bv_in_mem_buf, ((bytevector)bv)->data, ((bytevector)bv)->len);
|
memcpy(p->str_bv_in_mem_buf, ((bytevector) bv)->data, ((bytevector) bv)->len);
|
||||||
p->fp = fmemopen(p->str_bv_in_mem_buf, ((bytevector)bv)->len, "r");
|
p->fp = fmemopen(p->str_bv_in_mem_buf, ((bytevector) bv)->len, "r");
|
||||||
#endif
|
#endif
|
||||||
if (p->fp == NULL){
|
if (p->fp == NULL) {
|
||||||
Cyc_rt_raise2(data, "Unable to open input memory stream", obj_int2obj(errno));
|
Cyc_rt_raise2(data, "Unable to open input memory stream",
|
||||||
|
obj_int2obj(errno));
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -89,20 +91,21 @@ port_type *Cyc_io_open_output_string(void *data)
|
||||||
// Allocate port on the heap so the location of mem_buf does not change
|
// Allocate port on the heap so the location of mem_buf does not change
|
||||||
port_type *p;
|
port_type *p;
|
||||||
make_port(sp, NULL, 0);
|
make_port(sp, NULL, 0);
|
||||||
p = (port_type *)Cyc_heap_alloc_port(data, &sp);
|
p = (port_type *) Cyc_heap_alloc_port(data, &sp);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
#if CYC_HAVE_OPEN_MEMSTREAM
|
#if CYC_HAVE_OPEN_MEMSTREAM
|
||||||
p->fp = open_memstream(&(p->str_bv_in_mem_buf), &(p->str_bv_in_mem_buf_len));
|
p->fp = open_memstream(&(p->str_bv_in_mem_buf), &(p->str_bv_in_mem_buf_len));
|
||||||
#endif
|
#endif
|
||||||
if (p->fp == NULL){
|
if (p->fp == NULL) {
|
||||||
Cyc_rt_raise2(data, "Unable to open output memory stream", obj_int2obj(errno));
|
Cyc_rt_raise2(data, "Unable to open output memory stream",
|
||||||
|
obj_int2obj(errno));
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cyc_io_get_output_string(void *data, object cont, object port)
|
void Cyc_io_get_output_string(void *data, object cont, object port)
|
||||||
{
|
{
|
||||||
port_type *p = (port_type *)port;
|
port_type *p = (port_type *) port;
|
||||||
Cyc_check_port(data, port);
|
Cyc_check_port(data, port);
|
||||||
if (p->fp) {
|
if (p->fp) {
|
||||||
fflush(p->fp);
|
fflush(p->fp);
|
||||||
|
@ -112,14 +115,14 @@ void Cyc_io_get_output_string(void *data, object cont, object port)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
make_string_with_len(s, p->str_bv_in_mem_buf, p->str_bv_in_mem_buf_len);
|
make_string_with_len(s, p->str_bv_in_mem_buf, p->str_bv_in_mem_buf_len);
|
||||||
s.num_cp = Cyc_utf8_count_code_points((uint8_t *)string_str(&s));
|
s.num_cp = Cyc_utf8_count_code_points((uint8_t *) string_str(&s));
|
||||||
return_closcall1(data, cont, &s);
|
return_closcall1(data, cont, &s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cyc_io_get_output_bytevector(void *data, object cont, object port)
|
void Cyc_io_get_output_bytevector(void *data, object cont, object port)
|
||||||
{
|
{
|
||||||
port_type *p = (port_type *)port;
|
port_type *p = (port_type *) port;
|
||||||
Cyc_check_port(data, port);
|
Cyc_check_port(data, port);
|
||||||
if (p->fp) {
|
if (p->fp) {
|
||||||
fflush(p->fp);
|
fflush(p->fp);
|
||||||
|
@ -130,8 +133,8 @@ void Cyc_io_get_output_bytevector(void *data, object cont, object port)
|
||||||
{
|
{
|
||||||
object bv;
|
object bv;
|
||||||
alloc_bytevector(data, bv, p->str_bv_in_mem_buf_len);
|
alloc_bytevector(data, bv, p->str_bv_in_mem_buf_len);
|
||||||
memcpy(((bytevector)bv)->data, p->str_bv_in_mem_buf, p->str_bv_in_mem_buf_len);
|
memcpy(((bytevector) bv)->data, p->str_bv_in_mem_buf,
|
||||||
|
p->str_bv_in_mem_buf_len);
|
||||||
return_closcall1(data, cont, bv);
|
return_closcall1(data, cont, bv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue