Re-format code

This commit is contained in:
Justin Ethier 2024-01-17 19:43:47 -08:00
parent b44198744b
commit 3b921e7389
12 changed files with 2586 additions and 2357 deletions

View file

@ -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,7 +66,7 @@ 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;
} }
@ -77,7 +78,7 @@ 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();
@ -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,13 +244,13 @@ 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; unsigned long hash = 5381;
int c; int c;
@ -269,7 +263,8 @@ size_t hash_function(const char* str, size_t len) {
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;
@ -279,7 +274,10 @@ simple_hashset_t simple_hashset_create()
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 =
(struct simple_hashset_item_st *)calloc(set->capacity,
sizeof(struct
simple_hashset_item_st));
if (set->items == NULL) { if (set->items == NULL) {
simple_hashset_destroy(set); simple_hashset_destroy(set);
return NULL; return NULL;
@ -302,7 +300,8 @@ 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;
@ -315,8 +314,7 @@ static int simple_hashset_add_member(simple_hashset_t set, symbol_type* key, siz
while (set->items[index].hash != 0 && set->items[index].hash != 1) { while (set->items[index].hash != 0 && set->items[index].hash != 1) {
if (set->items[index].hash == hash) { if (set->items[index].hash == hash) {
return 0; return 0;
} } else {
else {
/* search free slot */ /* search free slot */
index = set->mask & (index + prime_2); index = set->mask & (index + prime_2);
} }
@ -337,25 +335,28 @@ 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 = (struct simple_hashset_item_st*)calloc(set->capacity, sizeof(struct simple_hashset_item_st)); set->items =
(struct simple_hashset_item_st *)calloc(set->capacity,
sizeof(struct
simple_hashset_item_st));
set->nitems = 0; set->nitems = 0;
set->n_deleted_items = 0; set->n_deleted_items = 0;
//assert(set->items); //assert(set->items);
for (index = 0; index < old_capacity; ++index) { for (index = 0; index < old_capacity; ++index) {
simple_hashset_add_member(set, old_items[index].item, old_items[index].hash); simple_hashset_add_member(set, old_items[index].item,
old_items[index].hash);
} }
free(old_items); 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);
@ -364,7 +365,7 @@ int simple_hashset_add(simple_hashset_t set, symbol_type* key)
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);
@ -379,5 +380,3 @@ int simple_hashset_is_member(simple_hashset_t set, symbol_type* key)
} }
return 0; return 0;
} }

View file

@ -17,14 +17,14 @@ struct ck_malloc {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// 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;
@ -34,26 +34,25 @@ struct ck_malloc {
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.
* *
@ -62,13 +61,13 @@ 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)
{ {
@ -101,7 +100,8 @@ 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 *);
@ -150,7 +150,7 @@ 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
@ -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:
@ -213,33 +208,23 @@ ck_array_commit(ck_array_t *array);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// 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 */

32
ffi.c
View file

@ -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;
@ -72,7 +75,7 @@ object Cyc_scm_call(gc_thread_data *parent_thd, object fnc, int argc, object *ar
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;
@ -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;
@ -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);
} }

315
gc.c
View file

@ -111,7 +111,7 @@ static mark_buffer *mark_buffer_init(unsigned initial_size)
return mb; return mb;
} }
static void *mark_buffer_get(mark_buffer *mb, unsigned i) // TODO: macro? static void *mark_buffer_get(mark_buffer * mb, unsigned i) // TODO: macro?
{ {
while (i >= mb->buf_len) { while (i >= mb->buf_len) {
// Not on this page, try the next one // Not on this page, try the next one
@ -126,7 +126,7 @@ static void *mark_buffer_get(mark_buffer *mb, unsigned i) // TODO: macro?
return mb->buf[i]; return mb->buf[i];
} }
static void mark_buffer_set(mark_buffer *mb, unsigned i, void *obj) static void mark_buffer_set(mark_buffer * mb, unsigned i, void *obj)
{ {
// Find index i // Find index i
while (i >= mb->buf_len) { while (i >= mb->buf_len) {
@ -141,7 +141,7 @@ static void mark_buffer_set(mark_buffer *mb, unsigned i, void *obj)
mb->buf[i] = obj; mb->buf[i] = obj;
} }
static void mark_buffer_free(mark_buffer *mb) static void mark_buffer_free(mark_buffer * mb)
{ {
mark_buffer *next; mark_buffer *next;
while (mb) { while (mb) {
@ -157,44 +157,48 @@ static void mark_buffer_free(mark_buffer *mb)
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
const int NUM_ALLOC_SIZES = 10; const int NUM_ALLOC_SIZES = 10;
static double allocated_size_counts[10] = { static double allocated_size_counts[10] = {
0,0,0,0,0, 0, 0, 0, 0, 0,
0,0,0,0,0}; 0, 0, 0, 0, 0
};
static double allocated_obj_counts[25] = { static double allocated_obj_counts[25] = {
0,0,0,0,0, 0, 0, 0, 0, 0,
0,0,0,0,0, 0, 0, 0, 0, 0,
0,0,0,0,0, 0, 0, 0, 0, 0,
0,0,0,0,0, 0, 0, 0, 0, 0,
0,0,0,0,0}; 0, 0, 0, 0, 0
};
// TODO: allocated object sizes (EG: 32, 64, etc). // TODO: allocated object sizes (EG: 32, 64, etc).
static double allocated_heap_counts[4] = {0, 0, 0, 0}; static double allocated_heap_counts[4] = { 0, 0, 0, 0 };
void print_allocated_obj_counts() void print_allocated_obj_counts()
{ {
int i; int i;
fprintf(stderr, "Allocated sizes:\n"); fprintf(stderr, "Allocated sizes:\n");
fprintf(stderr, "Size, Allocations\n"); fprintf(stderr, "Size, Allocations\n");
for (i = 0; i < NUM_ALLOC_SIZES; i++){ for (i = 0; i < NUM_ALLOC_SIZES; i++) {
fprintf(stderr, "%d, %lf\n", 32 + (i*32), allocated_size_counts[i]); fprintf(stderr, "%d, %lf\n", 32 + (i * 32), allocated_size_counts[i]);
} }
fprintf(stderr, "Allocated objects:\n"); fprintf(stderr, "Allocated objects:\n");
fprintf(stderr, "Tag, Allocations\n"); fprintf(stderr, "Tag, Allocations\n");
for (i = 0; i < 25; i++){ for (i = 0; i < 25; i++) {
fprintf(stderr, "%d, %lf\n", i, allocated_obj_counts[i]); fprintf(stderr, "%d, %lf\n", i, allocated_obj_counts[i]);
} }
fprintf(stderr, "Allocated heaps:\n"); fprintf(stderr, "Allocated heaps:\n");
fprintf(stderr, "Heap, Allocations\n"); fprintf(stderr, "Heap, Allocations\n");
for (i = 0; i < 4; i++){ for (i = 0; i < 4; i++) {
fprintf(stderr, "%d, %lf\n", i, allocated_heap_counts[i]); fprintf(stderr, "%d, %lf\n", i, allocated_heap_counts[i]);
} }
} }
void gc_log(FILE *stream, const char *format, ...) void gc_log(FILE * stream, const char *format, ...)
{ {
va_list vargs; va_list vargs;
time_t rawtime; time_t rawtime;
struct tm * timeinfo; struct tm *timeinfo;
time ( &rawtime ); time(&rawtime);
timeinfo = localtime ( &rawtime ); timeinfo = localtime(&rawtime);
fprintf(stream, "%.2d:%.2d:%.2d - ", fprintf(stream, "%.2d:%.2d:%.2d - ",
timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
@ -310,7 +314,7 @@ void gc_remove_mutator(gc_thread_data * thd)
* @param thd Thread data object of the m * @param thd Thread data object of the m
* @return A true value if the mutator is active, 0 otherwise. * @return A true value if the mutator is active, 0 otherwise.
*/ */
int gc_is_mutator_active(gc_thread_data *thd) int gc_is_mutator_active(gc_thread_data * thd)
{ {
ck_array_iterator_t iterator; ck_array_iterator_t iterator;
gc_thread_data *m; gc_thread_data *m;
@ -327,7 +331,7 @@ int gc_is_mutator_active(gc_thread_data *thd)
* @param thd Thread data object of the m * @param thd Thread data object of the m
* @return A true value if the mutator is found, 0 otherwise. * @return A true value if the mutator is found, 0 otherwise.
*/ */
int gc_is_mutator_new(gc_thread_data *thd) int gc_is_mutator_new(gc_thread_data * thd)
{ {
ck_array_iterator_t iterator; ck_array_iterator_t iterator;
gc_thread_data *m; gc_thread_data *m;
@ -371,9 +375,10 @@ void gc_free_old_thread_data()
* @param gc_heap Root of the heap * @param gc_heap Root of the heap
* @return Free space in bytes * @return Free space in bytes
*/ */
uint64_t gc_heap_free_size(gc_heap *h) { uint64_t gc_heap_free_size(gc_heap * h)
{
uint64_t free_size = 0; uint64_t free_size = 0;
for (; h; h = h->next){ for (; h; h = h->next) {
if (h->is_unswept == 1) { // Assume all free prior to sweep if (h->is_unswept == 1) { // Assume all free prior to sweep
free_size += h->size; free_size += h->size;
} else { } else {
@ -392,7 +397,7 @@ uint64_t gc_heap_free_size(gc_heap *h) {
* @return Pointer to the newly allocated heap page, or NULL * @return Pointer to the newly allocated heap page, or NULL
* if the allocation failed. * if the allocation failed.
*/ */
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_free_list *free, *next; gc_free_list *free, *next;
gc_heap *h; gc_heap *h;
@ -456,18 +461,18 @@ gc_heap *gc_heap_create(int heap_type, size_t size, gc_thread_data *thd)
* Assumes that there is no data currently on the heap page! * Assumes that there is no data currently on the heap page!
* @param h Heap page to initialize * @param h Heap page to initialize
*/ */
void gc_init_fixed_size_free_list(gc_heap *h) void gc_init_fixed_size_free_list(gc_heap * h)
{ {
// for this flavor, just layer a free list on top of unitialized memory // for this flavor, just layer a free list on top of unitialized memory
gc_free_list *next; gc_free_list *next;
//int i = 0; //int i = 0;
size_t remaining = h->size - (h->size % h->block_size) - h->block_size; // Starting at first one so skip it size_t remaining = h->size - (h->size % h->block_size) - h->block_size; // Starting at first one so skip it
next = h->free_list = (gc_free_list *)h->data; next = h->free_list = (gc_free_list *) h->data;
//printf("data start = %p\n", h->data); //printf("data start = %p\n", h->data);
//printf("data end = %p\n", h->data + h->size); //printf("data end = %p\n", h->data + h->size);
while (remaining >= h->block_size) { while (remaining >= h->block_size) {
//printf("%d init remaining=%d next = %p\n", i++, remaining, next); //printf("%d init remaining=%d next = %p\n", i++, remaining, next);
next->next = (gc_free_list *)(((char *) next) + h->block_size); next->next = (gc_free_list *) (((char *)next) + h->block_size);
next = next->next; next = next->next;
remaining -= h->block_size; remaining -= h->block_size;
} }
@ -479,11 +484,11 @@ void gc_init_fixed_size_free_list(gc_heap *h)
* @brief Diagnostic function to print all free lists on a fixed-size heap page * @brief Diagnostic function to print all free lists on a fixed-size heap page
* @param h Heap page to output * @param h Heap page to output
*/ */
void gc_print_fixed_size_free_list(gc_heap *h) void gc_print_fixed_size_free_list(gc_heap * h)
{ {
gc_free_list *f = h->free_list; gc_free_list *f = h->free_list;
fprintf(stderr, "printing free list:\n"); fprintf(stderr, "printing free list:\n");
while(f) { while (f) {
fprintf(stderr, "%p\n", f); fprintf(stderr, "%p\n", f);
f = f->next; f = f->next;
} }
@ -494,13 +499,15 @@ void gc_print_fixed_size_free_list(gc_heap *h)
* @brief Essentially this is half of the sweep code, for sweeping bump&pop * @brief Essentially this is half of the sweep code, for sweeping bump&pop
* @param h Heap page to convert * @param h Heap page to convert
*/ */
static size_t gc_convert_heap_page_to_free_list(gc_heap *h, gc_thread_data *thd) static size_t gc_convert_heap_page_to_free_list(gc_heap * h,
gc_thread_data * thd)
{ {
size_t freed = 0; size_t freed = 0;
object p; object p;
gc_free_list *next; gc_free_list *next;
int remaining = h->size - (h->size % h->block_size); int remaining = h->size - (h->size % h->block_size);
if (h->data_end == NULL) return 0; // Already converted if (h->data_end == NULL)
return 0; // Already converted
next = h->free_list = NULL; next = h->free_list = NULL;
while (remaining > h->remaining) { while (remaining > h->remaining) {
@ -509,8 +516,7 @@ static size_t gc_convert_heap_page_to_free_list(gc_heap *h, gc_thread_data *thd)
int color = mark(p); int color = mark(p);
// printf("found object %d color %d at %p with remaining=%lu\n", tag, color, p, remaining); // printf("found object %d color %d at %p with remaining=%lu\n", tag, color, p, remaining);
// free space, add it to the free list // free space, add it to the free list
if (color != thd->gc_alloc_color && if (color != thd->gc_alloc_color && color != thd->gc_trace_color) { //gc_color_clear)
color != thd->gc_trace_color) { //gc_color_clear)
// Run any finalizers // Run any finalizers
if (type_of(p) == mutex_tag) { if (type_of(p) == mutex_tag) {
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
@ -534,20 +540,19 @@ static size_t gc_convert_heap_page_to_free_list(gc_heap *h, gc_thread_data *thd)
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "mp_clear from sweep\n"); fprintf(stderr, "mp_clear from sweep\n");
#endif #endif
mp_clear(&(((bignum_type *)p)->bn)); mp_clear(&(((bignum_type *) p)->bn));
} else if (type_of(p) == c_opaque_tag && opaque_collect_ptr(p)) { } else if (type_of(p) == c_opaque_tag && opaque_collect_ptr(p)) {
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "free opaque pointer %p from sweep\n", opaque_ptr(p)); fprintf(stderr, "free opaque pointer %p from sweep\n", opaque_ptr(p));
#endif #endif
free( opaque_ptr(p) ); free(opaque_ptr(p));
} }
// Free block // Free block
freed += h->block_size; freed += h->block_size;
if (next == NULL) { if (next == NULL) {
next = h->free_list = p; next = h->free_list = p;
} } else {
else {
next->next = p; next->next = p;
next = next->next; next = next->next;
} }
@ -562,8 +567,7 @@ static size_t gc_convert_heap_page_to_free_list(gc_heap *h, gc_thread_data *thd)
// printf("no object at %p fill with free list\n", p); // printf("no object at %p fill with free list\n", p);
if (next == NULL) { if (next == NULL) {
next = h->free_list = p; next = h->free_list = p;
} } else {
else {
next->next = p; //(gc_free_list *)(((char *) next) + h->block_size); next->next = p; //(gc_free_list *)(((char *) next) + h->block_size);
next = next->next; next = next->next;
} }
@ -589,7 +593,7 @@ static size_t gc_convert_heap_page_to_free_list(gc_heap *h, gc_thread_data *thd)
* memory slots to the heap. It is only called by the collector thread after * memory slots to the heap. It is only called by the collector thread after
* the heap has been traced to identify live objects. * the heap has been traced to identify live objects.
*/ */
static gc_heap *gc_sweep_fixed_size(gc_heap * h, gc_thread_data *thd) static gc_heap *gc_sweep_fixed_size(gc_heap * h, gc_thread_data * thd)
{ {
short heap_is_empty; short heap_is_empty;
object p, end; object p, end;
@ -617,12 +621,13 @@ static gc_heap *gc_sweep_fixed_size(gc_heap * h, gc_thread_data *thd)
size_t remaining = h->size - (h->size % h->block_size); // - h->block_size; // Remove first one?? size_t remaining = h->size - (h->size % h->block_size); // - h->block_size; // Remove first one??
char *data_end = h->data + remaining; char *data_end = h->data + remaining;
heap_is_empty = 1; // Base case is an empty heap heap_is_empty = 1; // Base case is an empty heap
end = (object)data_end; end = (object) data_end;
p = h->data; p = h->data;
q = h->free_list; q = h->free_list;
while (p < end) { while (p < end) {
// find preceding/succeeding free list pointers for p // find preceding/succeeding free list pointers for p
for (r = (q?q->next:NULL); r && ((char *)r < (char *)p); q = r, r = r->next) ; for (r = (q ? q->next : NULL); r && ((char *)r < (char *)p);
q = r, r = r->next) ;
if ((char *)q == (char *)p || (char *)r == (char *)p) { // this is a free block, skip it if ((char *)q == (char *)p || (char *)r == (char *)p) { // this is a free block, skip it
//printf("Sweep skip free block %p remaining=%lu\n", p, remaining); //printf("Sweep skip free block %p remaining=%lu\n", p, remaining);
p = (object) (((char *)p) + h->block_size); p = (object) (((char *)p) + h->block_size);
@ -638,8 +643,7 @@ static gc_heap *gc_sweep_fixed_size(gc_heap * h, gc_thread_data *thd)
exit(1); exit(1);
} }
#endif #endif
if (mark(p) != thd->gc_alloc_color && if (mark(p) != thd->gc_alloc_color && mark(p) != thd->gc_trace_color) { //gc_color_clear)
mark(p) != thd->gc_trace_color) { //gc_color_clear)
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "sweep is freeing unmarked obj: %p with tag %d\n", p, fprintf(stderr, "sweep is freeing unmarked obj: %p with tag %d\n", p,
type_of(p)); type_of(p));
@ -667,7 +671,7 @@ static gc_heap *gc_sweep_fixed_size(gc_heap * h, gc_thread_data *thd)
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "mp_clear from sweep\n"); fprintf(stderr, "mp_clear from sweep\n");
#endif #endif
mp_clear(&(((bignum_type *)p)->bn)); mp_clear(&(((bignum_type *) p)->bn));
} }
// free p // free p
@ -682,12 +686,12 @@ static gc_heap *gc_sweep_fixed_size(gc_heap * h, gc_thread_data *thd)
// note if this is the case, either there is no free_list (see above case) or // note if this is the case, either there is no free_list (see above case) or
// the free list is after p, which is handled now. these are the only situations // the free list is after p, which is handled now. these are the only situations
// where there is no q // where there is no q
s = (gc_free_list *)p; s = (gc_free_list *) p;
s->next = h->free_list; s->next = h->free_list;
q = h->free_list = p; q = h->free_list = p;
//printf("sweep reclaimed remaining=%d, %p, assign h->free_list which was %p\n", remaining, p, h->free_list); //printf("sweep reclaimed remaining=%d, %p, assign h->free_list which was %p\n", remaining, p, h->free_list);
} else { } else {
s = (gc_free_list *)p; s = (gc_free_list *) p;
s->next = r; s->next = r;
q->next = s; q->next = s;
//printf("sweep reclaimed remaining=%d, %p, q=%p, r=%p\n", remaining, p, q, r); //printf("sweep reclaimed remaining=%d, %p, q=%p, r=%p\n", remaining, p, q, r);
@ -731,14 +735,15 @@ static gc_heap *gc_sweep_fixed_size(gc_heap * h, gc_thread_data *thd)
* @param prev_page Previous page in the heap * @param prev_page Previous page in the heap
* @return Previous page if successful, NULL otherwise * @return Previous page if successful, NULL otherwise
*/ */
gc_heap *gc_heap_free(gc_heap *page, gc_heap *prev_page) gc_heap *gc_heap_free(gc_heap * page, gc_heap * prev_page)
{ {
// At least for now, do not free first page // At least for now, do not free first page
if (prev_page == NULL || page == NULL) { if (prev_page == NULL || page == NULL) {
return NULL; return NULL;
} }
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
fprintf(stderr, "DEBUG freeing heap type %d page at addr: %p\n", page->type, page); fprintf(stderr, "DEBUG freeing heap type %d page at addr: %p\n", page->type,
page);
#endif #endif
prev_page->next = page->next; prev_page->next = page->next;
@ -751,19 +756,22 @@ gc_heap *gc_heap_free(gc_heap *page, gc_heap *prev_page)
* @param h Heap to inspect. The caller should acquire any necessary locks. * @param h Heap to inspect. The caller should acquire any necessary locks.
* @return A truthy value if the heap is empty, 0 otherwise. * @return A truthy value if the heap is empty, 0 otherwise.
*/ */
static int gc_is_heap_empty(gc_heap *h) static int gc_is_heap_empty(gc_heap * h)
{ {
gc_free_list *f; gc_free_list *f;
if (!h) return 0; if (!h)
return 0;
if (h->data_end) { // Fixed-size bump&pop if (h->data_end) { // Fixed-size bump&pop
return (h->remaining == (h->size - (h->size % h->block_size))); return (h->remaining == (h->size - (h->size % h->block_size)));
} }
if (!h->free_list) return 0; if (!h->free_list)
return 0;
f = h->free_list; f = h->free_list;
if (f->size != 0 || !f->next) return 0; if (f->size != 0 || !f->next)
return 0;
f = f->next; f = f->next;
return (f->size + gc_heap_align(gc_free_chunk_size)) == h->size; return (f->size + gc_heap_align(gc_free_chunk_size)) == h->size;
@ -792,13 +800,14 @@ void gc_print_stats(gc_heap * h)
if (f->size > free_max) if (f->size > free_max)
free_max = f->size; free_max = f->size;
} }
if (free == 0){ // No free chunks if (free == 0) { // No free chunks
free_min = 0; free_min = 0;
} }
heap_is_empty = gc_is_heap_empty(h); heap_is_empty = gc_is_heap_empty(h);
fprintf(stderr, fprintf(stderr,
"Heap type=%d, page size=%u, is empty=%d, used=%u, free=%u, free chunks=%u, min=%u, max=%u\n", "Heap type=%d, page size=%u, is empty=%d, used=%u, free=%u, free chunks=%u, min=%u, max=%u\n",
h->type, h->size, heap_is_empty, h->size - free, free, free_chunks, free_min, free_max); h->type, h->size, heap_is_empty, h->size - free, free, free_chunks,
free_min, free_max);
} }
} }
@ -814,9 +823,9 @@ void gc_print_stats(gc_heap * h)
*/ */
char *gc_copy_obj(object dest, char *obj, gc_thread_data * thd) char *gc_copy_obj(object dest, char *obj, gc_thread_data * thd)
{ {
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
allocated_obj_counts[type_of(obj)]++; allocated_obj_counts[type_of(obj)]++;
#endif #endif
switch (type_of(obj)) { switch (type_of(obj)) {
case closureN_tag:{ case closureN_tag:{
@ -827,7 +836,8 @@ char *gc_copy_obj(object dest, char *obj, gc_thread_data * thd)
hp->num_args = ((closureN) obj)->num_args; hp->num_args = ((closureN) obj)->num_args;
hp->num_elements = ((closureN) obj)->num_elements; hp->num_elements = ((closureN) obj)->num_elements;
hp->elements = (object *) (((char *)hp) + sizeof(closureN_type)); hp->elements = (object *) (((char *)hp) + sizeof(closureN_type));
memcpy(hp->elements, ((closureN)obj)->elements, sizeof(object *) * hp->num_elements); memcpy(hp->elements, ((closureN) obj)->elements,
sizeof(object *) * hp->num_elements);
return (char *)hp; return (char *)hp;
} }
case pair_tag:{ case pair_tag:{
@ -866,7 +876,8 @@ char *gc_copy_obj(object dest, char *obj, gc_thread_data * thd)
type_of(hp) = vector_tag; type_of(hp) = vector_tag;
hp->num_elements = ((vector) obj)->num_elements; hp->num_elements = ((vector) obj)->num_elements;
hp->elements = (object *) (((char *)hp) + sizeof(vector_type)); hp->elements = (object *) (((char *)hp) + sizeof(vector_type));
memcpy(hp->elements, ((vector)obj)->elements, sizeof(object *) * hp->num_elements); memcpy(hp->elements, ((vector) obj)->elements,
sizeof(object *) * hp->num_elements);
return (char *)hp; return (char *)hp;
} }
case bytevector_tag:{ case bytevector_tag:{
@ -893,21 +904,21 @@ char *gc_copy_obj(object dest, char *obj, gc_thread_data * thd)
hp->tok_end = ((port_type *) obj)->tok_end; hp->tok_end = ((port_type *) obj)->tok_end;
hp->tok_buf = ((port_type *) obj)->tok_buf; hp->tok_buf = ((port_type *) obj)->tok_buf;
hp->tok_buf_len = ((port_type *) obj)->tok_buf_len; hp->tok_buf_len = ((port_type *) obj)->tok_buf_len;
hp->mem_buf = ((port_type *)obj)->mem_buf; hp->mem_buf = ((port_type *) obj)->mem_buf;
hp->mem_buf_len = ((port_type *)obj)->mem_buf_len; hp->mem_buf_len = ((port_type *) obj)->mem_buf_len;
hp->str_bv_in_mem_buf = ((port_type *)obj)->str_bv_in_mem_buf; hp->str_bv_in_mem_buf = ((port_type *) obj)->str_bv_in_mem_buf;
hp->str_bv_in_mem_buf_len = ((port_type *)obj)->str_bv_in_mem_buf_len; hp->str_bv_in_mem_buf_len = ((port_type *) obj)->str_bv_in_mem_buf_len;
hp->read_len = ((port_type *)obj)->read_len; hp->read_len = ((port_type *) obj)->read_len;
return (char *)hp; return (char *)hp;
} }
case bignum_tag:{ case bignum_tag:{
bignum_type *hp = dest; bignum_type *hp = dest;
mark(hp) = thd->gc_alloc_color; mark(hp) = thd->gc_alloc_color;
type_of(hp) = bignum_tag; type_of(hp) = bignum_tag;
((bignum_type *)hp)->bn.used = ((bignum_type *)obj)->bn.used; ((bignum_type *) hp)->bn.used = ((bignum_type *) obj)->bn.used;
((bignum_type *)hp)->bn.alloc = ((bignum_type *)obj)->bn.alloc; ((bignum_type *) hp)->bn.alloc = ((bignum_type *) obj)->bn.alloc;
((bignum_type *)hp)->bn.sign = ((bignum_type *)obj)->bn.sign; ((bignum_type *) hp)->bn.sign = ((bignum_type *) obj)->bn.sign;
((bignum_type *)hp)->bn.dp = ((bignum_type *)obj)->bn.dp; ((bignum_type *) hp)->bn.dp = ((bignum_type *) obj)->bn.dp;
return (char *)hp; return (char *)hp;
} }
case cvar_tag:{ case cvar_tag:{
@ -935,7 +946,7 @@ char *gc_copy_obj(object dest, char *obj, gc_thread_data * thd)
atomic_type *hp = dest; atomic_type *hp = dest;
mark(hp) = thd->gc_alloc_color; mark(hp) = thd->gc_alloc_color;
type_of(hp) = atomic_tag; type_of(hp) = atomic_tag;
hp->obj = ((atomic_type *)obj)->obj; // TODO: should access via CK atomic operations, though this may not be needed at all since we alloc directly on heap hp->obj = ((atomic_type *) obj)->obj; // TODO: should access via CK atomic operations, though this may not be needed at all since we alloc directly on heap
return (char *)hp; return (char *)hp;
} }
case macro_tag:{ case macro_tag:{
@ -1010,7 +1021,7 @@ char *gc_copy_obj(object dest, char *obj, gc_thread_data * thd)
* increasing size using the Fibonnaci Sequence until reaching the * increasing size using the Fibonnaci Sequence until reaching the
* max size. * max size.
*/ */
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)
{ {
size_t new_size; size_t new_size;
gc_heap *h_last = h, *h_new; gc_heap *h_last = h, *h_new;
@ -1049,8 +1060,7 @@ gc_heap *gc_grow_heap(gc_heap * h, size_t size, gc_thread_data *thd)
new_size = HEAP_SIZE; new_size = HEAP_SIZE;
} }
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
fprintf(stderr, "Growing heap %d new page size = %zu\n", h->type, fprintf(stderr, "Growing heap %d new page size = %zu\n", h->type, new_size);
new_size);
#endif #endif
} }
h_last = gc_heap_last(h_last); // Ensure we don't unlink any heaps h_last = gc_heap_last(h_last); // Ensure we don't unlink any heaps
@ -1074,8 +1084,7 @@ gc_heap *gc_grow_heap(gc_heap * h, size_t size, gc_thread_data *thd)
* This function will fail if there is no space on the heap for the * This function will fail if there is no space on the heap for the
* requested object. * requested object.
*/ */
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)
{ {
gc_free_list *f1, *f2, *f3; gc_free_list *f1, *f2, *f3;
@ -1093,11 +1102,11 @@ void *gc_try_alloc(gc_heap * h, size_t size, char *obj,
if (h->type != HEAP_HUGE) { if (h->type != HEAP_HUGE) {
// Copy object into heap now to avoid any uninitialized memory issues // Copy object into heap now to avoid any uninitialized memory issues
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
if (size < (32 * NUM_ALLOC_SIZES)) { if (size < (32 * NUM_ALLOC_SIZES)) {
allocated_size_counts[(size / 32) - 1]++; allocated_size_counts[(size / 32) - 1]++;
} }
#endif #endif
gc_copy_obj(f2, obj, thd); gc_copy_obj(f2, obj, thd);
// Done after sweep now instead of with each allocation // Done after sweep now instead of with each allocation
h->free_size -= size; h->free_size -= size;
@ -1115,12 +1124,12 @@ void *gc_try_alloc(gc_heap * h, size_t size, char *obj,
* @param h Heap we are starting from (assume first in the chain) * @param h Heap we are starting from (assume first in the chain)
* @return Count of heaps that have not been swept yet. * @return Count of heaps that have not been swept yet.
*/ */
int gc_num_unswept_heaps(gc_heap *h) int gc_num_unswept_heaps(gc_heap * h)
{ {
int count = 0; int count = 0;
while (h) { while (h) {
if (h->is_unswept == 1 /*|| if (h->is_unswept == 1 /*||
gc_is_heap_empty(h)*/) { gc_is_heap_empty(h) */ ) {
count++; count++;
} }
h = h->next; h = h->next;
@ -1128,7 +1137,8 @@ int gc_num_unswept_heaps(gc_heap *h)
return count; return count;
} }
void gc_start_major_collection(gc_thread_data *thd){ void gc_start_major_collection(gc_thread_data * thd)
{
if (ck_pr_load_int(&gc_stage) == STAGE_RESTING) { if (ck_pr_load_int(&gc_stage) == STAGE_RESTING) {
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
gc_log(stderr, "gc_start_major_collection - initiating collector"); gc_log(stderr, "gc_start_major_collection - initiating collector");
@ -1137,10 +1147,11 @@ void gc_start_major_collection(gc_thread_data *thd){
} }
} }
void *gc_try_alloc_slow(gc_heap *h_passed, gc_heap *h, size_t size, char *obj, gc_thread_data *thd) void *gc_try_alloc_slow(gc_heap * h_passed, gc_heap * h, size_t size, char *obj,
gc_thread_data * thd)
{ {
#ifdef CYC_HIGH_RES_TIMERS #ifdef CYC_HIGH_RES_TIMERS
long long tstamp = hrt_get_current(); long long tstamp = hrt_get_current();
#endif #endif
gc_heap *h_start = h, *h_prev; gc_heap *h_start = h, *h_prev;
void *result = NULL; void *result = NULL;
@ -1168,8 +1179,8 @@ long long tstamp = hrt_get_current();
//} //}
gc_heap *keep = gc_sweep(h, thd); // Clean up garbage objects gc_heap *keep = gc_sweep(h, thd); // Clean up garbage objects
#ifdef CYC_HIGH_RES_TIMERS #ifdef CYC_HIGH_RES_TIMERS
fprintf(stderr, "sweep heap %p \n", h); fprintf(stderr, "sweep heap %p \n", h);
hrt_log_delta("gc sweep", tstamp); hrt_log_delta("gc sweep", tstamp);
#endif #endif
h_passed->num_unswept_children--; h_passed->num_unswept_children--;
if (!keep) { if (!keep) {
@ -1215,7 +1226,8 @@ hrt_log_delta("gc sweep", tstamp);
* This function will fail if there is no space on the heap for the * This function will fail if there is no space on the heap for the
* requested object. * requested object.
*/ */
static void *gc_try_alloc_fixed_size(gc_heap * h, size_t size, char *obj, gc_thread_data * thd) static void *gc_try_alloc_fixed_size(gc_heap * h, size_t size, char *obj,
gc_thread_data * thd)
{ {
void *result; void *result;
@ -1232,11 +1244,11 @@ static void *gc_try_alloc_fixed_size(gc_heap * h, size_t size, char *obj, gc_thr
if (result) { if (result) {
// Copy object into heap now to avoid any uninitialized memory issues // Copy object into heap now to avoid any uninitialized memory issues
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
if (size < (32 * NUM_ALLOC_SIZES)) { if (size < (32 * NUM_ALLOC_SIZES)) {
allocated_size_counts[(size / 32) - 1]++; allocated_size_counts[(size / 32) - 1]++;
} }
#endif #endif
gc_copy_obj(result, obj, thd); gc_copy_obj(result, obj, thd);
h->free_size -= size; h->free_size -= size;
@ -1245,10 +1257,11 @@ static void *gc_try_alloc_fixed_size(gc_heap * h, size_t size, char *obj, gc_thr
return NULL; return NULL;
} }
void *gc_try_alloc_slow_fixed_size(gc_heap *h_passed, gc_heap *h, size_t size, char *obj, gc_thread_data *thd) void *gc_try_alloc_slow_fixed_size(gc_heap * h_passed, gc_heap * h, size_t size,
char *obj, gc_thread_data * thd)
{ {
#ifdef CYC_HIGH_RES_TIMERS #ifdef CYC_HIGH_RES_TIMERS
long long tstamp = hrt_get_current(); long long tstamp = hrt_get_current();
#endif #endif
gc_heap *h_start = h, *h_prev; gc_heap *h_start = h, *h_prev;
void *result = NULL; void *result = NULL;
@ -1272,8 +1285,8 @@ long long tstamp = hrt_get_current();
unsigned int h_size = h->size; unsigned int h_size = h->size;
gc_heap *keep = gc_sweep_fixed_size(h, thd); // Clean up garbage objects gc_heap *keep = gc_sweep_fixed_size(h, thd); // Clean up garbage objects
#ifdef CYC_HIGH_RES_TIMERS #ifdef CYC_HIGH_RES_TIMERS
fprintf(stderr, "sweep fixed size heap %p size %lu \n", h, size); fprintf(stderr, "sweep fixed size heap %p size %lu \n", h, size);
hrt_log_delta("gc sweep fixed size", tstamp); hrt_log_delta("gc sweep fixed size", tstamp);
#endif #endif
h_passed->num_unswept_children--; h_passed->num_unswept_children--;
if (!keep) { if (!keep) {
@ -1313,7 +1326,7 @@ hrt_log_delta("gc sweep fixed size", tstamp);
* @param data The mutator's thread data object * @param data The mutator's thread data object
* @return Pointer to a heap object for the bignum * @return Pointer to a heap object for the bignum
*/ */
void *gc_alloc_bignum(gc_thread_data *data) void *gc_alloc_bignum(gc_thread_data * data)
{ {
int heap_grown, result; int heap_grown, result;
bignum_type *bn; bignum_type *bn;
@ -1322,11 +1335,11 @@ void *gc_alloc_bignum(gc_thread_data *data)
//tmp.hdr.mark = gc_color_red; //tmp.hdr.mark = gc_color_red;
//tmp.hdr.grayed = 0; //tmp.hdr.grayed = 0;
tmp.tag = bignum_tag; tmp.tag = bignum_tag;
bn = gc_alloc(((gc_thread_data *)data)->heap, sizeof(bignum_type), (char *)(&tmp), (gc_thread_data *)data, &heap_grown); bn = gc_alloc(((gc_thread_data *) data)->heap, sizeof(bignum_type),
(char *)(&tmp), (gc_thread_data *) data, &heap_grown);
if ((result = mp_init(&bignum_value(bn))) != MP_OKAY) { if ((result = mp_init(&bignum_value(bn))) != MP_OKAY) {
fprintf(stderr, "Error initializing number %s", fprintf(stderr, "Error initializing number %s", mp_error_to_string(result));
mp_error_to_string(result));
exit(1); exit(1);
} }
return bn; return bn;
@ -1338,13 +1351,13 @@ void *gc_alloc_bignum(gc_thread_data *data)
* @param src The bignum instance to copy to the heap * @param src The bignum instance to copy to the heap
* @return Pointer to the heap object * @return Pointer to the heap object
*/ */
void *gc_alloc_from_bignum(gc_thread_data *data, bignum_type *src) void *gc_alloc_from_bignum(gc_thread_data * data, bignum_type * src)
{ {
int heap_grown; int heap_grown;
return gc_alloc(((gc_thread_data *)data)->heap, sizeof(bignum_type), (char *)(src), (gc_thread_data *)data, &heap_grown); return gc_alloc(((gc_thread_data *) data)->heap, sizeof(bignum_type),
(char *)(src), (gc_thread_data *) data, &heap_grown);
} }
/** /**
* @brief Allocate memory on the heap for an object * @brief Allocate memory on the heap for an object
* @param hrt The root of the heap to allocate from * @param hrt The root of the heap to allocate from
@ -1365,7 +1378,8 @@ void *gc_alloc(gc_heap_root * hrt, size_t size, char *obj, gc_thread_data * thd,
gc_heap *h_passed, *h = NULL; gc_heap *h_passed, *h = NULL;
int heap_type; int heap_type;
void *(*try_alloc)(gc_heap * h, size_t size, char *obj, gc_thread_data * thd); void *(*try_alloc)(gc_heap * h, size_t size, char *obj, gc_thread_data * thd);
void *(*try_alloc_slow)(gc_heap *h_passed, gc_heap *h, size_t size, char *obj, gc_thread_data *thd); void *(*try_alloc_slow)(gc_heap * h_passed, gc_heap * h, size_t size,
char *obj, gc_thread_data * thd);
size = gc_heap_align(size); size = gc_heap_align(size);
if (size <= (32 * (LAST_FIXED_SIZE_HEAP_TYPE + 1))) { if (size <= (32 * (LAST_FIXED_SIZE_HEAP_TYPE + 1))) {
heap_type = (size - 1) / 32; heap_type = (size - 1) / 32;
@ -1399,12 +1413,13 @@ void *gc_alloc(gc_heap_root * hrt, size_t size, char *obj, gc_thread_data * thd,
h->is_full = 1; h->is_full = 1;
result = try_alloc_slow(h_passed, h, size, obj, thd); result = try_alloc_slow(h_passed, h, size, obj, thd);
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "slow alloc of %p\n", result); fprintf(stderr, "slow alloc of %p\n", result);
#endif #endif
if (result) { if (result) {
// Check if we need to start a major collection // Check if we need to start a major collection
if (heap_type != HEAP_HUGE && if (heap_type != HEAP_HUGE &&
(h_passed->num_unswept_children < GC_COLLECT_UNDER_UNSWEPT_HEAP_COUNT)) { (h_passed->num_unswept_children <
GC_COLLECT_UNDER_UNSWEPT_HEAP_COUNT)) {
gc_start_major_collection(thd); gc_start_major_collection(thd);
} }
} else { } else {
@ -1416,7 +1431,7 @@ fprintf(stderr, "slow alloc of %p\n", result);
*heap_grown = 1; *heap_grown = 1;
result = try_alloc_slow(h_passed, last, size, obj, thd); result = try_alloc_slow(h_passed, last, size, obj, thd);
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "slowest alloc of %p\n", result); fprintf(stderr, "slowest alloc of %p\n", result);
#endif #endif
if (result) { if (result) {
// We had to allocate memory, start a major collection ASAP! // We had to allocate memory, start a major collection ASAP!
@ -1444,8 +1459,9 @@ fprintf(stderr, "slowest alloc of %p\n", result);
#endif #endif
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "alloc %p size = %zu, obj=%p, tag=%d, mark=%d, thd->alloc=%d, thd->trace=%d\n", result, fprintf(stderr,
size, obj, type_of(obj), mark(((object) result)), "alloc %p size = %zu, obj=%p, tag=%d, mark=%d, thd->alloc=%d, thd->trace=%d\n",
result, size, obj, type_of(obj), mark(((object) result)),
thd->gc_alloc_color, thd->gc_trace_color); thd->gc_alloc_color, thd->gc_trace_color);
// Debug check, should no longer be necessary // Debug check, should no longer be necessary
//if (is_value_type(result)) { //if (is_value_type(result)) {
@ -1566,7 +1582,7 @@ void gc_collector_sweep()
* memory slots to the heap. It is only called by the allocator to free up space * memory slots to the heap. It is only called by the allocator to free up space
* after the heap has been traced to identify live objects. * after the heap has been traced to identify live objects.
*/ */
gc_heap *gc_sweep(gc_heap * h, gc_thread_data *thd) gc_heap *gc_sweep(gc_heap * h, gc_thread_data * thd)
{ {
size_t freed, size; size_t freed, size;
object p, end; object p, end;
@ -1590,7 +1606,7 @@ gc_heap *gc_sweep(gc_heap * h, gc_thread_data *thd)
//for (; h; prev_h = h, h = h->next) // All heaps //for (; h; prev_h = h, h = h->next) // All heaps
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
fprintf(stderr, "sweep heap %p, size = %zu\n", h, (size_t) h->size); fprintf(stderr, "sweep heap %p, size = %zu\n", h, (size_t)h->size);
#endif #endif
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
{ {
@ -1640,14 +1656,12 @@ gc_heap *gc_sweep(gc_heap * h, gc_thread_data *thd)
// - If the collector is currently tracing, objects not traced yet will // - If the collector is currently tracing, objects not traced yet will
// have the trace/clear color. We need to keep any of those to make sure // have the trace/clear color. We need to keep any of those to make sure
// the collector has a chance to trace the entire heap. // the collector has a chance to trace the entire heap.
if (//mark(p) != markColor && if ( //mark(p) != markColor &&
mark(p) != thd->gc_alloc_color && mark(p) != thd->gc_alloc_color && mark(p) != thd->gc_trace_color) { //gc_color_clear)
mark(p) != thd->gc_trace_color) { //gc_color_clear)
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "sweep is freeing unmarked obj: %p with tag %d mark %d - alloc color %d trace color %d\n", p, fprintf(stderr,
type_of(p), "sweep is freeing unmarked obj: %p with tag %d mark %d - alloc color %d trace color %d\n",
mark(p), p, type_of(p), mark(p), thd->gc_alloc_color, thd->gc_trace_color);
thd->gc_alloc_color, thd->gc_trace_color);
#endif #endif
//mark(p) = gc_color_blue; // Needed? //mark(p) = gc_color_blue; // Needed?
if (type_of(p) == mutex_tag) { if (type_of(p) == mutex_tag) {
@ -1672,7 +1686,7 @@ gc_heap *gc_sweep(gc_heap * h, gc_thread_data *thd)
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, "mp_clear from sweep\n"); fprintf(stderr, "mp_clear from sweep\n");
#endif #endif
mp_clear(&(((bignum_type *)p)->bn)); mp_clear(&(((bignum_type *) p)->bn));
} }
// free p // free p
if (((((char *)q) + q->size) == (char *)p) && (q != h->free_list)) { if (((((char *)q) + q->size) == (char *)p) && (q != h->free_list)) {
@ -1841,9 +1855,13 @@ static void mark_stack_or_heap_obj(gc_thread_data * thd, object obj, int locked)
grayed(obj) = 1; grayed(obj) = 1;
} else { } else {
// Value is on the heap, mark gray right now // Value is on the heap, mark gray right now
if (!locked) { pthread_mutex_lock(&(thd->lock)); } if (!locked) {
pthread_mutex_lock(&(thd->lock));
}
gc_mark_gray(thd, obj); gc_mark_gray(thd, obj);
if (!locked) { pthread_mutex_unlock(&(thd->lock)); } if (!locked) {
pthread_mutex_unlock(&(thd->lock));
}
} }
} }
@ -1957,11 +1975,11 @@ void gc_mut_cooperate(gc_thread_data * thd, int buf_len)
#endif #endif
// If we have finished tracing, clear any "full" bits on the heap // If we have finished tracing, clear any "full" bits on the heap
if(ck_pr_cas_8(&(thd->gc_done_tracing), 1, 0)) { if (ck_pr_cas_8(&(thd->gc_done_tracing), 1, 0)) {
int heap_type, unswept; int heap_type, unswept;
gc_heap *h_tmp, *h_head; gc_heap *h_tmp, *h_head;
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stdout, "done tracing, cooperator is clearing full bits\n"); fprintf(stdout, "done tracing, cooperator is clearing full bits\n");
#endif #endif
for (heap_type = 0; heap_type < NUM_HEAP_TYPES; heap_type++) { for (heap_type = 0; heap_type < NUM_HEAP_TYPES; heap_type++) {
h_head = h_tmp = thd->heap->heap[heap_type]; h_head = h_tmp = thd->heap->heap[heap_type];
@ -2010,7 +2028,8 @@ fprintf(stdout, "done tracing, cooperator is clearing full bits\n");
int heap_type, over_gc_collection_threshold = 0; int heap_type, over_gc_collection_threshold = 0;
for (heap_type = 0; heap_type < HEAP_HUGE; heap_type++) { for (heap_type = 0; heap_type < HEAP_HUGE; heap_type++) {
thd->cached_heap_free_sizes[heap_type] = gc_heap_free_size(thd->heap->heap[heap_type]); thd->cached_heap_free_sizes[heap_type] =
gc_heap_free_size(thd->heap->heap[heap_type]);
if (thd->cached_heap_free_sizes[heap_type] < if (thd->cached_heap_free_sizes[heap_type] <
thd->cached_heap_total_sizes[heap_type] * GC_COLLECTION_THRESHOLD) { thd->cached_heap_total_sizes[heap_type] * GC_COLLECTION_THRESHOLD) {
over_gc_collection_threshold = 1; over_gc_collection_threshold = 1;
@ -2020,9 +2039,12 @@ fprintf(stdout, "done tracing, cooperator is clearing full bits\n");
heap_type, heap_type,
thd->cached_heap_free_sizes[heap_type], thd->cached_heap_free_sizes[heap_type],
thd->cached_heap_total_sizes[heap_type]); thd->cached_heap_total_sizes[heap_type]);
if (thd->cached_heap_free_sizes[heap_type] > thd->cached_heap_total_sizes[heap_type]) { if (thd->cached_heap_free_sizes[heap_type] >
fprintf(stderr, "gc_mut_cooperate - Invalid cached heap sizes, free=%zu total=%zu\n", thd->cached_heap_total_sizes[heap_type]) {
thd->cached_heap_free_sizes[heap_type], thd->cached_heap_total_sizes[heap_type]); fprintf(stderr,
"gc_mut_cooperate - Invalid cached heap sizes, free=%zu total=%zu\n",
thd->cached_heap_free_sizes[heap_type],
thd->cached_heap_total_sizes[heap_type]);
exit(1); exit(1);
} }
#endif #endif
@ -2036,11 +2058,11 @@ fprintf(stdout, "done tracing, cooperator is clearing full bits\n");
// Separate huge heap threshold since these are typically allocated as whole pages // Separate huge heap threshold since these are typically allocated as whole pages
(thd->heap_num_huge_allocations > 100) (thd->heap_num_huge_allocations > 100)
)) { )) {
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
fprintf(stderr, fprintf(stderr,
"Less than %f%% of the heap is free, initiating collector\n", "Less than %f%% of the heap is free, initiating collector\n",
100.0 * GC_COLLECTION_THRESHOLD); 100.0 * GC_COLLECTION_THRESHOLD);
#endif #endif
ck_pr_cas_int(&gc_stage, STAGE_RESTING, STAGE_CLEAR_OR_MARKING); ck_pr_cas_int(&gc_stage, STAGE_RESTING, STAGE_CLEAR_OR_MARKING);
} }
} }
@ -2069,8 +2091,7 @@ void gc_mark_gray(gc_thread_data * thd, object obj)
// timing issues when incrementing colors and since if we ever reach a // timing issues when incrementing colors and since if we ever reach a
// purple object during tracing we would want to mark it. // purple object during tracing we would want to mark it.
// TODO: revisit if checking for gc_color_purple is truly necessary here and elsewhere. // TODO: revisit if checking for gc_color_purple is truly necessary here and elsewhere.
if (is_object_type(obj) && (mark(obj) == gc_color_clear || if (is_object_type(obj) && (mark(obj) == gc_color_clear || mark(obj) == gc_color_purple)) { // TODO: sync??
mark(obj) == gc_color_purple)) { // TODO: sync??
// Place marked object in a buffer to avoid repeated scans of the heap. // Place marked object in a buffer to avoid repeated scans of the heap.
// TODO: // TODO:
// Note that ideally this should be a lock-free data structure to make the // Note that ideally this should be a lock-free data structure to make the
@ -2096,7 +2117,8 @@ void gc_mark_gray2(gc_thread_data * thd, object obj)
{ {
if (is_object_type(obj) && (mark(obj) == gc_color_clear || if (is_object_type(obj) && (mark(obj) == gc_color_clear ||
mark(obj) == gc_color_purple)) { mark(obj) == gc_color_purple)) {
mark_buffer_set(thd->mark_buffer, thd->last_write + thd->pending_writes, obj); mark_buffer_set(thd->mark_buffer, thd->last_write + thd->pending_writes,
obj);
thd->pending_writes++; thd->pending_writes++;
} }
} }
@ -2119,8 +2141,9 @@ static void gc_collector_mark_gray(object parent, object obj)
fprintf(stderr, "mark gray parent = %p (%d) obj = %p\n", parent, fprintf(stderr, "mark gray parent = %p (%d) obj = %p\n", parent,
type_of(parent), obj); type_of(parent), obj);
} else if (is_object_type(obj)) { } else if (is_object_type(obj)) {
fprintf(stderr, "not marking gray, parent = %p (%d) obj = %p mark(obj) = %d, gc_color_clear = %d\n", parent, fprintf(stderr,
type_of(parent), obj, mark(obj), gc_color_clear); "not marking gray, parent = %p (%d) obj = %p mark(obj) = %d, gc_color_clear = %d\n",
parent, type_of(parent), obj, mark(obj), gc_color_clear);
} }
} }
#else #else
@ -2175,8 +2198,8 @@ void gc_mark_black(object obj)
} }
break; break;
} }
case atomic_tag: { case atomic_tag:{
atomic_type *a = (atomic_type *)obj; atomic_type *a = (atomic_type *) obj;
object o = ck_pr_load_ptr(&(a->obj)); object o = ck_pr_load_ptr(&(a->obj));
if (obj) { if (obj) {
gc_collector_mark_gray(obj, o); gc_collector_mark_gray(obj, o);
@ -2283,7 +2306,8 @@ void gc_collector_trace()
#if GC_DEBUG_VERBOSE #if GC_DEBUG_VERBOSE
fprintf(stderr, fprintf(stderr,
"gc_mark_black mark buffer %p, last_read = %d last_write = %d\n", "gc_mark_black mark buffer %p, last_read = %d last_write = %d\n",
mark_buffer_get(m->mark_buffer, m->last_read), m->last_read, last_write); mark_buffer_get(m->mark_buffer, m->last_read), m->last_read,
last_write);
#endif #endif
gc_mark_black(mark_buffer_get(m->mark_buffer, m->last_read)); gc_mark_black(mark_buffer_get(m->mark_buffer, m->last_read));
gc_empty_collector_stack(); gc_empty_collector_stack();
@ -2403,9 +2427,10 @@ void gc_wait_handshake()
) { ) {
//printf("DEBUG - update mutator GC status\n"); //printf("DEBUG - update mutator GC status\n");
ck_pr_cas_int(&(m->gc_status), statusm, statusc); ck_pr_cas_int(&(m->gc_status), statusm, statusc);
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
fprintf(stderr, "DEBUG - collector is cooperating for blocked mutator\n"); fprintf(stderr,
#endif "DEBUG - collector is cooperating for blocked mutator\n");
#endif
buf_len = buf_len =
gc_minor(m, m->stack_limit, m->stack_start, m->gc_cont, NULL, gc_minor(m, m->stack_limit, m->stack_start, m->gc_cont, NULL,
0); 0);
@ -2551,8 +2576,7 @@ static pthread_t collector_thread;
*/ */
void gc_start_collector() void gc_start_collector()
{ {
if (pthread_create if (pthread_create(&collector_thread, NULL, collector_main, NULL)) {
(&collector_thread, NULL, collector_main, NULL)) {
fprintf(stderr, "Error creating collector thread\n"); fprintf(stderr, "Error creating collector thread\n");
exit(1); exit(1);
} }
@ -2589,7 +2613,6 @@ void gc_mark_globals(object globals, object global_table)
} }
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// END tri-color marking section // END tri-color marking section
///////////////////////////////////////////// /////////////////////////////////////////////
@ -2626,8 +2649,7 @@ void gc_thread_data_init(gc_thread_data * thd, int mut_num, char *stack_base,
thd->mutations = NULL; thd->mutations = NULL;
thd->mutation_buflen = 128; thd->mutation_buflen = 128;
thd->mutation_count = 0; thd->mutation_count = 0;
thd->mutations = thd->mutations = vpbuffer_realloc(thd->mutations, &(thd->mutation_buflen));
vpbuffer_realloc(thd->mutations, &(thd->mutation_buflen));
thd->globals_changed = 1; thd->globals_changed = 1;
thd->param_objs = NULL; thd->param_objs = NULL;
thd->exception_handler_stack = NULL; thd->exception_handler_stack = NULL;
@ -2717,7 +2739,7 @@ void gc_thread_data_free(gc_thread_data * thd)
* *
* This function assumes appropriate locks are already held. * This function assumes appropriate locks are already held.
*/ */
void gc_heap_merge(gc_heap *hdest, gc_heap *hsrc) void gc_heap_merge(gc_heap * hdest, gc_heap * hsrc)
{ {
gc_heap *last = gc_heap_last(hdest); gc_heap *last = gc_heap_last(hdest);
last->next = hsrc; last->next = hsrc;
@ -2730,7 +2752,7 @@ void gc_heap_merge(gc_heap *hdest, gc_heap *hsrc)
* *
* Assumes appropriate locks are already held. * Assumes appropriate locks are already held.
*/ */
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)
{ {
gc_heap *hdest, *hsrc; gc_heap *hdest, *hsrc;
int heap_type; int heap_type;
@ -2783,15 +2805,15 @@ void Cyc_apply_from_buf(void *data, int argc, object prim, object * buf);
* @param obj Object to copy * @param obj Object to copy
* @param thd Thread data object for the applicable mutator * @param thd Thread data object for the applicable mutator
*/ */
void gc_recopy_obj(object obj, gc_thread_data *thd) void gc_recopy_obj(object obj, gc_thread_data * thd)
{ {
// Temporarily change obj type so we can copy it // Temporarily change obj type so we can copy it
object fwd = forward(obj); object fwd = forward(obj);
tag_type tag = type_of(fwd); tag_type tag = type_of(fwd);
type_of(obj) = tag; type_of(obj) = tag;
#if GC_DEBUG_TRACE #if GC_DEBUG_TRACE
fprintf(stderr, "\n!!! Recopying object %p with tag %d !!!\n\n", obj, tag); fprintf(stderr, "\n!!! Recopying object %p with tag %d !!!\n\n", obj, tag);
#endif #endif
gc_copy_obj(fwd, obj, thd); // Copy it again gc_copy_obj(fwd, obj, thd); // Copy it again
type_of(obj) = forward_tag; // Restore forwarding pointer tag on stack obj type_of(obj) = forward_tag; // Restore forwarding pointer tag on stack obj
} }
@ -2808,7 +2830,8 @@ void gc_recopy_obj(object obj, gc_thread_data *thd)
* it was blocking, the mutator will move any remaining stack objects to * it was blocking, the mutator will move any remaining stack objects to
* the heap and longjmp. * the heap and longjmp.
*/ */
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)
{ {
char stack_limit; char stack_limit;
// Transition from blocked back to runnable using CAS. // Transition from blocked back to runnable using CAS.
@ -2849,7 +2872,7 @@ void gc_mutator_thread_runnable(gc_thread_data * thd, object result, object mayb
thd->gc_args[0] = result; thd->gc_args[0] = result;
Cyc_apply_from_buf(thd, 2, thd->gc_cont, thd->gc_args); Cyc_apply_from_buf(thd, 2, thd->gc_cont, thd->gc_args);
} else { } else {
object buf[1] = {result}; object buf[1] = { result };
(((closure) (thd->gc_cont))->fn) (thd, thd->gc_cont, 1, buf); (((closure) (thd->gc_cont))->fn) (thd, thd->gc_cont, 1, buf);
} }
} }

View file

@ -86,7 +86,6 @@ 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;
@ -154,4 +153,3 @@ void hashset_to_array(hashset_t set, void **items)
} }
} }
} }

View file

@ -9,20 +9,20 @@
#include <limits.h> #include <limits.h>
#ifdef LTM_NO_FILE #ifdef LTM_NO_FILE
# warning LTM_NO_FILE has been deprecated, use MP_NO_FILE. #warning LTM_NO_FILE has been deprecated, use MP_NO_FILE.
# define MP_NO_FILE #define MP_NO_FILE
#endif #endif
#ifndef MP_NO_FILE #ifndef MP_NO_FILE
# include <stdio.h> #include <stdio.h>
#endif #endif
#ifdef MP_8BIT #ifdef MP_8BIT
# ifdef _MSC_VER #ifdef _MSC_VER
# pragma message("8-bit (MP_8BIT) support is deprecated and will be dropped completely in the next version.") #pragma message("8-bit (MP_8BIT) support is deprecated and will be dropped completely in the next version.")
# else #else
# warning "8-bit (MP_8BIT) support is deprecated and will be dropped completely in the next version." #warning "8-bit (MP_8BIT) support is deprecated and will be dropped completely in the next version."
# endif #endif
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -31,7 +31,7 @@ extern "C" {
/* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */
#if (defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__)) && !defined(MP_64BIT) #if (defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__)) && !defined(MP_64BIT)
# define MP_32BIT #define MP_32BIT
#endif #endif
/* detect 64-bit mode if possible */ /* detect 64-bit mode if possible */
@ -41,19 +41,19 @@ extern "C" {
defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \ defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \
defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \ defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \
defined(__LP64__) || defined(_LP64) || defined(__64BIT__) defined(__LP64__) || defined(_LP64) || defined(__64BIT__)
# if !(defined(MP_64BIT) || defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) #if !(defined(MP_64BIT) || defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
# if defined(__GNUC__) && !defined(__hppa) #if defined(__GNUC__) && !defined(__hppa)
/* we support 128bit integers only via: __attribute__((mode(TI))) */ /* we support 128bit integers only via: __attribute__((mode(TI))) */
# define MP_64BIT #define MP_64BIT
# else #else
/* otherwise we fall back to MP_32BIT even on 64bit platforms */ /* otherwise we fall back to MP_32BIT even on 64bit platforms */
# define MP_32BIT #define MP_32BIT
# endif #endif
# endif #endif
#endif #endif
#ifdef MP_DIGIT_BIT #ifdef MP_DIGIT_BIT
# error Defining MP_DIGIT_BIT is disallowed, use MP_8/16/31/32/64BIT #error Defining MP_DIGIT_BIT is disallowed, use MP_8/16/31/32/64BIT
#endif #endif
/* some default configurations. /* some default configurations.
@ -66,36 +66,36 @@ extern "C" {
*/ */
#ifdef MP_8BIT #ifdef MP_8BIT
typedef uint8_t mp_digit; typedef uint8_t mp_digit;
typedef uint16_t private_mp_word; typedef uint16_t private_mp_word;
# define MP_DIGIT_BIT 7 #define MP_DIGIT_BIT 7
#elif defined(MP_16BIT) #elif defined(MP_16BIT)
typedef uint16_t mp_digit; typedef uint16_t mp_digit;
typedef uint32_t private_mp_word; typedef uint32_t private_mp_word;
# define MP_DIGIT_BIT 15 #define MP_DIGIT_BIT 15
#elif defined(MP_64BIT) #elif defined(MP_64BIT)
/* for GCC only on supported platforms */ /* for GCC only on supported platforms */
typedef uint64_t mp_digit; typedef uint64_t mp_digit;
#if defined(__GNUC__) #if defined(__GNUC__)
typedef unsigned long private_mp_word __attribute__((mode(TI))); typedef unsigned long private_mp_word __attribute__((mode(TI)));
#endif #endif
# define MP_DIGIT_BIT 60 #define MP_DIGIT_BIT 60
#else #else
typedef uint32_t mp_digit; typedef uint32_t mp_digit;
typedef uint64_t private_mp_word; typedef uint64_t private_mp_word;
# ifdef MP_31BIT #ifdef MP_31BIT
/* /*
* This is an extension that uses 31-bit digits. * This is an extension that uses 31-bit digits.
* Please be aware that not all functions support this size, especially s_mp_mul_digs_fast * Please be aware that not all functions support this size, especially s_mp_mul_digs_fast
* will be reduced to work on small numbers only: * will be reduced to work on small numbers only:
* Up to 8 limbs, 248 bits instead of up to 512 limbs, 15872 bits with MP_28BIT. * Up to 8 limbs, 248 bits instead of up to 512 limbs, 15872 bits with MP_28BIT.
*/ */
# define MP_DIGIT_BIT 31 #define MP_DIGIT_BIT 31
# else #else
/* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
# define MP_DIGIT_BIT 28 #define MP_DIGIT_BIT 28
# define MP_28BIT #define MP_28BIT
# endif #endif
#endif #endif
/* mp_word is a private type */ /* mp_word is a private type */
@ -116,48 +116,48 @@ typedef uint64_t private_mp_word;
#define LTM_PRIME_2MSB_ON (MP_DEPRECATED_PRAGMA("LTM_PRIME_2MSB_ON has been deprecated, use MP_PRIME_2MSB_ON") MP_PRIME_2MSB_ON) #define LTM_PRIME_2MSB_ON (MP_DEPRECATED_PRAGMA("LTM_PRIME_2MSB_ON has been deprecated, use MP_PRIME_2MSB_ON") MP_PRIME_2MSB_ON)
#ifdef MP_USE_ENUMS #ifdef MP_USE_ENUMS
typedef enum { typedef enum {
MP_ZPOS = 0, /* positive */ MP_ZPOS = 0, /* positive */
MP_NEG = 1 /* negative */ MP_NEG = 1 /* negative */
} mp_sign; } mp_sign;
typedef enum { typedef enum {
MP_LT = -1, /* less than */ MP_LT = -1, /* less than */
MP_EQ = 0, /* equal */ MP_EQ = 0, /* equal */
MP_GT = 1 /* greater than */ MP_GT = 1 /* greater than */
} mp_ord; } mp_ord;
typedef enum { typedef enum {
MP_NO = 0, MP_NO = 0,
MP_YES = 1 MP_YES = 1
} mp_bool; } mp_bool;
typedef enum { typedef enum {
MP_OKAY = 0, /* no error */ MP_OKAY = 0, /* no error */
MP_ERR = -1, /* unknown error */ MP_ERR = -1, /* unknown error */
MP_MEM = -2, /* out of mem */ MP_MEM = -2, /* out of mem */
MP_VAL = -3, /* invalid input */ MP_VAL = -3, /* invalid input */
MP_ITER = -4, /* maximum iterations reached */ MP_ITER = -4, /* maximum iterations reached */
MP_BUF = -5 /* buffer overflow, supplied buffer too small */ MP_BUF = -5 /* buffer overflow, supplied buffer too small */
} mp_err; } mp_err;
typedef enum { typedef enum {
MP_LSB_FIRST = -1, MP_LSB_FIRST = -1,
MP_MSB_FIRST = 1 MP_MSB_FIRST = 1
} mp_order; } mp_order;
typedef enum { typedef enum {
MP_LITTLE_ENDIAN = -1, MP_LITTLE_ENDIAN = -1,
MP_NATIVE_ENDIAN = 0, MP_NATIVE_ENDIAN = 0,
MP_BIG_ENDIAN = 1 MP_BIG_ENDIAN = 1
} mp_endian; } mp_endian;
#else #else
typedef int mp_sign; typedef int mp_sign;
#define MP_ZPOS 0 /* positive integer */ #define MP_ZPOS 0 /* positive integer */
#define MP_NEG 1 /* negative */ #define MP_NEG 1 /* negative */
typedef int mp_ord; typedef int mp_ord;
#define MP_LT -1 /* less than */ #define MP_LT -1 /* less than */
#define MP_EQ 0 /* equal to */ #define MP_EQ 0 /* equal to */
#define MP_GT 1 /* greater than */ #define MP_GT 1 /* greater than */
typedef int mp_bool; typedef int mp_bool;
#define MP_YES 1 #define MP_YES 1
#define MP_NO 0 #define MP_NO 0
typedef int mp_err; typedef int mp_err;
#define MP_OKAY 0 /* no error */ #define MP_OKAY 0 /* no error */
#define MP_ERR -1 /* unknown error */ #define MP_ERR -1 /* unknown error */
#define MP_MEM -2 /* out of mem */ #define MP_MEM -2 /* out of mem */
@ -165,10 +165,10 @@ typedef int mp_err;
#define MP_RANGE (MP_DEPRECATED_PRAGMA("MP_RANGE has been deprecated in favor of MP_VAL") MP_VAL) #define MP_RANGE (MP_DEPRECATED_PRAGMA("MP_RANGE has been deprecated in favor of MP_VAL") MP_VAL)
#define MP_ITER -4 /* maximum iterations reached */ #define MP_ITER -4 /* maximum iterations reached */
#define MP_BUF -5 /* buffer overflow, supplied buffer too small */ #define MP_BUF -5 /* buffer overflow, supplied buffer too small */
typedef int mp_order; typedef int mp_order;
#define MP_LSB_FIRST -1 #define MP_LSB_FIRST -1
#define MP_MSB_FIRST 1 #define MP_MSB_FIRST 1
typedef int mp_endian; typedef int mp_endian;
#define MP_LITTLE_ENDIAN -1 #define MP_LITTLE_ENDIAN -1
#define MP_NATIVE_ENDIAN 0 #define MP_NATIVE_ENDIAN 0
#define MP_BIG_ENDIAN 1 #define MP_BIG_ENDIAN 1
@ -177,11 +177,8 @@ typedef int mp_endian;
/* tunable cutoffs */ /* tunable cutoffs */
#ifndef MP_FIXED_CUTOFFS #ifndef MP_FIXED_CUTOFFS
extern int extern int
KARATSUBA_MUL_CUTOFF, KARATSUBA_MUL_CUTOFF, KARATSUBA_SQR_CUTOFF, TOOM_MUL_CUTOFF, TOOM_SQR_CUTOFF;
KARATSUBA_SQR_CUTOFF,
TOOM_MUL_CUTOFF,
TOOM_SQR_CUTOFF;
#endif #endif
/* define this to use lower memory usage routines (exptmods mostly) */ /* define this to use lower memory usage routines (exptmods mostly) */
@ -189,14 +186,14 @@ TOOM_SQR_CUTOFF;
/* default precision */ /* default precision */
#ifndef MP_PREC #ifndef MP_PREC
# ifndef MP_LOW_MEM #ifndef MP_LOW_MEM
# define PRIVATE_MP_PREC 32 /* default digits of precision */ #define PRIVATE_MP_PREC 32 /* default digits of precision */
# elif defined(MP_8BIT) #elif defined(MP_8BIT)
# define PRIVATE_MP_PREC 16 /* default digits of precision */ #define PRIVATE_MP_PREC 16 /* default digits of precision */
# else #else
# define PRIVATE_MP_PREC 8 /* default digits of precision */ #define PRIVATE_MP_PREC 8 /* default digits of precision */
# endif #endif
# define MP_PREC (MP_DEPRECATED_PRAGMA("MP_PREC is an internal macro") PRIVATE_MP_PREC) #define MP_PREC (MP_DEPRECATED_PRAGMA("MP_PREC is an internal macro") PRIVATE_MP_PREC)
#endif #endif
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
@ -204,9 +201,9 @@ TOOM_SQR_CUTOFF;
#define MP_WARRAY (MP_DEPRECATED_PRAGMA("MP_WARRAY is an internal macro") PRIVATE_MP_WARRAY) #define MP_WARRAY (MP_DEPRECATED_PRAGMA("MP_WARRAY is an internal macro") PRIVATE_MP_WARRAY)
#if defined(__GNUC__) && __GNUC__ >= 4 #if defined(__GNUC__) && __GNUC__ >= 4
# define MP_NULL_TERMINATED __attribute__((sentinel)) #define MP_NULL_TERMINATED __attribute__((sentinel))
#else #else
# define MP_NULL_TERMINATED #define MP_NULL_TERMINATED
#endif #endif
/* /*
@ -225,23 +222,23 @@ TOOM_SQR_CUTOFF;
* tommath.h, disabling the warnings. * tommath.h, disabling the warnings.
*/ */
#ifndef MP_WUR #ifndef MP_WUR
# if defined(__GNUC__) && __GNUC__ >= 4 #if defined(__GNUC__) && __GNUC__ >= 4
# define MP_WUR __attribute__((warn_unused_result)) #define MP_WUR __attribute__((warn_unused_result))
# else #else
# define MP_WUR #define MP_WUR
# endif #endif
#endif #endif
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 405) #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 405)
# define MP_DEPRECATED(x) __attribute__((deprecated("replaced by " #x))) #define MP_DEPRECATED(x) __attribute__((deprecated("replaced by " #x)))
# define PRIVATE_MP_DEPRECATED_PRAGMA(s) _Pragma(#s) #define PRIVATE_MP_DEPRECATED_PRAGMA(s) _Pragma(#s)
# define MP_DEPRECATED_PRAGMA(s) PRIVATE_MP_DEPRECATED_PRAGMA(GCC warning s) #define MP_DEPRECATED_PRAGMA(s) PRIVATE_MP_DEPRECATED_PRAGMA(GCC warning s)
#elif defined(_MSC_VER) && _MSC_VER >= 1500 #elif defined(_MSC_VER) && _MSC_VER >= 1500
# define MP_DEPRECATED(x) __declspec(deprecated("replaced by " #x)) #define MP_DEPRECATED(x) __declspec(deprecated("replaced by " #x))
# define MP_DEPRECATED_PRAGMA(s) __pragma(message(s)) #define MP_DEPRECATED_PRAGMA(s) __pragma(message(s))
#else #else
# define MP_DEPRECATED(s) #define MP_DEPRECATED(s)
# define MP_DEPRECATED_PRAGMA(s) #define MP_DEPRECATED_PRAGMA(s)
#endif #endif
#define DIGIT_BIT (MP_DEPRECATED_PRAGMA("DIGIT_BIT macro is deprecated, MP_DIGIT_BIT instead") MP_DIGIT_BIT) #define DIGIT_BIT (MP_DEPRECATED_PRAGMA("DIGIT_BIT macro is deprecated, MP_DIGIT_BIT instead") MP_DIGIT_BIT)
@ -250,193 +247,204 @@ TOOM_SQR_CUTOFF;
#define SIGN(m) (MP_DEPRECATED_PRAGMA("SIGN macro is deprecated, use z->sign instead") (m)->sign) #define SIGN(m) (MP_DEPRECATED_PRAGMA("SIGN macro is deprecated, use z->sign instead") (m)->sign)
/* the infamous mp_int structure */ /* the infamous mp_int structure */
typedef struct { typedef struct {
int used, alloc; int used, alloc;
mp_sign sign; mp_sign sign;
mp_digit *dp; mp_digit *dp;
} mp_int; } mp_int;
/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
typedef int private_mp_prime_callback(unsigned char *dst, int len, void *dat); typedef int private_mp_prime_callback(unsigned char *dst, int len, void *dat);
typedef private_mp_prime_callback MP_DEPRECATED(mp_rand_source) ltm_prime_callback; typedef private_mp_prime_callback MP_DEPRECATED(mp_rand_source)
ltm_prime_callback;
/* error code to char* string */ /* error code to char* string */
const char *mp_error_to_string(mp_err code) MP_WUR; const char *mp_error_to_string(mp_err code) MP_WUR;
/* ---> init and deinit bignum functions <--- */ /* ---> init and deinit bignum functions <--- */
/* init a bignum */ /* init a bignum */
mp_err mp_init(mp_int *a) MP_WUR; mp_err mp_init(mp_int * a) MP_WUR;
/* free a bignum */ /* free a bignum */
void mp_clear(mp_int *a); void mp_clear(mp_int * a);
/* init a null terminated series of arguments */ /* init a null terminated series of arguments */
mp_err mp_init_multi(mp_int *mp, ...) MP_NULL_TERMINATED MP_WUR; mp_err mp_init_multi(mp_int * mp, ...) MP_NULL_TERMINATED MP_WUR;
/* clear a null terminated series of arguments */ /* clear a null terminated series of arguments */
void mp_clear_multi(mp_int *mp, ...) MP_NULL_TERMINATED; void mp_clear_multi(mp_int * mp, ...) MP_NULL_TERMINATED;
/* exchange two ints */ /* exchange two ints */
void mp_exch(mp_int *a, mp_int *b); void mp_exch(mp_int * a, mp_int * b);
/* shrink ram required for a bignum */ /* shrink ram required for a bignum */
mp_err mp_shrink(mp_int *a) MP_WUR; mp_err mp_shrink(mp_int * a) MP_WUR;
/* grow an int to a given size */ /* grow an int to a given size */
mp_err mp_grow(mp_int *a, int size) MP_WUR; mp_err mp_grow(mp_int * a, int size) MP_WUR;
/* init to a given number of digits */ /* init to a given number of digits */
mp_err mp_init_size(mp_int *a, int size) MP_WUR; mp_err mp_init_size(mp_int * a, int size) MP_WUR;
/* ---> Basic Manipulations <--- */ /* ---> Basic Manipulations <--- */
#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
mp_bool mp_iseven(const mp_int *a) MP_WUR; mp_bool mp_iseven(const mp_int * a) MP_WUR;
mp_bool mp_isodd(const mp_int *a) MP_WUR; mp_bool mp_isodd(const mp_int * a) MP_WUR;
#define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO) #define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
/* set to zero */ /* set to zero */
void mp_zero(mp_int *a); void mp_zero(mp_int * a);
/* get and set doubles */ /* get and set doubles */
double mp_get_double(const mp_int *a) MP_WUR; double mp_get_double(const mp_int * a) MP_WUR;
mp_err mp_set_double(mp_int *a, double b) MP_WUR; mp_err mp_set_double(mp_int * a, double b) MP_WUR;
/* get integer, set integer and init with integer (int32_t) */ /* get integer, set integer and init with integer (int32_t) */
int32_t mp_get_i32(const mp_int *a) MP_WUR; int32_t mp_get_i32(const mp_int * a) MP_WUR;
void mp_set_i32(mp_int *a, int32_t b); void mp_set_i32(mp_int * a, int32_t b);
mp_err mp_init_i32(mp_int *a, int32_t b) MP_WUR; mp_err mp_init_i32(mp_int * a, int32_t b) MP_WUR;
/* get integer, set integer and init with integer, behaves like two complement for negative numbers (uint32_t) */ /* get integer, set integer and init with integer, behaves like two complement for negative numbers (uint32_t) */
#define mp_get_u32(a) ((uint32_t)mp_get_i32(a)) #define mp_get_u32(a) ((uint32_t)mp_get_i32(a))
void mp_set_u32(mp_int *a, uint32_t b); void mp_set_u32(mp_int * a, uint32_t b);
mp_err mp_init_u32(mp_int *a, uint32_t b) MP_WUR; mp_err mp_init_u32(mp_int * a, uint32_t b) MP_WUR;
/* get integer, set integer and init with integer (int64_t) */ /* get integer, set integer and init with integer (int64_t) */
int64_t mp_get_i64(const mp_int *a) MP_WUR; int64_t mp_get_i64(const mp_int * a) MP_WUR;
void mp_set_i64(mp_int *a, int64_t b); void mp_set_i64(mp_int * a, int64_t b);
mp_err mp_init_i64(mp_int *a, int64_t b) MP_WUR; mp_err mp_init_i64(mp_int * a, int64_t b) MP_WUR;
/* get integer, set integer and init with integer, behaves like two complement for negative numbers (uint64_t) */ /* get integer, set integer and init with integer, behaves like two complement for negative numbers (uint64_t) */
#define mp_get_u64(a) ((uint64_t)mp_get_i64(a)) #define mp_get_u64(a) ((uint64_t)mp_get_i64(a))
void mp_set_u64(mp_int *a, uint64_t b); void mp_set_u64(mp_int * a, uint64_t b);
mp_err mp_init_u64(mp_int *a, uint64_t b) MP_WUR; mp_err mp_init_u64(mp_int * a, uint64_t b) MP_WUR;
/* get magnitude */ /* get magnitude */
uint32_t mp_get_mag_u32(const mp_int *a) MP_WUR; uint32_t mp_get_mag_u32(const mp_int * a) MP_WUR;
uint64_t mp_get_mag_u64(const mp_int *a) MP_WUR; uint64_t mp_get_mag_u64(const mp_int * a) MP_WUR;
unsigned long mp_get_mag_ul(const mp_int *a) MP_WUR; unsigned long mp_get_mag_ul(const mp_int * a) MP_WUR;
unsigned long long mp_get_mag_ull(const mp_int *a) MP_WUR; unsigned long long mp_get_mag_ull(const mp_int * a) MP_WUR;
/* get integer, set integer (long) */ /* get integer, set integer (long) */
long mp_get_l(const mp_int *a) MP_WUR; long mp_get_l(const mp_int * a) MP_WUR;
void mp_set_l(mp_int *a, long b); void mp_set_l(mp_int * a, long b);
mp_err mp_init_l(mp_int *a, long b) MP_WUR; mp_err mp_init_l(mp_int * a, long b) MP_WUR;
/* get integer, set integer (unsigned long) */ /* get integer, set integer (unsigned long) */
#define mp_get_ul(a) ((unsigned long)mp_get_l(a)) #define mp_get_ul(a) ((unsigned long)mp_get_l(a))
void mp_set_ul(mp_int *a, unsigned long b); void mp_set_ul(mp_int * a, unsigned long b);
mp_err mp_init_ul(mp_int *a, unsigned long b) MP_WUR; mp_err mp_init_ul(mp_int * a, unsigned long b) MP_WUR;
/* get integer, set integer (long long) */ /* get integer, set integer (long long) */
long long mp_get_ll(const mp_int *a) MP_WUR; long long mp_get_ll(const mp_int * a) MP_WUR;
void mp_set_ll(mp_int *a, long long b); void mp_set_ll(mp_int * a, long long b);
mp_err mp_init_ll(mp_int *a, long long b) MP_WUR; mp_err mp_init_ll(mp_int * a, long long b) MP_WUR;
/* get integer, set integer (unsigned long long) */ /* get integer, set integer (unsigned long long) */
#define mp_get_ull(a) ((unsigned long long)mp_get_ll(a)) #define mp_get_ull(a) ((unsigned long long)mp_get_ll(a))
void mp_set_ull(mp_int *a, unsigned long long b); void mp_set_ull(mp_int * a, unsigned long long b);
mp_err mp_init_ull(mp_int *a, unsigned long long b) MP_WUR; mp_err mp_init_ull(mp_int * a, unsigned long long b) MP_WUR;
/* set to single unsigned digit, up to MP_DIGIT_MAX */ /* set to single unsigned digit, up to MP_DIGIT_MAX */
void mp_set(mp_int *a, mp_digit b); void mp_set(mp_int * a, mp_digit b);
mp_err mp_init_set(mp_int *a, mp_digit b) MP_WUR; mp_err mp_init_set(mp_int * a, mp_digit b) MP_WUR;
/* get integer, set integer and init with integer (deprecated) */ /* get integer, set integer and init with integer (deprecated) */
MP_DEPRECATED(mp_get_mag_u32/mp_get_u32) unsigned long mp_get_int(const mp_int *a) MP_WUR; MP_DEPRECATED(mp_get_mag_u32 /
MP_DEPRECATED(mp_get_mag_ul/mp_get_ul) unsigned long mp_get_long(const mp_int *a) MP_WUR; mp_get_u32) unsigned long mp_get_int(const mp_int * a) MP_WUR;
MP_DEPRECATED(mp_get_mag_ull/mp_get_ull) unsigned long long mp_get_long_long(const mp_int *a) MP_WUR; MP_DEPRECATED(mp_get_mag_ul /
MP_DEPRECATED(mp_set_ul) mp_err mp_set_int(mp_int *a, unsigned long b); mp_get_ul) unsigned long mp_get_long(const mp_int * a) MP_WUR;
MP_DEPRECATED(mp_set_ul) mp_err mp_set_long(mp_int *a, unsigned long b); MP_DEPRECATED(mp_get_mag_ull /
MP_DEPRECATED(mp_set_ull) mp_err mp_set_long_long(mp_int *a, unsigned long long b); mp_get_ull) unsigned long long mp_get_long_long(const mp_int *
MP_DEPRECATED(mp_init_ul) mp_err mp_init_set_int(mp_int *a, unsigned long b) MP_WUR; a) MP_WUR;
MP_DEPRECATED(mp_set_ul) mp_err mp_set_int(mp_int * a, unsigned long b);
MP_DEPRECATED(mp_set_ul) mp_err mp_set_long(mp_int * a, unsigned long b);
MP_DEPRECATED(mp_set_ull) mp_err mp_set_long_long(mp_int * a,
unsigned long long b);
MP_DEPRECATED(mp_init_ul) mp_err mp_init_set_int(mp_int * a,
unsigned long b) MP_WUR;
/* copy, b = a */ /* copy, b = a */
mp_err mp_copy(const mp_int *a, mp_int *b) MP_WUR; mp_err mp_copy(const mp_int * a, mp_int * b) MP_WUR;
/* inits and copies, a = b */ /* inits and copies, a = b */
mp_err mp_init_copy(mp_int *a, const mp_int *b) MP_WUR; mp_err mp_init_copy(mp_int * a, const mp_int * b) MP_WUR;
/* trim unused digits */ /* trim unused digits */
void mp_clamp(mp_int *a); void mp_clamp(mp_int * a);
/* export binary data */ /* export binary data */
MP_DEPRECATED(mp_pack) mp_err mp_export(void *rop, size_t *countp, int order, size_t size, MP_DEPRECATED(mp_pack) mp_err mp_export(void *rop, size_t *countp, int order,
int endian, size_t nails, const mp_int *op) MP_WUR; size_t size, int endian,
size_t nails,
const mp_int * op) MP_WUR;
/* import binary data */ /* import binary data */
MP_DEPRECATED(mp_unpack) mp_err mp_import(mp_int *rop, size_t count, int order, MP_DEPRECATED(mp_unpack) mp_err mp_import(mp_int * rop, size_t count,
size_t size, int endian, size_t nails, int order, size_t size, int endian,
size_t nails,
const void *op) MP_WUR; const void *op) MP_WUR;
/* unpack binary data */ /* unpack binary data */
mp_err mp_unpack(mp_int *rop, size_t count, mp_order order, size_t size, mp_endian endian, mp_err mp_unpack(mp_int * rop, size_t count, mp_order order, size_t size,
size_t nails, const void *op) MP_WUR; mp_endian endian, size_t nails, const void *op) MP_WUR;
/* pack binary data */ /* pack binary data */
size_t mp_pack_count(const mp_int *a, size_t nails, size_t size) MP_WUR; size_t mp_pack_count(const mp_int * a, size_t nails, size_t size) MP_WUR;
mp_err mp_pack(void *rop, size_t maxcount, size_t *written, mp_order order, size_t size, mp_err mp_pack(void *rop, size_t maxcount, size_t *written, mp_order order,
mp_endian endian, size_t nails, const mp_int *op) MP_WUR; size_t size, mp_endian endian, size_t nails,
const mp_int * op) MP_WUR;
/* ---> digit manipulation <--- */ /* ---> digit manipulation <--- */
/* right shift by "b" digits */ /* right shift by "b" digits */
void mp_rshd(mp_int *a, int b); void mp_rshd(mp_int * a, int b);
/* left shift by "b" digits */ /* left shift by "b" digits */
mp_err mp_lshd(mp_int *a, int b) MP_WUR; mp_err mp_lshd(mp_int * a, int b) MP_WUR;
/* c = a / 2**b, implemented as c = a >> b */ /* c = a / 2**b, implemented as c = a >> b */
mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) MP_WUR; mp_err mp_div_2d(const mp_int * a, int b, mp_int * c, mp_int * d) MP_WUR;
/* b = a/2 */ /* b = a/2 */
mp_err mp_div_2(const mp_int *a, mp_int *b) MP_WUR; mp_err mp_div_2(const mp_int * a, mp_int * b) MP_WUR;
/* a/3 => 3c + d == a */ /* a/3 => 3c + d == a */
mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) MP_WUR; mp_err mp_div_3(const mp_int * a, mp_int * c, mp_digit * d) MP_WUR;
/* c = a * 2**b, implemented as c = a << b */ /* c = a * 2**b, implemented as c = a << b */
mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) MP_WUR; mp_err mp_mul_2d(const mp_int * a, int b, mp_int * c) MP_WUR;
/* b = a*2 */ /* b = a*2 */
mp_err mp_mul_2(const mp_int *a, mp_int *b) MP_WUR; mp_err mp_mul_2(const mp_int * a, mp_int * b) MP_WUR;
/* c = a mod 2**b */ /* c = a mod 2**b */
mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c) MP_WUR; mp_err mp_mod_2d(const mp_int * a, int b, mp_int * c) MP_WUR;
/* computes a = 2**b */ /* computes a = 2**b */
mp_err mp_2expt(mp_int *a, int b) MP_WUR; mp_err mp_2expt(mp_int * a, int b) MP_WUR;
/* Counts the number of lsbs which are zero before the first zero bit */ /* Counts the number of lsbs which are zero before the first zero bit */
int mp_cnt_lsb(const mp_int *a) MP_WUR; int mp_cnt_lsb(const mp_int * a) MP_WUR;
/* I Love Earth! */ /* I Love Earth! */
/* makes a pseudo-random mp_int of a given size */ /* makes a pseudo-random mp_int of a given size */
mp_err mp_rand(mp_int *a, int digits) MP_WUR; mp_err mp_rand(mp_int * a, int digits) MP_WUR;
/* makes a pseudo-random small int of a given size */ /* makes a pseudo-random small int of a given size */
MP_DEPRECATED(mp_rand) mp_err mp_rand_digit(mp_digit *r) MP_WUR; MP_DEPRECATED(mp_rand) mp_err mp_rand_digit(mp_digit * r) MP_WUR;
/* use custom random data source instead of source provided the platform */ /* use custom random data source instead of source provided the platform */
void mp_rand_source(mp_err(*source)(void *out, size_t size)); void mp_rand_source(mp_err(*source) (void *out, size_t size));
#ifdef MP_PRNG_ENABLE_LTM_RNG #ifdef MP_PRNG_ENABLE_LTM_RNG
# warning MP_PRNG_ENABLE_LTM_RNG has been deprecated, use mp_rand_source instead. #warning MP_PRNG_ENABLE_LTM_RNG has been deprecated, use mp_rand_source instead.
/* A last resort to provide random data on systems without any of the other /* A last resort to provide random data on systems without any of the other
* implemented ways to gather entropy. * implemented ways to gather entropy.
* It is compatible with `rng_get_bytes()` from libtomcrypt so you could * It is compatible with `rng_get_bytes()` from libtomcrypt so you could
* provide that one and then set `ltm_rng = rng_get_bytes;` */ * provide that one and then set `ltm_rng = rng_get_bytes;` */
extern unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void)); extern unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen,
extern void (*ltm_rng_callback)(void); void(*callback)(void));
extern void (*ltm_rng_callback)(void);
#endif #endif
/* ---> binary operations <--- */ /* ---> binary operations <--- */
@ -445,225 +453,250 @@ extern void (*ltm_rng_callback)(void);
* if the bit is 1, MP_NO if it is 0 and MP_VAL * if the bit is 1, MP_NO if it is 0 and MP_VAL
* in case of error * in case of error
*/ */
MP_DEPRECATED(s_mp_get_bit) int mp_get_bit(const mp_int *a, int b) MP_WUR; MP_DEPRECATED(s_mp_get_bit) int mp_get_bit(const mp_int * a, int b) MP_WUR;
/* c = a XOR b (two complement) */ /* c = a XOR b (two complement) */
MP_DEPRECATED(mp_xor) mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; MP_DEPRECATED(mp_xor) mp_err mp_tc_xor(const mp_int * a, const mp_int * b,
mp_err mp_xor(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_int * c) MP_WUR;
mp_err mp_xor(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* c = a OR b (two complement) */ /* c = a OR b (two complement) */
MP_DEPRECATED(mp_or) mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; MP_DEPRECATED(mp_or) mp_err mp_tc_or(const mp_int * a, const mp_int * b,
mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_int * c) MP_WUR;
mp_err mp_or(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* c = a AND b (two complement) */ /* c = a AND b (two complement) */
MP_DEPRECATED(mp_and) mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; MP_DEPRECATED(mp_and) mp_err mp_tc_and(const mp_int * a, const mp_int * b,
mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_int * c) MP_WUR;
mp_err mp_and(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* b = ~a (bitwise not, two complement) */ /* b = ~a (bitwise not, two complement) */
mp_err mp_complement(const mp_int *a, mp_int *b) MP_WUR; mp_err mp_complement(const mp_int * a, mp_int * b) MP_WUR;
/* right shift with sign extension */ /* right shift with sign extension */
MP_DEPRECATED(mp_signed_rsh) mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c) MP_WUR; MP_DEPRECATED(mp_signed_rsh) mp_err mp_tc_div_2d(const mp_int * a, int b,
mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c) MP_WUR; mp_int * c) MP_WUR;
mp_err mp_signed_rsh(const mp_int * a, int b, mp_int * c) MP_WUR;
/* ---> Basic arithmetic <--- */ /* ---> Basic arithmetic <--- */
/* b = -a */ /* b = -a */
mp_err mp_neg(const mp_int *a, mp_int *b) MP_WUR; mp_err mp_neg(const mp_int * a, mp_int * b) MP_WUR;
/* b = |a| */ /* b = |a| */
mp_err mp_abs(const mp_int *a, mp_int *b) MP_WUR; mp_err mp_abs(const mp_int * a, mp_int * b) MP_WUR;
/* compare a to b */ /* compare a to b */
mp_ord mp_cmp(const mp_int *a, const mp_int *b) MP_WUR; mp_ord mp_cmp(const mp_int * a, const mp_int * b) MP_WUR;
/* compare |a| to |b| */ /* compare |a| to |b| */
mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b) MP_WUR; mp_ord mp_cmp_mag(const mp_int * a, const mp_int * b) MP_WUR;
/* c = a + b */ /* c = a + b */
mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_err mp_add(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* c = a - b */ /* c = a - b */
mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_err mp_sub(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* c = a * b */ /* c = a * b */
mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_err mp_mul(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* b = a*a */ /* b = a*a */
mp_err mp_sqr(const mp_int *a, mp_int *b) MP_WUR; mp_err mp_sqr(const mp_int * a, mp_int * b) MP_WUR;
/* a/b => cb + d == a */ /* a/b => cb + d == a */
mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) MP_WUR; mp_err mp_div(const mp_int * a, const mp_int * b, mp_int * c,
mp_int * d) MP_WUR;
/* c = a mod b, 0 <= c < b */ /* c = a mod b, 0 <= c < b */
mp_err mp_mod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_err mp_mod(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* Increment "a" by one like "a++". Changes input! */ /* Increment "a" by one like "a++". Changes input! */
mp_err mp_incr(mp_int *a) MP_WUR; mp_err mp_incr(mp_int * a) MP_WUR;
/* Decrement "a" by one like "a--". Changes input! */ /* Decrement "a" by one like "a--". Changes input! */
mp_err mp_decr(mp_int *a) MP_WUR; mp_err mp_decr(mp_int * a) MP_WUR;
/* ---> single digit functions <--- */ /* ---> single digit functions <--- */
/* compare against a single digit */ /* compare against a single digit */
mp_ord mp_cmp_d(const mp_int *a, mp_digit b) MP_WUR; mp_ord mp_cmp_d(const mp_int * a, mp_digit b) MP_WUR;
/* c = a + b */ /* c = a + b */
mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; mp_err mp_add_d(const mp_int * a, mp_digit b, mp_int * c) MP_WUR;
/* c = a - b */ /* c = a - b */
mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; mp_err mp_sub_d(const mp_int * a, mp_digit b, mp_int * c) MP_WUR;
/* c = a * b */ /* c = a * b */
mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; mp_err mp_mul_d(const mp_int * a, mp_digit b, mp_int * c) MP_WUR;
/* a/b => cb + d == a */ /* a/b => cb + d == a */
mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) MP_WUR; mp_err mp_div_d(const mp_int * a, mp_digit b, mp_int * c,
mp_digit * d) MP_WUR;
/* c = a mod b, 0 <= c < b */ /* c = a mod b, 0 <= c < b */
mp_err mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c) MP_WUR; mp_err mp_mod_d(const mp_int * a, mp_digit b, mp_digit * c) MP_WUR;
/* ---> number theory <--- */ /* ---> number theory <--- */
/* d = a + b (mod c) */ /* d = a + b (mod c) */
mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; mp_err mp_addmod(const mp_int * a, const mp_int * b, const mp_int * c,
mp_int * d) MP_WUR;
/* d = a - b (mod c) */ /* d = a - b (mod c) */
mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; mp_err mp_submod(const mp_int * a, const mp_int * b, const mp_int * c,
mp_int * d) MP_WUR;
/* d = a * b (mod c) */ /* d = a * b (mod c) */
mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; mp_err mp_mulmod(const mp_int * a, const mp_int * b, const mp_int * c,
mp_int * d) MP_WUR;
/* c = a * a (mod b) */ /* c = a * a (mod b) */
mp_err mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_err mp_sqrmod(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* c = 1/a (mod b) */ /* c = 1/a (mod b) */
mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_err mp_invmod(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* c = (a, b) */ /* c = (a, b) */
mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_err mp_gcd(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* produces value such that U1*a + U2*b = U3 */ /* produces value such that U1*a + U2*b = U3 */
mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) MP_WUR; mp_err mp_exteuclid(const mp_int * a, const mp_int * b, mp_int * U1,
mp_int * U2, mp_int * U3) MP_WUR;
/* c = [a, b] or (a*b)/(a, b) */ /* c = [a, b] or (a*b)/(a, b) */
mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; mp_err mp_lcm(const mp_int * a, const mp_int * b, mp_int * c) MP_WUR;
/* finds one of the b'th root of a, such that |c|**b <= |a| /* finds one of the b'th root of a, such that |c|**b <= |a|
* *
* returns error if a < 0 and b is even * returns error if a < 0 and b is even
*/ */
mp_err mp_root_u32(const mp_int *a, uint32_t b, mp_int *c) MP_WUR; mp_err mp_root_u32(const mp_int * a, uint32_t b, mp_int * c) MP_WUR;
MP_DEPRECATED(mp_root_u32) mp_err mp_n_root(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; MP_DEPRECATED(mp_root_u32) mp_err mp_n_root(const mp_int * a, mp_digit b,
MP_DEPRECATED(mp_root_u32) mp_err mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) MP_WUR; mp_int * c) MP_WUR;
MP_DEPRECATED(mp_root_u32) mp_err mp_n_root_ex(const mp_int * a, mp_digit b,
mp_int * c, int fast) MP_WUR;
/* special sqrt algo */ /* special sqrt algo */
mp_err mp_sqrt(const mp_int *arg, mp_int *ret) MP_WUR; mp_err mp_sqrt(const mp_int * arg, mp_int * ret) MP_WUR;
/* special sqrt (mod prime) */ /* special sqrt (mod prime) */
mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) MP_WUR; mp_err mp_sqrtmod_prime(const mp_int * n, const mp_int * prime,
mp_int * ret) MP_WUR;
/* is number a square? */ /* is number a square? */
mp_err mp_is_square(const mp_int *arg, mp_bool *ret) MP_WUR; mp_err mp_is_square(const mp_int * arg, mp_bool * ret) MP_WUR;
/* computes the jacobi c = (a | n) (or Legendre if b is prime) */ /* computes the jacobi c = (a | n) (or Legendre if b is prime) */
MP_DEPRECATED(mp_kronecker) mp_err mp_jacobi(const mp_int *a, const mp_int *n, int *c) MP_WUR; MP_DEPRECATED(mp_kronecker) mp_err mp_jacobi(const mp_int * a,
const mp_int * n,
int *c) MP_WUR;
/* computes the Kronecker symbol c = (a | p) (like jacobi() but with {a,p} in Z */ /* computes the Kronecker symbol c = (a | p) (like jacobi() but with {a,p} in Z */
mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) MP_WUR; mp_err mp_kronecker(const mp_int * a, const mp_int * p, int *c) MP_WUR;
/* used to setup the Barrett reduction for a given modulus b */ /* used to setup the Barrett reduction for a given modulus b */
mp_err mp_reduce_setup(mp_int *a, const mp_int *b) MP_WUR; mp_err mp_reduce_setup(mp_int * a, const mp_int * b) MP_WUR;
/* Barrett Reduction, computes a (mod b) with a precomputed value c /* Barrett Reduction, computes a (mod b) with a precomputed value c
* *
* Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely * Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely
* compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code]. * compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code].
*/ */
mp_err mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) MP_WUR; mp_err mp_reduce(mp_int * x, const mp_int * m, const mp_int * mu) MP_WUR;
/* setups the montgomery reduction */ /* setups the montgomery reduction */
mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho) MP_WUR; mp_err mp_montgomery_setup(const mp_int * n, mp_digit * rho) MP_WUR;
/* computes a = B**n mod b without division or multiplication useful for /* computes a = B**n mod b without division or multiplication useful for
* normalizing numbers in a Montgomery system. * normalizing numbers in a Montgomery system.
*/ */
mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) MP_WUR; mp_err mp_montgomery_calc_normalization(mp_int * a, const mp_int * b) MP_WUR;
/* computes x/R == x (mod N) via Montgomery Reduction */ /* computes x/R == x (mod N) via Montgomery Reduction */
mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) MP_WUR; mp_err mp_montgomery_reduce(mp_int * x, const mp_int * n,
mp_digit rho) MP_WUR;
/* returns 1 if a is a valid DR modulus */ /* returns 1 if a is a valid DR modulus */
mp_bool mp_dr_is_modulus(const mp_int *a) MP_WUR; mp_bool mp_dr_is_modulus(const mp_int * a) MP_WUR;
/* sets the value of "d" required for mp_dr_reduce */ /* sets the value of "d" required for mp_dr_reduce */
void mp_dr_setup(const mp_int *a, mp_digit *d); void mp_dr_setup(const mp_int * a, mp_digit * d);
/* reduces a modulo n using the Diminished Radix method */ /* reduces a modulo n using the Diminished Radix method */
mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k) MP_WUR; mp_err mp_dr_reduce(mp_int * x, const mp_int * n, mp_digit k) MP_WUR;
/* returns true if a can be reduced with mp_reduce_2k */ /* returns true if a can be reduced with mp_reduce_2k */
mp_bool mp_reduce_is_2k(const mp_int *a) MP_WUR; mp_bool mp_reduce_is_2k(const mp_int * a) MP_WUR;
/* determines k value for 2k reduction */ /* determines k value for 2k reduction */
mp_err mp_reduce_2k_setup(const mp_int *a, mp_digit *d) MP_WUR; mp_err mp_reduce_2k_setup(const mp_int * a, mp_digit * d) MP_WUR;
/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
mp_err mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d) MP_WUR; mp_err mp_reduce_2k(mp_int * a, const mp_int * n, mp_digit d) MP_WUR;
/* returns true if a can be reduced with mp_reduce_2k_l */ /* returns true if a can be reduced with mp_reduce_2k_l */
mp_bool mp_reduce_is_2k_l(const mp_int *a) MP_WUR; mp_bool mp_reduce_is_2k_l(const mp_int * a) MP_WUR;
/* determines k value for 2k reduction */ /* determines k value for 2k reduction */
mp_err mp_reduce_2k_setup_l(const mp_int *a, mp_int *d) MP_WUR; mp_err mp_reduce_2k_setup_l(const mp_int * a, mp_int * d) MP_WUR;
/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
mp_err mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d) MP_WUR; mp_err mp_reduce_2k_l(mp_int * a, const mp_int * n, const mp_int * d) MP_WUR;
/* Y = G**X (mod P) */ /* Y = G**X (mod P) */
mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) MP_WUR; mp_err mp_exptmod(const mp_int * G, const mp_int * X, const mp_int * P,
mp_int * Y) MP_WUR;
/* ---> Primes <--- */ /* ---> Primes <--- */
/* number of primes */ /* number of primes */
#ifdef MP_8BIT #ifdef MP_8BIT
# define PRIVATE_MP_PRIME_TAB_SIZE 31 #define PRIVATE_MP_PRIME_TAB_SIZE 31
#else #else
# define PRIVATE_MP_PRIME_TAB_SIZE 256 #define PRIVATE_MP_PRIME_TAB_SIZE 256
#endif #endif
#define PRIME_SIZE (MP_DEPRECATED_PRAGMA("PRIME_SIZE has been made internal") PRIVATE_MP_PRIME_TAB_SIZE) #define PRIME_SIZE (MP_DEPRECATED_PRAGMA("PRIME_SIZE has been made internal") PRIVATE_MP_PRIME_TAB_SIZE)
/* table of first PRIME_SIZE primes */ /* table of first PRIME_SIZE primes */
MP_DEPRECATED(internal) extern const mp_digit ltm_prime_tab[PRIVATE_MP_PRIME_TAB_SIZE]; MP_DEPRECATED(internal) extern const mp_digit
ltm_prime_tab[PRIVATE_MP_PRIME_TAB_SIZE];
/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ /* result=1 if a is divisible by one of the first PRIME_SIZE primes */
MP_DEPRECATED(mp_prime_is_prime) mp_err mp_prime_is_divisible(const mp_int *a, mp_bool *result) MP_WUR; MP_DEPRECATED(mp_prime_is_prime) mp_err mp_prime_is_divisible(const mp_int *
a,
mp_bool *
result) MP_WUR;
/* performs one Fermat test of "a" using base "b". /* performs one Fermat test of "a" using base "b".
* Sets result to 0 if composite or 1 if probable prime * Sets result to 0 if composite or 1 if probable prime
*/ */
mp_err mp_prime_fermat(const mp_int *a, const mp_int *b, mp_bool *result) MP_WUR; mp_err mp_prime_fermat(const mp_int * a, const mp_int * b,
mp_bool * result) MP_WUR;
/* performs one Miller-Rabin test of "a" using base "b". /* performs one Miller-Rabin test of "a" using base "b".
* Sets result to 0 if composite or 1 if probable prime * Sets result to 0 if composite or 1 if probable prime
*/ */
mp_err mp_prime_miller_rabin(const mp_int *a, const mp_int *b, mp_bool *result) MP_WUR; mp_err mp_prime_miller_rabin(const mp_int * a, const mp_int * b,
mp_bool * result) MP_WUR;
/* This gives [for a given bit size] the number of trials required /* This gives [for a given bit size] the number of trials required
* such that Miller-Rabin gives a prob of failure lower than 2^-96 * such that Miller-Rabin gives a prob of failure lower than 2^-96
*/ */
int mp_prime_rabin_miller_trials(int size) MP_WUR; int mp_prime_rabin_miller_trials(int size) MP_WUR;
/* performs one strong Lucas-Selfridge test of "a". /* performs one strong Lucas-Selfridge test of "a".
* Sets result to 0 if composite or 1 if probable prime * Sets result to 0 if composite or 1 if probable prime
*/ */
mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) MP_WUR; mp_err mp_prime_strong_lucas_selfridge(const mp_int * a,
mp_bool * result) MP_WUR;
/* performs one Frobenius test of "a" as described by Paul Underwood. /* performs one Frobenius test of "a" as described by Paul Underwood.
* Sets result to 0 if composite or 1 if probable prime * Sets result to 0 if composite or 1 if probable prime
*/ */
mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) MP_WUR; mp_err mp_prime_frobenius_underwood(const mp_int * N,
mp_bool * result) MP_WUR;
/* performs t random rounds of Miller-Rabin on "a" additional to /* performs t random rounds of Miller-Rabin on "a" additional to
* bases 2 and 3. Also performs an initial sieve of trial * bases 2 and 3. Also performs an initial sieve of trial
@ -679,14 +712,14 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) MP_WUR;
* *
* Sets result to 1 if probably prime, 0 otherwise * Sets result to 1 if probably prime, 0 otherwise
*/ */
mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) MP_WUR; mp_err mp_prime_is_prime(const mp_int * a, int t, mp_bool * result) MP_WUR;
/* finds the next prime after the number "a" using "t" trials /* finds the next prime after the number "a" using "t" trials
* of Miller-Rabin. * of Miller-Rabin.
* *
* bbs_style = 1 means the prime must be congruent to 3 mod 4 * bbs_style = 1 means the prime must be congruent to 3 mod 4
*/ */
mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) MP_WUR; mp_err mp_prime_next_prime(mp_int * a, int t, int bbs_style) MP_WUR;
/* makes a truly random prime of a given size (bytes), /* makes a truly random prime of a given size (bytes),
* call with bbs = 1 if you want it to be congruent to 3 mod 4 * call with bbs = 1 if you want it to be congruent to 3 mod 4
@ -712,49 +745,70 @@ mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) MP_WUR;
* so it can be NULL * so it can be NULL
* *
*/ */
MP_DEPRECATED(mp_prime_rand) mp_err mp_prime_random_ex(mp_int *a, int t, int size, int flags, MP_DEPRECATED(mp_prime_rand) mp_err mp_prime_random_ex(mp_int * a, int t,
private_mp_prime_callback cb, void *dat) MP_WUR; int size, int flags,
mp_err mp_prime_rand(mp_int *a, int t, int size, int flags) MP_WUR; private_mp_prime_callback
cb, void *dat) MP_WUR;
mp_err mp_prime_rand(mp_int * a, int t, int size, int flags) MP_WUR;
/* Integer logarithm to integer base */ /* Integer logarithm to integer base */
mp_err mp_log_u32(const mp_int *a, uint32_t base, uint32_t *c) MP_WUR; mp_err mp_log_u32(const mp_int * a, uint32_t base, uint32_t * c) MP_WUR;
/* c = a**b */ /* c = a**b */
mp_err mp_expt_u32(const mp_int *a, uint32_t b, mp_int *c) MP_WUR; mp_err mp_expt_u32(const mp_int * a, uint32_t b, mp_int * c) MP_WUR;
MP_DEPRECATED(mp_expt_u32) mp_err mp_expt_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; MP_DEPRECATED(mp_expt_u32) mp_err mp_expt_d(const mp_int * a, mp_digit b,
MP_DEPRECATED(mp_expt_u32) mp_err mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) MP_WUR; mp_int * c) MP_WUR;
MP_DEPRECATED(mp_expt_u32) mp_err mp_expt_d_ex(const mp_int * a, mp_digit b,
mp_int * c, int fast) MP_WUR;
/* ---> radix conversion <--- */ /* ---> radix conversion <--- */
int mp_count_bits(const mp_int *a) MP_WUR; int mp_count_bits(const mp_int * a) MP_WUR;
MP_DEPRECATED(mp_ubin_size) int mp_unsigned_bin_size(const mp_int *
a) MP_WUR;
MP_DEPRECATED(mp_from_ubin) mp_err mp_read_unsigned_bin(mp_int * a,
const unsigned char
*b, int c) MP_WUR;
MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin(const mp_int * a,
unsigned char *b) MP_WUR;
MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin_n(const mp_int * a,
unsigned char *b,
unsigned long *outlen)
MP_WUR;
MP_DEPRECATED(mp_ubin_size) int mp_unsigned_bin_size(const mp_int *a) MP_WUR; MP_DEPRECATED(mp_sbin_size) int mp_signed_bin_size(const mp_int * a) MP_WUR;
MP_DEPRECATED(mp_from_ubin) mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) MP_WUR; MP_DEPRECATED(mp_from_sbin) mp_err mp_read_signed_bin(mp_int * a,
MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin(const mp_int *a, unsigned char *b) MP_WUR; const unsigned char *b,
MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) MP_WUR; int c) MP_WUR;
MP_DEPRECATED(mp_to_sbin) mp_err mp_to_signed_bin(const mp_int * a,
unsigned char *b) MP_WUR;
MP_DEPRECATED(mp_to_sbin) mp_err mp_to_signed_bin_n(const mp_int * a,
unsigned char *b,
unsigned long *outlen)
MP_WUR;
MP_DEPRECATED(mp_sbin_size) int mp_signed_bin_size(const mp_int *a) MP_WUR; size_t mp_ubin_size(const mp_int * a) MP_WUR;
MP_DEPRECATED(mp_from_sbin) mp_err mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) MP_WUR; mp_err mp_from_ubin(mp_int * a, const unsigned char *buf, size_t size) MP_WUR;
MP_DEPRECATED(mp_to_sbin) mp_err mp_to_signed_bin(const mp_int *a, unsigned char *b) MP_WUR; mp_err mp_to_ubin(const mp_int * a, unsigned char *buf, size_t maxlen,
MP_DEPRECATED(mp_to_sbin) mp_err mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) MP_WUR; size_t *written) MP_WUR;
size_t mp_ubin_size(const mp_int *a) MP_WUR; size_t mp_sbin_size(const mp_int * a) MP_WUR;
mp_err mp_from_ubin(mp_int *a, const unsigned char *buf, size_t size) MP_WUR; mp_err mp_from_sbin(mp_int * a, const unsigned char *buf, size_t size) MP_WUR;
mp_err mp_to_ubin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written) MP_WUR; mp_err mp_to_sbin(const mp_int * a, unsigned char *buf, size_t maxlen,
size_t *written) MP_WUR;
size_t mp_sbin_size(const mp_int *a) MP_WUR; mp_err mp_read_radix(mp_int * a, const char *str, int radix) MP_WUR;
mp_err mp_from_sbin(mp_int *a, const unsigned char *buf, size_t size) MP_WUR; MP_DEPRECATED(mp_to_radix) mp_err mp_toradix(const mp_int * a, char *str,
mp_err mp_to_sbin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written) MP_WUR; int radix) MP_WUR;
MP_DEPRECATED(mp_to_radix) mp_err mp_toradix_n(const mp_int * a, char *str,
mp_err mp_read_radix(mp_int *a, const char *str, int radix) MP_WUR; int radix, int maxlen) MP_WUR;
MP_DEPRECATED(mp_to_radix) mp_err mp_toradix(const mp_int *a, char *str, int radix) MP_WUR; mp_err mp_to_radix(const mp_int * a, char *str, size_t maxlen,
MP_DEPRECATED(mp_to_radix) mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) MP_WUR; size_t *written, int radix) MP_WUR;
mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, int radix) MP_WUR; mp_err mp_radix_size(const mp_int * a, int radix, int *size) MP_WUR;
mp_err mp_radix_size(const mp_int *a, int radix, int *size) MP_WUR;
#ifndef MP_NO_FILE #ifndef MP_NO_FILE
mp_err mp_fread(mp_int *a, int radix, FILE *stream) MP_WUR; mp_err mp_fread(mp_int * a, int radix, FILE * stream) MP_WUR;
mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR; mp_err mp_fwrite(const mp_int * a, int radix, FILE * stream) MP_WUR;
#endif #endif
#define mp_read_raw(mp, str, len) (MP_DEPRECATED_PRAGMA("replaced by mp_read_signed_bin") mp_read_signed_bin((mp), (str), (len))) #define mp_read_raw(mp, str, len) (MP_DEPRECATED_PRAGMA("replaced by mp_read_signed_bin") mp_read_signed_bin((mp), (str), (len)))
@ -777,5 +831,4 @@ mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View file

@ -71,5 +71,4 @@ extern "C" {
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View file

@ -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)

View file

@ -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,8 +558,10 @@ 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_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_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,
@ -569,13 +571,12 @@ object Cyc_num_op_va_list(void *data, int argc,
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)

View file

@ -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
}; };
/** /**
@ -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);
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_try_alloc_slow(gc_heap *h_passed, gc_heap *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, 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;
/** /**
@ -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.
@ -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 */

View file

@ -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);
} }
} }

1737
runtime.c

File diff suppressed because it is too large Load diff