Mercurial > repos > rhope
diff runtime/transaction.c @ 186:ba35ab624ec2
Add support for raw C function output from C backend as well as an option to use Boehm-GC instead of reference counting
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 07 Oct 2011 00:10:02 -0700 |
parents | a68e6828d896 |
children |
line wrap: on
line diff
--- a/runtime/transaction.c Wed Jul 27 21:32:40 2011 -0700 +++ b/runtime/transaction.c Fri Oct 07 00:10:02 2011 -0700 @@ -1,7 +1,11 @@ #include "transaction.h" #include <stdarg.h> #include <string.h> +#ifdef USE_GC +#include <gc/gc.h> +#else #include <stdlib.h> +#endif rh_mutex(trans_lock) @@ -15,23 +19,32 @@ return &(trans->cells[idx]); trans = trans->chain; } - return NULL; + return NULL; } +#ifdef RAW_FUNC +transaction * cur_transaction; +void real_begin_transaction(int numobjs,...) +#else void begin_transaction(context * ct, int numobjs,...) +#endif { mutable_object *obj; transaction *parent; va_list args; int32_t idx,got_global_lock=0; - parent = ct->transaction ? ct->transaction : NULL; + parent = cur_transaction ? cur_transaction : NULL; - ct->transaction = malloc(sizeof(transaction)+((numobjs-1)*sizeof(trans_cell))); - ct->transaction->parent = parent; - ct->transaction->chain = NULL; +#ifdef USE_GC + cur_transaction = GC_malloc(sizeof(transaction)+((numobjs-1)*sizeof(trans_cell))); +#else + cur_transaction = malloc(sizeof(transaction)+((numobjs-1)*sizeof(trans_cell))); +#endif + cur_transaction->parent = parent; + cur_transaction->chain = NULL; rh_mutex_init(ct->lock); - ct->transaction->num_cells = numobjs; + cur_transaction->num_cells = numobjs; va_start(args, numobjs); if (parent) { @@ -39,22 +52,22 @@ for (idx = 0; idx < numobjs; ++idx) { obj = va_arg(args, mutable_object *); - ct->transaction->cells[idx].obj = obj; - ct->transaction->cells[idx].parent = find_obj_cell(parent, obj); - if (ct->transaction->cells[idx].parent) + cur_transaction->cells[idx].obj = obj; + cur_transaction->cells[idx].parent = find_obj_cell(parent, obj); + if (cur_transaction->cells[idx].parent) { - ct->transaction->cells[idx].local_data = ct->transaction->cells[idx].parent->local_data; - ct->transaction->cells[idx].orig_version = ct->transaction->cells[idx].parent->local_version; + cur_transaction->cells[idx].local_data = cur_transaction->cells[idx].parent->local_data; + cur_transaction->cells[idx].orig_version = cur_transaction->cells[idx].parent->local_version; } else { if (!got_global_lock) { rh_lock(trans_lock); got_global_lock = 1; } - ct->transaction->cells[idx].local_data = obj->data; - ct->transaction->cells[idx].orig_version = obj->version; + cur_transaction->cells[idx].local_data = obj->data; + cur_transaction->cells[idx].orig_version = obj->version; } - ct->transaction->cells[idx].local_version = 0; + cur_transaction->cells[idx].local_version = 0; } if (got_global_lock) { @@ -66,16 +79,19 @@ for (idx = 0; idx < numobjs; ++idx) { obj = va_arg(args, mutable_object *); - ct->transaction->cells[idx].obj = obj; - ct->transaction->cells[idx].parent = NULL; - ct->transaction->cells[idx].local_data = add_ref(obj->data); - ct->transaction->cells[idx].orig_version = obj->version; - ct->transaction->cells[idx].local_version = 0; + cur_transaction->cells[idx].obj = obj; + cur_transaction->cells[idx].parent = NULL; + cur_transaction->cells[idx].local_data = add_ref(obj->data); + cur_transaction->cells[idx].orig_version = obj->version; + cur_transaction->cells[idx].local_version = 0; } rh_unlock(trans_lock); } } +#ifdef USE_GC +#define free_trans(trans) +#else void free_trans(transaction * trans) { if (trans) @@ -84,17 +100,22 @@ free(trans); } } +#endif +#ifdef RAW_FUNC +int32_t real_commit_transaction(int32_t readonly) +#else int32_t commit_transaction(context * ct, int32_t readonly) +#endif { transaction *tmp_trans, *current; object * tmp_obj; int32_t idx,numaddparent; - if (ct->transaction->parent) + if (cur_transaction->parent) { - rh_lock(ct->transaction->parent->lock); - current = ct->transaction; + rh_lock(cur_transaction->parent->lock); + current = cur_transaction; while(current) { for (idx = 0; idx < current->num_cells; ++idx) @@ -103,13 +124,13 @@ { if (current->cells[idx].parent->local_version != current->cells[idx].orig_version) { - rh_unlock(ct->transaction->parent->lock); + rh_unlock(cur_transaction->parent->lock); return 0; } } else { - if(find_obj_cell(ct->transaction->parent->chain, current->cells[idx].obj)) + if(find_obj_cell(cur_transaction->parent->chain, current->cells[idx].obj)) { - rh_unlock(ct->transaction->parent->lock); + rh_unlock(cur_transaction->parent->lock); return 0; } else numaddparent++; @@ -119,45 +140,49 @@ } if (numaddparent) { +#ifdef USE_GC + tmp_trans = GC_malloc(sizeof(transaction)+(numaddparent - 1)*sizeof(trans_cell)); +#else tmp_trans = malloc(sizeof(transaction)+(numaddparent - 1)*sizeof(trans_cell)); - tmp_trans->chain = ct->transaction->parent->chain; +#endif + tmp_trans->chain = cur_transaction->parent->chain; tmp_trans->num_cells = 0; - ct->transaction->parent->chain = tmp_trans; + cur_transaction->parent->chain = tmp_trans; } - current = ct->transaction; + current = cur_transaction; while(current) { - for (idx = 0; idx < ct->transaction->num_cells; ++idx) + for (idx = 0; idx < cur_transaction->num_cells; ++idx) { - if (ct->transaction->cells[idx].parent) + if (cur_transaction->cells[idx].parent) { //Only commit a particular object if a change has been made - if (ct->transaction->cells[idx].local_version) + if (cur_transaction->cells[idx].local_version) { - tmp_obj = ct->transaction->cells[idx].parent->local_data; - ct->transaction->cells[idx].parent->local_data = ct->transaction->cells[idx].local_data; + tmp_obj = cur_transaction->cells[idx].parent->local_data; + cur_transaction->cells[idx].parent->local_data = cur_transaction->cells[idx].local_data; release_ref(tmp_obj); - ct->transaction->cells[idx].parent->local_version++; + cur_transaction->cells[idx].parent->local_version++; } else { - release_ref(ct->transaction->cells[idx].local_data); + release_ref(cur_transaction->cells[idx].local_data); } } else { - memcpy(&(tmp_trans->cells[tmp_trans->num_cells++]), &(ct->transaction->cells[idx]), sizeof(trans_cell)); + memcpy(&(tmp_trans->cells[tmp_trans->num_cells++]), &(cur_transaction->cells[idx]), sizeof(trans_cell)); } } current = current->chain; } - rh_unlock(ct->transaction->parent->lock); + rh_unlock(cur_transaction->parent->lock); } else { if(readonly) { - for (idx = 0; idx < ct->transaction->num_cells; ++idx) + for (idx = 0; idx < cur_transaction->num_cells; ++idx) { - release_ref(ct->transaction->cells[idx].local_data); + release_ref(cur_transaction->cells[idx].local_data); } } else { rh_lock(trans_lock); - current = ct->transaction; + current = cur_transaction; while(current) { for (idx = 0; idx < current->num_cells; ++idx) @@ -170,7 +195,7 @@ } current = current->chain; } - current = ct->transaction; + current = cur_transaction; while(current) { for (idx = 0; idx < current->num_cells; ++idx) @@ -191,21 +216,26 @@ rh_unlock(trans_lock); } } - rh_mutex_del(ct->transaction->lock); - tmp_trans = ct->transaction->parent; - free_trans(ct->transaction); - ct->transaction = tmp_trans; + rh_mutex_del(cur_transaction->lock); + tmp_trans = cur_transaction->parent; + free_trans(cur_transaction); + cur_transaction = tmp_trans; return 1; } + +#ifdef RAW_FUNC +void prep_retry() +#else void prep_retry(context * ct) +#endif { transaction * current; int32_t idx,got_global_lock=0; - if (ct->transaction->parent) + if (cur_transaction->parent) { - rh_lock(ct->transaction->parent->lock); - current = ct->transaction; + rh_lock(cur_transaction->parent->lock); + current = cur_transaction; while(current) { for (idx = 0; idx < current->num_cells; ++idx) @@ -213,7 +243,7 @@ release_ref(current->cells[idx].local_data); current->cells[idx].local_version = 0; if (!current->cells[idx].parent) - current->cells[idx].parent = find_obj_cell(ct->transaction->parent, current->cells[idx].obj); + current->cells[idx].parent = find_obj_cell(cur_transaction->parent, current->cells[idx].obj); if (current->cells[idx].parent) { current->cells[idx].local_data = current->cells[idx].parent->local_data; @@ -234,10 +264,10 @@ { rh_unlock(trans_lock); } - rh_unlock(ct->transaction->parent->lock); + rh_unlock(cur_transaction->parent->lock); } else { rh_lock(trans_lock); - current = ct->transaction; + current = cur_transaction; while(current) { for (idx = 0; idx < current->num_cells; ++idx)