Added critical regions for native threads
authorstefan <none@none>
Wed, 14 Jan 2004 12:42:52 +0000 (12:42 +0000)
committerstefan <none@none>
Wed, 14 Jan 2004 12:42:52 +0000 (12:42 +0000)
jit/codegen.inc
jit/i386/codegen.c
src/threads/green/threads.c
src/threads/green/threads.h
src/vm/jit/codegen.inc
src/vm/jit/i386/codegen.c
threads/thread.c
threads/thread.h

index 1d7c4aa22d6e5c22662714e57b4c0518c78095c4..77b7afaf62aa5e144b5910a646aeff06accdee8b 100644 (file)
@@ -48,7 +48,7 @@
    memory. All functions writing values into the data area return the offset
    relative the begin of the code area (start of procedure).   
 
-   $Id: codegen.inc 592 2003-11-09 19:46:15Z twisti $
+   $Id: codegen.inc 883 2004-01-14 12:42:52Z stefan $
 
 */
 
 #include <string.h>
 #include "toolbox/memory.h"
 #include "toolbox/loging.h"
+#include "threads/thread.h"
 
 
+/************************* critical sections  *********************************/
+
+struct threadcritnodetemp {
+       struct threadcritnodetemp *next;
+       int mcodebegin, mcodeend;
+};
+
 #define MCODEINITSIZE (1<<15)       /* 32 Kbyte code area initialization size */
 #define DSEGINITSIZE  (1<<12)       /*  4 Kbyte data area initialization size */
 
@@ -78,6 +86,11 @@ static branchref *xnullrefs;        /* list of null check branches            */
 static branchref *xcastrefs;        /* list of cast check branches            */
 static branchref *xdivrefs;         /* list of divide by zero branches        */
 
+static struct threadcritnodetemp *threadcrit;
+                                    /* List of critical code regions          */
+static struct threadcritnodetemp threadcritcurrent;
+static int threadcritcount;         /* Number of critical regions             */
+
 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
 
 void codegen_init();                /* allocates code and data area           */
@@ -103,6 +116,8 @@ static void codegen_addxboundrefs(void *branchptr);
 static void codegen_addxnullrefs(void *branchptr);
 static void codegen_addxcastrefs(void *branchptr);
 static void codegen_addxdivrefs(void *branchptr);
+static void codegen_threadcritstart(int offset);
+static void codegen_threadcritstop(int offset);
 
 void dseg_display(s4 *s4ptr);
 
@@ -131,6 +146,11 @@ void codegen_init()
        xnullrefs = NULL;
        xcastrefs = NULL;
        xdivrefs = NULL;
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       threadcritcurrent.next = NULL;
+       threadcritcount = 0;
+#endif
 }
 
 
@@ -384,13 +404,19 @@ static void codegen_finish(int mcodelen)
        jumpref *jr;
        u1 *epoint;
 
+       int extralen = 0;
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       extralen += sizeof(threadcritnode) * threadcritcount;
+#endif
+
        count_code_len += mcodelen;
        count_data_len += dseglen;
 
        dseglen = ALIGN(dseglen, MAX_ALIGN);
 
        method -> mcodelength = mcodelen + dseglen;
-       method -> mcode = CNEW(u1, mcodelen + dseglen);
+       method -> mcode = CNEW(u1, mcodelen + dseglen + extralen);
 
        memcpy ( method->mcode, dsegtop - dseglen, dseglen);
        memcpy ( method->mcode + dseglen, mcodebase, mcodelen);
@@ -418,6 +444,23 @@ static void codegen_finish(int mcodelen)
                }
        }
 #endif
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       {
+               threadcritnode *n = (threadcritnode*) (method->mcode + mcodelen + dseglen);
+               int i;
+               struct threadcritnodetemp *nt = threadcrit;
+
+               for (i=0; i<threadcritcount; i++)
+               {
+                       n->mcodebegin = method->mcode + nt->mcodebegin;
+                       n->mcodeend = method->mcode + nt->mcodeend;
+                       thread_registercritical(n);
+                       n++;
+                       nt = nt->next;
+               }
+       }
+#endif
 }
 
 
@@ -433,6 +476,21 @@ void dseg_display(s4 *s4ptr)
        printf("  --- begin of data segment: %p\n", s4ptr);
 }
 
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+void codegen_threadcritstart(int offset)
+{
+       threadcritcurrent.mcodebegin = offset;
+}
+
+void codegen_threadcritstop(int offset)
+{
+       threadcritcurrent.next = threadcrit;
+       threadcritcurrent.mcodeend = offset;
+       threadcrit = DNEW(struct threadcritnodetemp);
+       *threadcrit = threadcritcurrent;
+       threadcritcount++;
+}
+#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.
index 167fd3a0229424152463c71397402ae1db6c9c60..5362a0847f10deb5419fd8bf8d444bab24491be6 100644 (file)
@@ -28,7 +28,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.c 862 2004-01-06 23:42:01Z stefan $
+   $Id: codegen.c 883 2004-01-14 12:42:52Z stefan $
 
 */
 
@@ -319,7 +319,6 @@ static int reg_of_var(stackptr v, int tempregnum)
 void catch_NullPointerException(int sig)
 {
        sigset_t nsig;
-       int      instr;
 /*     long     faultaddr; */
 
        void **_p = (void **) &sig;
@@ -4423,9 +4422,15 @@ gen_method: {
                                        i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
                                        i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
                                        i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                                       codegen_threadcritstart(mcodeptr - mcodebase);
+#endif
                                        if (d != REG_ITMP3) {
                                                i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
                                                i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                                               codegen_threadcritstop(mcodeptr - mcodebase);
+#endif
                                                i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
 
                                        } else {
@@ -4433,6 +4438,9 @@ gen_method: {
                                                i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
                                                i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
                                                i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                                               codegen_threadcritstop(mcodeptr - mcodebase);
+#endif
                                        }
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
index 7f1d2cf39fb9f45321ff5d2ddf7f7ffe3140f9b7..5a94efa9a4448bc2f005137bb6dad3fe6278c26b 100644 (file)
 #include "asmpart.h"
 #include "toolbox/loging.h"
 #include "toolbox/memory.h"
+#include "toolbox/avl.h"
 
 #if defined(NATIVE_THREADS)
+
+static struct avl_table *criticaltree;
+
+static int criticalcompare(const void *pa, const void *pb, void *param)
+{
+       const threadcritnode *na = pa;
+       const threadcritnode *nb = pb;
+
+       if (na->mcodebegin < nb->mcodebegin)
+               return -1;
+       if (na->mcodebegin > nb->mcodebegin)
+               return 1;
+       return 0;
+}
+
+static const threadcritnode *findcritical(u1 *mcodeptr)
+{
+    struct avl_node *n = criticaltree->avl_root;
+    const threadcritnode *m = NULL;
+    if (!n)
+        return NULL;
+    for (;;)
+    {
+        const threadcritnode *d = n->avl_data;
+        if (mcodeptr == d->mcodebegin)
+            return d;
+        if (mcodeptr < d->mcodebegin) {
+            if (n->avl_link[0])
+                n = n->avl_link[0];
+            else
+                return m;
+        } else {
+            if (n->avl_link[1]) {
+                m = n->avl_data;
+                n = n->avl_link[1];
+            } else
+                return n->avl_data;
+        }
+    }
+}
+
+void thread_registercritical(threadcritnode *n)
+{
+       avl_insert(criticaltree, n);
+}
+
+static int thread_checkcritical(u1 *mcodeptr)
+{
+       const threadcritnode *n = findcritical(mcodeptr);
+       if (!n)
+               return 0;
+       return (mcodeptr < n->mcodeend);
+}
+
 pthread_mutex_t cast_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t compiler_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
@@ -128,8 +183,13 @@ freeThreadStack (thread *tid)
 void
 initThreads(u1 *stackbottom)
 {
-#if defined(NATIVE_THREADS) && !defined(HAVE___THREAD)
+#if defined(NATIVE_THREADS)
+#if !defined(HAVE___THREAD)
        pthread_key_create(&tkey_threadinfo, NULL);
+#endif
+
+    criticaltree = avl_create(criticalcompare, NULL, NULL);
+
 #endif
 
        thread *the_main_thread;
index 3b9a48d8a45f6461cbb132dfb5af8674652aefad..b7fa974525c458240fe1c8474f95884f268a6070 100644 (file)
@@ -175,10 +175,20 @@ typedef struct {
        java_objectheader *_exceptionptr;
 } nativethread;
 
-#if defined(NATIVE_THREADS) && !defined(HAVE___THREAD)
+#if defined(NATIVE_THREADS)
+
+#if !defined(HAVE___THREAD)
 extern pthread_key_t tkey_threadinfo;
 #endif
 
+typedef struct {
+       u1 *mcodebegin, *mcodeend;
+} threadcritnode;
+
+void thread_registercritical(threadcritnode *);
+
+#endif
+
 #else
 
 #define intsDisable()
index 1d7c4aa22d6e5c22662714e57b4c0518c78095c4..77b7afaf62aa5e144b5910a646aeff06accdee8b 100644 (file)
@@ -48,7 +48,7 @@
    memory. All functions writing values into the data area return the offset
    relative the begin of the code area (start of procedure).   
 
-   $Id: codegen.inc 592 2003-11-09 19:46:15Z twisti $
+   $Id: codegen.inc 883 2004-01-14 12:42:52Z stefan $
 
 */
 
 #include <string.h>
 #include "toolbox/memory.h"
 #include "toolbox/loging.h"
+#include "threads/thread.h"
 
 
+/************************* critical sections  *********************************/
+
+struct threadcritnodetemp {
+       struct threadcritnodetemp *next;
+       int mcodebegin, mcodeend;
+};
+
 #define MCODEINITSIZE (1<<15)       /* 32 Kbyte code area initialization size */
 #define DSEGINITSIZE  (1<<12)       /*  4 Kbyte data area initialization size */
 
@@ -78,6 +86,11 @@ static branchref *xnullrefs;        /* list of null check branches            */
 static branchref *xcastrefs;        /* list of cast check branches            */
 static branchref *xdivrefs;         /* list of divide by zero branches        */
 
+static struct threadcritnodetemp *threadcrit;
+                                    /* List of critical code regions          */
+static struct threadcritnodetemp threadcritcurrent;
+static int threadcritcount;         /* Number of critical regions             */
+
 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
 
 void codegen_init();                /* allocates code and data area           */
@@ -103,6 +116,8 @@ static void codegen_addxboundrefs(void *branchptr);
 static void codegen_addxnullrefs(void *branchptr);
 static void codegen_addxcastrefs(void *branchptr);
 static void codegen_addxdivrefs(void *branchptr);
+static void codegen_threadcritstart(int offset);
+static void codegen_threadcritstop(int offset);
 
 void dseg_display(s4 *s4ptr);
 
@@ -131,6 +146,11 @@ void codegen_init()
        xnullrefs = NULL;
        xcastrefs = NULL;
        xdivrefs = NULL;
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       threadcritcurrent.next = NULL;
+       threadcritcount = 0;
+#endif
 }
 
 
@@ -384,13 +404,19 @@ static void codegen_finish(int mcodelen)
        jumpref *jr;
        u1 *epoint;
 
+       int extralen = 0;
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       extralen += sizeof(threadcritnode) * threadcritcount;
+#endif
+
        count_code_len += mcodelen;
        count_data_len += dseglen;
 
        dseglen = ALIGN(dseglen, MAX_ALIGN);
 
        method -> mcodelength = mcodelen + dseglen;
-       method -> mcode = CNEW(u1, mcodelen + dseglen);
+       method -> mcode = CNEW(u1, mcodelen + dseglen + extralen);
 
        memcpy ( method->mcode, dsegtop - dseglen, dseglen);
        memcpy ( method->mcode + dseglen, mcodebase, mcodelen);
@@ -418,6 +444,23 @@ static void codegen_finish(int mcodelen)
                }
        }
 #endif
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       {
+               threadcritnode *n = (threadcritnode*) (method->mcode + mcodelen + dseglen);
+               int i;
+               struct threadcritnodetemp *nt = threadcrit;
+
+               for (i=0; i<threadcritcount; i++)
+               {
+                       n->mcodebegin = method->mcode + nt->mcodebegin;
+                       n->mcodeend = method->mcode + nt->mcodeend;
+                       thread_registercritical(n);
+                       n++;
+                       nt = nt->next;
+               }
+       }
+#endif
 }
 
 
@@ -433,6 +476,21 @@ void dseg_display(s4 *s4ptr)
        printf("  --- begin of data segment: %p\n", s4ptr);
 }
 
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+void codegen_threadcritstart(int offset)
+{
+       threadcritcurrent.mcodebegin = offset;
+}
+
+void codegen_threadcritstop(int offset)
+{
+       threadcritcurrent.next = threadcrit;
+       threadcritcurrent.mcodeend = offset;
+       threadcrit = DNEW(struct threadcritnodetemp);
+       *threadcrit = threadcritcurrent;
+       threadcritcount++;
+}
+#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.
index 167fd3a0229424152463c71397402ae1db6c9c60..5362a0847f10deb5419fd8bf8d444bab24491be6 100644 (file)
@@ -28,7 +28,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.c 862 2004-01-06 23:42:01Z stefan $
+   $Id: codegen.c 883 2004-01-14 12:42:52Z stefan $
 
 */
 
@@ -319,7 +319,6 @@ static int reg_of_var(stackptr v, int tempregnum)
 void catch_NullPointerException(int sig)
 {
        sigset_t nsig;
-       int      instr;
 /*     long     faultaddr; */
 
        void **_p = (void **) &sig;
@@ -4423,9 +4422,15 @@ gen_method: {
                                        i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
                                        i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
                                        i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                                       codegen_threadcritstart(mcodeptr - mcodebase);
+#endif
                                        if (d != REG_ITMP3) {
                                                i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
                                                i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                                               codegen_threadcritstop(mcodeptr - mcodebase);
+#endif
                                                i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
 
                                        } else {
@@ -4433,6 +4438,9 @@ gen_method: {
                                                i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
                                                i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
                                                i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                                               codegen_threadcritstop(mcodeptr - mcodebase);
+#endif
                                        }
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
index 7f1d2cf39fb9f45321ff5d2ddf7f7ffe3140f9b7..5a94efa9a4448bc2f005137bb6dad3fe6278c26b 100644 (file)
 #include "asmpart.h"
 #include "toolbox/loging.h"
 #include "toolbox/memory.h"
+#include "toolbox/avl.h"
 
 #if defined(NATIVE_THREADS)
+
+static struct avl_table *criticaltree;
+
+static int criticalcompare(const void *pa, const void *pb, void *param)
+{
+       const threadcritnode *na = pa;
+       const threadcritnode *nb = pb;
+
+       if (na->mcodebegin < nb->mcodebegin)
+               return -1;
+       if (na->mcodebegin > nb->mcodebegin)
+               return 1;
+       return 0;
+}
+
+static const threadcritnode *findcritical(u1 *mcodeptr)
+{
+    struct avl_node *n = criticaltree->avl_root;
+    const threadcritnode *m = NULL;
+    if (!n)
+        return NULL;
+    for (;;)
+    {
+        const threadcritnode *d = n->avl_data;
+        if (mcodeptr == d->mcodebegin)
+            return d;
+        if (mcodeptr < d->mcodebegin) {
+            if (n->avl_link[0])
+                n = n->avl_link[0];
+            else
+                return m;
+        } else {
+            if (n->avl_link[1]) {
+                m = n->avl_data;
+                n = n->avl_link[1];
+            } else
+                return n->avl_data;
+        }
+    }
+}
+
+void thread_registercritical(threadcritnode *n)
+{
+       avl_insert(criticaltree, n);
+}
+
+static int thread_checkcritical(u1 *mcodeptr)
+{
+       const threadcritnode *n = findcritical(mcodeptr);
+       if (!n)
+               return 0;
+       return (mcodeptr < n->mcodeend);
+}
+
 pthread_mutex_t cast_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t compiler_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
@@ -128,8 +183,13 @@ freeThreadStack (thread *tid)
 void
 initThreads(u1 *stackbottom)
 {
-#if defined(NATIVE_THREADS) && !defined(HAVE___THREAD)
+#if defined(NATIVE_THREADS)
+#if !defined(HAVE___THREAD)
        pthread_key_create(&tkey_threadinfo, NULL);
+#endif
+
+    criticaltree = avl_create(criticalcompare, NULL, NULL);
+
 #endif
 
        thread *the_main_thread;
index 3b9a48d8a45f6461cbb132dfb5af8674652aefad..b7fa974525c458240fe1c8474f95884f268a6070 100644 (file)
@@ -175,10 +175,20 @@ typedef struct {
        java_objectheader *_exceptionptr;
 } nativethread;
 
-#if defined(NATIVE_THREADS) && !defined(HAVE___THREAD)
+#if defined(NATIVE_THREADS)
+
+#if !defined(HAVE___THREAD)
 extern pthread_key_t tkey_threadinfo;
 #endif
 
+typedef struct {
+       u1 *mcodebegin, *mcodeend;
+} threadcritnode;
+
+void thread_registercritical(threadcritnode *);
+
+#endif
+
 #else
 
 #define intsDisable()