]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Implement some of the locking code for the debugging API.
authorRhys Weatherley <rweather@southern-storm.com.au>
Thu, 28 Oct 2004 01:23:08 +0000 (01:23 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Thu, 28 Oct 2004 01:23:08 +0000 (01:23 +0000)
ChangeLog
configure.in
jit/jit-debugger.c
jit/jit-thread.c
jit/jit-thread.h

index b357014105b63030259c4c985f7eec31b8f10396..e148e979a99160150136782655f4c8bdb4762b5f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
 
+2004-10-28  Rhys Weatherley  <rweather@southern-storm.com.au>
+
+       * configure.in, jit/jit-debugger.c, jit/jit-thread.c,
+       jit/jit-thread.h: implement some of the locking code
+       for the debugging API.
+
 2004-10-12  Evin Robertson  <evin@users.sourceforge.net>
 
        * jit/jit-rules-x86.c (output_branch): correct the offset
index ad771397e29423305c9ebe4b77956121535b09b4..bd97aabd611f11f7270f5fad5f2adf1aa8836bec 100644 (file)
@@ -93,6 +93,7 @@ AC_HEADER_STDC
 AC_CHECK_HEADERS(string.h strings.h memory.h stdlib.h stdarg.h varargs.h)
 AC_CHECK_HEADERS(tgmath.h math.h ieeefp.h pthread.h unistd.h sys/types.h)
 AC_CHECK_HEADERS(sys/mman.h fcntl.h dlfcn.h sys/cygwin.h sys/stat.h)
+AC_CHECK_HEADERS(time.h sys/time.h)
 
 dnl A macro that helps detect the size of types in a cross-compile environment.
 AC_DEFUN([AC_COMPILE_CHECK_SIZEOF],
index b677290d1ff9f5bbdcf21c4b52813782e553aac5..45d71c5f1c9e2466d1c0b8781bf26a48f42f2227 100644 (file)
@@ -154,6 +154,7 @@ typedef struct jit_debugger_thread
 {
        struct jit_debugger_thread *next;
        jit_debugger_thread_id_t        id;
+       jit_thread_id_t                         native_id;
        int                                volatile     run_type;
        jit_function_t                          find_func;
        jit_nint                                        last_data1;
@@ -167,6 +168,8 @@ typedef struct jit_debugger_thread
  */
 struct jit_debugger
 {
+       jit_monitor_t                             queue_lock;
+       jit_monitor_t                             run_lock;
        jit_context_t                             context;
        jit_debugger_linked_event_t * volatile events;
        jit_debugger_linked_event_t * volatile last_event;
@@ -175,18 +178,12 @@ struct jit_debugger
 /*
  * Lock the debugger object.
  */
-static void lock_debugger(jit_debugger_t dbg)
-{
-       /* TODO */
-}
+#define        lock_debugger(dbg)              jit_monitor_lock(&((dbg)->run_lock))
 
 /*
  * Unlock the debugger object.
  */
-static void unlock_debugger(jit_debugger_t dbg)
-{
-       /* TODO */
-}
+#define        unlock_debugger(dbg)    jit_monitor_unlock(&((dbg)->run_lock))
 
 /*
  * Suspend the current thread until it is marked as running again.
@@ -194,16 +191,16 @@ static void unlock_debugger(jit_debugger_t dbg)
  */
 static void suspend_thread(jit_debugger_t dbg, jit_debugger_thread_t thread)
 {
-       /* TODO */
+       while(thread->run_type == JIT_RUN_TYPE_STOPPED)
+       {
+               jit_monitor_wait(&(dbg->run_lock), -1);
+       }
 }
 
 /*
  * Wake all threads that are waiting on the debugger's monitor.
  */
-static void wakeup_all(jit_debugger_t dbg)
-{
-       /* TODO */
-}
+#define        wakeup_all(dbg)         jit_monitor_signal_all(&((dbg)->run_lock))
 
 /*
  * Get the information block for the current thread.
@@ -238,6 +235,7 @@ static void add_event(jit_debugger_t dbg, jit_debugger_event_t *_event)
 {
        jit_debugger_linked_event_t *event = (jit_debugger_linked_event_t *)_event;
        event->next = 0;
+       jit_monitor_lock(&(dbg->queue_lock));
        if(dbg->last_event)
        {
                dbg->last_event->next = event;
@@ -247,7 +245,8 @@ static void add_event(jit_debugger_t dbg, jit_debugger_event_t *_event)
                dbg->events = event;
        }
        dbg->last_event = event;
-       wakeup_all(dbg);
+       jit_monitor_signal(&(dbg->queue_lock));
+       jit_monitor_unlock(&(dbg->queue_lock));
 }
 
 /*@
@@ -258,8 +257,7 @@ static void add_event(jit_debugger_t dbg, jit_debugger_event_t *_event)
 @*/
 int jit_debugging_possible(void)
 {
-       /* TODO */
-       return 1;
+       return JIT_THREADS_SUPPORTED;
 }
 
 /*@
@@ -285,6 +283,8 @@ jit_debugger_t jit_debugger_create(jit_context_t context)
                }
                dbg->context = context;
                context->debugger = dbg;
+               jit_monitor_create(&(dbg->queue_lock));
+               jit_monitor_create(&(dbg->run_lock));
                return dbg;
        }
        else
@@ -348,8 +348,11 @@ jit_debugger_t jit_debugger_from_context(jit_context_t context)
 @*/
 jit_debugger_thread_id_t jit_debugger_get_self(jit_debugger_t dbg)
 {
-       /* TODO */
-       return 0;
+       jit_thread_id_t id = jit_thread_self();
+       jit_debugger_thread_id_t thread;
+       thread = jit_debugger_get_thread(dbg, &id);
+       jit_thread_release_self(id);
+       return thread;
 }
 
 /*@
@@ -380,8 +383,20 @@ int jit_debugger_get_native_thread
                (jit_debugger_t dbg, jit_debugger_thread_id_t thread,
                 void *native_thread)
 {
-       /* TODO */
-       return 0;
+       jit_debugger_thread_t th;
+       lock_debugger(dbg);
+       th = get_specific_thread(dbg, thread);
+       if(th)
+       {
+               jit_memcpy(native_thread, &(th->native_id), sizeof(th->native_id));
+               unlock_debugger(dbg);
+               return 1;
+       }
+       else
+       {
+               unlock_debugger(dbg);
+               return 0;
+       }
 }
 
 /*@
@@ -398,7 +413,16 @@ int jit_debugger_get_native_thread
 void jit_debugger_set_breakable
                (jit_debugger_t dbg, const void *native_thread, int flag)
 {
-       /* TODO */
+       jit_debugger_thread_t th;
+       jit_debugger_thread_id_t id;
+       id = jit_debugger_get_thread(dbg, native_thread);
+       lock_debugger(dbg);
+       th = get_specific_thread(dbg, id);
+       if(th)
+       {
+               th->breakable = flag;
+       }
+       unlock_debugger(dbg);
 }
 
 /*@
@@ -479,8 +503,26 @@ void jit_debugger_detach_self(jit_debugger_t dbg)
 int jit_debugger_wait_event
                (jit_debugger_t dbg, jit_debugger_event_t *event, jit_int timeout)
 {
-       /* TODO */
-       return 0;
+       jit_debugger_linked_event_t *levent;
+       jit_monitor_lock(&(dbg->queue_lock));
+       if((levent = dbg->events) == 0)
+       {
+               if(!jit_monitor_wait(&(dbg->queue_lock), timeout))
+               {
+                       jit_monitor_unlock(&(dbg->queue_lock));
+                       return 0;
+               }
+               levent = dbg->events;
+       }
+       *event = levent->event;
+       dbg->events = levent->next;
+       if(!(levent->next))
+       {
+               dbg->last_event = 0;
+       }
+       jit_free(levent);
+       jit_monitor_unlock(&(dbg->queue_lock));
+       return 1;
 }
 
 /*@
index aceb66002b522d98404e66dada480f754d127fa1..a013528d3f3f9c79c6af510d40a2b4f21fef715e 100644 (file)
  */
 
 #include "jit-internal.h"
+#if TIME_WITH_SYS_TIME
+       #include <sys/time.h>
+    #include <time.h>
+#else
+    #if HAVE_SYS_TIME_H
+               #include <sys/time.h>
+    #elif !defined(__palmos__)
+        #include <time.h>
+    #endif
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <errno.h>
 
 #if defined(JIT_THREADS_PTHREAD)
 
@@ -53,6 +67,15 @@ static void init_win32_thread(void)
        control_key = TlsAlloc();
 }
 
+jit_thread_id_t _jit_thread_self(void)
+{
+       HANDLE new_handle;
+       DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+                                       GetCurrentProcess(), &new_handle,
+                                       0, 0, DUPLICATE_SAME_ACCESS);
+       return new_handle;
+}
+
 #else /* No thread package */
 
 /*
@@ -126,3 +149,53 @@ jit_thread_id_t _jit_thread_current_id(void)
        return 1;
 #endif
 }
+
+int _jit_monitor_wait(jit_monitor_t *mon, jit_int timeout)
+{
+#if defined(JIT_THREADS_PTHREAD)
+       if(timeout < 0)
+       {
+               pthread_cond_wait(&(mon->_cond), &(mon->_mutex));
+               return 1;
+       }
+       else
+       {
+               struct timeval tv;
+               struct timespec ts;
+               int result;
+
+               gettimeofday(&tv, 0);
+               ts.tv_sec = tv.tv_sec + (long)(timeout / 1000);
+               ts.tv_nsec = (tv.tv_usec + (long)((timeout % 1000) * 1000)) * 1000L;
+               if(ts.tv_nsec >= 1000000000L)
+               {
+                       ++(ts.tv_sec);
+                       ts.tv_nsec -= 1000000000L;
+               }
+
+               /* Wait until we are signalled or the timeout expires */
+               do
+               {
+                       result = pthread_cond_timedwait(&(mon->_cond), &(mon->_mutex), &ts);
+               }
+               while(result == EINTR);
+               return ((result == 0) ? 1 : 0);
+       }
+#elif defined(JIT_THREADS_WIN32)
+       DWORD result;
+       ++(mon->_waiting);
+       if(timeout >= 0)
+       {
+               result = SignalObjectAndWait(mon->_mutex, mon->_cond,
+                                                                        (DWORD)timeout, FALSE);
+       }
+       else
+       {
+               result = SignalObjectAndWait(mon->_mutex, mon->_cond, INFINITE, FALSE);
+       }
+       WaitForSingleObject(mon->_mutex, INFINITE);
+       return (result == WAIT_OBJECT_0);
+#else
+       return 0;
+#endif
+}
index 3737cd8899cba20f95e8bc98ed038fec870b3ae0..b38da047363304aa0768e1b298feac199796b2e5 100644 (file)
@@ -51,12 +51,19 @@ extern      "C" {
 #if defined(JIT_THREADS_PTHREAD)
 typedef pthread_t jit_thread_id_t;
 #define        jit_thread_id_equal(x,y)        (pthread_equal((x), (y)))
+#define        jit_thread_self()                       (pthread_self())
+#define        jit_thread_release_self(t)      do { ; } while (0)
 #elif defined(JIT_THREADS_WIN32)
 typedef HANDLE jit_thread_id_t;
 #define        jit_thread_id_equal(x,y)        ((x) == (y))
+jit_thread_id_t _jit_thread_self(void);
+#define        jit_thread_self()                       _jit_thread_self()
+#define        jit_thread_release_self(t)      CloseHandle((t))
 #else
 typedef int jit_thread_id_t;
 #define        jit_thread_id_equal(x,y)        ((x) == (y))
+#define        jit_thread_self()                       1
+#define        jit_thread_release_self(t)      do { ; } while (0)
 #endif
 
 /*
@@ -108,6 +115,104 @@ typedef int jit_mutex_t;
 
 #endif
 
+/*
+ * Define the primitive monitor operations.
+ */
+
+#if defined(JIT_THREADS_PTHREAD)
+
+typedef struct
+{
+       pthread_mutex_t _mutex;
+       pthread_cond_t  _cond;
+
+} jit_monitor_t;
+#define        jit_monitor_create(mon) \
+               do { \
+                       pthread_mutex_init(&((mon)->_mutex), 0); \
+                       pthread_cond_init(&((mon)->_cond), 0); \
+               } while (0)
+#define        jit_monitor_destroy(mon)        \
+               do { \
+                       pthread_cond_destroy(&((mon)->_cond)); \
+                       pthread_mutex_destroy(&((mon)->_mutex)); \
+               } while (0)
+#define        jit_monitor_lock(mon)                   \
+               do { \
+                       pthread_mutex_lock(&((mon)->_mutex)); \
+               } while (0)
+#define        jit_monitor_unlock(mon)                 \
+               do { \
+                       pthread_mutex_unlock(&((mon)->_mutex)); \
+               } while (0)
+#define        jit_monitor_signal(mon)                 \
+               do { \
+                       pthread_cond_signal(&((mon)->_cond)); \
+               } while (0)
+#define        jit_monitor_signal_all(mon)             \
+               do { \
+                       pthread_cond_broadcast(&((mon)->_cond)); \
+               } while (0)
+
+#elif defined(JIT_THREADS_WIN32)
+
+typedef struct
+{
+       HANDLE  _mutex;
+       HANDLE  _cond;
+       LONG volatile _waiting;
+} jit_monitor_t;
+#define        jit_monitor_create(mon)                 \
+               do { \
+                       (mon)->_mutex = CreateMutex(NULL, FALSE, NULL); \
+                       (mon)->_cond = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); \
+                       (mon)->_waiting = 0; \
+               } while (0)
+#define        jit_monitor_destroy(mon)                \
+               do { \
+                       CloseHandle((mon)->_cond); \
+                       CloseHandle((mon)->_mutex); \
+               } while (0)
+#define        jit_monitor_lock(mon)                   \
+               do { \
+                       WaitForSingleObject((mon)->_mutex, INFINITE); \
+               } while (0)
+#define        jit_monitor_unlock(mon)                 \
+               do { \
+                       ReleaseMutex((mon)->_mutex); \
+               } while (0)
+#define        jit_monitor_signal(mon)                 \
+               do { \
+                       if((mon)->_waiting > 0) \
+                       { \
+                               --((mon)->_waiting); \
+                               ReleaseSemaphore((mon)->_cond, 1, NULL); \
+                       } \
+               } while (0)
+#define        jit_monitor_signal_all(mon)             \
+               do { \
+                       LONG _count = (mon)->_waiting; \
+                       if(_count > 0) \
+                       { \
+                               (mon)->_waiting = 0; \
+                               ReleaseSemaphore((mon)->_cond, _count, NULL); \
+                       } \
+               } while (0)
+
+#else
+
+typedef int jit_monitor_t;
+#define        jit_monitor_create(mon)                 do { ; } while (0)
+#define        jit_monitor_destroy(mon)                do { ; } while (0)
+#define        jit_monitor_lock(mon)                   do { ; } while (0)
+#define        jit_monitor_unlock(mon)                 do { ; } while (0)
+#define        jit_monitor_signal(mon)                 do { ; } while (0)
+#define        jit_monitor_signal_all(mon)             do { ; } while (0)
+
+#endif
+int _jit_monitor_wait(jit_monitor_t *mon, jit_int timeout);
+#define        jit_monitor_wait(mon,timeout)   _jit_monitor_wait((mon), (timeout))
+
 #ifdef __cplusplus
 };
 #endif