Browse Source

Implement some of the locking code for the debugging API.

cache-refactoring
Rhys Weatherley 20 years ago
parent
commit
7e107abaf2
  1. 6
      ChangeLog
  2. 1
      configure.in
  3. 88
      jit/jit-debugger.c
  4. 73
      jit/jit-thread.c
  5. 105
      jit/jit-thread.h

6
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

1
configure.in

@ -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],

88
jit/jit-debugger.c

@ -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;
}
/*@

73
jit/jit-thread.c

@ -19,6 +19,20 @@
*/
#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
}

105
jit/jit-thread.h

@ -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

Loading…
Cancel
Save