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)