* libguile/threads.c (scm_unlock_mutex): Bind to unlock-mutex.
* libguile/threads.h: Remove scm_unlock_mutex_timed.
* libguile/deprecated.h: Add scm_unlock_mutex_timed.
* libguile/deprecated.c (scm_unlock_mutex_timed): Deprecate.
* test-suite/tests/threads.test: Update unlock-mutex tests to use
wait-condition-variable if they would wait on a cond.
* libguile/threads.c (enum fat_mutex_kind): New data type, replacing
separate flags.
(struct fat_mutex): Adapt.
(make_fat_mutex): Fat mutexes can only be one of three kinds, not one
of 4 kinds. (Recursive unowned mutexes are not a thing.)
(scm_make_mutex): Adapt.
(scm_make_mutex_with_kind): New function, replacing
scm_make_mutex_with_flags. Still bound to make-mutex.
(scm_make_recursive_mutex): Adapt.
(fat_mutex_lock, fat_mutex_unlock): Adapt.
* libguile/threads.h (scm_make_mutex_with_kind): New decl.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_make_mutex_with_flags): Deprecate.
* libguile/threads.c (fat_mutex_lock): allow-external-unlock mutexes
can't be recursive, but a recursive lock attempt can be unblocked by
an external thread, so these mutexes shouldn't throw an error on
recursive lock attempts.
* test-suite/tests/srfi-18.test: Add tests.
* libguile/threads.h (scm_i_thread):
* libguile/threads.c (guilify_self_1, on_thread_exit)
(scm_pthread_cond_wait, scm_pthread_cond_timedwait): The thread-local
held_mutex field is no longer needed, now that we cancel threads via
interrupts instead of pthread_cancel.
* module/ice-9/threads.scm (cancel-tag): New variable.
(cancel-thread): New Scheme function.
(call-with-new-thread): Install a prompt around the thread.
* libguile/threads.h (scm_i_thread): Remove cancelled member.
* libguile/threads.c (scm_cancel_thread): Call out to Scheme. Always
available, and works on the current thread too.
(scm_set_thread_cleanup_x, scm_thread_cleanup): Adapt.
(scm_init_ice_9_threads): Capture cancel-thread var.
* doc/ref/api-scheduling.texi (Threads): Update.
* NEWS: Update.
* libguile/__scm.h (SCM_TICK): Always define as scm_async_tick().
* libguile/error.c (scm_syserror, scm_syserror_msg):
* libguile/fports.c (fport_read, fport_write):
* libguile/_scm.h (SCM_SYSCALL): Replace SCM_ASYNC_TICK with
scm_async_tick ().
(SCM_ASYNC_TICK, SCM_ASYNC_TICK_WITH_CODE)
(SCM_ASYNC_TICK_WITH_GUARD_CODE): Remove internal definitions. We
inline into vm-engine.c, the only place where it matters.
* libguile/async.h:
* libguile/async.c (scm_async_tick, scm_i_setup_sleep):
(scm_i_reset_sleep, scm_system_async_mark_for_thread):
* libguile/threads.h (struct scm_thread_wake_data):
* libguile/threads.h (scm_i_thread):
* libguile/threads.c (block_self, guilify_self_1, scm_std_select):
Rewrite to use sequentially-consistent atomic references.
* libguile/atomics-internal.h (scm_atomic_set_pointer):
(scm_atomic_ref_pointer): New definitions.
* libguile/finalizers.c (queue_finalizer_async): We can allocate, so
just use scm_system_async_mark_for_thread instead of the set-cdr!
shenanigans.
* libguile/scmsigs.c (take_signal):
* libguile/gc.c (queue_after_gc_hook): Adapt to new asyncs mechanism.
Can't allocate but we're just manipulating the current thread when no
other threads are running so we should be good.
* libguile/vm-engine.c (VM_HANDLE_INTERRUPTS): Inline the async_tick
business.
Reported by Sylvain Beucler <beuc@beuc.net>.
* configure.ac: Check for 'pthread_cancel'.
* libguile/threads.c (scm_cancel_thread): Conditionalize on
!SCM_USE_PTHREAD_THREADS || defined HAVE_PTHREAD_CANCEL.
* test-suite/tests/threads.test (require-cancel-thread): New procedure.
("timed joining fails if timeout exceeded", "join-thread returns
timeoutval on timeout", "cancel succeeds", "handler result passed to
join", "can cancel self"): Use it.
* libguile/threads.c (thread_mark): There is a window in which the
thread has a handle but doesn't yet have the set of pointerless
freelists, so don't unconditionally dereference
t->pointerless_freelists.
* libguile/iselect.h:
* libguile/threads.c:
* libguile/deprecated.h: Rely on Gnulib for sys/select.h.
* libguile/filesys.c: Rely on Gnulib for 'lstat' and 'mkstemp'.
* libguile/bdw-gc.h: Remove a needless compatibility hack.
* libguile/gc-inline.h: New file, implementing thread-local freelists
providing faster allocation if we already have a scm_i_thread*
pointer. Based on gc_inline.h from libgc.
* libguile/threads.h (scm_i_thread): Add freelists here.
* libguile/threads.c (guilify_self_1, guilify_self_2): Initialize
freelists.
* libguile/vm.c: Include gc-inline.h.
* libguile/vm-engine.c: Rename current_thread to thread. Use
scm_inline_cons instead of scm_cons, scm_inline_cell instead of
scm_cell, and scm_inline_words instead of words.
* libguile/threads.c (thread_mark): Mark the VM stack, if we have one.
(on_thread_exit): Free the VM stack here.
* libguile/vm.c (make_vm): Allocate the VM stack using mmap, and arrange
for it to be marked by the thread marker.
(scm_i_vm_mark_stack, scm_i_vm_free_stack): New internal interfaces.
(allocate_stack, free_stack): New helpers.
* libguile/threads.c (thread_mark): A mark procedure for threads.
Eventually will mark the stack.
(guilify_self_1): Move initialization of VP earlier. Allocate thread
using thread_gc_kind.
(scm_threads_prehistory): Initialize thread_gc_kind.
Reported and debugged by Andrew Gaylard <ag@computer.org>.
* libguile/threads.c (remqueue): When removing the last element from a
queue with more than one element, set (car q) to the previous element.
* THANKS: Thank Andrew Gaylard.
Reported by Chaos Eternal <chaoseternal@shlug.org>
Based on a patch by Nala Ginrut <nalaginrut@gmail.com>
* libguile/threads.c (scm_unlock_mutex_timed): If 'timeout' argument
is false, interpret that as no timeout.
* doc/ref/api-scheduling.texi (Mutexes and Condition Variables):
Update documentation.
* libguile/iselect.h: If we do not have sys/select.h, don't provide
scm_std_select, SELECT_TYPE, FD_SET, FD_ZERO, FD_ISSET, or FD_CLR.
Guile should not be setting these macros in public API. This is an
incompatible change on mingw, but oh well.
* libguile/threads.c: Rely on gnulib's select, and use that to implement
scm_std_select.
* libguile/deprecated.h:
* libguile/deprecated.c: Only provide scm_internal_select if we have
sys/select.h.
* libguile/threads.c (do_thread_exit): Don't assert m->owner == t->handle
since that is not the case when MUTEX was abandoned by T. Reported by Mark
Weaver and others.
* libguile/finalizers.c: New excitement! We'll be running finalizers
asynchronously, from asyncs. This will make it safer to allocate
while holding a mutex.
(GC_set_finalizer_notifier): Add back-compat shim.
* libguile/init.c (scm_i_init_guile): Init the async finalizer mechanism
during boot.
* libguile/gc.c (scm_storage_prehistory): Tell libgc we'll be finalizing
on demand.
(scm_gc): Explicitly run finalizers here.
* libguile/threads.c (guilify_self_2): Run finalizers here if
queue_finalizer_async happened to run during guilify_self_1.
* configure.ac: Add check for GC_set_finalizer_notifier.
* 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.
* libguile/async.c:
* libguile/deprecation.c:
* libguile/fluids.c:
* libguile/gc.c:
* libguile/instructions.c:
* libguile/ports.c:
* libguile/posix.c:
* libguile/strings.c:
* libguile/threads.c: Use the SCM_PTHREAD_ATFORK_LOCK_STATIC_MUTEX
mechanism to lock a number of static mutexen.