2019-06-20 13:44:47 +02:00
|
|
|
|
/* Copyright 1995-1998,2000-2014,2018-2019
|
2018-06-20 20:01:49 +02:00
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
|
|
|
|
This file is part of Guile.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is free software: you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU Lesser General Public License as published
|
|
|
|
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
License along with Guile. If not, see
|
|
|
|
|
|
<https://www.gnu.org/licenses/>. */
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
|
2008-09-13 15:35:27 +02:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
|
2018-06-17 19:46:33 +02:00
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
#include <full-read.h>
|
|
|
|
|
|
#include <nproc.h>
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
#include <stdio.h>
|
2018-06-17 19:46:33 +02:00
|
|
|
|
#include <stdlib.h>
|
2006-10-09 23:40:48 +00:00
|
|
|
|
#include <string.h> /* for memset used by FD_ZERO on Solaris 10 */
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
#include <sys/time.h>
|
2018-06-17 19:46:33 +02:00
|
|
|
|
#include <unistd.h>
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
|
2011-12-22 10:28:23 -05:00
|
|
|
|
#if HAVE_PTHREAD_NP_H
|
|
|
|
|
|
# include <pthread_np.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "async.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "bdw-gc.h"
|
|
|
|
|
|
#include "boolean.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "continuations.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "deprecation.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "dynwind.h"
|
|
|
|
|
|
#include "eval.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "extensions.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "fluids.h"
|
|
|
|
|
|
#include "gc-inline.h"
|
|
|
|
|
|
#include "gc.h"
|
|
|
|
|
|
#include "gsubr.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "hashtab.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "init.h"
|
|
|
|
|
|
#include "iselect.h"
|
2018-08-20 08:48:00 +02:00
|
|
|
|
#include "jit.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "list.h"
|
|
|
|
|
|
#include "modules.h"
|
|
|
|
|
|
#include "numbers.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "pairs.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "ports.h"
|
|
|
|
|
|
#include "scmsigs.h"
|
|
|
|
|
|
#include "strings.h"
|
|
|
|
|
|
#include "symbols.h"
|
|
|
|
|
|
#include "variable.h"
|
2018-10-07 15:15:02 +02:00
|
|
|
|
#include "version.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "vm.h"
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "threads.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <gc/gc_mark.h>
|
|
|
|
|
|
|
2011-01-22 19:55:31 +01:00
|
|
|
|
|
2013-11-22 13:01:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The GC "kind" for threads that allow them to mark their VM
|
|
|
|
|
|
stacks. */
|
|
|
|
|
|
static int thread_gc_kind;
|
|
|
|
|
|
|
|
|
|
|
|
static struct GC_ms_entry *
|
|
|
|
|
|
thread_mark (GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
|
|
|
|
|
|
struct GC_ms_entry *mark_stack_limit, GC_word env)
|
|
|
|
|
|
{
|
|
|
|
|
|
int word;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
struct scm_thread *t = (struct scm_thread *) addr;
|
2013-11-22 13:01:53 +01:00
|
|
|
|
|
|
|
|
|
|
if (SCM_UNPACK (t->handle) == 0)
|
|
|
|
|
|
/* T must be on the free-list; ignore. (See warning in
|
|
|
|
|
|
gc_mark.h.) */
|
|
|
|
|
|
return mark_stack_ptr;
|
|
|
|
|
|
|
2013-11-22 14:41:19 +01:00
|
|
|
|
/* Mark T. We could be more precise, but it doesn't matter. */
|
2013-11-22 13:01:53 +01:00
|
|
|
|
for (word = 0; word * sizeof (*addr) < sizeof (*t); word++)
|
|
|
|
|
|
mark_stack_ptr = GC_MARK_AND_PUSH ((void *) addr[word],
|
|
|
|
|
|
mark_stack_ptr, mark_stack_limit,
|
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
2014-02-02 16:04:58 +01:00
|
|
|
|
/* The pointerless freelists are threaded through their first word,
|
|
|
|
|
|
but GC doesn't know to trace them (as they are pointerless), so we
|
|
|
|
|
|
need to do that here. See the comments at the top of libgc's
|
|
|
|
|
|
gc_inline.h. */
|
2019-06-20 13:44:47 +02:00
|
|
|
|
for (size_t n = 0; n < SCM_INLINE_GC_FREELIST_COUNT; n++)
|
2014-02-21 14:42:24 +01:00
|
|
|
|
{
|
2019-06-20 13:44:47 +02:00
|
|
|
|
void *chain = t->pointerless_freelists[n];
|
|
|
|
|
|
if (chain)
|
2014-02-21 14:42:24 +01:00
|
|
|
|
{
|
2019-06-20 13:44:47 +02:00
|
|
|
|
/* The first link is already marked by the thread itsel, so we
|
|
|
|
|
|
just have to mark the tail. */
|
|
|
|
|
|
while ((chain = *(void **)chain))
|
|
|
|
|
|
mark_stack_ptr = GC_mark_and_push (chain, mark_stack_ptr,
|
|
|
|
|
|
mark_stack_limit, NULL);
|
2014-02-21 14:42:24 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-02-02 16:04:58 +01:00
|
|
|
|
|
2018-06-24 09:32:11 +02:00
|
|
|
|
mark_stack_ptr = scm_i_vm_mark_stack (&t->vm, mark_stack_ptr,
|
|
|
|
|
|
mark_stack_limit);
|
2013-11-22 14:41:19 +01:00
|
|
|
|
|
2013-11-22 13:01:53 +01:00
|
|
|
|
return mark_stack_ptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-11-30 18:43:41 +01:00
|
|
|
|
|
2008-03-08 16:22:40 +00:00
|
|
|
|
static void
|
|
|
|
|
|
to_timespec (SCM t, scm_t_timespec *waittime)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_pair (t))
|
|
|
|
|
|
{
|
|
|
|
|
|
waittime->tv_sec = scm_to_ulong (SCM_CAR (t));
|
|
|
|
|
|
waittime->tv_nsec = scm_to_ulong (SCM_CDR (t)) * 1000;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
double time = scm_to_double (t);
|
|
|
|
|
|
double sec = scm_c_truncate (time);
|
|
|
|
|
|
|
|
|
|
|
|
waittime->tv_sec = (long) sec;
|
2008-03-24 21:51:09 +00:00
|
|
|
|
waittime->tv_nsec = (long) ((time - sec) * 1000000000);
|
2008-03-08 16:22:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-11-22 13:01:53 +01:00
|
|
|
|
|
2009-09-15 00:39:04 +02:00
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
/*** Queues */
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
|
2009-09-15 00:39:04 +02:00
|
|
|
|
/* Note: We annotate with "GC-robust" assignments whose purpose is to avoid
|
|
|
|
|
|
the risk of false references leading to unbounded retained space as
|
|
|
|
|
|
described in "Bounding Space Usage of Conservative Garbage Collectors",
|
|
|
|
|
|
H.J. Boehm, 2001. */
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Make an empty queue data structure.
|
|
|
|
|
|
*/
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
static SCM
|
|
|
|
|
|
make_queue ()
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_cons (SCM_EOL, SCM_EOL);
|
|
|
|
|
|
}
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
|
2016-11-01 21:26:42 +01:00
|
|
|
|
static scm_i_pthread_mutex_t queue_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Put T at the back of Q and return a handle that can be used with
|
|
|
|
|
|
remqueue to remove T from Q again.
|
|
|
|
|
|
*/
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
static SCM
|
|
|
|
|
|
enqueue (SCM q, SCM t)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM c = scm_cons (t, SCM_EOL);
|
2016-11-01 21:26:42 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&queue_lock);
|
2004-09-22 17:41:37 +00:00
|
|
|
|
if (scm_is_null (SCM_CDR (q)))
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_SETCDR (q, c);
|
|
|
|
|
|
else
|
|
|
|
|
|
SCM_SETCDR (SCM_CAR (q), c);
|
|
|
|
|
|
SCM_SETCAR (q, c);
|
2016-11-01 21:26:42 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&queue_lock);
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
return c;
|
|
|
|
|
|
}
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Remove the element that the handle C refers to from the queue Q. C
|
|
|
|
|
|
must have been returned from a call to enqueue. The return value
|
|
|
|
|
|
is zero when the element referred to by C has already been removed.
|
|
|
|
|
|
Otherwise, 1 is returned.
|
|
|
|
|
|
*/
|
|
|
|
|
|
static int
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
remqueue (SCM q, SCM c)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM p, prev = q;
|
2016-11-01 21:26:42 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&queue_lock);
|
2004-09-22 17:41:37 +00:00
|
|
|
|
for (p = SCM_CDR (q); !scm_is_null (p); p = SCM_CDR (p))
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (p, c))
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (c, SCM_CAR (q)))
|
2013-06-17 14:43:58 -04:00
|
|
|
|
SCM_SETCAR (q, scm_is_eq (prev, q) ? SCM_EOL : prev);
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_SETCDR (prev, SCM_CDR (c));
|
2009-09-15 00:39:04 +02:00
|
|
|
|
|
|
|
|
|
|
/* GC-robust */
|
|
|
|
|
|
SCM_SETCDR (c, SCM_EOL);
|
|
|
|
|
|
|
2016-11-01 21:26:42 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&queue_lock);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return 1;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
prev = p;
|
|
|
|
|
|
}
|
2016-11-01 21:26:42 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&queue_lock);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return 0;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Remove the front-most element from the queue Q and return it.
|
|
|
|
|
|
Return SCM_BOOL_F when Q is empty.
|
|
|
|
|
|
*/
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
static SCM
|
|
|
|
|
|
dequeue (SCM q)
|
|
|
|
|
|
{
|
Fix hang in srfi-18.test
* libguile/threads.h (held_mutex): New field.
* libguile/threads.c (enqueue, remqueue, dequeue): Use critical
section to protect access to the queue.
(guilify_self_1): Initialize held_mutex field.
(on_thread_exit): If held_mutex non-null, unlock it.
(fat_mutex_unlock, fat_cond_free, scm_make_condition_variable,
fat_cond_signal, fat_cond_broadcast): Delete now unnecessary uses
of c->lock.
(fat_mutex_unlock): Pass m->lock to block_self() instead of
c->lock; move scm_i_pthread_mutex_unlock(m->lock) call from before
block_self() to after.
(scm_pthread_cond_wait, scm_pthread_cond_timedwait,
scm_i_thread_sleep_for_gc): Set held_mutex before pthread call;
reset it afterwards.
I was seeing a hang in srfi-18.test, when running make check in master,
in the "exception handler installation is thread-safe" test. It wasn't
100% reproducible, so looked like a race.
The problem is that wait-condition-variable is not actually
atomic in the way that it is supposed to be. It unlocks the mutex,
then starts waiting on the cond var. So it is possible for another
thread to lock the same mutex, and signal the cond var, before the
wait-condition-variable thread starts waiting.
In order for wait-condition-variable to be atomic - e.g. in a race
where thread A holds (Scheme-level) mutex M, and calls
(wait-condition-variable C M), and thread B calls (begin (lock-mutex
M) (signal-condition-variable C)) - it needs to call pthread_cond_wait
with the same underlying mutex as is involved in the `lock-mutex'
call. In terms of the threads.c code, this means that it has to use
M->lock, not C->lock.
block_self() used its mutex arg for two purposes: for protecting
access and changes to the wait queue, and for the pthread_cond_wait
call. But it wouldn't work reliably to use M->lock to protect C's
wait queue, because in theory two threads can call
(wait-condition-variable C M1) and (wait-condition-variable C M2)
concurrently, with M1 and M2 different. So we either have to pass
both C->lock and M->lock into block_self(), or use some other mutex to
protect the wait queue. For this patch, I switched to using the
critical section mutex, because that is a global and so easily
available. (If that turns out to be a problem for performance, we
could make each queue structure have its own mutex, but there's no
reason to believe yet that it is a problem, because the critical
section mutex isn't used much overall.)
So then we call block_self() with M->lock, and move where M->lock is
unlocked to after the block_self() call, instead of before.
That solves the first hang, but introduces a new one, when a SRFI-18
thread is terminated (`thread-terminate!') between being launched
(`make-thread') and started (`thread-start!'). The problem now is
that pthread_cond_wait is a cancellation point (see man
pthread_cancel), so the pthread_cond_wait call is one of the few
places where a thread-terminate! call can take effect. If the thread
is cancelled at that point, M->lock ends up still being locked, and
then when do_thread_exit() tries to lock M->lock again, it hangs.
The fix for that is a new `held_mutex' field in scm_i_thread, which is
set to point to the mutex just before a pthread_cond_(timed)wait call,
and set to NULL again afterwards. If on_thread_exit() finds that
held_mutex is non-NULL, it unlocks that mutex.
A detail is that checking and unlocking held_mutex must be done before
on_thread_exit() calls scm_i_ensure_signal_delivery_thread(), because
the innards of scm_i_ensure_signal_delivery_thread() can do another
pthread_cond_wait() call and so overwrite held_mutex. But that's OK,
because it's fine for the mutex check and unlock to happen outside
Guile mode.
Lastly, C->lock is then not needed, so I've removed it.
2008-10-22 08:45:42 +01:00
|
|
|
|
SCM c;
|
2016-11-01 21:26:42 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&queue_lock);
|
Fix hang in srfi-18.test
* libguile/threads.h (held_mutex): New field.
* libguile/threads.c (enqueue, remqueue, dequeue): Use critical
section to protect access to the queue.
(guilify_self_1): Initialize held_mutex field.
(on_thread_exit): If held_mutex non-null, unlock it.
(fat_mutex_unlock, fat_cond_free, scm_make_condition_variable,
fat_cond_signal, fat_cond_broadcast): Delete now unnecessary uses
of c->lock.
(fat_mutex_unlock): Pass m->lock to block_self() instead of
c->lock; move scm_i_pthread_mutex_unlock(m->lock) call from before
block_self() to after.
(scm_pthread_cond_wait, scm_pthread_cond_timedwait,
scm_i_thread_sleep_for_gc): Set held_mutex before pthread call;
reset it afterwards.
I was seeing a hang in srfi-18.test, when running make check in master,
in the "exception handler installation is thread-safe" test. It wasn't
100% reproducible, so looked like a race.
The problem is that wait-condition-variable is not actually
atomic in the way that it is supposed to be. It unlocks the mutex,
then starts waiting on the cond var. So it is possible for another
thread to lock the same mutex, and signal the cond var, before the
wait-condition-variable thread starts waiting.
In order for wait-condition-variable to be atomic - e.g. in a race
where thread A holds (Scheme-level) mutex M, and calls
(wait-condition-variable C M), and thread B calls (begin (lock-mutex
M) (signal-condition-variable C)) - it needs to call pthread_cond_wait
with the same underlying mutex as is involved in the `lock-mutex'
call. In terms of the threads.c code, this means that it has to use
M->lock, not C->lock.
block_self() used its mutex arg for two purposes: for protecting
access and changes to the wait queue, and for the pthread_cond_wait
call. But it wouldn't work reliably to use M->lock to protect C's
wait queue, because in theory two threads can call
(wait-condition-variable C M1) and (wait-condition-variable C M2)
concurrently, with M1 and M2 different. So we either have to pass
both C->lock and M->lock into block_self(), or use some other mutex to
protect the wait queue. For this patch, I switched to using the
critical section mutex, because that is a global and so easily
available. (If that turns out to be a problem for performance, we
could make each queue structure have its own mutex, but there's no
reason to believe yet that it is a problem, because the critical
section mutex isn't used much overall.)
So then we call block_self() with M->lock, and move where M->lock is
unlocked to after the block_self() call, instead of before.
That solves the first hang, but introduces a new one, when a SRFI-18
thread is terminated (`thread-terminate!') between being launched
(`make-thread') and started (`thread-start!'). The problem now is
that pthread_cond_wait is a cancellation point (see man
pthread_cancel), so the pthread_cond_wait call is one of the few
places where a thread-terminate! call can take effect. If the thread
is cancelled at that point, M->lock ends up still being locked, and
then when do_thread_exit() tries to lock M->lock again, it hangs.
The fix for that is a new `held_mutex' field in scm_i_thread, which is
set to point to the mutex just before a pthread_cond_(timed)wait call,
and set to NULL again afterwards. If on_thread_exit() finds that
held_mutex is non-NULL, it unlocks that mutex.
A detail is that checking and unlocking held_mutex must be done before
on_thread_exit() calls scm_i_ensure_signal_delivery_thread(), because
the innards of scm_i_ensure_signal_delivery_thread() can do another
pthread_cond_wait() call and so overwrite held_mutex. But that's OK,
because it's fine for the mutex check and unlock to happen outside
Guile mode.
Lastly, C->lock is then not needed, so I've removed it.
2008-10-22 08:45:42 +01:00
|
|
|
|
c = SCM_CDR (q);
|
2004-09-22 17:41:37 +00:00
|
|
|
|
if (scm_is_null (c))
|
Fix hang in srfi-18.test
* libguile/threads.h (held_mutex): New field.
* libguile/threads.c (enqueue, remqueue, dequeue): Use critical
section to protect access to the queue.
(guilify_self_1): Initialize held_mutex field.
(on_thread_exit): If held_mutex non-null, unlock it.
(fat_mutex_unlock, fat_cond_free, scm_make_condition_variable,
fat_cond_signal, fat_cond_broadcast): Delete now unnecessary uses
of c->lock.
(fat_mutex_unlock): Pass m->lock to block_self() instead of
c->lock; move scm_i_pthread_mutex_unlock(m->lock) call from before
block_self() to after.
(scm_pthread_cond_wait, scm_pthread_cond_timedwait,
scm_i_thread_sleep_for_gc): Set held_mutex before pthread call;
reset it afterwards.
I was seeing a hang in srfi-18.test, when running make check in master,
in the "exception handler installation is thread-safe" test. It wasn't
100% reproducible, so looked like a race.
The problem is that wait-condition-variable is not actually
atomic in the way that it is supposed to be. It unlocks the mutex,
then starts waiting on the cond var. So it is possible for another
thread to lock the same mutex, and signal the cond var, before the
wait-condition-variable thread starts waiting.
In order for wait-condition-variable to be atomic - e.g. in a race
where thread A holds (Scheme-level) mutex M, and calls
(wait-condition-variable C M), and thread B calls (begin (lock-mutex
M) (signal-condition-variable C)) - it needs to call pthread_cond_wait
with the same underlying mutex as is involved in the `lock-mutex'
call. In terms of the threads.c code, this means that it has to use
M->lock, not C->lock.
block_self() used its mutex arg for two purposes: for protecting
access and changes to the wait queue, and for the pthread_cond_wait
call. But it wouldn't work reliably to use M->lock to protect C's
wait queue, because in theory two threads can call
(wait-condition-variable C M1) and (wait-condition-variable C M2)
concurrently, with M1 and M2 different. So we either have to pass
both C->lock and M->lock into block_self(), or use some other mutex to
protect the wait queue. For this patch, I switched to using the
critical section mutex, because that is a global and so easily
available. (If that turns out to be a problem for performance, we
could make each queue structure have its own mutex, but there's no
reason to believe yet that it is a problem, because the critical
section mutex isn't used much overall.)
So then we call block_self() with M->lock, and move where M->lock is
unlocked to after the block_self() call, instead of before.
That solves the first hang, but introduces a new one, when a SRFI-18
thread is terminated (`thread-terminate!') between being launched
(`make-thread') and started (`thread-start!'). The problem now is
that pthread_cond_wait is a cancellation point (see man
pthread_cancel), so the pthread_cond_wait call is one of the few
places where a thread-terminate! call can take effect. If the thread
is cancelled at that point, M->lock ends up still being locked, and
then when do_thread_exit() tries to lock M->lock again, it hangs.
The fix for that is a new `held_mutex' field in scm_i_thread, which is
set to point to the mutex just before a pthread_cond_(timed)wait call,
and set to NULL again afterwards. If on_thread_exit() finds that
held_mutex is non-NULL, it unlocks that mutex.
A detail is that checking and unlocking held_mutex must be done before
on_thread_exit() calls scm_i_ensure_signal_delivery_thread(), because
the innards of scm_i_ensure_signal_delivery_thread() can do another
pthread_cond_wait() call and so overwrite held_mutex. But that's OK,
because it's fine for the mutex check and unlock to happen outside
Guile mode.
Lastly, C->lock is then not needed, so I've removed it.
2008-10-22 08:45:42 +01:00
|
|
|
|
{
|
2016-11-01 21:26:42 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&queue_lock);
|
Fix hang in srfi-18.test
* libguile/threads.h (held_mutex): New field.
* libguile/threads.c (enqueue, remqueue, dequeue): Use critical
section to protect access to the queue.
(guilify_self_1): Initialize held_mutex field.
(on_thread_exit): If held_mutex non-null, unlock it.
(fat_mutex_unlock, fat_cond_free, scm_make_condition_variable,
fat_cond_signal, fat_cond_broadcast): Delete now unnecessary uses
of c->lock.
(fat_mutex_unlock): Pass m->lock to block_self() instead of
c->lock; move scm_i_pthread_mutex_unlock(m->lock) call from before
block_self() to after.
(scm_pthread_cond_wait, scm_pthread_cond_timedwait,
scm_i_thread_sleep_for_gc): Set held_mutex before pthread call;
reset it afterwards.
I was seeing a hang in srfi-18.test, when running make check in master,
in the "exception handler installation is thread-safe" test. It wasn't
100% reproducible, so looked like a race.
The problem is that wait-condition-variable is not actually
atomic in the way that it is supposed to be. It unlocks the mutex,
then starts waiting on the cond var. So it is possible for another
thread to lock the same mutex, and signal the cond var, before the
wait-condition-variable thread starts waiting.
In order for wait-condition-variable to be atomic - e.g. in a race
where thread A holds (Scheme-level) mutex M, and calls
(wait-condition-variable C M), and thread B calls (begin (lock-mutex
M) (signal-condition-variable C)) - it needs to call pthread_cond_wait
with the same underlying mutex as is involved in the `lock-mutex'
call. In terms of the threads.c code, this means that it has to use
M->lock, not C->lock.
block_self() used its mutex arg for two purposes: for protecting
access and changes to the wait queue, and for the pthread_cond_wait
call. But it wouldn't work reliably to use M->lock to protect C's
wait queue, because in theory two threads can call
(wait-condition-variable C M1) and (wait-condition-variable C M2)
concurrently, with M1 and M2 different. So we either have to pass
both C->lock and M->lock into block_self(), or use some other mutex to
protect the wait queue. For this patch, I switched to using the
critical section mutex, because that is a global and so easily
available. (If that turns out to be a problem for performance, we
could make each queue structure have its own mutex, but there's no
reason to believe yet that it is a problem, because the critical
section mutex isn't used much overall.)
So then we call block_self() with M->lock, and move where M->lock is
unlocked to after the block_self() call, instead of before.
That solves the first hang, but introduces a new one, when a SRFI-18
thread is terminated (`thread-terminate!') between being launched
(`make-thread') and started (`thread-start!'). The problem now is
that pthread_cond_wait is a cancellation point (see man
pthread_cancel), so the pthread_cond_wait call is one of the few
places where a thread-terminate! call can take effect. If the thread
is cancelled at that point, M->lock ends up still being locked, and
then when do_thread_exit() tries to lock M->lock again, it hangs.
The fix for that is a new `held_mutex' field in scm_i_thread, which is
set to point to the mutex just before a pthread_cond_(timed)wait call,
and set to NULL again afterwards. If on_thread_exit() finds that
held_mutex is non-NULL, it unlocks that mutex.
A detail is that checking and unlocking held_mutex must be done before
on_thread_exit() calls scm_i_ensure_signal_delivery_thread(), because
the innards of scm_i_ensure_signal_delivery_thread() can do another
pthread_cond_wait() call and so overwrite held_mutex. But that's OK,
because it's fine for the mutex check and unlock to happen outside
Guile mode.
Lastly, C->lock is then not needed, so I've removed it.
2008-10-22 08:45:42 +01:00
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_SETCDR (q, SCM_CDR (c));
|
2004-09-22 17:41:37 +00:00
|
|
|
|
if (scm_is_null (SCM_CDR (q)))
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_SETCAR (q, SCM_EOL);
|
2016-11-01 21:26:42 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&queue_lock);
|
2009-09-15 00:39:04 +02:00
|
|
|
|
|
|
|
|
|
|
/* GC-robust */
|
|
|
|
|
|
SCM_SETCDR (c, SCM_EOL);
|
|
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
return SCM_CAR (c);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/*** Thread smob routines */
|
2005-01-24 23:41:14 +00:00
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
thread_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
|
|
|
|
|
|
{
|
2007-01-15 23:42:45 +00:00
|
|
|
|
/* On a Gnu system pthread_t is an unsigned long, but on mingw it's a
|
|
|
|
|
|
struct. A cast like "(unsigned long) t->pthread" is a syntax error in
|
|
|
|
|
|
the struct case, hence we go via a union, and extract according to the
|
|
|
|
|
|
size of pthread_t. */
|
|
|
|
|
|
union {
|
|
|
|
|
|
scm_i_pthread_t p;
|
|
|
|
|
|
unsigned short us;
|
|
|
|
|
|
unsigned int ui;
|
|
|
|
|
|
unsigned long ul;
|
2018-06-21 08:39:03 +02:00
|
|
|
|
uintmax_t um;
|
2007-01-15 23:42:45 +00:00
|
|
|
|
} u;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_THREAD_DATA (exp);
|
2007-01-15 23:42:45 +00:00
|
|
|
|
scm_i_pthread_t p = t->pthread;
|
2018-06-21 08:39:03 +02:00
|
|
|
|
uintmax_t id;
|
2007-01-15 23:42:45 +00:00
|
|
|
|
u.p = p;
|
|
|
|
|
|
if (sizeof (p) == sizeof (unsigned short))
|
|
|
|
|
|
id = u.us;
|
|
|
|
|
|
else if (sizeof (p) == sizeof (unsigned int))
|
|
|
|
|
|
id = u.ui;
|
|
|
|
|
|
else if (sizeof (p) == sizeof (unsigned long))
|
|
|
|
|
|
id = u.ul;
|
|
|
|
|
|
else
|
|
|
|
|
|
id = u.um;
|
|
|
|
|
|
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts ("#<thread ", port);
|
2007-01-15 23:42:45 +00:00
|
|
|
|
scm_uintprint (id, 10, port);
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts (" (", port);
|
* variable.c, threads.c, struct.c, stackchk.c, smob.c, root.c,
print.c, ports.c, mallocs.c, hooks.c, hashtab.c, fports.c,
guardians.c, filesys.c, coop-pthreads.c, continuations.c: Use
scm_uintprint to print unsigned integers, raw heap words, and
adresses, using a cast to scm_t_bits to turn pointers into
integers.
2004-10-22 15:13:12 +00:00
|
|
|
|
scm_uintprint ((scm_t_bits)t, 16, port);
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts (")>", port);
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-09-14 23:37:15 +02:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/*** Blocking on queues. */
|
2002-10-03 22:48:15 +00:00
|
|
|
|
|
2016-10-26 22:32:51 +02:00
|
|
|
|
/* See also scm_system_async_mark_for_thread for how such a block is
|
2005-03-02 20:42:01 +00:00
|
|
|
|
interrputed.
|
|
|
|
|
|
*/
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Put the current thread on QUEUE and go to sleep, waiting for it to
|
|
|
|
|
|
be woken up by a call to 'unblock_from_queue', or to be
|
|
|
|
|
|
interrupted. Upon return of this function, the current thread is
|
|
|
|
|
|
no longer on QUEUE, even when the sleep has been interrupted.
|
|
|
|
|
|
|
Fix hang in srfi-18.test
* libguile/threads.h (held_mutex): New field.
* libguile/threads.c (enqueue, remqueue, dequeue): Use critical
section to protect access to the queue.
(guilify_self_1): Initialize held_mutex field.
(on_thread_exit): If held_mutex non-null, unlock it.
(fat_mutex_unlock, fat_cond_free, scm_make_condition_variable,
fat_cond_signal, fat_cond_broadcast): Delete now unnecessary uses
of c->lock.
(fat_mutex_unlock): Pass m->lock to block_self() instead of
c->lock; move scm_i_pthread_mutex_unlock(m->lock) call from before
block_self() to after.
(scm_pthread_cond_wait, scm_pthread_cond_timedwait,
scm_i_thread_sleep_for_gc): Set held_mutex before pthread call;
reset it afterwards.
I was seeing a hang in srfi-18.test, when running make check in master,
in the "exception handler installation is thread-safe" test. It wasn't
100% reproducible, so looked like a race.
The problem is that wait-condition-variable is not actually
atomic in the way that it is supposed to be. It unlocks the mutex,
then starts waiting on the cond var. So it is possible for another
thread to lock the same mutex, and signal the cond var, before the
wait-condition-variable thread starts waiting.
In order for wait-condition-variable to be atomic - e.g. in a race
where thread A holds (Scheme-level) mutex M, and calls
(wait-condition-variable C M), and thread B calls (begin (lock-mutex
M) (signal-condition-variable C)) - it needs to call pthread_cond_wait
with the same underlying mutex as is involved in the `lock-mutex'
call. In terms of the threads.c code, this means that it has to use
M->lock, not C->lock.
block_self() used its mutex arg for two purposes: for protecting
access and changes to the wait queue, and for the pthread_cond_wait
call. But it wouldn't work reliably to use M->lock to protect C's
wait queue, because in theory two threads can call
(wait-condition-variable C M1) and (wait-condition-variable C M2)
concurrently, with M1 and M2 different. So we either have to pass
both C->lock and M->lock into block_self(), or use some other mutex to
protect the wait queue. For this patch, I switched to using the
critical section mutex, because that is a global and so easily
available. (If that turns out to be a problem for performance, we
could make each queue structure have its own mutex, but there's no
reason to believe yet that it is a problem, because the critical
section mutex isn't used much overall.)
So then we call block_self() with M->lock, and move where M->lock is
unlocked to after the block_self() call, instead of before.
That solves the first hang, but introduces a new one, when a SRFI-18
thread is terminated (`thread-terminate!') between being launched
(`make-thread') and started (`thread-start!'). The problem now is
that pthread_cond_wait is a cancellation point (see man
pthread_cancel), so the pthread_cond_wait call is one of the few
places where a thread-terminate! call can take effect. If the thread
is cancelled at that point, M->lock ends up still being locked, and
then when do_thread_exit() tries to lock M->lock again, it hangs.
The fix for that is a new `held_mutex' field in scm_i_thread, which is
set to point to the mutex just before a pthread_cond_(timed)wait call,
and set to NULL again afterwards. If on_thread_exit() finds that
held_mutex is non-NULL, it unlocks that mutex.
A detail is that checking and unlocking held_mutex must be done before
on_thread_exit() calls scm_i_ensure_signal_delivery_thread(), because
the innards of scm_i_ensure_signal_delivery_thread() can do another
pthread_cond_wait() call and so overwrite held_mutex. But that's OK,
because it's fine for the mutex check and unlock to happen outside
Guile mode.
Lastly, C->lock is then not needed, so I've removed it.
2008-10-22 08:45:42 +01:00
|
|
|
|
The caller of block_self must hold MUTEX. It will be atomically
|
2005-03-02 20:42:01 +00:00
|
|
|
|
unlocked while sleeping, just as with scm_i_pthread_cond_wait.
|
|
|
|
|
|
|
|
|
|
|
|
When WAITTIME is not NULL, the sleep will be aborted at that time.
|
|
|
|
|
|
|
|
|
|
|
|
The return value of block_self is an errno value. It will be zero
|
|
|
|
|
|
when the sleep has been successfully completed by a call to
|
|
|
|
|
|
unblock_from_queue, EINTR when it has been interrupted by the
|
|
|
|
|
|
delivery of a system async, and ETIMEDOUT when the timeout has
|
|
|
|
|
|
expired.
|
|
|
|
|
|
|
|
|
|
|
|
The system asyncs themselves are not executed by block_self.
|
|
|
|
|
|
*/
|
|
|
|
|
|
static int
|
2016-11-13 15:08:45 +01:00
|
|
|
|
block_self (SCM queue, scm_i_pthread_mutex_t *mutex,
|
2005-03-02 20:42:01 +00:00
|
|
|
|
const scm_t_timespec *waittime)
|
2005-01-24 23:41:14 +00:00
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM q_handle;
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
2016-12-29 18:46:16 +01:00
|
|
|
|
if (scm_i_prepare_to_wait_on_cond (t, mutex, &t->sleep_cond))
|
|
|
|
|
|
return EINTR;
|
|
|
|
|
|
|
|
|
|
|
|
t->block_asyncs++;
|
|
|
|
|
|
q_handle = enqueue (queue, t->handle);
|
|
|
|
|
|
if (waittime == NULL)
|
|
|
|
|
|
err = scm_i_scm_pthread_cond_wait (&t->sleep_cond, mutex);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
else
|
2016-12-29 18:46:16 +01:00
|
|
|
|
err = scm_i_scm_pthread_cond_timedwait (&t->sleep_cond, mutex, waittime);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2016-12-29 18:46:16 +01:00
|
|
|
|
/* When we are still on QUEUE, we have been interrupted. We
|
|
|
|
|
|
report this only when no other error (such as a timeout) has
|
|
|
|
|
|
happened above.
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (remqueue (queue, q_handle) && err == 0)
|
|
|
|
|
|
err = EINTR;
|
|
|
|
|
|
t->block_asyncs--;
|
|
|
|
|
|
scm_i_wait_finished (t);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
|
|
|
|
|
return err;
|
2005-01-24 23:41:14 +00:00
|
|
|
|
}
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
Fix hang in srfi-18.test
* libguile/threads.h (held_mutex): New field.
* libguile/threads.c (enqueue, remqueue, dequeue): Use critical
section to protect access to the queue.
(guilify_self_1): Initialize held_mutex field.
(on_thread_exit): If held_mutex non-null, unlock it.
(fat_mutex_unlock, fat_cond_free, scm_make_condition_variable,
fat_cond_signal, fat_cond_broadcast): Delete now unnecessary uses
of c->lock.
(fat_mutex_unlock): Pass m->lock to block_self() instead of
c->lock; move scm_i_pthread_mutex_unlock(m->lock) call from before
block_self() to after.
(scm_pthread_cond_wait, scm_pthread_cond_timedwait,
scm_i_thread_sleep_for_gc): Set held_mutex before pthread call;
reset it afterwards.
I was seeing a hang in srfi-18.test, when running make check in master,
in the "exception handler installation is thread-safe" test. It wasn't
100% reproducible, so looked like a race.
The problem is that wait-condition-variable is not actually
atomic in the way that it is supposed to be. It unlocks the mutex,
then starts waiting on the cond var. So it is possible for another
thread to lock the same mutex, and signal the cond var, before the
wait-condition-variable thread starts waiting.
In order for wait-condition-variable to be atomic - e.g. in a race
where thread A holds (Scheme-level) mutex M, and calls
(wait-condition-variable C M), and thread B calls (begin (lock-mutex
M) (signal-condition-variable C)) - it needs to call pthread_cond_wait
with the same underlying mutex as is involved in the `lock-mutex'
call. In terms of the threads.c code, this means that it has to use
M->lock, not C->lock.
block_self() used its mutex arg for two purposes: for protecting
access and changes to the wait queue, and for the pthread_cond_wait
call. But it wouldn't work reliably to use M->lock to protect C's
wait queue, because in theory two threads can call
(wait-condition-variable C M1) and (wait-condition-variable C M2)
concurrently, with M1 and M2 different. So we either have to pass
both C->lock and M->lock into block_self(), or use some other mutex to
protect the wait queue. For this patch, I switched to using the
critical section mutex, because that is a global and so easily
available. (If that turns out to be a problem for performance, we
could make each queue structure have its own mutex, but there's no
reason to believe yet that it is a problem, because the critical
section mutex isn't used much overall.)
So then we call block_self() with M->lock, and move where M->lock is
unlocked to after the block_self() call, instead of before.
That solves the first hang, but introduces a new one, when a SRFI-18
thread is terminated (`thread-terminate!') between being launched
(`make-thread') and started (`thread-start!'). The problem now is
that pthread_cond_wait is a cancellation point (see man
pthread_cancel), so the pthread_cond_wait call is one of the few
places where a thread-terminate! call can take effect. If the thread
is cancelled at that point, M->lock ends up still being locked, and
then when do_thread_exit() tries to lock M->lock again, it hangs.
The fix for that is a new `held_mutex' field in scm_i_thread, which is
set to point to the mutex just before a pthread_cond_(timed)wait call,
and set to NULL again afterwards. If on_thread_exit() finds that
held_mutex is non-NULL, it unlocks that mutex.
A detail is that checking and unlocking held_mutex must be done before
on_thread_exit() calls scm_i_ensure_signal_delivery_thread(), because
the innards of scm_i_ensure_signal_delivery_thread() can do another
pthread_cond_wait() call and so overwrite held_mutex. But that's OK,
because it's fine for the mutex check and unlock to happen outside
Guile mode.
Lastly, C->lock is then not needed, so I've removed it.
2008-10-22 08:45:42 +01:00
|
|
|
|
/* Wake up the first thread on QUEUE, if any. The awoken thread is
|
|
|
|
|
|
returned, or #f if the queue was empty.
|
2005-03-02 20:42:01 +00:00
|
|
|
|
*/
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
unblock_from_queue (SCM queue)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM thread = dequeue (queue);
|
|
|
|
|
|
if (scm_is_true (thread))
|
|
|
|
|
|
scm_i_pthread_cond_signal (&SCM_I_THREAD_DATA(thread)->sleep_cond);
|
|
|
|
|
|
return thread;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-09-11 00:03:03 +02:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Getting into and out of guile mode.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2011-03-18 13:18:47 +01:00
|
|
|
|
/* Key used to attach a cleanup handler to a given thread. Also, if
|
|
|
|
|
|
thread-local storage is unavailable, this key is used to retrieve the
|
|
|
|
|
|
current thread with `pthread_getspecific ()'. */
|
|
|
|
|
|
scm_i_pthread_key_t scm_i_thread_key;
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-10-02 16:32:34 +02:00
|
|
|
|
#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
|
|
|
|
|
|
|
|
|
|
|
|
/* When thread-local storage (TLS) is available, a pointer to the
|
|
|
|
|
|
current-thread object is kept in TLS. Note that storing the thread-object
|
|
|
|
|
|
itself in TLS (rather than a pointer to some malloc'd memory) is not
|
|
|
|
|
|
possible since thread objects may live longer than the actual thread they
|
|
|
|
|
|
represent. */
|
2018-06-26 11:40:22 +02:00
|
|
|
|
SCM_THREAD_LOCAL scm_thread *scm_i_current_thread = NULL;
|
2009-10-02 16:32:34 +02:00
|
|
|
|
|
2011-03-18 13:18:47 +01:00
|
|
|
|
#endif /* SCM_HAVE_THREAD_STORAGE_CLASS */
|
2009-10-02 16:32:34 +02:00
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static scm_i_pthread_mutex_t thread_admin_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
static scm_thread *all_threads = NULL;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static int thread_count;
|
|
|
|
|
|
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
static SCM default_dynamic_state;
|
2011-06-16 19:35:14 +02:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Perform first stage of thread initialisation, in non-guile mode.
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
*/
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static void
|
2017-02-28 13:14:02 +01:00
|
|
|
|
guilify_self_1 (struct GC_stack_base *base, int needs_unregister)
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread t;
|
2011-03-25 15:35:20 +01:00
|
|
|
|
|
|
|
|
|
|
/* We must arrange for SCM_I_CURRENT_THREAD to point to a valid value
|
|
|
|
|
|
before allocating anything in this thread, because allocation could
|
|
|
|
|
|
cause GC to run, and GC could cause finalizers, which could invoke
|
|
|
|
|
|
Scheme functions, which need the current thread to be set. */
|
|
|
|
|
|
|
2018-06-24 08:59:42 +02:00
|
|
|
|
memset (&t, 0, sizeof (t));
|
|
|
|
|
|
|
2011-03-25 15:35:20 +01:00
|
|
|
|
t.pthread = scm_i_pthread_self ();
|
|
|
|
|
|
t.handle = SCM_BOOL_F;
|
|
|
|
|
|
t.result = SCM_BOOL_F;
|
2016-10-26 22:32:51 +02:00
|
|
|
|
t.pending_asyncs = SCM_EOL;
|
2011-03-25 15:35:20 +01:00
|
|
|
|
t.block_asyncs = 1;
|
|
|
|
|
|
t.base = base->mem_base;
|
|
|
|
|
|
t.continuation_root = SCM_EOL;
|
|
|
|
|
|
t.continuation_base = t.base;
|
|
|
|
|
|
scm_i_pthread_cond_init (&t.sleep_cond, NULL);
|
2018-06-24 09:32:11 +02:00
|
|
|
|
scm_i_vm_prepare_stack (&t.vm);
|
2011-03-25 15:35:20 +01:00
|
|
|
|
|
2011-06-16 18:27:57 +02:00
|
|
|
|
if (pipe2 (t.sleep_pipe, O_CLOEXEC) != 0)
|
2008-11-30 18:43:41 +01:00
|
|
|
|
/* FIXME: Error conditions during the initialization phase are handled
|
|
|
|
|
|
gracelessly since public functions such as `scm_init_guile ()'
|
|
|
|
|
|
currently have type `void'. */
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
2011-03-25 15:35:20 +01:00
|
|
|
|
t.exited = 0;
|
|
|
|
|
|
t.guile_mode = 0;
|
2017-02-28 13:14:02 +01:00
|
|
|
|
t.needs_unregister = needs_unregister;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2011-03-25 15:35:20 +01:00
|
|
|
|
/* The switcheroo. */
|
|
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t_ptr = &t;
|
2011-03-25 15:35:20 +01:00
|
|
|
|
|
|
|
|
|
|
GC_disable ();
|
2013-11-22 13:01:53 +01:00
|
|
|
|
t_ptr = GC_generic_malloc (sizeof (*t_ptr), thread_gc_kind);
|
2011-03-25 15:35:20 +01:00
|
|
|
|
memcpy (t_ptr, &t, sizeof t);
|
|
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_setspecific (scm_i_thread_key, t_ptr);
|
2011-03-18 13:18:47 +01:00
|
|
|
|
|
|
|
|
|
|
#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
|
2011-03-25 15:35:20 +01:00
|
|
|
|
/* Cache the current thread in TLS for faster lookup. */
|
|
|
|
|
|
scm_i_current_thread = t_ptr;
|
2011-03-18 13:18:47 +01:00
|
|
|
|
#endif
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2011-03-25 15:35:20 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&thread_admin_mutex);
|
|
|
|
|
|
t_ptr->next_thread = all_threads;
|
|
|
|
|
|
all_threads = t_ptr;
|
|
|
|
|
|
thread_count++;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
GC_enable ();
|
|
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Perform second stage of thread initialisation, in guile mode.
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
*/
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static void
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
guilify_self_2 (SCM dynamic_state)
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2008-09-18 22:55:16 +02:00
|
|
|
|
t->guile_mode = 1;
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM_NEWSMOB (t->handle, scm_tc16_thread, t);
|
2006-04-02 21:04:30 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
t->continuation_root = scm_cons (t->handle, SCM_EOL);
|
|
|
|
|
|
t->continuation_base = t->base;
|
|
|
|
|
|
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
t->dynamic_state = scm_gc_typed_calloc (scm_t_dynamic_state);
|
2017-03-07 20:57:59 +01:00
|
|
|
|
t->dynamic_state->thread_local_values = scm_c_make_hash_table (0);
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
scm_set_current_dynamic_state (dynamic_state);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
the dynamic stack is really a stack now, instead of a list
* libguile/dynstack.h:
* libguile/dynstack.c: New files, implementing the dynamic stack as a
true stack instead of a linked list. This lowers the cost of
dynwinds: frames, winders, prompts, with-fluids, and dynamic-wind.
For the most part, we allocate these items directly on the stack.
* libguile/dynwinds.h:
* libguile/dynwinds.c: Adapt all manipulators of the wind stack to use
interfaces from dynstack.c. Remove heap-allocated winder and frame
object types.
(scm_dowinds, scm_i_dowinds): Remove these. The first was exported,
but it was not a public interface.
* libguile/continuations.c:
* libguile/continuations.h (scm_t_contregs): Continuation objects
reference scm_t_dynstack* values now. Adapt to the new interfaces.
* libguile/control.c:
* libguile/control.h: There is no longer a scm_tc7_prompt kind of object
that can be allocated on the heap. Instead, the prompt flags, key,
and registers are pushed on the dynwind stack. (The registers are
still on the heap.) Also, since the vm_cont will reference the
dynwinds, make the partial continuation stub take just one extra arg,
instead of storing the intwinds separately in the object table.
* libguile/fluids.c:
* libguile/fluids.h: No more with-fluids objects; instead, the fluids go
on the dynstack. The values still have to be on the heap, though.
(scm_prepare_fluids, scm_swap_fluids): New internal functions,
replacing scm_i_make_with_fluids and scm_i_swap_with_fluids.
* libguile/print.c: Remove prompt and with-fluids printers.
* libguile/tags.h: Revert prompt and with-fluids tc7 values to what they
were before they were allocated.
* libguile/vm-i-system.c (partial_cont_call): Just pop the vmcont, the
intwinds will not be passed as a second arg. Rewind the dynamic stack
from within the VM, so that any rewinder sees valid prompt entries.
(call_cc, tail_call_cc): Adapt to pass the dynstack to
scm_i_vm_capture_stack.
(prompt, wind, unwind, wind_fluids, unwind_fluids): Adapt to the new
interfaces.
* libguile/vm.h (scm_i_capture_current_stack): Rename from
scm_i_vm_capture_continuation.
(scm_i_vm_capture_stack): Take a dynstack as an argument.
* libguile/vm.c (vm_reinstate_partial_continuation): Don't wind here, as
that could result in winders seeing invalid prompts.
* libguile/eval.c:
* libguile/root.c:
* libguile/stacks.c:
* libguile/threads.c:
* libguile/threads.h:
* libguile/throw.c: Adapt other users of dynwinds to use the dynstack.
2012-03-03 17:01:16 +01:00
|
|
|
|
t->dynstack.base = scm_gc_malloc (16 * sizeof (scm_t_bits), "dynstack");
|
|
|
|
|
|
t->dynstack.limit = t->dynstack.base + 16;
|
|
|
|
|
|
t->dynstack.top = t->dynstack.base + SCM_DYNSTACK_HEADER_LEN;
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
t->block_asyncs = 0;
|
2012-02-24 13:18:48 +01:00
|
|
|
|
|
|
|
|
|
|
/* See note in finalizers.c:queue_finalizer_async(). */
|
|
|
|
|
|
GC_invoke_finalizers ();
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2008-03-08 16:22:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
static void
|
2005-03-02 20:42:01 +00:00
|
|
|
|
on_thread_exit (void *v)
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2017-01-08 13:44:38 +01:00
|
|
|
|
/* This handler is executed in non-guile mode. Note that although
|
|
|
|
|
|
libgc isn't guaranteed to see thread-locals, for this thread-local
|
|
|
|
|
|
that isn't an issue as we have the all_threads list. */
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = (scm_thread *) v, **tp;
|
2005-03-09 19:13:59 +00:00
|
|
|
|
|
2016-11-14 21:57:46 +01:00
|
|
|
|
t->exited = 1;
|
2005-03-09 19:13:59 +00:00
|
|
|
|
|
2016-11-14 21:57:46 +01:00
|
|
|
|
close (t->sleep_pipe[0]);
|
|
|
|
|
|
close (t->sleep_pipe[1]);
|
|
|
|
|
|
t->sleep_pipe[0] = t->sleep_pipe[1] = -1;
|
2005-03-09 19:13:59 +00:00
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&thread_admin_mutex);
|
|
|
|
|
|
for (tp = &all_threads; *tp; tp = &(*tp)->next_thread)
|
|
|
|
|
|
if (*tp == t)
|
|
|
|
|
|
{
|
|
|
|
|
|
*tp = t->next_thread;
|
2009-09-15 00:39:04 +02:00
|
|
|
|
|
|
|
|
|
|
/* GC-robust */
|
|
|
|
|
|
t->next_thread = NULL;
|
|
|
|
|
|
|
2005-03-09 19:13:59 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
thread_count--;
|
2007-10-20 11:09:58 +00:00
|
|
|
|
|
2018-06-24 09:32:11 +02:00
|
|
|
|
/* Prevent any concurrent or future marker from visiting this
|
|
|
|
|
|
thread. */
|
|
|
|
|
|
t->handle = SCM_PACK (0);
|
|
|
|
|
|
|
2007-10-20 11:09:58 +00:00
|
|
|
|
/* If there's only one other thread, it could be the signal delivery
|
|
|
|
|
|
thread, so we need to notify it to shut down by closing its read pipe.
|
|
|
|
|
|
If it's not the signal delivery thread, then closing the read pipe isn't
|
|
|
|
|
|
going to hurt. */
|
|
|
|
|
|
if (thread_count <= 1)
|
|
|
|
|
|
scm_i_close_signal_pipe ();
|
|
|
|
|
|
|
2005-03-09 19:13:59 +00:00
|
|
|
|
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
|
|
|
|
|
|
|
2017-01-08 13:44:38 +01:00
|
|
|
|
/* Although this thread has exited, the thread object might still be
|
|
|
|
|
|
alive. Release unused memory. */
|
2019-06-20 13:44:47 +02:00
|
|
|
|
for (size_t n = 0; n < SCM_INLINE_GC_FREELIST_COUNT; n++)
|
|
|
|
|
|
t->freelists[n] = t->pointerless_freelists[n] = NULL;
|
2017-01-08 13:44:38 +01:00
|
|
|
|
t->dynamic_state = NULL;
|
|
|
|
|
|
t->dynstack.base = NULL;
|
|
|
|
|
|
t->dynstack.top = NULL;
|
|
|
|
|
|
t->dynstack.limit = NULL;
|
2018-06-24 08:59:42 +02:00
|
|
|
|
scm_i_vm_free_stack (&t->vm);
|
2018-09-17 09:28:41 +02:00
|
|
|
|
#if ENABLE_JIT
|
2018-08-20 08:48:00 +02:00
|
|
|
|
scm_jit_state_free (t->jit_state);
|
2018-09-17 09:28:41 +02:00
|
|
|
|
#endif
|
2018-08-20 08:48:00 +02:00
|
|
|
|
t->jit_state = NULL;
|
2013-11-22 14:41:19 +01:00
|
|
|
|
|
2017-02-28 13:14:02 +01:00
|
|
|
|
#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
|
|
|
|
|
|
scm_i_current_thread = NULL;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2011-04-13 12:03:50 +02:00
|
|
|
|
#if SCM_USE_PTHREAD_THREADS
|
2017-02-28 13:14:02 +01:00
|
|
|
|
if (t->needs_unregister)
|
|
|
|
|
|
GC_unregister_my_thread ();
|
2011-03-29 21:27:54 -07:00
|
|
|
|
#endif
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static scm_i_pthread_once_t init_thread_key_once = SCM_I_PTHREAD_ONCE_INIT;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static void
|
|
|
|
|
|
init_thread_key (void)
|
|
|
|
|
|
{
|
2011-03-18 13:18:47 +01:00
|
|
|
|
scm_i_pthread_key_create (&scm_i_thread_key, on_thread_exit);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
2011-01-22 19:55:31 +01:00
|
|
|
|
/* Perform any initializations necessary to make the current thread
|
|
|
|
|
|
known to Guile (via SCM_I_CURRENT_THREAD), initializing Guile itself,
|
|
|
|
|
|
if necessary.
|
2005-01-24 19:14:54 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
BASE is the stack base to use with GC.
|
|
|
|
|
|
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
DYNAMIC_STATE is the set of fluid values to start with.
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2011-01-22 19:55:31 +01:00
|
|
|
|
Returns zero when the thread was known to guile already; otherwise
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return 1.
|
2011-01-22 19:55:31 +01:00
|
|
|
|
|
|
|
|
|
|
Note that it could be the case that the thread was known
|
|
|
|
|
|
to Guile, but not in guile mode (because we are within a
|
|
|
|
|
|
scm_without_guile call). Check SCM_I_CURRENT_THREAD->guile_mode to
|
|
|
|
|
|
be sure. New threads are put into guile mode implicitly. */
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
|
|
|
|
|
static int
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
scm_i_init_thread_for_guile (struct GC_stack_base *base,
|
|
|
|
|
|
SCM dynamic_state)
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_i_pthread_once (&init_thread_key_once, init_thread_key);
|
|
|
|
|
|
|
2011-01-22 19:55:31 +01:00
|
|
|
|
if (SCM_I_CURRENT_THREAD)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Thread is already known to Guile.
|
|
|
|
|
|
*/
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2005-03-02 20:42:01 +00:00
|
|
|
|
{
|
|
|
|
|
|
/* This thread has not been guilified yet.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&scm_i_init_mutex);
|
|
|
|
|
|
if (scm_initialized_p == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* First thread ever to enter Guile. Run the full
|
|
|
|
|
|
initialization.
|
|
|
|
|
|
*/
|
|
|
|
|
|
scm_i_init_guile (base);
|
2011-03-25 13:01:51 +01:00
|
|
|
|
|
2013-11-22 10:51:56 +01:00
|
|
|
|
#if SCM_USE_PTHREAD_THREADS
|
2011-03-25 13:01:51 +01:00
|
|
|
|
/* Allow other threads to come in later. */
|
|
|
|
|
|
GC_allow_register_threads ();
|
2011-03-29 21:25:04 -07:00
|
|
|
|
#endif
|
2011-03-25 13:01:51 +01:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_i_pthread_mutex_unlock (&scm_i_init_mutex);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2017-02-28 13:14:02 +01:00
|
|
|
|
int needs_unregister = 0;
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Guile is already initialized, but this thread enters it for
|
|
|
|
|
|
the first time. Only initialize this thread.
|
|
|
|
|
|
*/
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&scm_i_init_mutex);
|
2011-03-25 13:01:51 +01:00
|
|
|
|
|
|
|
|
|
|
/* Register this thread with libgc. */
|
2011-04-13 12:03:50 +02:00
|
|
|
|
#if SCM_USE_PTHREAD_THREADS
|
2017-02-28 13:14:02 +01:00
|
|
|
|
if (GC_register_my_thread (base) == GC_SUCCESS)
|
|
|
|
|
|
needs_unregister = 1;
|
2011-04-13 12:03:50 +02:00
|
|
|
|
#endif
|
2011-03-25 13:01:51 +01:00
|
|
|
|
|
2017-02-28 13:14:02 +01:00
|
|
|
|
guilify_self_1 (base, needs_unregister);
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
guilify_self_2 (dynamic_state);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-03-25 13:01:51 +01:00
|
|
|
|
void
|
|
|
|
|
|
scm_init_guile ()
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2011-03-25 13:01:51 +01:00
|
|
|
|
struct GC_stack_base stack_base;
|
|
|
|
|
|
|
|
|
|
|
|
if (GC_get_stack_base (&stack_base) == GC_SUCCESS)
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
scm_i_init_thread_for_guile (&stack_base, default_dynamic_state);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2011-03-25 13:01:51 +01:00
|
|
|
|
fprintf (stderr, "Failed to get stack base for current thread.\n");
|
2011-05-15 15:27:30 +02:00
|
|
|
|
exit (EXIT_FAILURE);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
2005-01-24 19:14:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-03-25 13:01:51 +01:00
|
|
|
|
struct with_guile_args
|
2011-01-22 19:55:31 +01:00
|
|
|
|
{
|
|
|
|
|
|
GC_fn_type func;
|
|
|
|
|
|
void *data;
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
SCM dynamic_state;
|
2011-01-22 19:55:31 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
|
with_guile_trampoline (void *data)
|
|
|
|
|
|
{
|
2011-03-25 13:01:51 +01:00
|
|
|
|
struct with_guile_args *args = data;
|
2011-01-22 19:55:31 +01:00
|
|
|
|
|
|
|
|
|
|
return scm_c_with_continuation_barrier (args->func, args->data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-03-25 13:01:51 +01:00
|
|
|
|
static void *
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
with_guile (struct GC_stack_base *base, void *data)
|
2005-03-02 20:42:01 +00:00
|
|
|
|
{
|
|
|
|
|
|
void *res;
|
2011-01-22 19:55:31 +01:00
|
|
|
|
int new_thread;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t;
|
2011-03-25 13:01:51 +01:00
|
|
|
|
struct with_guile_args *args = data;
|
2007-10-20 11:09:58 +00:00
|
|
|
|
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
new_thread = scm_i_init_thread_for_guile (base, args->dynamic_state);
|
2011-01-22 19:55:31 +01:00
|
|
|
|
t = SCM_I_CURRENT_THREAD;
|
|
|
|
|
|
if (new_thread)
|
2007-10-20 11:09:58 +00:00
|
|
|
|
{
|
2011-01-22 19:55:31 +01:00
|
|
|
|
/* We are in Guile mode. */
|
|
|
|
|
|
assert (t->guile_mode);
|
|
|
|
|
|
|
2011-03-25 13:01:51 +01:00
|
|
|
|
res = scm_c_with_continuation_barrier (args->func, args->data);
|
2011-01-22 19:55:31 +01:00
|
|
|
|
|
|
|
|
|
|
/* Leave Guile mode. */
|
|
|
|
|
|
t->guile_mode = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (t->guile_mode)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Already in Guile mode. */
|
2011-03-25 13:01:51 +01:00
|
|
|
|
res = scm_c_with_continuation_barrier (args->func, args->data);
|
2007-10-20 11:09:58 +00:00
|
|
|
|
}
|
2008-05-14 23:52:49 +01:00
|
|
|
|
else
|
2011-01-22 19:55:31 +01:00
|
|
|
|
{
|
|
|
|
|
|
/* We are not in Guile mode, either because we are not within a
|
|
|
|
|
|
scm_with_guile, or because we are within a scm_without_guile.
|
2008-09-18 22:55:16 +02:00
|
|
|
|
|
2011-01-22 19:55:31 +01:00
|
|
|
|
This call to scm_with_guile() could happen from anywhere on the
|
|
|
|
|
|
stack, and in particular lower on the stack than when it was
|
|
|
|
|
|
when this thread was first guilified. Thus, `base' must be
|
|
|
|
|
|
updated. */
|
|
|
|
|
|
#if SCM_STACK_GROWS_UP
|
2011-03-25 13:01:51 +01:00
|
|
|
|
if (SCM_STACK_PTR (base->mem_base) < t->base)
|
|
|
|
|
|
t->base = SCM_STACK_PTR (base->mem_base);
|
2011-01-22 19:55:31 +01:00
|
|
|
|
#else
|
2011-03-25 13:01:51 +01:00
|
|
|
|
if (SCM_STACK_PTR (base->mem_base) > t->base)
|
|
|
|
|
|
t->base = SCM_STACK_PTR (base->mem_base);
|
2011-01-22 19:55:31 +01:00
|
|
|
|
#endif
|
2008-09-18 22:55:16 +02:00
|
|
|
|
|
2011-01-22 19:55:31 +01:00
|
|
|
|
t->guile_mode = 1;
|
2013-11-22 10:51:56 +01:00
|
|
|
|
res = GC_call_with_gc_active (with_guile_trampoline, args);
|
2011-01-22 19:55:31 +01:00
|
|
|
|
t->guile_mode = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return res;
|
2008-09-18 22:55:16 +02:00
|
|
|
|
}
|
2009-10-09 14:42:07 +02:00
|
|
|
|
|
2011-03-25 13:01:51 +01:00
|
|
|
|
static void *
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
scm_i_with_guile (void *(*func)(void *), void *data, SCM dynamic_state)
|
2011-03-25 13:01:51 +01:00
|
|
|
|
{
|
|
|
|
|
|
struct with_guile_args args;
|
|
|
|
|
|
|
|
|
|
|
|
args.func = func;
|
|
|
|
|
|
args.data = data;
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
args.dynamic_state = dynamic_state;
|
2011-03-25 13:01:51 +01:00
|
|
|
|
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
return GC_call_with_stack_base (with_guile, &args);
|
2011-03-25 13:01:51 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
|
scm_with_guile (void *(*func)(void *), void *data)
|
|
|
|
|
|
{
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
return scm_i_with_guile (func, data, default_dynamic_state);
|
2011-03-25 13:01:51 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
void *
|
|
|
|
|
|
scm_without_guile (void *(*func)(void *), void *data)
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2008-09-18 22:55:16 +02:00
|
|
|
|
void *result;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD;
|
2008-09-18 22:55:16 +02:00
|
|
|
|
|
2011-01-22 19:55:31 +01:00
|
|
|
|
if (t->guile_mode)
|
2008-09-18 22:55:16 +02:00
|
|
|
|
{
|
2011-01-22 19:55:31 +01:00
|
|
|
|
SCM_I_CURRENT_THREAD->guile_mode = 0;
|
2013-11-22 10:51:56 +01:00
|
|
|
|
result = GC_do_blocking (func, data);
|
2011-01-22 19:55:31 +01:00
|
|
|
|
SCM_I_CURRENT_THREAD->guile_mode = 1;
|
2008-09-18 22:55:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2011-01-22 19:55:31 +01:00
|
|
|
|
/* Otherwise we're not in guile mode, so nothing to do. */
|
2008-09-18 22:55:16 +02:00
|
|
|
|
result = func (data);
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2008-09-18 22:55:16 +02:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/*** Thread creation */
|
|
|
|
|
|
|
2016-10-25 22:24:19 +02:00
|
|
|
|
/* Because (ice-9 boot-9) loads up (ice-9 threads), we know that this
|
|
|
|
|
|
variable will get loaded before a call to scm_call_with_new_thread
|
|
|
|
|
|
and therefore no lock or pthread_once_t is needed. */
|
|
|
|
|
|
static SCM call_with_new_thread_var;
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_call_with_new_thread (SCM thunk, SCM handler)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM call_with_new_thread = scm_variable_ref (call_with_new_thread_var);
|
|
|
|
|
|
if (SCM_UNBNDP (handler))
|
|
|
|
|
|
return scm_call_1 (call_with_new_thread, thunk);
|
|
|
|
|
|
return scm_call_2 (call_with_new_thread, thunk, handler);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-11 22:17:24 +01:00
|
|
|
|
typedef struct launch_data launch_data;
|
|
|
|
|
|
|
|
|
|
|
|
struct launch_data {
|
|
|
|
|
|
launch_data *prev;
|
|
|
|
|
|
launch_data *next;
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
SCM dynamic_state;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM thunk;
|
2017-01-11 22:17:24 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* GC-protect the launch data for new threads. */
|
|
|
|
|
|
static launch_data *protected_launch_data;
|
|
|
|
|
|
static scm_i_pthread_mutex_t protected_launch_data_lock =
|
|
|
|
|
|
SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
protect_launch_data (launch_data *data)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&protected_launch_data_lock);
|
|
|
|
|
|
data->next = protected_launch_data;
|
|
|
|
|
|
if (protected_launch_data)
|
|
|
|
|
|
protected_launch_data->prev = data;
|
|
|
|
|
|
protected_launch_data = data;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&protected_launch_data_lock);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
unprotect_launch_data (launch_data *data)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&protected_launch_data_lock);
|
|
|
|
|
|
if (data->next)
|
|
|
|
|
|
data->next->prev = data->prev;
|
|
|
|
|
|
if (data->prev)
|
|
|
|
|
|
data->prev->next = data->next;
|
|
|
|
|
|
else
|
|
|
|
|
|
protected_launch_data = data->next;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&protected_launch_data_lock);
|
|
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static void *
|
|
|
|
|
|
really_launch (void *d)
|
|
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD;
|
2017-01-11 22:17:24 +01:00
|
|
|
|
unprotect_launch_data (d);
|
2017-01-08 13:02:56 +01:00
|
|
|
|
/* The thread starts with asyncs blocked. */
|
|
|
|
|
|
t->block_asyncs++;
|
2016-10-25 22:24:19 +02:00
|
|
|
|
SCM_I_CURRENT_THREAD->result = scm_call_0 (((launch_data *)d)->thunk);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return 0;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static void *
|
|
|
|
|
|
launch_thread (void *d)
|
|
|
|
|
|
{
|
|
|
|
|
|
launch_data *data = (launch_data *)d;
|
|
|
|
|
|
scm_i_pthread_detach (scm_i_pthread_self ());
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
scm_i_with_guile (really_launch, d, data->dynamic_state);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-25 22:24:19 +02:00
|
|
|
|
SCM_INTERNAL SCM scm_sys_call_with_new_thread (SCM);
|
|
|
|
|
|
SCM_DEFINE (scm_sys_call_with_new_thread, "%call-with-new-thread", 1, 0, 0,
|
|
|
|
|
|
(SCM thunk), "")
|
|
|
|
|
|
#define FUNC_NAME s_scm_sys_call_with_new_thread
|
|
|
|
|
|
{
|
|
|
|
|
|
launch_data *data;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_i_pthread_t id;
|
|
|
|
|
|
int err;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM_ASSERT (scm_is_true (scm_thunk_p (thunk)), thunk, SCM_ARG1, FUNC_NAME);
|
|
|
|
|
|
|
2011-11-29 20:26:40 +01:00
|
|
|
|
GC_collect_a_little ();
|
2016-10-25 22:24:19 +02:00
|
|
|
|
data = scm_gc_typed_calloc (launch_data);
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
data->dynamic_state = scm_current_dynamic_state ();
|
2016-10-25 22:24:19 +02:00
|
|
|
|
data->thunk = thunk;
|
2017-01-11 22:17:24 +01:00
|
|
|
|
protect_launch_data (data);
|
2016-10-25 22:24:19 +02:00
|
|
|
|
err = scm_i_pthread_create (&id, NULL, launch_thread, data);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
if (err)
|
|
|
|
|
|
{
|
|
|
|
|
|
errno = err;
|
|
|
|
|
|
scm_syserror (NULL);
|
|
|
|
|
|
}
|
2013-03-13 11:01:38 +01:00
|
|
|
|
|
2016-10-25 22:24:19 +02:00
|
|
|
|
return SCM_UNSPECIFIED;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_spawn_thread (scm_t_catch_body body, void *body_data,
|
|
|
|
|
|
scm_t_catch_handler handler, void *handler_data)
|
|
|
|
|
|
{
|
2016-11-14 21:25:53 +01:00
|
|
|
|
SCM body_closure, handler_closure;
|
2008-05-14 23:52:49 +01:00
|
|
|
|
|
Rebase throw/catch on top of raise-exception/with-exception-handler
* libguile/exceptions.c:
* libguile/exceptions.h: New files.
* libguile.h: Add exceptions.h.
* libguile/Makefile.am (libguile_@GUILE_EFFECTIVE_VERSION@_la_SOURCES):
(DOT_X_FILES, DOT_DOC_FILES, modinclude_HEADERS): Add exceptions.c and
exceptions.h.
* libguile/init.c (scm_i_init_guile): Initialize exceptions.
* libguile/threads.c (scm_spawn_thread): Use new names for
scm_i_make_catch_handler and scm_c_make_thunk.
* libguile/throw.c: Rewrite to be implemented in terms of
with-exception-handler / raise-exception.
* libguile/throw.h: Use data types from exceptions.h. Move
scm_report_stack_overflow and scm_report_out_of_memory to
exceptions.[ch].
* module/ice-9/boot-9.scm (&error, &programming-error)
(&non-continuable, make-exception-from-throw, raise-exception)
(with-exception-handler): New top-level definitions.
(throw, catch, with-throw-handler): Rewrite in terms of
with-exception-handler and raise-exception.
: New top-level definitions.
* module/ice-9/exceptions.scm: Adapt to re-export &error,
&programming-error, &non-continuable, raise-exception, and
with-exception-handler from boot-9.
(make-quit-exception, guile-quit-exception-converter): New exception
converters.
(make-exception-from-throw): Override core binding.
* test-suite/tests/eval.test ("inner trim with prompt tag"): Adapt to
"with-exception-handler" being the procedure on the stack.
("outer trim with prompt tag"): Likewise.
* test-suite/tests/exceptions.test (throw-test): Use pass-if-equal.
* module/srfi/srfi-34.scm: Reimplement in terms of core exceptions, and
make "guard" actually re-raise continuations with the original "raise"
continuation.
2019-11-08 15:31:00 +01:00
|
|
|
|
body_closure = scm_c_make_thunk (body, body_data);
|
2016-11-14 21:25:53 +01:00
|
|
|
|
handler_closure = handler == NULL ? SCM_UNDEFINED :
|
Rebase throw/catch on top of raise-exception/with-exception-handler
* libguile/exceptions.c:
* libguile/exceptions.h: New files.
* libguile.h: Add exceptions.h.
* libguile/Makefile.am (libguile_@GUILE_EFFECTIVE_VERSION@_la_SOURCES):
(DOT_X_FILES, DOT_DOC_FILES, modinclude_HEADERS): Add exceptions.c and
exceptions.h.
* libguile/init.c (scm_i_init_guile): Initialize exceptions.
* libguile/threads.c (scm_spawn_thread): Use new names for
scm_i_make_catch_handler and scm_c_make_thunk.
* libguile/throw.c: Rewrite to be implemented in terms of
with-exception-handler / raise-exception.
* libguile/throw.h: Use data types from exceptions.h. Move
scm_report_stack_overflow and scm_report_out_of_memory to
exceptions.[ch].
* module/ice-9/boot-9.scm (&error, &programming-error)
(&non-continuable, make-exception-from-throw, raise-exception)
(with-exception-handler): New top-level definitions.
(throw, catch, with-throw-handler): Rewrite in terms of
with-exception-handler and raise-exception.
: New top-level definitions.
* module/ice-9/exceptions.scm: Adapt to re-export &error,
&programming-error, &non-continuable, raise-exception, and
with-exception-handler from boot-9.
(make-quit-exception, guile-quit-exception-converter): New exception
converters.
(make-exception-from-throw): Override core binding.
* test-suite/tests/eval.test ("inner trim with prompt tag"): Adapt to
"with-exception-handler" being the procedure on the stack.
("outer trim with prompt tag"): Likewise.
* test-suite/tests/exceptions.test (throw-test): Use pass-if-equal.
* module/srfi/srfi-34.scm: Reimplement in terms of core exceptions, and
make "guard" actually re-raise continuations with the original "raise"
continuation.
2019-11-08 15:31:00 +01:00
|
|
|
|
scm_i_make_catch_handler (handler, handler_data);
|
2012-01-12 00:38:22 +01:00
|
|
|
|
|
2016-11-14 21:25:53 +01:00
|
|
|
|
return scm_call_with_new_thread (body_closure, handler_closure);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2002-12-18 13:42:58 +00:00
|
|
|
|
SCM_DEFINE (scm_yield, "yield", 0, 0, 0,
|
|
|
|
|
|
(),
|
|
|
|
|
|
"Move the calling thread to the end of the scheduling queue.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_yield
|
|
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return scm_from_bool (scm_i_sched_yield ());
|
2002-12-18 13:42:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2016-10-27 21:22:28 +02:00
|
|
|
|
static SCM cancel_thread_var;
|
2014-07-04 15:52:15 +02:00
|
|
|
|
|
2016-10-27 21:22:28 +02:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_cancel_thread (SCM thread)
|
2007-10-20 11:09:58 +00:00
|
|
|
|
{
|
2016-10-27 21:22:28 +02:00
|
|
|
|
scm_call_1 (scm_variable_ref (cancel_thread_var), thread);
|
2007-10-20 11:09:58 +00:00
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
2014-07-04 15:52:15 +02:00
|
|
|
|
|
2016-11-14 21:35:44 +01:00
|
|
|
|
static SCM join_thread_var;
|
|
|
|
|
|
|
2016-11-05 19:39:12 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_join_thread (SCM thread)
|
2008-03-08 16:22:40 +00:00
|
|
|
|
{
|
2016-11-14 21:35:44 +01:00
|
|
|
|
return scm_call_1 (scm_variable_ref (join_thread_var), thread);
|
2008-03-08 16:22:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-11-14 21:35:44 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_join_thread_timed (SCM thread, SCM timeout, SCM timeoutval)
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
{
|
2016-11-14 21:35:44 +01:00
|
|
|
|
SCM join_thread = scm_variable_ref (join_thread_var);
|
2008-02-07 01:24:31 +00:00
|
|
|
|
|
2016-11-14 21:35:44 +01:00
|
|
|
|
if (SCM_UNBNDP (timeout))
|
|
|
|
|
|
return scm_call_1 (join_thread, thread);
|
|
|
|
|
|
else if (SCM_UNBNDP (timeoutval))
|
|
|
|
|
|
return scm_call_2 (join_thread, thread, timeout);
|
2008-03-08 16:22:40 +00:00
|
|
|
|
else
|
2016-11-14 21:35:44 +01:00
|
|
|
|
return scm_call_3 (join_thread, thread, timeout, timeoutval);
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2008-03-08 16:22:40 +00:00
|
|
|
|
SCM_DEFINE (scm_thread_p, "thread?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
|
|
|
|
|
"Return @code{#t} if @var{obj} is a thread.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_thread_p
|
|
|
|
|
|
{
|
|
|
|
|
|
return SCM_I_IS_THREAD(obj) ? SCM_BOOL_T : SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
|
2016-11-08 20:23:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
|
|
|
|
|
|
/* We implement our own mutex type since we want them to be 'fair', we
|
|
|
|
|
|
want to do fancy things while waiting for them (like running
|
|
|
|
|
|
asyncs) and we might want to add things that are nice for
|
|
|
|
|
|
debugging.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2016-11-08 20:23:20 +01:00
|
|
|
|
enum scm_mutex_kind {
|
2016-11-08 20:20:06 +01:00
|
|
|
|
/* A standard mutex can only be locked once. If you try to lock it
|
|
|
|
|
|
again from the thread that locked it to begin with (the "owner"
|
|
|
|
|
|
thread), it throws an error. It can only be unlocked from the
|
|
|
|
|
|
thread that locked it in the first place. */
|
2016-11-08 20:23:20 +01:00
|
|
|
|
SCM_MUTEX_STANDARD,
|
2016-11-08 20:20:06 +01:00
|
|
|
|
/* A recursive mutex can be locked multiple times by its owner. It
|
|
|
|
|
|
then has to be unlocked the corresponding number of times, and like
|
|
|
|
|
|
standard mutexes can only be unlocked by the owner thread. */
|
2016-11-08 20:23:20 +01:00
|
|
|
|
SCM_MUTEX_RECURSIVE,
|
2016-11-08 20:20:06 +01:00
|
|
|
|
/* An unowned mutex is like a standard mutex, except that it can be
|
|
|
|
|
|
unlocked by any thread. A corrolary of this behavior is that a
|
|
|
|
|
|
thread's attempt to lock a mutex that it already owns will block
|
|
|
|
|
|
instead of signalling an error, as it could be that some other
|
|
|
|
|
|
thread unlocks the mutex, allowing the owner thread to proceed.
|
|
|
|
|
|
This kind of mutex is a bit strange and is here for use by
|
|
|
|
|
|
SRFI-18. */
|
2016-11-08 20:23:20 +01:00
|
|
|
|
SCM_MUTEX_UNOWNED
|
2016-11-08 20:20:06 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_mutex {
|
2016-11-08 20:20:06 +01:00
|
|
|
|
scm_i_pthread_mutex_t lock;
|
2016-11-13 15:55:58 +01:00
|
|
|
|
/* The thread that owns this mutex, or #f if the mutex is unlocked. */
|
2016-11-08 20:20:06 +01:00
|
|
|
|
SCM owner;
|
2016-11-13 15:55:58 +01:00
|
|
|
|
/* Queue of threads waiting for this mutex. */
|
|
|
|
|
|
SCM waiting;
|
|
|
|
|
|
/* For SCM_MUTEX_RECURSIVE (and only SCM_MUTEX_RECURSIVE), the
|
|
|
|
|
|
recursive lock count. The first lock does not count. */
|
|
|
|
|
|
int level;
|
2016-11-08 20:23:20 +01:00
|
|
|
|
};
|
2016-11-08 20:20:06 +01:00
|
|
|
|
|
2016-11-08 20:37:38 +01:00
|
|
|
|
#define SCM_MUTEXP(x) SCM_SMOB_PREDICATE (scm_tc16_mutex, x)
|
|
|
|
|
|
#define SCM_MUTEX_DATA(x) ((struct scm_mutex *) SCM_SMOB_DATA (x))
|
|
|
|
|
|
#define SCM_MUTEX_KIND(x) ((enum scm_mutex_kind) (SCM_SMOB_FLAGS (x) & 0x3))
|
1999-12-13 03:40:23 +00:00
|
|
|
|
|
2005-01-24 23:41:14 +00:00
|
|
|
|
static int
|
2016-11-08 20:20:06 +01:00
|
|
|
|
scm_mutex_print (SCM mx, SCM port, scm_print_state *pstate SCM_UNUSED)
|
2005-01-24 23:41:14 +00:00
|
|
|
|
{
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_mutex *m = SCM_MUTEX_DATA (mx);
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts ("#<mutex ", port);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_uintprint ((scm_t_bits)m, 16, port);
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts (">", port);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return 1;
|
2005-01-24 23:41:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2008-03-24 21:51:09 +00:00
|
|
|
|
SCM_SYMBOL (allow_external_unlock_sym, "allow-external-unlock");
|
|
|
|
|
|
SCM_SYMBOL (recursive_sym, "recursive");
|
2008-03-08 16:22:40 +00:00
|
|
|
|
|
2016-11-05 11:14:17 +01:00
|
|
|
|
SCM_DEFINE (scm_make_mutex_with_kind, "make-mutex", 0, 1, 0,
|
|
|
|
|
|
(SCM kind),
|
|
|
|
|
|
"Create a new mutex. If @var{kind} is not given, the mutex\n"
|
|
|
|
|
|
"will be a standard non-recursive mutex. Otherwise pass\n"
|
|
|
|
|
|
"@code{recursive} to make a recursive mutex, or\n"
|
|
|
|
|
|
"@code{allow-external-unlock} to make a non-recursive mutex\n"
|
|
|
|
|
|
"that can be unlocked from any thread.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_mutex_with_kind
|
2005-01-24 23:41:14 +00:00
|
|
|
|
{
|
2016-11-08 20:23:20 +01:00
|
|
|
|
enum scm_mutex_kind mkind = SCM_MUTEX_STANDARD;
|
|
|
|
|
|
struct scm_mutex *m;
|
2016-11-08 20:20:06 +01:00
|
|
|
|
scm_i_pthread_mutex_t lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
2008-03-08 16:22:40 +00:00
|
|
|
|
|
2016-11-05 11:14:17 +01:00
|
|
|
|
if (!SCM_UNBNDP (kind))
|
2008-03-08 16:22:40 +00:00
|
|
|
|
{
|
2016-11-05 11:14:17 +01:00
|
|
|
|
if (scm_is_eq (kind, allow_external_unlock_sym))
|
2016-11-08 20:23:20 +01:00
|
|
|
|
mkind = SCM_MUTEX_UNOWNED;
|
2016-11-05 11:14:17 +01:00
|
|
|
|
else if (scm_is_eq (kind, recursive_sym))
|
2016-11-08 20:23:20 +01:00
|
|
|
|
mkind = SCM_MUTEX_RECURSIVE;
|
2008-05-14 23:52:49 +01:00
|
|
|
|
else
|
2016-11-05 11:14:17 +01:00
|
|
|
|
SCM_MISC_ERROR ("unsupported mutex kind: ~a", scm_list_1 (kind));
|
2008-03-08 16:22:40 +00:00
|
|
|
|
}
|
2016-11-05 11:14:17 +01:00
|
|
|
|
|
2016-11-08 20:23:20 +01:00
|
|
|
|
m = scm_gc_malloc (sizeof (struct scm_mutex), "mutex");
|
2016-11-08 20:20:06 +01:00
|
|
|
|
/* Because PTHREAD_MUTEX_INITIALIZER is static, it's plain old data,
|
|
|
|
|
|
and so we can just copy it. */
|
|
|
|
|
|
memcpy (&m->lock, &lock, sizeof (m->lock));
|
|
|
|
|
|
m->owner = SCM_BOOL_F;
|
|
|
|
|
|
m->level = 0;
|
|
|
|
|
|
m->waiting = make_queue ();
|
|
|
|
|
|
|
2016-11-08 20:37:38 +01:00
|
|
|
|
return scm_new_smob (scm_tc16_mutex | (mkind << 16), (scm_t_bits) m);
|
2005-01-24 23:41:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_make_mutex (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_make_mutex_with_kind (SCM_UNDEFINED);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM_DEFINE (scm_make_recursive_mutex, "make-recursive-mutex", 0, 0, 0,
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
(void),
|
2005-03-02 20:42:01 +00:00
|
|
|
|
"Create a new recursive mutex. ")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_recursive_mutex
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
{
|
2016-11-05 11:14:17 +01:00
|
|
|
|
return scm_make_mutex_with_kind (recursive_sym);
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_lock_mutex (SCM mx)
|
2005-03-02 20:42:01 +00:00
|
|
|
|
{
|
2016-11-08 20:20:06 +01:00
|
|
|
|
return scm_timed_lock_mutex (mx, SCM_UNDEFINED);
|
|
|
|
|
|
}
|
2008-03-08 16:22:40 +00:00
|
|
|
|
|
2016-11-13 15:47:21 +01:00
|
|
|
|
static inline SCM
|
|
|
|
|
|
lock_mutex (enum scm_mutex_kind kind, struct scm_mutex *m,
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *current_thread, scm_t_timespec *waittime)
|
2016-11-13 15:47:21 +01:00
|
|
|
|
#define FUNC_NAME "lock-mutex"
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_scm_pthread_mutex_lock (&m->lock);
|
|
|
|
|
|
|
|
|
|
|
|
if (scm_is_eq (m->owner, SCM_BOOL_F))
|
|
|
|
|
|
{
|
|
|
|
|
|
m->owner = current_thread->handle;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (kind == SCM_MUTEX_RECURSIVE &&
|
|
|
|
|
|
scm_is_eq (m->owner, current_thread->handle))
|
|
|
|
|
|
{
|
|
|
|
|
|
m->level++;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (kind == SCM_MUTEX_STANDARD &&
|
|
|
|
|
|
scm_is_eq (m->owner, current_thread->handle))
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
SCM_MISC_ERROR ("mutex already locked by thread", SCM_EOL);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
while (1)
|
|
|
|
|
|
{
|
|
|
|
|
|
int err = block_self (m->waiting, &m->lock, waittime);
|
|
|
|
|
|
|
|
|
|
|
|
if (err == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_eq (m->owner, SCM_BOOL_F))
|
|
|
|
|
|
{
|
|
|
|
|
|
m->owner = current_thread->handle;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (err == ETIMEDOUT)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (err == EINTR)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
scm_async_tick ();
|
|
|
|
|
|
scm_i_scm_pthread_mutex_lock (&m->lock);
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Shouldn't happen. */
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
errno = err;
|
|
|
|
|
|
SCM_SYSERROR;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
SCM_DEFINE (scm_timed_lock_mutex, "lock-mutex", 1, 1, 0,
|
|
|
|
|
|
(SCM mutex, SCM timeout),
|
|
|
|
|
|
"Lock mutex @var{mutex}. If the mutex is already locked, "
|
|
|
|
|
|
"the calling thread blocks until the mutex becomes available.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_timed_lock_mutex
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_timespec cwaittime, *waittime = NULL;
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_mutex *m;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD;
|
2016-11-13 15:47:21 +01:00
|
|
|
|
SCM ret;
|
2008-03-08 16:22:40 +00:00
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
SCM_VALIDATE_MUTEX (1, mutex);
|
|
|
|
|
|
m = SCM_MUTEX_DATA (mutex);
|
|
|
|
|
|
|
|
|
|
|
|
if (! SCM_UNBNDP (timeout) && ! scm_is_false (timeout))
|
|
|
|
|
|
{
|
|
|
|
|
|
to_timespec (timeout, &cwaittime);
|
|
|
|
|
|
waittime = &cwaittime;
|
|
|
|
|
|
}
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2016-11-13 15:47:21 +01:00
|
|
|
|
/* Specialized lock_mutex implementations according to the mutex
|
|
|
|
|
|
kind. */
|
|
|
|
|
|
switch (SCM_MUTEX_KIND (mutex))
|
2005-03-02 20:42:01 +00:00
|
|
|
|
{
|
2016-11-13 15:47:21 +01:00
|
|
|
|
case SCM_MUTEX_STANDARD:
|
|
|
|
|
|
ret = lock_mutex (SCM_MUTEX_STANDARD, m, t, waittime);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SCM_MUTEX_RECURSIVE:
|
|
|
|
|
|
ret = lock_mutex (SCM_MUTEX_RECURSIVE, m, t, waittime);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SCM_MUTEX_UNOWNED:
|
|
|
|
|
|
ret = lock_mutex (SCM_MUTEX_UNOWNED, m, t, waittime);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
2016-11-13 15:47:21 +01:00
|
|
|
|
|
|
|
|
|
|
scm_remember_upto_here_1 (mutex);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
}
|
2005-01-24 23:41:14 +00:00
|
|
|
|
#undef FUNC_NAME
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
|
2011-05-22 15:23:27 -04:00
|
|
|
|
static void
|
|
|
|
|
|
lock_mutex_return_void (SCM mx)
|
|
|
|
|
|
{
|
|
|
|
|
|
(void) scm_lock_mutex (mx);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
unlock_mutex_return_void (SCM mx)
|
|
|
|
|
|
{
|
|
|
|
|
|
(void) scm_unlock_mutex (mx);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-07 21:30:24 +00:00
|
|
|
|
void
|
2006-01-29 00:23:28 +00:00
|
|
|
|
scm_dynwind_lock_mutex (SCM mutex)
|
2005-03-07 21:30:24 +00:00
|
|
|
|
{
|
2011-05-22 15:23:27 -04:00
|
|
|
|
scm_dynwind_unwind_handler_with_scm (unlock_mutex_return_void, mutex,
|
2006-01-29 00:23:28 +00:00
|
|
|
|
SCM_F_WIND_EXPLICITLY);
|
2011-05-22 15:23:27 -04:00
|
|
|
|
scm_dynwind_rewind_handler_with_scm (lock_mutex_return_void, mutex,
|
2006-01-29 00:23:28 +00:00
|
|
|
|
SCM_F_WIND_EXPLICITLY);
|
2005-03-07 21:30:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-11-02 21:29:22 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_try_mutex (SCM mutex)
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
{
|
2016-11-05 19:39:12 +01:00
|
|
|
|
return scm_timed_lock_mutex (mutex, SCM_INUM0);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
2005-01-24 23:41:14 +00:00
|
|
|
|
|
2016-11-13 15:16:20 +01:00
|
|
|
|
/* This function is static inline so that the compiler can specialize it
|
|
|
|
|
|
against the mutex kind. */
|
|
|
|
|
|
static inline void
|
|
|
|
|
|
unlock_mutex (enum scm_mutex_kind kind, struct scm_mutex *m,
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *current_thread)
|
2016-11-13 15:16:20 +01:00
|
|
|
|
#define FUNC_NAME "unlock-mutex"
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_scm_pthread_mutex_lock (&m->lock);
|
|
|
|
|
|
|
|
|
|
|
|
if (!scm_is_eq (m->owner, current_thread->handle))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_eq (m->owner, SCM_BOOL_F))
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
SCM_MISC_ERROR ("mutex not locked", SCM_EOL);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (kind != SCM_MUTEX_UNOWNED)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
SCM_MISC_ERROR ("mutex not locked by current thread", SCM_EOL);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (kind == SCM_MUTEX_RECURSIVE && m->level > 0)
|
|
|
|
|
|
m->level--;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m->owner = SCM_BOOL_F;
|
|
|
|
|
|
/* Wake up one waiter. */
|
|
|
|
|
|
unblock_from_queue (m->waiting);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
SCM_DEFINE (scm_unlock_mutex, "unlock-mutex", 1, 0, 0, (SCM mutex),
|
|
|
|
|
|
"Unlocks @var{mutex}. The calling thread must already hold\n"
|
|
|
|
|
|
"the lock on @var{mutex}, unless the mutex was created with\n"
|
|
|
|
|
|
"the @code{allow-external-unlock} option; otherwise an error\n"
|
|
|
|
|
|
"will be signalled.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_unlock_mutex
|
|
|
|
|
|
{
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_mutex *m;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD;
|
2008-03-08 16:22:40 +00:00
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
SCM_VALIDATE_MUTEX (1, mutex);
|
2008-03-08 16:22:40 +00:00
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
m = SCM_MUTEX_DATA (mutex);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2016-11-13 15:16:20 +01:00
|
|
|
|
/* Specialized unlock_mutex implementations according to the mutex
|
|
|
|
|
|
kind. */
|
|
|
|
|
|
switch (SCM_MUTEX_KIND (mutex))
|
2016-11-13 12:43:46 +01:00
|
|
|
|
{
|
2016-11-13 15:16:20 +01:00
|
|
|
|
case SCM_MUTEX_STANDARD:
|
|
|
|
|
|
unlock_mutex (SCM_MUTEX_STANDARD, m, t);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SCM_MUTEX_RECURSIVE:
|
|
|
|
|
|
unlock_mutex (SCM_MUTEX_RECURSIVE, m, t);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SCM_MUTEX_UNOWNED:
|
|
|
|
|
|
unlock_mutex (SCM_MUTEX_UNOWNED, m, t);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
2016-11-13 12:43:46 +01:00
|
|
|
|
}
|
2008-03-08 16:22:40 +00:00
|
|
|
|
|
2016-11-13 15:16:20 +01:00
|
|
|
|
scm_remember_upto_here_1 (mutex);
|
2016-11-05 11:51:02 +01:00
|
|
|
|
|
|
|
|
|
|
return SCM_BOOL_T;
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2008-03-08 16:22:40 +00:00
|
|
|
|
SCM_DEFINE (scm_mutex_p, "mutex?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
|
|
|
|
|
"Return @code{#t} if @var{obj} is a mutex.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_mutex_p
|
|
|
|
|
|
{
|
|
|
|
|
|
return SCM_MUTEXP (obj) ? SCM_BOOL_T : SCM_BOOL_F;
|
|
|
|
|
|
}
|
2008-05-14 23:52:49 +01:00
|
|
|
|
#undef FUNC_NAME
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_mutex_owner, "mutex-owner", 1, 0, 0,
|
|
|
|
|
|
(SCM mx),
|
|
|
|
|
|
"Return the thread owning @var{mx}, or @code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_mutex_owner
|
|
|
|
|
|
{
|
2008-04-13 19:51:23 -04:00
|
|
|
|
SCM owner;
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_mutex *m = NULL;
|
2008-04-13 19:51:23 -04:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM_VALIDATE_MUTEX (1, mx);
|
2008-04-13 19:51:23 -04:00
|
|
|
|
m = SCM_MUTEX_DATA (mx);
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&m->lock);
|
|
|
|
|
|
owner = m->owner;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
|
|
|
|
|
|
return owner;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_mutex_level, "mutex-level", 1, 0, 0,
|
|
|
|
|
|
(SCM mx),
|
2008-04-13 19:51:23 -04:00
|
|
|
|
"Return the lock level of mutex @var{mx}.")
|
2005-03-02 20:42:01 +00:00
|
|
|
|
#define FUNC_NAME s_scm_mutex_level
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_MUTEX (1, mx);
|
2016-11-13 15:16:20 +01:00
|
|
|
|
if (SCM_MUTEX_KIND (mx) == SCM_MUTEX_RECURSIVE)
|
|
|
|
|
|
return scm_from_int (SCM_MUTEX_DATA (mx)->level + 1);
|
|
|
|
|
|
else if (scm_is_eq (SCM_MUTEX_DATA (mx)->owner, SCM_BOOL_F))
|
|
|
|
|
|
return SCM_INUM0;
|
|
|
|
|
|
else
|
|
|
|
|
|
return SCM_INUM1;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2008-04-13 19:51:23 -04:00
|
|
|
|
SCM_DEFINE (scm_mutex_locked_p, "mutex-locked?", 1, 0, 0,
|
|
|
|
|
|
(SCM mx),
|
|
|
|
|
|
"Returns @code{#t} if the mutex @var{mx} is locked.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_mutex_locked_p
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_MUTEX (1, mx);
|
2016-11-13 15:16:20 +01:00
|
|
|
|
if (scm_is_eq (SCM_MUTEX_DATA (mx)->owner, SCM_BOOL_F))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
else
|
|
|
|
|
|
return SCM_BOOL_T;
|
2008-04-13 19:51:23 -04:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
|
2016-11-08 20:23:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct scm_cond {
|
2016-11-08 20:20:06 +01:00
|
|
|
|
scm_i_pthread_mutex_t lock;
|
|
|
|
|
|
SCM waiting; /* the threads waiting for this condition. */
|
2016-11-08 20:23:20 +01:00
|
|
|
|
};
|
2016-11-08 20:20:06 +01:00
|
|
|
|
|
|
|
|
|
|
#define SCM_CONDVARP(x) SCM_SMOB_PREDICATE (scm_tc16_condvar, x)
|
2016-11-08 20:23:20 +01:00
|
|
|
|
#define SCM_CONDVAR_DATA(x) ((struct scm_cond *) SCM_SMOB_DATA (x))
|
2016-11-08 20:20:06 +01:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static int
|
2016-11-08 20:23:20 +01:00
|
|
|
|
scm_cond_print (SCM cv, SCM port, scm_print_state *pstate SCM_UNUSED)
|
2005-03-02 20:42:01 +00:00
|
|
|
|
{
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_cond *c = SCM_CONDVAR_DATA (cv);
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts ("#<condition-variable ", port);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_uintprint ((scm_t_bits)c, 16, port);
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts (">", port);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_DEFINE (scm_make_condition_variable, "make-condition-variable", 0, 0, 0,
|
|
|
|
|
|
(void),
|
|
|
|
|
|
"Make a new condition variable.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_condition_variable
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
{
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_cond *c;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM cv;
|
|
|
|
|
|
|
2016-11-08 20:23:20 +01:00
|
|
|
|
c = scm_gc_malloc (sizeof (struct scm_cond), "condition variable");
|
2005-03-02 20:42:01 +00:00
|
|
|
|
c->waiting = SCM_EOL;
|
|
|
|
|
|
SCM_NEWSMOB (cv, scm_tc16_condvar, (scm_t_bits) c);
|
|
|
|
|
|
c->waiting = make_queue ();
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
return cv;
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
#undef FUNC_NAME
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
|
2016-11-13 15:16:20 +01:00
|
|
|
|
static inline SCM
|
|
|
|
|
|
timed_wait (enum scm_mutex_kind kind, struct scm_mutex *m, struct scm_cond *c,
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *current_thread, scm_t_timespec *waittime)
|
2016-11-13 15:16:20 +01:00
|
|
|
|
#define FUNC_NAME "wait-condition-variable"
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_scm_pthread_mutex_lock (&m->lock);
|
|
|
|
|
|
|
|
|
|
|
|
if (!scm_is_eq (m->owner, current_thread->handle))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_eq (m->owner, SCM_BOOL_F))
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
SCM_MISC_ERROR ("mutex not locked", SCM_EOL);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (kind != SCM_MUTEX_UNOWNED)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
SCM_MISC_ERROR ("mutex not locked by current thread", SCM_EOL);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
|
{
|
|
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
|
|
|
|
/* Unlock the mutex. */
|
|
|
|
|
|
if (kind == SCM_MUTEX_RECURSIVE && m->level > 0)
|
|
|
|
|
|
m->level--;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m->owner = SCM_BOOL_F;
|
|
|
|
|
|
/* Wake up one waiter. */
|
|
|
|
|
|
unblock_from_queue (m->waiting);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Wait for someone to signal the cond, a timeout, or an
|
|
|
|
|
|
interrupt. */
|
|
|
|
|
|
err = block_self (c->waiting, &m->lock, waittime);
|
|
|
|
|
|
|
|
|
|
|
|
/* We woke up for some reason. Reacquire the mutex before doing
|
2017-01-08 13:18:13 +01:00
|
|
|
|
anything else.
|
|
|
|
|
|
|
|
|
|
|
|
FIXME: We disable interrupts while reacquiring the mutex. If
|
|
|
|
|
|
we allow interrupts here, there's the risk of a nonlocal exit
|
|
|
|
|
|
before we reaquire the mutex, which would be visible to user
|
|
|
|
|
|
code.
|
|
|
|
|
|
|
|
|
|
|
|
For example the unwind handler in
|
|
|
|
|
|
|
|
|
|
|
|
(with-mutex m (wait-condition-variable c m))
|
|
|
|
|
|
|
|
|
|
|
|
that tries to unlock M could see M in an already-unlocked
|
|
|
|
|
|
state, if an interrupt while waiting on C caused the wait to
|
|
|
|
|
|
abort and the woke thread lost the race to reacquire M. That's
|
|
|
|
|
|
not great. Maybe it's necessary but for now we just disable
|
|
|
|
|
|
interrupts while reaquiring a mutex after a wait. */
|
|
|
|
|
|
current_thread->block_asyncs++;
|
2016-11-30 22:56:54 +01:00
|
|
|
|
if (kind == SCM_MUTEX_RECURSIVE &&
|
|
|
|
|
|
scm_is_eq (m->owner, current_thread->handle))
|
2016-11-13 15:16:20 +01:00
|
|
|
|
{
|
|
|
|
|
|
m->level++;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
while (1)
|
|
|
|
|
|
{
|
2016-11-30 22:56:54 +01:00
|
|
|
|
if (scm_is_eq (m->owner, SCM_BOOL_F))
|
|
|
|
|
|
{
|
|
|
|
|
|
m->owner = current_thread->handle;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&m->lock);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2016-11-13 15:16:20 +01:00
|
|
|
|
block_self (m->waiting, &m->lock, waittime);
|
|
|
|
|
|
}
|
2017-01-08 13:18:13 +01:00
|
|
|
|
current_thread->block_asyncs--;
|
2016-11-13 15:16:20 +01:00
|
|
|
|
|
|
|
|
|
|
/* Now that we have the mutex again, handle the return value. */
|
|
|
|
|
|
if (err == 0)
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
else if (err == ETIMEDOUT)
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
else if (err == EINTR)
|
2016-11-30 22:56:54 +01:00
|
|
|
|
/* Let caller run scm_async_tick() and loop. */
|
|
|
|
|
|
return SCM_BOOL_T;
|
2016-11-13 15:16:20 +01:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Shouldn't happen. */
|
|
|
|
|
|
errno = err;
|
|
|
|
|
|
SCM_SYSERROR;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_DEFINE (scm_timed_wait_condition_variable, "wait-condition-variable", 2, 1, 0,
|
2016-11-08 20:20:06 +01:00
|
|
|
|
(SCM cond, SCM mutex, SCM timeout),
|
2012-01-11 23:33:01 -05:00
|
|
|
|
"Wait until condition variable @var{cv} has been signalled. While waiting, "
|
|
|
|
|
|
"mutex @var{mx} is atomically unlocked (as with @code{unlock-mutex}) and "
|
|
|
|
|
|
"is locked again when this function returns. When @var{t} is given, "
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
"it specifies a point in time where the waiting should be aborted. It "
|
|
|
|
|
|
"can be either a integer as returned by @code{current-time} or a pair "
|
|
|
|
|
|
"as returned by @code{gettimeofday}. When the waiting is aborted the "
|
|
|
|
|
|
"mutex is locked and @code{#f} is returned. When the condition "
|
|
|
|
|
|
"variable is in fact signalled, the mutex is also locked and @code{#t} "
|
|
|
|
|
|
"is returned. ")
|
|
|
|
|
|
#define FUNC_NAME s_scm_timed_wait_condition_variable
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
{
|
2016-11-08 20:20:06 +01:00
|
|
|
|
scm_t_timespec waittime_val, *waittime = NULL;
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_cond *c;
|
|
|
|
|
|
struct scm_mutex *m;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD;
|
2016-11-13 15:16:20 +01:00
|
|
|
|
SCM ret;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
SCM_VALIDATE_CONDVAR (1, cond);
|
|
|
|
|
|
SCM_VALIDATE_MUTEX (2, mutex);
|
|
|
|
|
|
|
|
|
|
|
|
c = SCM_CONDVAR_DATA (cond);
|
|
|
|
|
|
m = SCM_MUTEX_DATA (mutex);
|
2008-05-14 23:52:49 +01:00
|
|
|
|
|
2016-11-08 20:20:06 +01:00
|
|
|
|
if (!SCM_UNBNDP (timeout))
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2016-11-08 20:20:06 +01:00
|
|
|
|
to_timespec (timeout, &waittime_val);
|
|
|
|
|
|
waittime = &waittime_val;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-11-13 15:16:20 +01:00
|
|
|
|
/* Specialized timed_wait implementations according to the mutex
|
|
|
|
|
|
kind. */
|
|
|
|
|
|
switch (SCM_MUTEX_KIND (mutex))
|
2016-11-08 20:20:06 +01:00
|
|
|
|
{
|
2016-11-13 15:16:20 +01:00
|
|
|
|
case SCM_MUTEX_STANDARD:
|
|
|
|
|
|
ret = timed_wait (SCM_MUTEX_STANDARD, m, c, t, waittime);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SCM_MUTEX_RECURSIVE:
|
|
|
|
|
|
ret = timed_wait (SCM_MUTEX_RECURSIVE, m, c, t, waittime);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SCM_MUTEX_UNOWNED:
|
|
|
|
|
|
ret = timed_wait (SCM_MUTEX_UNOWNED, m, c, t, waittime);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
2016-11-08 20:20:06 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-11-13 15:16:20 +01:00
|
|
|
|
scm_remember_upto_here_2 (mutex, cond);
|
2016-11-08 20:20:06 +01:00
|
|
|
|
|
2016-11-13 15:16:20 +01:00
|
|
|
|
return ret;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
2016-11-08 20:20:06 +01:00
|
|
|
|
#undef FUNC_NAME
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_DEFINE (scm_signal_condition_variable, "signal-condition-variable", 1, 0, 0,
|
|
|
|
|
|
(SCM cv),
|
|
|
|
|
|
"Wake up one thread that is waiting for @var{cv}")
|
|
|
|
|
|
#define FUNC_NAME s_scm_signal_condition_variable
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
{
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_cond *c;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_VALIDATE_CONDVAR (1, cv);
|
2016-11-08 20:20:06 +01:00
|
|
|
|
c = SCM_CONDVAR_DATA (cv);
|
|
|
|
|
|
unblock_from_queue (c->waiting);
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
return SCM_BOOL_T;
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
#undef FUNC_NAME
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_DEFINE (scm_broadcast_condition_variable, "broadcast-condition-variable", 1, 0, 0,
|
|
|
|
|
|
(SCM cv),
|
|
|
|
|
|
"Wake up all threads that are waiting for @var{cv}. ")
|
|
|
|
|
|
#define FUNC_NAME s_scm_broadcast_condition_variable
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
{
|
2016-11-08 20:23:20 +01:00
|
|
|
|
struct scm_cond *c;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_VALIDATE_CONDVAR (1, cv);
|
2016-11-08 20:20:06 +01:00
|
|
|
|
c = SCM_CONDVAR_DATA (cv);
|
|
|
|
|
|
while (scm_is_true (unblock_from_queue (c->waiting)))
|
|
|
|
|
|
;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
return SCM_BOOL_T;
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
#undef FUNC_NAME
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
|
2008-03-08 16:22:40 +00:00
|
|
|
|
SCM_DEFINE (scm_condition_variable_p, "condition-variable?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
|
|
|
|
|
"Return @code{#t} if @var{obj} is a condition variable.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_condition_variable_p
|
|
|
|
|
|
{
|
|
|
|
|
|
return SCM_CONDVARP(obj) ? SCM_BOOL_T : SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2004-08-19 17:16:01 +00:00
|
|
|
|
|
2008-09-26 23:10:26 +02:00
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
/*** Select */
|
|
|
|
|
|
|
2008-09-26 23:10:26 +02:00
|
|
|
|
struct select_args
|
|
|
|
|
|
{
|
|
|
|
|
|
int nfds;
|
2013-03-09 22:45:33 +01:00
|
|
|
|
fd_set *read_fds;
|
|
|
|
|
|
fd_set *write_fds;
|
|
|
|
|
|
fd_set *except_fds;
|
2008-09-26 23:10:26 +02:00
|
|
|
|
struct timeval *timeout;
|
|
|
|
|
|
|
|
|
|
|
|
int result;
|
|
|
|
|
|
int errno_value;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
|
do_std_select (void *args)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct select_args *select_args;
|
|
|
|
|
|
|
|
|
|
|
|
select_args = (struct select_args *) args;
|
|
|
|
|
|
|
|
|
|
|
|
select_args->result =
|
|
|
|
|
|
select (select_args->nfds,
|
|
|
|
|
|
select_args->read_fds, select_args->write_fds,
|
|
|
|
|
|
select_args->except_fds, select_args->timeout);
|
|
|
|
|
|
select_args->errno_value = errno;
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2002-11-10 22:04:26 +00:00
|
|
|
|
int
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_std_select (int nfds,
|
2013-03-09 22:45:33 +01:00
|
|
|
|
fd_set *readfds,
|
|
|
|
|
|
fd_set *writefds,
|
|
|
|
|
|
fd_set *exceptfds,
|
2005-03-02 20:42:01 +00:00
|
|
|
|
struct timeval *timeout)
|
|
|
|
|
|
{
|
|
|
|
|
|
fd_set my_readfds;
|
|
|
|
|
|
int res, eno, wakeup_fd;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD;
|
2008-09-26 23:10:26 +02:00
|
|
|
|
struct select_args args;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
|
|
|
|
|
if (readfds == NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
FD_ZERO (&my_readfds);
|
|
|
|
|
|
readfds = &my_readfds;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-03-01 17:23:48 +01:00
|
|
|
|
if (scm_i_prepare_to_wait_on_fd (t, t->sleep_pipe[1]))
|
|
|
|
|
|
{
|
|
|
|
|
|
eno = EINTR;
|
|
|
|
|
|
res = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
wakeup_fd = t->sleep_pipe[0];
|
|
|
|
|
|
FD_SET (wakeup_fd, readfds);
|
|
|
|
|
|
if (wakeup_fd >= nfds)
|
|
|
|
|
|
nfds = wakeup_fd+1;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2017-03-01 17:23:48 +01:00
|
|
|
|
args.nfds = nfds;
|
|
|
|
|
|
args.read_fds = readfds;
|
|
|
|
|
|
args.write_fds = writefds;
|
|
|
|
|
|
args.except_fds = exceptfds;
|
|
|
|
|
|
args.timeout = timeout;
|
2008-09-26 23:10:26 +02:00
|
|
|
|
|
2017-03-01 17:23:48 +01:00
|
|
|
|
/* Explicitly cooperate with the GC. */
|
|
|
|
|
|
scm_without_guile (do_std_select, &args);
|
2008-09-26 23:10:26 +02:00
|
|
|
|
|
2017-03-01 17:23:48 +01:00
|
|
|
|
res = args.result;
|
|
|
|
|
|
eno = args.errno_value;
|
2008-09-26 23:10:26 +02:00
|
|
|
|
|
2017-03-01 17:23:48 +01:00
|
|
|
|
scm_i_wait_finished (t);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
|
2017-03-01 17:23:48 +01:00
|
|
|
|
if (res > 0 && FD_ISSET (wakeup_fd, readfds))
|
|
|
|
|
|
{
|
|
|
|
|
|
char dummy;
|
|
|
|
|
|
full_read (wakeup_fd, &dummy, 1);
|
2008-11-30 18:43:41 +01:00
|
|
|
|
|
2017-03-01 17:23:48 +01:00
|
|
|
|
FD_CLR (wakeup_fd, readfds);
|
|
|
|
|
|
res -= 1;
|
|
|
|
|
|
if (res == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
eno = EINTR;
|
|
|
|
|
|
res = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2005-03-02 20:42:01 +00:00
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
errno = eno;
|
|
|
|
|
|
return res;
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* Convenience API for blocking while in guile mode. */
|
2005-01-24 23:41:14 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
#if SCM_USE_PTHREAD_THREADS
|
2004-03-03 16:53:15 +00:00
|
|
|
|
|
2008-09-26 23:18:25 +02:00
|
|
|
|
/* It seems reasonable to not run procedures related to mutex and condition
|
|
|
|
|
|
variables within `GC_do_blocking ()' since, (i) the GC can operate even
|
|
|
|
|
|
without it, and (ii) the only potential gain would be GC latency. See
|
|
|
|
|
|
http://thread.gmane.org/gmane.comp.programming.garbage-collection.boehmgc/2245/focus=2251
|
|
|
|
|
|
for a discussion of the pros and cons. */
|
|
|
|
|
|
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
int
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_pthread_mutex_lock (scm_i_pthread_mutex_t *mutex)
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
int res = scm_i_pthread_mutex_lock (mutex);
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static void
|
2006-04-17 00:05:42 +00:00
|
|
|
|
do_unlock (void *data)
|
* __scm.h (SCM_DEFER_INTS, SCM_ALLOW_INTS): New definitions.
Simply lock a thread C API recursive mutex.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): Removed.
* eval.c: Replaced SOURCE_SECTION_START / SOURCE_SECTION_END with
direct calls to scm_rec_mutex_lock / unlock around the three calls
to scm_m_expand_body.
* eval.c, eval.h (promise_free): New function.
(scm_force): Rewritten; Now thread-safe; Removed
SCM_DEFER/ALLOW_INTS.
* pthread-threads.h: Added partially implemented plugin interface
for recursive mutexes. These are, for now, only intended to be
used internally within the Guile implementation.
* pthread-threads.c: New file.
* threads.c: Conditionally #include "pthread-threads.c".
* eval.c, eval.h (scm_makprom, scm_force): Rewritten to be
thread-safe;
* snarf.h (SCM_MUTEX, SCM_GLOBAL_MUTEX, SCM_REC_MUTEX,
SCM_GLOBAL_REC_MUTEX): New macros.
* eval.c, threads.c, threads.h, snarf.h: Rewrote critical section
macros---use mutexes instead.
* tags.h (SCM_IM_FUTURE): New tag.
* eval.c (scm_m_future): New primitive macro.
(SCM_CEVAL): Support futures.
(unmemocopy): Support unmemoization of futures.
* print.c (scm_isymnames): Name of future isym.
2002-12-15 14:24:34 +00:00
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_i_pthread_mutex_unlock ((scm_i_pthread_mutex_t *)data);
|
* __scm.h (SCM_DEFER_INTS, SCM_ALLOW_INTS): New definitions.
Simply lock a thread C API recursive mutex.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): Removed.
* eval.c: Replaced SOURCE_SECTION_START / SOURCE_SECTION_END with
direct calls to scm_rec_mutex_lock / unlock around the three calls
to scm_m_expand_body.
* eval.c, eval.h (promise_free): New function.
(scm_force): Rewritten; Now thread-safe; Removed
SCM_DEFER/ALLOW_INTS.
* pthread-threads.h: Added partially implemented plugin interface
for recursive mutexes. These are, for now, only intended to be
used internally within the Guile implementation.
* pthread-threads.c: New file.
* threads.c: Conditionally #include "pthread-threads.c".
* eval.c, eval.h (scm_makprom, scm_force): Rewritten to be
thread-safe;
* snarf.h (SCM_MUTEX, SCM_GLOBAL_MUTEX, SCM_REC_MUTEX,
SCM_GLOBAL_REC_MUTEX): New macros.
* eval.c, threads.c, threads.h, snarf.h: Rewrote critical section
macros---use mutexes instead.
* tags.h (SCM_IM_FUTURE): New tag.
* eval.c (scm_m_future): New primitive macro.
(SCM_CEVAL): Support futures.
(unmemocopy): Support unmemoization of futures.
* print.c (scm_isymnames): Name of future isym.
2002-12-15 14:24:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2006-01-29 00:23:28 +00:00
|
|
|
|
scm_dynwind_pthread_mutex_lock (scm_i_pthread_mutex_t *mutex)
|
* __scm.h (SCM_DEFER_INTS, SCM_ALLOW_INTS): New definitions.
Simply lock a thread C API recursive mutex.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): Removed.
* eval.c: Replaced SOURCE_SECTION_START / SOURCE_SECTION_END with
direct calls to scm_rec_mutex_lock / unlock around the three calls
to scm_m_expand_body.
* eval.c, eval.h (promise_free): New function.
(scm_force): Rewritten; Now thread-safe; Removed
SCM_DEFER/ALLOW_INTS.
* pthread-threads.h: Added partially implemented plugin interface
for recursive mutexes. These are, for now, only intended to be
used internally within the Guile implementation.
* pthread-threads.c: New file.
* threads.c: Conditionally #include "pthread-threads.c".
* eval.c, eval.h (scm_makprom, scm_force): Rewritten to be
thread-safe;
* snarf.h (SCM_MUTEX, SCM_GLOBAL_MUTEX, SCM_REC_MUTEX,
SCM_GLOBAL_REC_MUTEX): New macros.
* eval.c, threads.c, threads.h, snarf.h: Rewrote critical section
macros---use mutexes instead.
* tags.h (SCM_IM_FUTURE): New tag.
* eval.c (scm_m_future): New primitive macro.
(SCM_CEVAL): Support futures.
(unmemocopy): Support unmemoization of futures.
* print.c (scm_isymnames): Name of future isym.
2002-12-15 14:24:34 +00:00
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_i_scm_pthread_mutex_lock (mutex);
|
2006-04-17 00:05:42 +00:00
|
|
|
|
scm_dynwind_unwind_handler (do_unlock, mutex, SCM_F_WIND_EXPLICITLY);
|
* __scm.h (SCM_DEFER_INTS, SCM_ALLOW_INTS): New definitions.
Simply lock a thread C API recursive mutex.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): Removed.
* eval.c: Replaced SOURCE_SECTION_START / SOURCE_SECTION_END with
direct calls to scm_rec_mutex_lock / unlock around the three calls
to scm_m_expand_body.
* eval.c, eval.h (promise_free): New function.
(scm_force): Rewritten; Now thread-safe; Removed
SCM_DEFER/ALLOW_INTS.
* pthread-threads.h: Added partially implemented plugin interface
for recursive mutexes. These are, for now, only intended to be
used internally within the Guile implementation.
* pthread-threads.c: New file.
* threads.c: Conditionally #include "pthread-threads.c".
* eval.c, eval.h (scm_makprom, scm_force): Rewritten to be
thread-safe;
* snarf.h (SCM_MUTEX, SCM_GLOBAL_MUTEX, SCM_REC_MUTEX,
SCM_GLOBAL_REC_MUTEX): New macros.
* eval.c, threads.c, threads.h, snarf.h: Rewrote critical section
macros---use mutexes instead.
* tags.h (SCM_IM_FUTURE): New tag.
* eval.c (scm_m_future): New primitive macro.
(SCM_CEVAL): Support futures.
(unmemocopy): Support unmemoization of futures.
* print.c (scm_isymnames): Name of future isym.
2002-12-15 14:24:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
int
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_pthread_cond_wait (scm_i_pthread_cond_t *cond, scm_i_pthread_mutex_t *mutex)
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
{
|
2016-11-05 00:22:15 +01:00
|
|
|
|
return scm_i_pthread_cond_wait (cond, mutex);
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-01-24 23:41:14 +00:00
|
|
|
|
int
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_pthread_cond_timedwait (scm_i_pthread_cond_t *cond,
|
|
|
|
|
|
scm_i_pthread_mutex_t *mutex,
|
|
|
|
|
|
const scm_t_timespec *wt)
|
2005-01-24 23:41:14 +00:00
|
|
|
|
{
|
2016-11-05 00:22:15 +01:00
|
|
|
|
return scm_i_pthread_cond_timedwait (cond, mutex, wt);
|
2005-01-24 23:41:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
#endif
|
2005-01-24 23:41:14 +00:00
|
|
|
|
|
2013-11-17 04:00:29 -05:00
|
|
|
|
static void
|
|
|
|
|
|
do_unlock_with_asyncs (void *data)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_unlock ((scm_i_pthread_mutex_t *)data);
|
|
|
|
|
|
SCM_I_CURRENT_THREAD->block_asyncs--;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_i_dynwind_pthread_mutex_lock_block_asyncs (scm_i_pthread_mutex_t *mutex)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_I_CURRENT_THREAD->block_asyncs++;
|
|
|
|
|
|
scm_i_scm_pthread_mutex_lock (mutex);
|
|
|
|
|
|
scm_dynwind_unwind_handler (do_unlock_with_asyncs, mutex,
|
|
|
|
|
|
SCM_F_WIND_EXPLICITLY);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
unsigned long
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_std_usleep (unsigned long usecs)
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
{
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
tv.tv_usec = usecs % 1000000;
|
|
|
|
|
|
tv.tv_sec = usecs / 1000000;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_std_select (0, NULL, NULL, NULL, &tv);
|
|
|
|
|
|
return tv.tv_sec * 1000000 + tv.tv_usec;
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
unsigned int
|
|
|
|
|
|
scm_std_sleep (unsigned int secs)
|
2002-11-07 13:55:25 +00:00
|
|
|
|
{
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
|
|
tv.tv_sec = secs;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_std_select (0, NULL, NULL, NULL, &tv);
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
return tv.tv_sec;
|
2002-11-07 13:55:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
/*** Misc */
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_current_thread, "current-thread", 0, 0, 0,
|
|
|
|
|
|
(void),
|
|
|
|
|
|
"Return the thread that called this function.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_current_thread
|
|
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
return SCM_I_CURRENT_THREAD->handle;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static SCM
|
|
|
|
|
|
scm_c_make_list (size_t n, SCM fill)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM res = SCM_EOL;
|
|
|
|
|
|
while (n-- > 0)
|
|
|
|
|
|
res = scm_cons (fill, res);
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_DEFINE (scm_all_threads, "all-threads", 0, 0, 0,
|
|
|
|
|
|
(void),
|
|
|
|
|
|
"Return a list of all threads.")
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
#define FUNC_NAME s_scm_all_threads
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/* We can not allocate while holding the thread_admin_mutex because
|
|
|
|
|
|
of the way GC is done.
|
|
|
|
|
|
*/
|
|
|
|
|
|
int n = thread_count;
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t;
|
2005-03-02 20:42:01 +00:00
|
|
|
|
SCM list = scm_c_make_list (n, SCM_UNSPECIFIED), *l;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_i_pthread_mutex_lock (&thread_admin_mutex);
|
|
|
|
|
|
l = &list;
|
|
|
|
|
|
for (t = all_threads; t && n > 0; t = t->next_thread)
|
|
|
|
|
|
{
|
2007-10-20 11:09:58 +00:00
|
|
|
|
if (t != scm_i_signal_delivery_thread)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_SETCAR (*l, t->handle);
|
|
|
|
|
|
l = SCM_CDRLOC (*l);
|
|
|
|
|
|
}
|
2005-03-02 20:42:01 +00:00
|
|
|
|
n--;
|
|
|
|
|
|
}
|
|
|
|
|
|
*l = SCM_EOL;
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
|
|
|
|
|
|
return list;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
2005-03-02 20:42:01 +00:00
|
|
|
|
#undef FUNC_NAME
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_thread_exited_p, "thread-exited?", 1, 0, 0,
|
|
|
|
|
|
(SCM thread),
|
|
|
|
|
|
"Return @code{#t} iff @var{thread} has exited.\n")
|
|
|
|
|
|
#define FUNC_NAME s_scm_thread_exited_p
|
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (scm_c_thread_exited_p (thread));
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2002-11-10 22:04:26 +00:00
|
|
|
|
int
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
scm_c_thread_exited_p (SCM thread)
|
|
|
|
|
|
#define FUNC_NAME s_scm_thread_exited_p
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *t;
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
SCM_VALIDATE_THREAD (1, thread);
|
2005-03-02 20:42:01 +00:00
|
|
|
|
t = SCM_I_THREAD_DATA (thread);
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
return t->exited;
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
}
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
#undef FUNC_NAME
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
|
2011-04-25 22:41:58 +02:00
|
|
|
|
SCM_DEFINE (scm_total_processor_count, "total-processor-count", 0, 0, 0,
|
|
|
|
|
|
(void),
|
|
|
|
|
|
"Return the total number of processors of the machine, which\n"
|
|
|
|
|
|
"is guaranteed to be at least 1. A ``processor'' here is a\n"
|
|
|
|
|
|
"thread execution unit, which can be either:\n\n"
|
|
|
|
|
|
"@itemize\n"
|
|
|
|
|
|
"@item an execution core in a (possibly multi-core) chip, in a\n"
|
|
|
|
|
|
" (possibly multi- chip) module, in a single computer, or\n"
|
|
|
|
|
|
"@item a thread execution unit inside a core in the case of\n"
|
|
|
|
|
|
" @dfn{hyper-threaded} CPUs.\n"
|
|
|
|
|
|
"@end itemize\n\n"
|
|
|
|
|
|
"Which of the two definitions is used, is unspecified.\n")
|
|
|
|
|
|
#define FUNC_NAME s_scm_total_processor_count
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_ulong (num_processors (NPROC_ALL));
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_current_processor_count, "current-processor-count", 0, 0, 0,
|
|
|
|
|
|
(void),
|
|
|
|
|
|
"Like @code{total-processor-count}, but return the number of\n"
|
|
|
|
|
|
"processors available to the current process. See\n"
|
|
|
|
|
|
"@code{setaffinity} and @code{getaffinity} for more\n"
|
|
|
|
|
|
"information.\n")
|
|
|
|
|
|
#define FUNC_NAME s_scm_current_processor_count
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_ulong (num_processors (NPROC_CURRENT));
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
static scm_i_pthread_cond_t wake_up_cond;
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
static int threads_initialized_p = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
/*** Initialization */
|
|
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_t scm_i_misc_mutex;
|
|
|
|
|
|
|
2005-10-23 20:47:49 +00:00
|
|
|
|
#if SCM_USE_PTHREAD_THREADS
|
|
|
|
|
|
pthread_mutexattr_t scm_i_pthread_mutexattr_recursive[1];
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
void
|
2011-03-25 13:01:51 +01:00
|
|
|
|
scm_threads_prehistory (void *base)
|
2005-03-02 20:42:01 +00:00
|
|
|
|
{
|
2005-10-23 20:47:49 +00:00
|
|
|
|
#if SCM_USE_PTHREAD_THREADS
|
|
|
|
|
|
pthread_mutexattr_init (scm_i_pthread_mutexattr_recursive);
|
|
|
|
|
|
pthread_mutexattr_settype (scm_i_pthread_mutexattr_recursive,
|
|
|
|
|
|
PTHREAD_MUTEX_RECURSIVE);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_i_pthread_mutex_init (&scm_i_misc_mutex, NULL);
|
|
|
|
|
|
scm_i_pthread_cond_init (&wake_up_cond, NULL);
|
2008-05-14 23:52:49 +01:00
|
|
|
|
|
2013-11-22 13:01:53 +01:00
|
|
|
|
thread_gc_kind =
|
|
|
|
|
|
GC_new_kind (GC_new_free_list (),
|
|
|
|
|
|
GC_MAKE_PROC (GC_new_proc (thread_mark), 0),
|
|
|
|
|
|
0, 1);
|
|
|
|
|
|
|
2017-02-28 13:14:02 +01:00
|
|
|
|
guilify_self_1 ((struct GC_stack_base *) base, 0);
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
scm_t_bits scm_tc16_thread;
|
|
|
|
|
|
scm_t_bits scm_tc16_mutex;
|
|
|
|
|
|
scm_t_bits scm_tc16_condvar;
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
|
2016-10-23 20:28:48 +02:00
|
|
|
|
static void
|
|
|
|
|
|
scm_init_ice_9_threads (void *unused)
|
|
|
|
|
|
{
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "threads.x"
|
2016-10-25 22:24:19 +02:00
|
|
|
|
|
2016-10-27 21:22:28 +02:00
|
|
|
|
cancel_thread_var =
|
|
|
|
|
|
scm_module_variable (scm_current_module (),
|
|
|
|
|
|
scm_from_latin1_symbol ("cancel-thread"));
|
2016-11-14 21:35:44 +01:00
|
|
|
|
join_thread_var =
|
|
|
|
|
|
scm_module_variable (scm_current_module (),
|
|
|
|
|
|
scm_from_latin1_symbol ("join-thread"));
|
2016-10-25 22:24:19 +02:00
|
|
|
|
call_with_new_thread_var =
|
|
|
|
|
|
scm_module_variable (scm_current_module (),
|
|
|
|
|
|
scm_from_latin1_symbol ("call-with-new-thread"));
|
2016-10-23 20:28:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
void
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_init_threads ()
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_tc16_thread = scm_make_smob_type ("thread", sizeof (scm_thread));
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
scm_set_smob_print (scm_tc16_thread, thread_print);
|
|
|
|
|
|
|
2016-11-08 20:23:20 +01:00
|
|
|
|
scm_tc16_mutex = scm_make_smob_type ("mutex", sizeof (struct scm_mutex));
|
2016-11-08 20:20:06 +01:00
|
|
|
|
scm_set_smob_print (scm_tc16_mutex, scm_mutex_print);
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_tc16_condvar = scm_make_smob_type ("condition-variable",
|
2016-11-08 20:23:20 +01:00
|
|
|
|
sizeof (struct scm_cond));
|
|
|
|
|
|
scm_set_smob_print (scm_tc16_condvar, scm_cond_print);
|
* threads.h: Do not include "libguile/coop-defs.h". Include
"libguile/pthread-threads.h" for USE_COPT_THREADS. Removed
(previously deprecated) C level thread API prototypes. They are
now in the thread package specific headers, "null-threads.h" and
"pthread-threads.h".
(SCM_VALIDATE_THREAD, SCM_VALIDATE_MUTEX, SCM_VALIDATE_CONDVAR):
New.
(scm_threads_init): Removed.
(SCM_CRITICAL_SECTION_START, SCM_CRITICAL_SECTION_END,
SCM_THREAD_SWITCHING_CODE, scm_i_switch_counter,
SCM_I_THREAD_SWITCH_COUNT): Define here.
(scm_single_thread_p): Removed.
(scm_call_with_new_thread): Take two args directly instead of list
of two args.
(scm_i_thread_data, scm_i_set_thread_data, SCM_THREAD_LOCAL_DATA,
SCM_SET_THREAD_LOCAL_DATA): Define here.
* threads.c: Merged with "coop-pthreads.c".
2002-12-02 01:00:41 +00:00
|
|
|
|
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
default_dynamic_state = SCM_BOOL_F;
|
|
|
|
|
|
guilify_self_2 (scm_i_make_initial_dynamic_state ());
|
* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
(SCM_NONREC_CRITICAL_SECTION_START,
SCM_NONREC_CRITICAL_SECTION_END, SCM_REC_CRITICAL_SECTION_START,
SCM_REC_CRITICAL_SECTION_END): New macros.
(SCM_CRITICAL_SECTION_START/END): Defined here.
* eval.c: Insert SOURCE_SECTION_START / SOURCE_SECTION_END around
the three calls to scm_m_expand_body.
* gc.h: #include "libguile/pthread-threads.h";
(SCM_FREELIST_CREATE, SCM_FREELIST_LOC): New macros.
* gc.c (scm_i_freelist, scm_i_freelist2): Defined to be of type
scm_t_key;
* gc.c, gc-freelist.c, inline.h: Use SCM_FREELIST_LOC for freelist
access.
* gc-freelist.c (scm_gc_init_freelist): Create freelist keys.
* gc-freelist.c, threads.c (really_launch): Use
SCM_FREELIST_CREATE.
* gc-malloc.c (scm_realloc, scm_gc_register_collectable_memory):
* gc.c (scm_i_expensive_validation_check, scm_gc,
scm_gc_for_newcell): Put threads to sleep before doing GC-related
heap administration so that those pieces of code are executed
single-threaded. We might consider rewriting these code sections
in terms of a "call_gc_code_singly_threaded" construct instead of
calling the pair of scm_i_thread_put_to_sleep () and
scm_i_thread_wake_up (). Also, we would want to have as many of
these sections eleminated.
* init.c (scm_init_guile_1): Call scm_threads_prehistory.
* inline.h: #include "libguile/threads.h"
* pthread-threads.h: Macros now conform more closely to the
pthreads interface. Some of them now take a second argument.
* threads.c, threads.h: Many changes.
* configure.in: Temporarily replaced "copt" threads option with new
option "pthreads".
(USE_PTHREAD_THREADS): Define if pthreads configured.
2002-12-09 13:42:58 +00:00
|
|
|
|
threads_initialized_p = 1;
|
2005-03-07 21:30:24 +00:00
|
|
|
|
|
2016-10-23 20:28:48 +02:00
|
|
|
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
|
|
|
|
|
"scm_init_ice_9_threads",
|
|
|
|
|
|
scm_init_ice_9_threads, NULL);
|
Merge threads directory into libguile.
* coop-defs.h, coop-threads.c, coop-threads.h, coop.c, threads.c,
threads.h: New source files.
* Makefile.am (EXTRA_libguile_la_SOURCES): Add threads.c.
(noinst_HEADERS): Add coop-threads.c, coop-threads.h, coop.c
here; see comment.
(modinclude_HEADERS): Add threads.h, coop-defs.h.
(EXTRA_DIST): Add fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus.
* configure.in: If we're using threads, include threads.o in
LIBOBJS.
* _scm.h, libguile.h: threads.h lives in this directory now.
* fsu-pthreads.h, mit-pthreads.c, mit-pthreads.h,
coop-threads.c.cygnus, coop-threads.h.cygnus: New files, not
currently used, but brought along for information's sake.
* ChangeLog-threads: log from old 'threads' directory.
* Makefile.in, configure: Rebuilt.
1997-04-15 01:34:36 +00:00
|
|
|
|
}
|
2000-03-19 19:01:16 +00:00
|
|
|
|
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
void
|
2005-03-02 20:42:01 +00:00
|
|
|
|
scm_init_threads_default_dynamic_state ()
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
{
|
Reimplement dynamic states
There are two goals: one, to use less memory per dynamic state in order
to allow millions of dynamic states to be allocated in light-weight
threading scenarios. The second goal is to prevent dynamic states from
being actively mutated in two threads at once. This second goal does
mean that dynamic states object that escape into scheme are now copies
that won't receive further updates; an incompatible change, but one
which we hope doesn't affect anyone.
* libguile/cache-internal.h: New file.
* libguile/fluids.c (is_dynamic_state, get_dynamic_state)
(save_dynamic_state, restore_dynamic_state, add_entry)
(copy_value_table): New functions.
(scm_i_fluid_print, scm_i_dynamic_state_print): Move up.
(new_fluid): No need for a number.
(scm_fluid_p: scm_is_fluid): Inline IS_FLUID uses.
(fluid_set_x, fluid_ref): Adapt to dynamic state changes.
(scm_fluid_set_x, scm_fluid_unset_x): Call fluid_set_x.
(scm_swap_fluid): Rewrite in terms of fluid_ref and fluid_set.
(swap_fluid): Use internal fluid_set_x.
(scm_i_make_initial_dynamic_state): Adapt to dynamic state
representation change.
(scm_dynamic_state_p, scm_is_dynamic_state): Use new accessors.
(scm_current_dynamic_state): Use make_dynamic_state.
(scm_dynwind_current_dynamic_state): Use new accessor.
* libguile/fluids.h: Remove internal definitions. Add new struct
definition.
* libguile/threads.h (scm_i_thread): Use scm_t_dynamic_state for dynamic
state.
* libguile/threads.c (guilify_self_1, guilify_self_2):
(scm_i_init_thread_for_guile, scm_init_guile):
(scm_call_with_new_thread):
(scm_init_threads, scm_init_threads_default_dynamic_state): Adapt to
scm_i_thread change.
(scm_i_with_guile, with_guile): Remove "and parent" suffix.
(scm_i_reset_fluid): Remove unneeded function.
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Remove
scm_make_dynamic_state docs. Update current-dynamic-state docs.
* libguile/vm-engine.c (vm_engine): Update fluid-ref and fluid-set!
inlined fast paths for dynamic state changes.
* libguile/vm.c (vm_error_unbound_fluid): Remove now-unused function.
* NEWS: Update.
* module/ice-9/deprecated.scm (make-dynamic-state): New definition.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_dynamic_state): Move here.
* libguile/__scm.h (scm_t_dynamic_state): New typedef.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_fluid):
(scm_dynstack_unwind_fluid): Take raw dynstate in these internal
functions.
* libguile/throw.c (catch): Adapt to dynstack changes.
2016-11-27 21:33:30 +01:00
|
|
|
|
default_dynamic_state = scm_current_dynamic_state ();
|
* threads.h: Include "coop-pthreads.h" when requested.
(scm_threads_make_mutex, scm_threads_lock_mutex,
scm_threads_unlock_mutex, scm_threads_monitor): Removed, they were
not implemented anyway.
(scm_init_thread_procs, scm_try_mutex,
scm_timed_condition_variable_wait,
scm_broadcast_condition_variable, scm_c_thread_exited_p,
scm_thread_exited_p): New prototypes.
(struct timespec): Define if not already defined.
(scm_t_mutex, scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_t_cond, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Declarations moved here and
deprecated.
* threads.c: Include <errno.h>. Include "coop-pthreads.c" when
requested.
(scm_thread_exited_p): New.
(scm_try_mutex, scm_broadcast_condition_variable): Newly
registered procedures.
(scm_wait_condition_variable, scm_timed_wait_condition_variable):
Use the latter as the procedure for "wait-condition-variable",
thus offering a optional timeout parameter to Scheme.
(scm_wait_condition_variable): Implement in terms of
scm_timed_wait_condition_variable.
(scm_mutex_init, scm_mutex_lock, scm_mutex_trylock,
scm_mutex_unlock, scm_mutex_destroy, scm_cond_init,
scm_cond_wait, scm_cond_timedwait, scm_cond_signal,
scm_cond_broadcast, scm_cond_destroy): Implement in terms of
scm_make_mutex, etc, and deprecate.
(scm_init_threads): Do not create smobs, leave this to
scm_threads_init. Do not include "threads.x" file.
(scm_init_thread_procs): New, include "threads.x" here.
* null-threads.h (scm_null_mutex, scm_null_mutex_init,
scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed.
(scm_mutex_init, scm_mutex_lock, scm_mutex_unlock, scm_cond_init,
scm_cond_wait, scm_cond_signal, scm_cond_broadcast,
scm_cond_destory): Do not define, they are now deprecated and
handled by threads.{h,c}.
* null-threads.c (scm_null_mutex, scm_null_cond): Define here.
(scm_threads_init): Create smobs here, using the appropriate
sizes.
(block): Removed, now unused.
(scm_c_thread_exited_p): New.
(scm_null_mutex_init, scm_null_mutex_lock, scm_null_mutex_unlock,
scm_null_mutex_destroy, scm_null_condvar_init,
scm_null_condvar_wait, scm_null_condvar_signal,
scm_null_condvar_destroy): Removed and updated users to do their
task directly.
(scm_try_mutex, timeval_subtract,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
* coop-threads.c (scm_threads_init): Create smobs here, using the
appropriate sizes.
(scm_c_thread_exited_p, scm_try_mutex,
scm_timed_wait_condition_variable,
scm_broadcast_condition_variable): New.
(scm_wait_condition_variable): Removed.
2002-10-27 20:12:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-08-19 00:06:14 +02:00
|
|
|
|
|
|
|
|
|
|
|