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:
Zoltan Somogyi
2005-06-20 02:16:44 +00:00
parent 49dcb0a998
commit 0023d13f18
6 changed files with 204 additions and 186 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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