RPA Toolkit
dev
authormstoilov <mstoilov@b0bb84a5-424d-4f98-af44-3ef3f117eb03>
Thu, 15 Jul 2010 07:16:26 +0000 (00:16 -0700)
committermstoilov <mstoilov@b0bb84a5-424d-4f98-af44-3ef3f117eb03>
Thu, 15 Jul 2010 07:16:26 +0000 (00:16 -0700)
git-svn-id: svn+ssh://svn.crossrain.com/svn/rpase/trunk/rtk@130 b0bb84a5-424d-4f98-af44-3ef3f117eb03

arch/linux/x86_64/rtypes.h
rlib/ratomic.h
rlib/rmem.c
rlib/rspinlock.h
tests/build/linux/robject-tests.mk
tests/rlock-test.c

index a74b072..19d9949 100644 (file)
@@ -32,6 +32,8 @@ typedef unsigned int ruint32;
 typedef signed long rint64;
 typedef unsigned long ruint64;
 typedef unsigned long rword;
+typedef unsigned long rsize_t;
+typedef signed long rssize_t;
 typedef unsigned int ratomic;
 
 /*
index c075b89..1567254 100644 (file)
@@ -8,8 +8,8 @@ extern "C" {
 
 rboolean r_atomic_compare_and_exchange(volatile ratomic *ptr, ratomic oldval, ratomic newval);
 ratomic r_atomic_exchange(volatile ratomic *ptr, ratomic val);
-ratomic r_atomic_add(volatile ratomic *ptr, ratomic val);
-ratomic r_atomic_sub(volatile ratomic *ptr, ratomic val);
+void r_atomic_add(volatile ratomic *ptr, ratomic val);
+void r_atomic_sub(volatile ratomic *ptr, ratomic val);
 
 #ifdef __cplusplus
 }
index 1e63f5d..b7c6818 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+#include "rspinlock.h"
 #include "rmem.h"
 
-long int g_allocmem = 0;
-long int g_maxmem = 0;
+static rspinlock g_lock = R_SPINLOCK_INIT;
+static long int g_allocmem = 0;
+static long int g_maxmem = 0;
+
+typedef struct _RMemAllocVTable {
+       rpointer (*malloc)(rsize_t size);
+       void (*free)(rpointer ptr);
+       rpointer (*realloc)(rpointer ptr, rsize_t size);
+} RMemAllocVTable;
+
+
+static rpointer r_std_malloc(rsize_t size)
+{
+       return malloc((size_t)size);
+}
+
+
+static void r_std_free(rpointer ptr)
+{
+       free((void*)ptr);
+}
+
+
+static rpointer r_std_realloc(rpointer ptr, rsize_t size)
+{
+       return realloc((void*)ptr, (size_t)size);
+}
+
+
+static rpointer r_dbg_malloc(rsize_t size)
+{
+       rword *mem = NULL;
+       size += sizeof(rword);
+       mem = (rword*)malloc((size_t)(size));
+       *((rword*)mem) = size;
+       r_spinlock_lock(&g_lock);
+       g_allocmem += size;
+       if (g_maxmem < g_allocmem)
+               g_maxmem = g_allocmem;
+       r_spinlock_unlock(&g_lock);
+       mem += 1;
+       return (void*)mem;
+}
+
+
+static void r_dbg_free(rpointer ptr)
+{
+       rword *mem = (void*)(((rword*)ptr) - 1);
+       rword size;
+       if (!ptr)
+               return;
+       size = *mem;
+       r_spinlock_lock(&g_lock);
+       g_allocmem -= size;
+       r_spinlock_unlock(&g_lock);
+       free((void*)mem);
+}
+
+
+static rpointer r_dbg_realloc(rpointer ptr, rsize_t size)
+{
+       rword *mem = (void*)(((rword*)ptr) - 1);
+       rword csize;
+       if (!ptr)
+               return r_malloc(size);
+       csize = *mem;
+       r_spinlock_lock(&g_lock);
+       g_allocmem -= csize;
+       r_spinlock_unlock(&g_lock);
+       size += sizeof(long);
+       mem = (rword*)realloc((void*)mem, (size_t)(size));
+       *mem = size;
+       r_spinlock_lock(&g_lock);
+       g_allocmem += size;
+       if (g_maxmem < g_allocmem)
+               g_maxmem = g_allocmem;
+       r_spinlock_unlock(&g_lock);
+       mem += 1;
+       return (void*)mem;
+}
+
+
+static RMemAllocVTable g_stdMemAlloc = {
+       r_std_malloc,
+       r_std_free,
+       r_std_realloc,
+};
+
+
+static RMemAllocVTable g_dbgMemAlloc = {
+       r_dbg_malloc,
+       r_dbg_free,
+       r_dbg_realloc,
+};
 
 
 rpointer r_malloc(unsigned long size)
@@ -83,14 +176,3 @@ void *r_memcpy(void *dest, const void *src, unsigned long n)
        return memcpy(dest, src, (size_t)n);
 }
 
-
-rboolean r_atomic_int_compare_and_exchange (volatile rint *atomic, rint oldval, rint newval)
-{
-  rint result;
-
-  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
-            : "=a" (result), "=m" (*atomic)
-            : "r" (newval), "m" (*atomic), "0" (oldval));
-
-  return result == oldval;
-}
index 558d7e9..1aaeb9a 100644 (file)
@@ -8,6 +8,7 @@
 extern "C" {
 #endif
 
+#define R_SPINLOCK_INIT 0
 #define R_SPINLOCK_BUSY 1
 typedef ratomic rspinlock;
 
index b9ccbfb..51b1e4f 100644 (file)
@@ -1,11 +1,12 @@
 ROBJECT_SRCDIR = $(SRCDIR)/robject
+RLIB_SRCDIR = $(SRCDIR)/rlib
 TESTS_SRCDIR = $(SRCDIR)/tests
-INCLUDE = -I$(SRCDIR)/arch/$(OS)/$(ARCHDIR) -I$(ROBJECT_SRCDIR)
-LIBS = -L$(ROBJECT_SRCDIR)/build/$(OS)/$(ARCHDIR)/out -lrobject --static
+INCLUDE = -I$(SRCDIR)/arch/$(OS)/$(ARCHDIR) -I$(ROBJECT_SRCDIR) -I$(RLIB_SRCDIR)
+LIBS =  -L$(ROBJECT_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
+LIBS += -L$(RLIB_SRCDIR)/build/$(OS)/$(ARCHDIR)/out -lrlib -lpthread --static
 
 
 TESTS  = \
-       $(OUTDIR)/robject-ver \
        $(OUTDIR)/rlock-test \
 
 all : $(OUTDIR) $(TESTS)
index b842c0a..d3ca0c7 100644 (file)
@@ -1,8 +1,79 @@
+#include <pthread.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include "rspinlock.h"
 
+#define NUM_THREADS 10
+#define NUM_ITERATIONS 100000
 
-int main(int argc, char *argv[])
-{
+static rspinlock g_lock;
+static ruint32 g_result;
+
+
+void *test_busy_work(void *t) {
+       ruint32 r;
+       ruint32 i;
+       long tid = (long)t;
+
+       printf("Thread %ld starting...\n", tid);
+       for (i = 0; i < NUM_ITERATIONS; i++) {
+               r_spinlock_lock(&g_lock);
+               r = g_result;
+               r = r + 1;
+               g_result = r;
+               r_spinlock_unlock(&g_lock);
+       }
+       printf("Thread %ld done. \n", tid);
+       pthread_exit((void*) t);
+}
+
+
+int main(int argc, char *argv[]) {
+       pthread_t thread[NUM_THREADS];
+       pthread_attr_t attr;
+       int rc;
+       long t;
+       void *status;
+
+       /* Initialize the global varibales */
+       r_spinlock_init(&g_lock);
+       g_result = 0;
+
+       /* Initialize and set thread detached attribute */
+       pthread_attr_init(&attr);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+       for (t = 0; t < NUM_THREADS; t++) {
+               printf("Main: creating thread %ld\n", t);
+               rc = pthread_create(&thread[t], &attr, test_busy_work, (void *) t);
+               if (rc) {
+                       printf("ERROR; return code from pthread_create() is %d\n", rc);
+                       exit(-1);
+               }
+       }
+
+       /* Free attribute and wait for the other threads */
+       pthread_attr_destroy(&attr);
+       for (t = 0; t < NUM_THREADS; t++) {
+               rc = pthread_join(thread[t], &status);
+               if (rc) {
+                       printf("ERROR; return code from pthread_join() is %d\n", rc);
+                       exit(-1);
+               }
+               printf("Main: completed join with thread %ld having a status of %ld\n",
+                               t, (long) status);
+       }
+
+       printf("Main: program completed. Exiting. Expected Result = %d, Actual Result = %d\n",
+                       NUM_ITERATIONS * NUM_THREADS, g_result);
+       if (g_result == NUM_ITERATIONS * NUM_THREADS)
+               printf("Test PASSED\n");
+       else
+               printf("Test FAILED\n");
+       pthread_exit(NULL);
+}
+
+int maine(int argc, char *argv[]) {
        fprintf(stdout, "It works!\n");
        return 0;
 }