[m-dev.] For review: coroutining changes
Thomas Charles Conway
conway at hydra.cs.mu.oz.au
Mon Dec 14 11:19:53 AEDT 1998
On Fri, Dec 11, 1998 at 03:02:52PM EST, Fergus Henderson wrote:
> On 11-Dec-1998, Thomas Charles Conway <conway at hydra.cs.mu.oz.au> wrote:
> > Fergus,
> >
> > I thought I'd posted a reply to your review with the requested changes,
> > but if I did it seems to have landed in the bit bucket. Here it is again.
>
> > +++ mercury_conf.h.in 1998/11/30 04:03:26
> > @@ -90,6 +90,7 @@
> > ** HAVE_GETPAGESIZE we have the getpagesize() system call.
> > ** HAVE_MPROTECT we have the mprotect() system call.
> > ** HAVE_MEMALIGN we have the memalign() function.
> > +** HAVE_SELECT we have the select() function.
> > ** HAVE_STRERROR we have the strerror() function.
> > ** HAVE_SETITIMER we have the setitimer() function.
> > ** HAVE_MEMMOVE we have the memmove() function.
>
> As I said in my comments last time,
> this documentation for HAVE_SELECT is misleading.
> See my comment from last time for further details.
Okay, okay, so I've changed it to MR_CAN_DO_PENDING_IO
>
> > +++ mercury_context.c 1998/11/30 04:20:29
> > +#include "mercury_reg_workarounds.h" /* for `MR_fd* stuff' */
>
> The closing single quote is in the wrong place.
Fixed.
>
> > +void schedule(MR_Context *ctxt);
> > +
> > +/*
> > #define schedule(cptr) \
>
> Why is this definition commented out?
> You should document the reason.
Fixed.
>
> > +++ mercury_misc.c 1998/11/30 03:57:26
> > @@ -523,3 +523,4 @@
> > {
> > HASH_STRING_FUNC_BODY
> > }
> > +
>
> This change should not be part of this diff.
>
> Please review your own diffs before posting them ;)
Fixed.
>
> > --- mercury_misc.h 1998/11/09 10:24:38 1.11
> > +++ mercury_misc.h 1998/11/30 03:57:37
> ...
> > +#include <sys/types.h> /* for fd_set */
>
> This should be #ifdefd.
> <sys/types.h> is not ANSI.
>
> > --- mercury_reg_workarounds.h ---
> ...
> > /*
> > ** mercury_misc.h - MR_fd_zero
> > */
>
> The comment is wrong.
>
Fixed.
> > #if HAVE_SELECT
>
> That should be #ifdef rather than #if.
> (Actually `#if' works, but it may result in compiler warnings.)
Fixed.
Here's the diff again.
--
Thomas Conway <conway at cs.mu.oz.au> )O+
To a killer whale, otters are like hairy popcorn -- Paul Dayton
cvs diff: Diffing .
Index: configure.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/configure.in,v
retrieving revision 1.142
diff -u -r1.142 configure.in
--- configure.in 1998/11/11 07:07:28 1.142
+++ configure.in 1998/12/14 00:09:00
@@ -1147,6 +1147,32 @@
fi
AC_SUBST(IO_HAVE_TEMPNAM)
#-----------------------------------------------------------------------------#
+AC_MSG_CHECKING(to see if we can handle contexts blocking on IO)
+AC_CACHE_VAL(mercury_cv_can_do_pending_io,
+ AC_TRY_RUN([
+ #include <sys/types.h>
+ #include <sys/time.h>
+ int main() {
+ fd_set f;
+ struct timeval zero;
+ int err;
+
+ FD_ZERO(&f);
+ zero.tv_sec = 0;
+ zero.tv_usec = 0;
+ err = select(1, &f, &f, &f, &zero);
+ exit(err != 0);
+ }],
+ [mercury_cv_can_do_pending_io=yes],
+ [mercury_cv_can_do_pending_io=no],
+ [mercury_cv_can_do_pending_io=no])
+)
+AC_MSG_RESULT($mercury_cv_can_do_pending_io)
+if test "$mercury_cv_can_do_pending_io" = yes; then
+ AC_DEFINE(MR_CAN_DO_PENDING_IO)
+fi
+AC_SUBST(MR_CAN_DO_PENDING_IO)
+#-----------------------------------------------------------------------------#
#
# For Irix 5, gcc labels don't work with shared libraries,
# so if we're using gcc labels, we need to use non-shared libraries,
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing bytecode/test
cvs diff: Diffing compiler
Index: compiler/pragma_c_gen.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/pragma_c_gen.m,v
retrieving revision 1.23
diff -u -r1.23 pragma_c_gen.m
--- pragma_c_gen.m 1998/11/20 04:08:53 1.23
+++ pragma_c_gen.m 1998/11/25 22:59:47
@@ -382,14 +382,19 @@
%
% Code fragments to obtain and release the global lock
%
+ code_info__get_module_info(ModuleInfo),
{ ThreadSafe = thread_safe ->
ObtainLock = pragma_c_raw_code(""),
ReleaseLock = pragma_c_raw_code("")
;
- ObtainLock =
- pragma_c_raw_code("\tMR_OBTAIN_GLOBAL_C_LOCK();\n"),
- ReleaseLock =
- pragma_c_raw_code("\tMR_RELEASE_GLOBAL_C_LOCK();\n")
+ module_info_pred_info(ModuleInfo, PredId, PredInfo),
+ pred_info_name(PredInfo, Name),
+ string__append_list(["\tMR_OBTAIN_GLOBAL_C_LOCK(""",
+ Name, """);\n"], ObtainLockStr),
+ ObtainLock = pragma_c_raw_code(ObtainLockStr),
+ string__append_list(["\tMR_RELEASE_GLOBAL_C_LOCK(""",
+ Name, """);\n"], ReleaseLockStr),
+ ReleaseLock = pragma_c_raw_code(ReleaseLockStr)
},
%
@@ -447,7 +452,7 @@
% join all the components of the pragma_c together
%
{ Components = [InputComp, SaveRegsComp, ObtainLock, C_Code_Comp,
- CheckR1_Comp, ReleaseLock, RestoreRegsComp,
+ ReleaseLock, CheckR1_Comp, RestoreRegsComp,
OutputComp] },
{ PragmaCCode = node([
pragma_c(Decls, Components, MayCallMercury, MaybeFailLabel, no)
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/exceptions
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
Index: library/char.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/char.m,v
retrieving revision 1.25
diff -u -r1.25 char.m
--- char.m 1998/05/11 20:12:36 1.25
+++ char.m 1998/10/14 23:52:12
@@ -401,16 +401,18 @@
%-----------------------------------------------------------------------------%
-:- pragma c_code(char__to_int(Character::in, Int::out), will_not_call_mercury, "
+:- pragma c_code(char__to_int(Character::in, Int::out),
+ [will_not_call_mercury, thread_safe] , "
Int = (UnsignedChar) Character;
").
-:- pragma c_code(char__to_int(Character::in, Int::in), will_not_call_mercury, "
+:- pragma c_code(char__to_int(Character::in, Int::in),
+ [will_not_call_mercury, thread_safe] , "
SUCCESS_INDICATOR = ((UnsignedChar) Character == Int);
").
-:- pragma c_code(char__to_int(Character::out, Int::in), will_not_call_mercury,
-"
+:- pragma c_code(char__to_int(Character::out, Int::in),
+ [will_not_call_mercury, thread_safe] , "
/*
** If the integer doesn't fit into a char, then
** the assignment `Character = Int' below will truncate it.
@@ -427,7 +429,8 @@
char__min_char_value(0).
:- pragma c_header_code("#include <limits.h>").
-:- pragma c_code(char__max_char_value(Max::out), will_not_call_mercury, "
+:- pragma c_code(char__max_char_value(Max::out),
+ [will_not_call_mercury, thread_safe], "
Max = UCHAR_MAX;
").
Index: library/std_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/std_util.m,v
retrieving revision 1.137
diff -u -r1.137 std_util.m
--- std_util.m 1998/11/19 06:11:00 1.137
+++ std_util.m 1998/11/22 22:46:20
@@ -959,14 +959,17 @@
% to make sure that the compiler doesn't issue any determinism warnings
% for them.
-:- pragma c_code(semidet_succeed, will_not_call_mercury,
+:- pragma c_code(semidet_succeed, [will_not_call_mercury, thread_safe],
"SUCCESS_INDICATOR = TRUE;").
-:- pragma c_code(semidet_fail, will_not_call_mercury,
+:- pragma c_code(semidet_fail, [will_not_call_mercury, thread_safe],
"SUCCESS_INDICATOR = FALSE;").
-:- pragma c_code(cc_multi_equal(X::in, Y::out), will_not_call_mercury,
+:- pragma c_code(cc_multi_equal(X::in, Y::out),
+ [will_not_call_mercury, thread_safe],
"Y = X;").
-:- pragma c_code(cc_multi_equal(X::di, Y::uo), will_not_call_mercury,
+:- pragma c_code(cc_multi_equal(X::di, Y::uo),
+ [will_not_call_mercury, thread_safe],
"Y = X;").
+
%-----------------------------------------------------------------------------%
% The type `std_util:type_info/0' happens to use much the same
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
Index: runtime/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/Mmakefile,v
retrieving revision 1.42
diff -u -r1.42 Mmakefile
--- Mmakefile 1998/11/09 10:24:41 1.42
+++ Mmakefile 1998/11/30 03:57:13
@@ -56,6 +56,7 @@
mercury_overflow.h \
mercury_prof.h \
mercury_prof_mem.h \
+ mercury_reg_workarounds.h \
mercury_regorder.h \
mercury_regs.h \
mercury_signal.h \
@@ -113,6 +114,7 @@
mercury_misc.c \
mercury_prof.c \
mercury_prof_mem.c \
+ mercury_reg_workarounds.c \
mercury_regs.c \
mercury_signal.c \
mercury_stack_trace.c \
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.8
diff -u -r1.8 mercury_conf.h.in
--- mercury_conf.h.in 1998/10/16 06:18:44 1.8
+++ mercury_conf.h.in 1998/12/14 00:10:53
@@ -233,6 +233,12 @@
*/
#undef MR_CANNOT_USE_STRUCTURE_ASSIGNMENT
+/*
+** To handle contexts suspended on IO operations we use the select() system
+** call and supporting data structures which while POSIX, are not ANSI.
+*/
+#undef MR_CAN_DO_PENDING_IO
+
/*---------------------------------------------------------------------------*/
#include "mercury_conf_param.h"
Index: runtime/mercury_context.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_context.c,v
retrieving revision 1.16
diff -u -r1.16 mercury_context.c
--- mercury_context.c 1998/11/11 02:14:16 1.16
+++ mercury_context.c 1998/12/14 00:11:41
@@ -17,10 +17,15 @@
#ifdef MR_THREAD_SAFE
#include "mercury_thread.h"
#endif
+#ifdef MR_CAN_DO_PENDING_IO
+ #include <sys/types.h> /* for fd_set */
+ #include <sys/time.h> /* for struct timeval */
+#endif
#include "mercury_memory_handlers.h"
#include "mercury_context.h"
-#include "mercury_engine.h" /* for `MR_memdebug' */
+#include "mercury_engine.h" /* for `MR_memdebug' */
+#include "mercury_reg_workarounds.h" /* for `MR_fd*' stuff */
MR_Context *MR_runqueue_head;
MR_Context *MR_runqueue_tail;
@@ -29,6 +34,11 @@
MercuryCond *MR_runqueue_cond;
#endif
+MR_PendingContext *MR_pending_contexts;
+#ifdef MR_THREAD_SAFE
+ MercuryLock *MR_pending_contexts_lock;
+#endif
+
/*
** free_context_list is a global linked list of unused context
** structures. If the MemoryZone pointers are not NULL,
@@ -57,6 +67,9 @@
pthread_mutex_init(&MR_global_lock, MR_MUTEX_ATTR);
+ MR_pending_contexts_lock = make(MercuryLock);
+ pthread_mutex_init(MR_pending_contexts_lock, MR_MUTEX_ATTR);
+
MR_KEY_CREATE(&MR_engine_base_key, NULL);
#endif
@@ -160,6 +173,101 @@
fatal_error("computation floundered");
}
+/*
+** Check to see if any contexts that blocked on IO have become
+** runnable. Return the number of contexts that are still blocked.
+** The parameter specifies whether or not the call to select should
+** block or not.
+*/
+static int
+check_pending_contexts(Bool block)
+{
+#ifdef MR_CAN_DO_PENDING_IO
+
+ int err, max_id, n_ids;
+ fd_set rd_set, wr_set, ex_set;
+ struct timeval timeout;
+ MR_PendingContext *pctxt;
+
+ if (MR_pending_contexts == NULL) {
+ return 0;
+ }
+
+ MR_fd_zero(&rd_set); MR_fd_zero(&wr_set); MR_fd_zero(&ex_set);
+ max_id = -1;
+ for (pctxt = MR_pending_contexts ; pctxt ; pctxt = pctxt -> next) {
+ if (pctxt->waiting_mode & MR_PENDING_READ) {
+ if (max_id > pctxt->fd) max_id = pctxt->fd;
+ FD_SET(pctxt->fd, &rd_set);
+ }
+ if (pctxt->waiting_mode & MR_PENDING_WRITE) {
+ if (max_id > pctxt->fd) max_id = pctxt->fd;
+ FD_SET(pctxt->fd, &wr_set);
+ }
+ if (pctxt->waiting_mode & MR_PENDING_EXEC) {
+ if (max_id > pctxt->fd) max_id = pctxt->fd;
+ FD_SET(pctxt->fd, &ex_set);
+ }
+ }
+ max_id++;
+
+ if (max_id == 0) {
+ fatal_error("no fd's set!");
+ }
+
+ if (block) {
+ err = select(max_id, &rd_set, &wr_set, &ex_set, NULL);
+ } else {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ err = select(max_id, &rd_set, &wr_set, &ex_set, &timeout);
+ }
+
+ if (err < 0) {
+ fatal_error("select failed!");
+ }
+
+ n_ids = 0;
+ for (pctxt = MR_pending_contexts; pctxt; pctxt = pctxt -> next) {
+ n_ids++;
+ if ( ((pctxt->waiting_mode & MR_PENDING_READ)
+ && FD_ISSET(pctxt->fd, &rd_set))
+ || ((pctxt->waiting_mode & MR_PENDING_WRITE)
+ && FD_ISSET(pctxt->fd, &wr_set))
+ || ((pctxt->waiting_mode & MR_PENDING_EXEC)
+ && FD_ISSET(pctxt->fd, &ex_set))
+ )
+ {
+ schedule(pctxt->context);
+ }
+ }
+
+ return n_ids;
+
+#else /* !MR_CAN_DO_PENDING_IO */
+
+ fatal_error("select() unavailable!");
+
+#endif
+}
+
+
+void
+schedule(MR_Context *ctxt)
+{
+ ctxt->next = NULL;
+ MR_LOCK(MR_runqueue_lock, "schedule");
+ if (MR_runqueue_tail) {
+ MR_runqueue_tail->next = ctxt;
+ MR_runqueue_tail = ctxt;
+ } else {
+ MR_runqueue_head = ctxt;
+ MR_runqueue_tail = ctxt;
+ }
+ MR_SIGNAL(MR_runqueue_cond);
+ MR_UNLOCK(MR_runqueue_lock, "schedule");
+}
+
Define_extern_entry(do_runnext);
BEGIN_MODULE(scheduler_module)
@@ -179,43 +287,54 @@
MR_LOCK(MR_runqueue_lock, "do_runnext (i)");
while (1) {
- if (MR_exit_now = TRUE) {
+ if (MR_exit_now == TRUE) {
MR_UNLOCK(MR_runqueue_lock, "do_runnext (ii)");
destroy_thread(MR_engine_base);
}
tmp = MR_runqueue_head;
+ /* XXX check pending io */
prev = NULL;
while(tmp != NULL) {
- if (depth > 0 && tmp->owner_thread == thd
- || tmp->owner_thread == NULL)
+ if ((depth > 0 && tmp->owner_thread == thd)
+ || (tmp->owner_thread == (MercuryThread) NULL)) {
break;
+ }
prev = tmp;
tmp = tmp->next;
}
- if (tmp != NULL)
+ if (tmp != NULL) {
break;
+ }
MR_WAIT(MR_runqueue_cond, MR_runqueue_lock);
}
MR_ENGINE(this_context) = tmp;
- if (prev != NULL)
+ if (prev != NULL) {
prev->next = tmp->next;
- else
+ } else {
MR_runqueue_head = tmp->next;
- if (MR_runqueue_tail == tmp)
+ }
+ if (MR_runqueue_tail == tmp) {
MR_runqueue_tail = prev;
+ }
MR_UNLOCK(MR_runqueue_lock, "do_runnext (iii)");
load_context(MR_ENGINE(this_context));
GOTO(MR_ENGINE(this_context)->resume);
}
#else /* !MR_THREAD_SAFE */
{
- if (MR_runqueue_head == NULL)
+ if (MR_runqueue_head == NULL && MR_pending_contexts == NULL) {
fatal_error("empty runqueue!");
+ }
+ while (MR_runqueue_head == NULL) {
+ check_pending_contexts(TRUE); /* block */
+ }
+
MR_ENGINE(this_context) = MR_runqueue_head;
MR_runqueue_head = MR_runqueue_head->next;
- if (MR_runqueue_head == NULL)
+ if (MR_runqueue_head == NULL) {
MR_runqueue_tail = NULL;
+ }
load_context(MR_ENGINE(this_context));
GOTO(MR_ENGINE(this_context)->resume);
Index: runtime/mercury_context.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_context.h,v
retrieving revision 1.8
diff -u -r1.8 mercury_context.h
--- mercury_context.h 1998/11/11 02:14:16 1.8
+++ mercury_context.h 1998/12/14 00:04:55
@@ -129,8 +129,7 @@
typedef MR_Context Context; /* for backwards compatibility */
/*
-** the runqueue is a linked list of contexts that are
-** runnable.
+** The runqueue is a linked list of contexts that are runnable.
*/
extern MR_Context *MR_runqueue_head;
extern MR_Context *MR_runqueue_tail;
@@ -139,7 +138,41 @@
extern MercuryCond *MR_runqueue_cond;
#endif
+/*
+** As well as the runqueue, we maintain a linked list of contexts
+** and associated file descriptors that are suspended blocked for
+** reads/writes/exceptions. When the runqueue becomes empty, if
+** this list is not empty then we call select and block until one
+** or more of the file descriptors become ready for I/O, then
+** wake the appropriate context.
+** In addition, we should periodically check to see if the list of blocked
+** contexts is non-empty and if so, poll to wake any contexts that
+** can unblock. This, while not yielding true fairness (since this
+** requires the current context to perform some yield-like action),
+** ensures that it is possible for programmers to write concurrent
+** programs with continuous computation and interleaved I/O dependent
+** computation in a straight-forward manner. This polling is not
+** currently implemented.
+*/
+
+typedef enum {
+ MR_PENDING_READ = 0x01,
+ MR_PENDING_WRITE = 0x02,
+ MR_PENDING_EXEC = 0x04
+} MR_WaitingMode;
+
+typedef struct MR_PENDING_CONTEXT {
+ struct MR_PENDING_CONTEXT *next;
+ MR_Context *context;
+ int fd;
+ MR_WaitingMode waiting_mode;
+} MR_PendingContext;
+extern MR_PendingContext *MR_pending_contexts;
+#ifdef MR_THREAD_SAFE
+ extern MercuryLock *MR_pending_contexts_lock;
+#endif
+
/*
** Initializes a context structure.
*/
@@ -179,21 +212,8 @@
** schedule(MR_Context *cptr):
** Append a context onto the end of the run queue.
*/
-#define schedule(cptr) \
- do { \
- MR_Context *ctxt = (MR_Context *) (cptr); \
- ctxt->next = NULL; \
- MR_LOCK(MR_runqueue_lock, "schedule"); \
- if (MR_runqueue_tail) { \
- MR_runqueue_tail->next = ctxt; \
- MR_runqueue_tail = ctxt; \
- } else { \
- MR_runqueue_head = ctxt; \
- MR_runqueue_tail = ctxt; \
- } \
- MR_SIGNAL(MR_runqueue_cond); \
- MR_UNLOCK(MR_runqueue_lock, "schedule"); \
- } while(0)
+
+void schedule(MR_Context *ctxt);
Declare_entry(do_runnext);
#define runnext() \
Index: runtime/mercury_misc.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_misc.h,v
retrieving revision 1.11
diff -u -r1.11 mercury_misc.h
--- mercury_misc.h 1998/11/09 10:24:38 1.11
+++ mercury_misc.h 1998/11/30 03:57:37
@@ -10,6 +10,7 @@
** fatal_error(),
** checked_malloc(),
** MR_memcpy
+** MR_fd_zero
*/
#ifndef MERCURY_MISC_H
@@ -17,6 +18,7 @@
#include "mercury_types.h" /* for `Code *' */
#include <stdlib.h> /* for `size_t' */
+#include <sys/types.h> /* for fd_set */
#ifdef MR_LOWLEVEL_DEBUG
extern void mkframe_msg(void);
Index: runtime/mercury_thread.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_thread.c,v
retrieving revision 1.7
diff -u -r1.7 mercury_thread.c
--- mercury_thread.c 1998/09/21 10:21:40 1.7
+++ mercury_thread.c 1998/10/07 01:54:53
@@ -125,15 +125,13 @@
}
#endif
-#ifdef MR_THREAD_SAFE
+#if defined(MR_THREAD_SAFE) && defined(MR_DEBUG_THREADS)
void
MR_mutex_lock(MercuryLock *lock, const char *from)
{
int err;
-#ifdef MR_DEBUG_THREADS
fprintf(stderr, "%d locking on %p (%s)\n", pthread_self(), lock, from);
-#endif
err = pthread_mutex_lock(lock);
assert(err == 0);
}
@@ -143,10 +141,8 @@
{
int err;
-#ifdef MR_DEBUG_THREADS
fprintf(stderr, "%d unlocking on %p (%s)\n",
pthread_self(), lock, from);
-#endif
err = pthread_mutex_unlock(lock);
assert(err == 0);
}
@@ -156,9 +152,7 @@
{
int err;
-#ifdef MR_DEBUG_THREADS
fprintf(stderr, "%d signaling %p\n", pthread_self(), cond);
-#endif
err = pthread_cond_broadcast(cond);
assert(err == 0);
}
@@ -168,9 +162,7 @@
{
int err;
-#ifdef MR_DEBUG_THREADS
fprintf(stderr, "%d waiting on %p (%p)\n", pthread_self(), cond, lock);
-#endif
err = pthread_cond_wait(cond, lock);
assert(err == 0);
}
Index: runtime/mercury_thread.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_thread.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_thread.h
--- mercury_thread.h 1998/08/07 00:50:30 1.3
+++ mercury_thread.h 1998/11/25 23:10:21
@@ -15,7 +15,7 @@
#if defined(MR_DIGITAL_UNIX_PTHREADS)
#define MR_MUTEX_ATTR pthread_mutexattr_default
#define MR_COND_ATTR pthread_condattr_default
- #define MR_THREAD_ATTR pthread_attr_default
+ #define MR_THREAD_ATTR pthread_attr_default
#else
#define MR_MUTEX_ATTR NULL
#define MR_COND_ATTR NULL
@@ -27,7 +27,7 @@
typedef pthread_mutex_t MercuryLock;
typedef pthread_cond_t MercuryCond;
- #if 0
+ #ifndef MR_DEBUG_THREADS
/*
** The following macros should be used once the
** use of locking in the generated code is considered
@@ -57,11 +57,11 @@
** predicates which are not thread-safe.
** See the comments below.
*/
- #define MR_OBTAIN_GLOBAL_C_LOCK() MR_mutex_lock(&MR_global_lock, \
- "pragma c code");
+ #define MR_OBTAIN_GLOBAL_C_LOCK(where) MR_LOCK(&MR_global_lock, \
+ (where));
- #define MR_RELEASE_GLOBAL_C_LOCK() MR_mutex_unlock(&MR_global_lock, \
- "pragma c code");
+ #define MR_RELEASE_GLOBAL_C_LOCK(where) MR_UNLOCK(&MR_global_lock, \
+ (where));
#if defined(MR_DIGITAL_UNIX_PTHREADS)
#define MR_GETSPECIFIC(key) ({ \
Index: runtime/mercury_types.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_types.h,v
retrieving revision 1.13
diff -u -r1.13 mercury_types.h
--- mercury_types.h 1998/07/28 03:10:01 1.13
+++ mercury_types.h 1998/08/24 04:49:19
@@ -65,9 +65,6 @@
/* continuation function type, for --high-level-C option */
typedef void (*Cont) (void);
-/* spinlocks -- see mercury_spinlock.h */
-typedef Word SpinLock;
-
/*
** semidet predicates indicate success or failure by leaving nonzero or zero
** respectively in register r1
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing scripts
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing trial
cvs diff: Diffing util
---mercury_reg_workarounds.h---
/*
** Copyright (C) 1998 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
/*
** mercury_reg_workarounds.h - MR_fd_zero
*/
#ifndef MERCURY_REG_WORKAROUNDS_H
#define MERCURY_REG_WORKAROUNDS_H
#ifdef MR_CAN_DO_PENDING_IO
#include <sys/types.h> /* for fd_set */
#endif
/*
** We use a forwarding function to FD_ZERO because the Linux headers
** use an asm fragment which conflicts with our use of global registers.
*/
#ifdef MR_CAN_DO_PENDING_IO
void MR_fd_zero(fd_set *fdset);
#endif
#endif /* not MERCURY_REG_WORKAROUNDS_H */
---mercury_reg_workarounds.c---
/*
** Copyright (C) 1998 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
/*
** All the functions in this file work around problems caused by
** our use of global registers conflicting with the use of registers
** by gcc, or asm fragments in the GNU headers.
*/
#include "mercury_conf.h"
#include "mercury_reg_workarounds.h"
#ifdef MR_CAN_DO_PENDING_IO
void
MR_fd_zero(fd_set *fdset)
{
FD_ZERO(fdset);
}
#endif
More information about the developers
mailing list