mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 20:34:19 +00:00
Fix some layout issues in these files. There are no algorithmic
Estimated hours taken: 0.2 Branches: main runtime/mercury_calls.h: runtime/mercury_prof.h: runtime/mercury_signal.h: runtime/mercury_string.h: runtime/mercury_thread.c: runtime/mercury_thread.h: Fix some layout issues in these files. There are no algorithmic changes.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 1995-2000, 2004 The University of Melbourne.
|
||||
** Copyright (C) 1995-2000, 2004-2005 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.
|
||||
*/
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
** On some systems [basically those using PIC (Position Independent MR_Code)],
|
||||
** On some systems [basically those using PIC (Position Independent Code)],
|
||||
** if we're using gcc non-local gotos to jump between functions then
|
||||
** we need to do ASM_FIXUP_REGS after each return from a procedure call.
|
||||
** However, if we're using asm labels, then this is done in the
|
||||
@@ -48,7 +48,7 @@
|
||||
ASM_FIXUP_REGS \
|
||||
MR_GOTO(succ_cont); \
|
||||
})
|
||||
/* same as above, but with MR_GOTO_LABEL rather than MR_GOTO */
|
||||
/* same as above, but with MR_GOTO_LABEL rather than MR_GOTO */
|
||||
#define MR_noprof_call_localret(proc, succ_cont) \
|
||||
({ \
|
||||
__label__ fixup_gp; \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 1995-1997,2000-2002, 2004 The University of Melbourne.
|
||||
** Copyright (C) 1995-1997,2000-2002, 2004-2005 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.
|
||||
*/
|
||||
@@ -76,7 +76,8 @@ extern MR_Code * volatile MR_prof_current_proc;
|
||||
** mercury_label.c to record the address of each entry label.
|
||||
*/
|
||||
|
||||
extern void MR_prof_output_addr_decl(const char *name, const MR_Code *address);
|
||||
extern void MR_prof_output_addr_decl(const char *name,
|
||||
const MR_Code *address);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 1998, 2000, 2002, 2004 The University of Melbourne.
|
||||
** Copyright (C) 1998, 2000, 2002, 2004-2005 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.
|
||||
*/
|
||||
@@ -57,59 +57,65 @@ typedef struct sigaction MR_signal_action;
|
||||
typedef MR_Code * MR_signal_action;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** MR_setup_signal sets a signal handler (handler) to handle
|
||||
** signals of the given signal type (sig).
|
||||
** If the handler cannot be setup, it aborts with the given
|
||||
** error message.
|
||||
**
|
||||
** If the signal handler requires siginfo to be provided (e.g.
|
||||
** it needs access to stored registers), need_info must be
|
||||
** MR_TRUE. Note that on some platforms, signal information is
|
||||
** provided regardless of the value of need_info.
|
||||
*/
|
||||
extern void MR_setup_signal(int sig, MR_Code *handler, MR_bool need_info,
|
||||
const char * error_message);
|
||||
/*
|
||||
** MR_setup_signal sets a signal handler (handler) to handle
|
||||
** signals of the given signal type (sig).
|
||||
** If the handler cannot be setup, it aborts with the given
|
||||
** error message.
|
||||
**
|
||||
** If the signal handler requires siginfo to be provided (e.g.
|
||||
** it needs access to stored registers), need_info must be
|
||||
** MR_TRUE. Note that on some platforms, signal information is
|
||||
** provided regardless of the value of need_info.
|
||||
*/
|
||||
|
||||
/*
|
||||
** As above, but don't arrange for system calls to be
|
||||
** restarted if the signal is received.
|
||||
*/
|
||||
extern void MR_setup_signal_no_restart(int sig, MR_Code *handler,
|
||||
MR_bool need_info, const char * error_message);
|
||||
extern void MR_setup_signal(int sig, MR_Code *handler, MR_bool need_info,
|
||||
const char * error_message);
|
||||
|
||||
/*
|
||||
** As above, but initialize a signal action suitable to be
|
||||
** passed to MR_set_signal_action rather than setting a
|
||||
** signal handler for a signal.
|
||||
*/
|
||||
extern void MR_init_signal_action(MR_signal_action* act, MR_Code *handler,
|
||||
MR_bool need_info, MR_bool should_restart_system_call);
|
||||
/*
|
||||
** As above, but don't arrange for system calls to be
|
||||
** restarted if the signal is received.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Get the current action for the given signal.
|
||||
** If the action cannot be retrieved, it aborts with the given
|
||||
** error message.
|
||||
*/
|
||||
extern void MR_get_signal_action(int sig, MR_signal_action *old_action,
|
||||
const char *error_message);
|
||||
extern void MR_setup_signal_no_restart(int sig, MR_Code *handler,
|
||||
MR_bool need_info, const char * error_message);
|
||||
|
||||
/*
|
||||
** Restore the action for the given signal to the result
|
||||
** of a previous call to MR_get_signal_action().
|
||||
** If the action cannot be set, it aborts with the given
|
||||
** error message.
|
||||
*/
|
||||
extern void MR_set_signal_action(int sig, MR_signal_action *action,
|
||||
const char *error_message);
|
||||
/*
|
||||
** As above, but initialize a signal action suitable to be
|
||||
** passed to MR_set_signal_action rather than setting a
|
||||
** signal handler for a signal.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Change the behaviour of system calls when the
|
||||
** the specified signal is received.
|
||||
** If restart is MR_TRUE they will be restarted, if it
|
||||
** is MR_FALSE, they won't. This function may have no
|
||||
** effect on some systems.
|
||||
*/
|
||||
extern void MR_signal_should_restart(int sig, MR_bool restart);
|
||||
extern void MR_init_signal_action(MR_signal_action* act, MR_Code *handler,
|
||||
MR_bool need_info, MR_bool should_restart_system_call);
|
||||
|
||||
/*
|
||||
** Get the current action for the given signal.
|
||||
** If the action cannot be retrieved, it aborts with the given
|
||||
** error message.
|
||||
*/
|
||||
|
||||
extern void MR_get_signal_action(int sig, MR_signal_action *old_action,
|
||||
const char *error_message);
|
||||
|
||||
/*
|
||||
** Restore the action for the given signal to the result
|
||||
** of a previous call to MR_get_signal_action().
|
||||
** If the action cannot be set, it aborts with the given
|
||||
** error message.
|
||||
*/
|
||||
|
||||
extern void MR_set_signal_action(int sig, MR_signal_action *action,
|
||||
const char *error_message);
|
||||
|
||||
/*
|
||||
** Change the behaviour of system calls when the
|
||||
** the specified signal is received.
|
||||
** If restart is MR_TRUE they will be restarted, if it
|
||||
** is MR_FALSE, they won't. This function may have no
|
||||
** effect on some systems.
|
||||
*/
|
||||
|
||||
extern void MR_signal_should_restart(int sig, MR_bool restart);
|
||||
|
||||
#endif /* not MERCURY_SIGNAL_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 1995-2004 The University of Melbourne.
|
||||
** Copyright (C) 1995-2005 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.
|
||||
*/
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
/*
|
||||
** MR_bool MR_string_equal(MR_ConstString s1, MR_ConstString s2):
|
||||
** Return true iff the two Mercury strings s1 and s2 are equal.
|
||||
** Return true iff the two Mercury strings s1 and s2 are equal.
|
||||
*/
|
||||
|
||||
#define MR_string_equal(s1,s2) (strcmp((char*)(s1),(char*)(s2))==0)
|
||||
@@ -79,10 +79,10 @@
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
** void MR_make_aligned_string_copy(MR_String ptr, const char * string);
|
||||
** Same as MR_make_aligned_string(ptr, string), except that the string
|
||||
** is guaranteed to be copied. This is useful for copying C strings
|
||||
** onto the Mercury heap.
|
||||
** void MR_make_aligned_string_copy(MR_String ptr, const char * string):
|
||||
** Same as MR_make_aligned_string(ptr, string), except that the string
|
||||
** is guaranteed to be copied. This is useful for copying C strings
|
||||
** onto the Mercury heap.
|
||||
**
|
||||
** BEWARE: this may modify `MR_hp', so it must only be called from
|
||||
** places where `MR_hp' is valid. If calling it from inside a C function,
|
||||
@@ -105,9 +105,9 @@
|
||||
|
||||
/*
|
||||
** void MR_make_aligned_string_copy_saved_hp(MR_String ptr,
|
||||
** const char * string);
|
||||
** Same as MR_make_aligned_string_copy(ptr, string), except that it uses
|
||||
** MR_offset_incr_saved_hp_atomic instead of MR_offset_incr_hp_atomic.
|
||||
** const char * string):
|
||||
** Same as MR_make_aligned_string_copy(ptr, string), except that it uses
|
||||
** MR_offset_incr_saved_hp_atomic instead of MR_offset_incr_hp_atomic.
|
||||
*/
|
||||
|
||||
#define MR_make_aligned_string_copy_saved_hp(ptr, string) \
|
||||
@@ -125,9 +125,9 @@
|
||||
|
||||
/*
|
||||
** void MR_make_aligned_string_copy_saved_hp_quote(MR_String ptr,
|
||||
** const char * string);
|
||||
** Same as MR_make_aligned_string_copy_saved_hp(ptr, string), except that
|
||||
** it puts double quote marks at the start and end of the string.
|
||||
** const char * string):
|
||||
** Same as MR_make_aligned_string_copy_saved_hp(ptr, string), except that
|
||||
** it puts double quote marks at the start and end of the string.
|
||||
*/
|
||||
|
||||
#define MR_make_aligned_string_copy_saved_hp_quote(ptr, string) \
|
||||
@@ -145,7 +145,7 @@
|
||||
|
||||
/*
|
||||
** void MR_allocate_aligned_string_msg(MR_String ptr, size_t len,
|
||||
** MR_Code *proclabel);
|
||||
** MR_Code *proclabel):
|
||||
** Allocate enough word aligned memory to hold len characters. Also
|
||||
** record for memory profiling purposes the location, proclabel, of the
|
||||
** allocation if profiling is enabled.
|
||||
@@ -171,8 +171,8 @@
|
||||
|
||||
/*
|
||||
** MR_do_hash_string(int & hash, MR_Word string):
|
||||
** Given a Mercury string `string', set `hash' to the hash value
|
||||
** for that string. (`hash' must be an lvalue.)
|
||||
** Given a Mercury string `string', set `hash' to the hash value
|
||||
** for that string. (`hash' must be an lvalue.)
|
||||
**
|
||||
** This is an implementation detail used to implement MR_hash_string().
|
||||
** It should not be used directly. Use MR_hash_string() instead.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
** Copyright (C) 1997-2001, 2003 The University of Melbourne.
|
||||
** vim: ts=4 sw=4 expandtab
|
||||
*/
|
||||
/*
|
||||
** Copyright (C) 1997-2001, 2003, 2005 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.
|
||||
*/
|
||||
@@ -8,63 +11,61 @@
|
||||
#include "mercury_regs.h"
|
||||
#include "mercury_engine.h"
|
||||
#include "mercury_memory.h"
|
||||
#include "mercury_context.h" /* for MR_do_runnext */
|
||||
#include "mercury_context.h" /* for MR_do_runnext */
|
||||
#include "mercury_thread.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef MR_THREAD_SAFE
|
||||
MercuryThreadKey MR_exception_handler_key;
|
||||
MercuryThreadKey MR_engine_base_key;
|
||||
MercuryLock MR_global_lock;
|
||||
#ifdef MR_THREAD_SAFE
|
||||
MercuryThreadKey MR_exception_handler_key;
|
||||
MercuryThreadKey MR_engine_base_key;
|
||||
MercuryLock MR_global_lock;
|
||||
#endif
|
||||
|
||||
MR_bool MR_exit_now;
|
||||
MR_bool MR_debug_threads = MR_FALSE;
|
||||
MR_bool MR_exit_now;
|
||||
MR_bool MR_debug_threads = MR_FALSE;
|
||||
|
||||
#ifdef MR_THREAD_SAFE
|
||||
|
||||
static void *
|
||||
MR_create_thread_2(void *goal);
|
||||
static void *MR_create_thread_2(void *goal);
|
||||
|
||||
MercuryThread *
|
||||
MR_create_thread(MR_ThreadGoal *goal)
|
||||
{
|
||||
MercuryThread *thread;
|
||||
pthread_attr_t attrs;
|
||||
int err;
|
||||
MercuryThread *thread;
|
||||
pthread_attr_t attrs;
|
||||
int err;
|
||||
|
||||
thread = MR_GC_NEW(MercuryThread);
|
||||
pthread_attr_init(&attrs);
|
||||
err = pthread_create(thread, &attrs, MR_create_thread_2,
|
||||
(void *) goal);
|
||||
thread = MR_GC_NEW(MercuryThread);
|
||||
pthread_attr_init(&attrs);
|
||||
err = pthread_create(thread, &attrs, MR_create_thread_2, (void *) goal);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "pthread_create returned %d (errno = %d)\n",
|
||||
err, errno);
|
||||
fprintf(stderr, "pthread_create returned %d (errno = %d)\n", err, errno);
|
||||
#endif
|
||||
|
||||
if (err != 0)
|
||||
MR_fatal_error("error creating thread");
|
||||
if (err != 0) {
|
||||
MR_fatal_error("error creating thread");
|
||||
}
|
||||
|
||||
return thread;
|
||||
return thread;
|
||||
}
|
||||
|
||||
static void *
|
||||
MR_create_thread_2(void *goal0)
|
||||
{
|
||||
MR_ThreadGoal *goal;
|
||||
MR_ThreadGoal *goal;
|
||||
|
||||
goal = (MR_ThreadGoal *) goal0;
|
||||
if (goal != NULL) {
|
||||
MR_init_thread(MR_use_now);
|
||||
(goal->func)(goal->arg);
|
||||
} else {
|
||||
MR_init_thread(MR_use_later);
|
||||
}
|
||||
goal = (MR_ThreadGoal *) goal0;
|
||||
if (goal != NULL) {
|
||||
MR_init_thread(MR_use_now);
|
||||
(goal->func)(goal->arg);
|
||||
} else {
|
||||
MR_init_thread(MR_use_later);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* MR_THREAD_SAFE */
|
||||
@@ -72,58 +73,55 @@ MR_create_thread_2(void *goal0)
|
||||
MR_bool
|
||||
MR_init_thread(MR_when_to_use when_to_use)
|
||||
{
|
||||
MercuryEngine *eng;
|
||||
MercuryEngine *eng;
|
||||
|
||||
#ifdef MR_THREAD_SAFE
|
||||
/*
|
||||
** Check to see whether there is already an engine
|
||||
** that is initialized in this thread. If so we just
|
||||
** return, there's nothing for us to do.
|
||||
*/
|
||||
if (MR_GETSPECIFIC(MR_engine_base_key)) {
|
||||
return MR_FALSE;
|
||||
}
|
||||
/*
|
||||
** Check to see whether there is already an engine that is initialized
|
||||
** in this thread. If so we just return, there's nothing for us to do.
|
||||
*/
|
||||
if (MR_GETSPECIFIC(MR_engine_base_key)) {
|
||||
return MR_FALSE;
|
||||
}
|
||||
#endif
|
||||
eng = MR_create_engine();
|
||||
eng = MR_create_engine();
|
||||
|
||||
#ifdef MR_THREAD_SAFE
|
||||
pthread_setspecific(MR_engine_base_key, eng);
|
||||
MR_restore_registers();
|
||||
pthread_setspecific(MR_engine_base_key, eng);
|
||||
MR_restore_registers();
|
||||
#ifdef MR_ENGINE_BASE_REGISTER
|
||||
MR_engine_base = eng;
|
||||
MR_engine_base = eng;
|
||||
#endif
|
||||
#else
|
||||
MR_memcpy(&MR_engine_base, eng,
|
||||
sizeof(MercuryEngine));
|
||||
MR_restore_registers();
|
||||
MR_memcpy(&MR_engine_base, eng, sizeof(MercuryEngine));
|
||||
MR_restore_registers();
|
||||
#endif
|
||||
MR_load_engine_regs(MR_cur_engine());
|
||||
MR_load_context(MR_ENGINE(MR_eng_this_context));
|
||||
MR_load_engine_regs(MR_cur_engine());
|
||||
MR_load_context(MR_ENGINE(MR_eng_this_context));
|
||||
|
||||
MR_save_registers();
|
||||
MR_save_registers();
|
||||
|
||||
#ifdef MR_THREAD_SAFE
|
||||
MR_ENGINE(MR_eng_owner_thread) = pthread_self();
|
||||
#ifdef MR_THREAD_SAFE
|
||||
MR_ENGINE(MR_eng_owner_thread) = pthread_self();
|
||||
#endif
|
||||
|
||||
switch (when_to_use) {
|
||||
case MR_use_later :
|
||||
switch (when_to_use) {
|
||||
case MR_use_later :
|
||||
#ifdef MR_HIGHLEVEL_CODE
|
||||
MR_fatal_error("Sorry, not implemented: "
|
||||
"--high-level-code and multiple engines");
|
||||
MR_fatal_error("Sorry, not implemented: "
|
||||
"--high-level-code and multiple engines");
|
||||
#else
|
||||
(void) MR_call_engine(MR_ENTRY(MR_do_runnext),
|
||||
MR_FALSE);
|
||||
(void) MR_call_engine(MR_ENTRY(MR_do_runnext), MR_FALSE);
|
||||
#endif
|
||||
MR_destroy_engine(eng);
|
||||
return MR_FALSE;
|
||||
MR_destroy_engine(eng);
|
||||
return MR_FALSE;
|
||||
|
||||
case MR_use_now :
|
||||
return MR_TRUE;
|
||||
|
||||
default:
|
||||
MR_fatal_error("init_thread was passed a bad value");
|
||||
}
|
||||
case MR_use_now :
|
||||
return MR_TRUE;
|
||||
|
||||
default:
|
||||
MR_fatal_error("init_thread was passed a bad value");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -133,26 +131,26 @@ void
|
||||
MR_finalize_thread_engine(void)
|
||||
{
|
||||
#ifdef MR_THREAD_SAFE
|
||||
MercuryEngine *eng;
|
||||
MercuryEngine *eng;
|
||||
|
||||
eng = MR_GETSPECIFIC(MR_engine_base_key);
|
||||
pthread_setspecific(MR_engine_base_key, NULL);
|
||||
/*
|
||||
** XXX calling destroy_engine(eng) here appears to segfault.
|
||||
** This should probably be investigated and fixed.
|
||||
*/
|
||||
MR_finalize_engine(eng);
|
||||
eng = MR_GETSPECIFIC(MR_engine_base_key);
|
||||
pthread_setspecific(MR_engine_base_key, NULL);
|
||||
/*
|
||||
** XXX calling destroy_engine(eng) here appears to segfault.
|
||||
** This should probably be investigated and fixed.
|
||||
*/
|
||||
MR_finalize_engine(eng);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MR_THREAD_SAFE
|
||||
#ifdef MR_THREAD_SAFE
|
||||
|
||||
void
|
||||
MR_destroy_thread(void *eng0)
|
||||
{
|
||||
MercuryEngine *eng = eng0;
|
||||
MR_destroy_engine(eng);
|
||||
pthread_exit(0);
|
||||
MercuryEngine *eng = eng0;
|
||||
MR_destroy_engine(eng);
|
||||
pthread_exit(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -162,42 +160,43 @@ MR_destroy_thread(void *eng0)
|
||||
void
|
||||
MR_mutex_lock(MercuryLock *lock, const char *from)
|
||||
{
|
||||
int err;
|
||||
int err;
|
||||
|
||||
fprintf(stderr, "%d locking on %p (%s)\n", pthread_self(), lock, from);
|
||||
err = pthread_mutex_lock(lock);
|
||||
assert(err == 0);
|
||||
fprintf(stderr, "%ld locking on %p (%s)\n",
|
||||
(long) pthread_self(), lock, from);
|
||||
err = pthread_mutex_lock(lock);
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MR_mutex_unlock(MercuryLock *lock, const char *from)
|
||||
{
|
||||
int err;
|
||||
int err;
|
||||
|
||||
fprintf(stderr, "%d unlocking on %p (%s)\n",
|
||||
pthread_self(), lock, from);
|
||||
err = pthread_mutex_unlock(lock);
|
||||
assert(err == 0);
|
||||
fprintf(stderr, "%ld unlocking on %p (%s)\n",
|
||||
(long) pthread_self(), lock, from);
|
||||
err = pthread_mutex_unlock(lock);
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MR_cond_signal(MercuryCond *cond)
|
||||
{
|
||||
int err;
|
||||
int err;
|
||||
|
||||
fprintf(stderr, "%d signaling %p\n", pthread_self(), cond);
|
||||
err = pthread_cond_broadcast(cond);
|
||||
assert(err == 0);
|
||||
fprintf(stderr, "%ld signaling %p\n", (long) pthread_self(), cond);
|
||||
err = pthread_cond_broadcast(cond);
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MR_cond_wait(MercuryCond *cond, MercuryLock *lock)
|
||||
{
|
||||
int err;
|
||||
int err;
|
||||
|
||||
fprintf(stderr, "%d waiting on %p (%p)\n", pthread_self(), cond, lock);
|
||||
err = pthread_cond_wait(cond, lock);
|
||||
assert(err == 0);
|
||||
fprintf(stderr, "%d waiting on %p (%p)\n", pthread_self(), cond, lock);
|
||||
err = pthread_cond_wait(cond, lock);
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 1997-1998, 2000, 2003 The University of Melbourne.
|
||||
** Copyright (C) 1997-1998, 2000, 2003, 2005 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.
|
||||
*/
|
||||
@@ -20,7 +20,7 @@
|
||||
#else
|
||||
#define MR_MUTEX_ATTR NULL
|
||||
#define MR_COND_ATTR NULL
|
||||
#define MR_THREAD_ATTR NULL
|
||||
#define MR_THREAD_ATTR NULL
|
||||
#endif
|
||||
|
||||
typedef pthread_t MercuryThread;
|
||||
@@ -51,20 +51,28 @@
|
||||
#define MR_LOCK(lck, from) \
|
||||
( MR_debug_threads ? \
|
||||
MR_mutex_lock((lck), (from)) \
|
||||
: pthread_mutex_lock((lck)))
|
||||
: \
|
||||
pthread_mutex_lock((lck)) \
|
||||
)
|
||||
#define MR_UNLOCK(lck, from) \
|
||||
( MR_debug_threads ? \
|
||||
MR_mutex_unlock((lck), (from)) \
|
||||
: pthread_mutex_unlock((lck)))
|
||||
: \
|
||||
pthread_mutex_unlock((lck)) \
|
||||
)
|
||||
|
||||
#define MR_SIGNAL(cnd) \
|
||||
( MR_debug_threads ? \
|
||||
MR_cond_signal((cnd)) \
|
||||
: pthread_cond_signal((cnd)))
|
||||
: \
|
||||
pthread_cond_signal((cnd)) \
|
||||
)
|
||||
#define MR_WAIT(cnd, mtx) \
|
||||
( MR_debug_threads ? \
|
||||
MR_cond_wait((cnd), (mtx)) \
|
||||
: pthread_cond_wait((cnd), (mtx)))
|
||||
: \
|
||||
pthread_cond_wait((cnd), (mtx)) \
|
||||
)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -101,27 +109,30 @@
|
||||
** structure containing a function and an argument. The function will
|
||||
** be called with the given argument in the new thread.
|
||||
*/
|
||||
|
||||
MercuryThread *MR_create_thread(MR_ThreadGoal *);
|
||||
void MR_destroy_thread(void *eng);
|
||||
extern MR_bool MR_exit_now;
|
||||
|
||||
/*
|
||||
** MR_global_lock is a mutex for ensuring that only one non-threadsafe
|
||||
** piece of pragma c code executes at a time. If `not_threadsafe' is
|
||||
** given or `threadsafe' is not given in the attributes of a pragma
|
||||
** c code definition of a predicate, then the generated code will
|
||||
** obtain this lock before executing the C code fragment, and then
|
||||
** release it afterwards.
|
||||
** XXX we should emit a warning if may_call_mercury and not_threadsafe
|
||||
** (the defaults) are specified since if you obtain the lock then
|
||||
** call back into Mercury deadlock could result.
|
||||
*/
|
||||
/*
|
||||
** MR_global_lock is a mutex for ensuring that only one non-threadsafe
|
||||
** piece of pragma c code executes at a time. If `not_threadsafe' is
|
||||
** given or `threadsafe' is not given in the attributes of a pragma
|
||||
** c code definition of a predicate, then the generated code will
|
||||
** obtain this lock before executing the C code fragment, and then
|
||||
** release it afterwards.
|
||||
** XXX we should emit a warning if may_call_mercury and not_threadsafe
|
||||
** (the defaults) are specified since if you obtain the lock then
|
||||
** call back into Mercury deadlock could result.
|
||||
*/
|
||||
|
||||
extern MercuryLock MR_global_lock;
|
||||
|
||||
/*
|
||||
** MR_exception_handler_key stores a key which can be used to get
|
||||
** the current exception handler for the current thread.
|
||||
*/
|
||||
/*
|
||||
** MR_exception_handler_key stores a key which can be used to get
|
||||
** the current exception handler for the current thread.
|
||||
*/
|
||||
|
||||
extern MercuryThreadKey MR_exception_handler_key;
|
||||
|
||||
#else /* not MR_THREAD_SAFE */
|
||||
@@ -147,6 +158,7 @@
|
||||
** runqueue. The engine is destroyed when the execution of work from
|
||||
** the runqueue returns.
|
||||
*/
|
||||
|
||||
typedef enum { MR_use_now, MR_use_later } MR_when_to_use;
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user