mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2025-12-06 02:40:26 -08:00
core: factor out process managament from thread managament
This is a preliminary step towards coroutines and for switching global env in single-threaded builds.
This commit is contained in:
parent
f49cc7f3fd
commit
0f4e9b1e17
13 changed files with 123 additions and 67 deletions
|
|
@ -12,7 +12,7 @@ ECL_FPE_CODE=fpe_x86.c
|
|||
|
||||
!if "$(ECL_THREADS)" != ""
|
||||
ECL_THREADS_FLAG=1
|
||||
THREADS_OBJ= process.obj mutex.obj condition_variable.obj rwlock.obj \
|
||||
THREADS_OBJ= thread.obj mutex.obj condition_variable.obj rwlock.obj \
|
||||
semaphore.obj barrier.obj mailbox.obj atomic.obj
|
||||
!else
|
||||
ECL_THREADS_FLAG=0
|
||||
|
|
@ -111,7 +111,7 @@ OBJS = main.obj symbol.obj package.obj cons.obj list.obj\
|
|||
time.obj unixint.obj memory.obj \
|
||||
mapfun.obj multival.obj hash.obj format.obj pathname.obj\
|
||||
structure.obj load.obj unixfsys.obj unixsys.obj \
|
||||
ffi.obj alloc_2.obj tcp.obj $(THREADS_OBJ) serialize.obj \
|
||||
ffi.obj alloc_2.obj tcp.obj $(THREADS_OBJ) process.obj serialize.obj \
|
||||
$(ECL_UCD_OBJ) $(ECL_SSE_OBJ)
|
||||
|
||||
all: $(DPP) ..\eclmin.lib ..\cinit.obj
|
||||
|
|
|
|||
2
src/aclocal.m4
vendored
2
src/aclocal.m4
vendored
|
|
@ -267,7 +267,7 @@ THREAD_CFLAGS=''
|
|||
THREAD_LIBS=''
|
||||
THREAD_GC_FLAGS='--enable-threads=posix'
|
||||
INSTALL_TARGET='install'
|
||||
THREAD_OBJ="$THREAD_OBJ threads/process threads/mutex threads/condition_variable threads/semaphore threads/barrier threads/mailbox threads/rwlock"
|
||||
THREAD_OBJ="$THREAD_OBJ threads/thread threads/mutex threads/condition_variable threads/semaphore threads/barrier threads/mailbox threads/rwlock"
|
||||
clibs='-lm'
|
||||
SONAME=''
|
||||
SONAME_LDFLAGS=''
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ OBJS = main.o symbol.o package.o cons.o list.o apply.o eval.o \
|
|||
cmpaux.o macros.o backq.o stacks.o time.o unixint.o mapfun.o \
|
||||
multival.o hash.o format.o pathname.o structure.o load.o \
|
||||
unixfsys.o unixsys.o serialize.o ffi.o sse2.o @EXTRA_OBJS@ \
|
||||
threads/atomic.o
|
||||
threads/atomic.o process.o
|
||||
|
||||
.PHONY: all
|
||||
|
||||
|
|
|
|||
|
|
@ -483,6 +483,7 @@ cl_boot(int argc, char **argv)
|
|||
setbuf(stdin, stdin_buf);
|
||||
setbuf(stdout, stdout_buf);
|
||||
#endif
|
||||
init_process();
|
||||
|
||||
ARGC = argc;
|
||||
ARGV = argv;
|
||||
|
|
@ -492,7 +493,9 @@ cl_boot(int argc, char **argv)
|
|||
init_alloc();
|
||||
GC_disable();
|
||||
env = cl_core.first_env;
|
||||
init_threads(env);
|
||||
#ifdef ECL_THREADS
|
||||
init_threads();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 1) Initialize symbols and packages
|
||||
|
|
|
|||
104
src/c/process.d
Normal file
104
src/c/process.d
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
/* vim: set filetype=c tabstop=2 shiftwidth=2 expandtab: */
|
||||
|
||||
/*
|
||||
* process.c - managing the process environment(s)
|
||||
*
|
||||
* Copyright (c) 2003 Juan Jose Garcia Ripoll
|
||||
* Copyright (c) 2023 Daniel Kochmański
|
||||
*
|
||||
* See file 'LICENSE' for the copyright details.
|
||||
*
|
||||
*/
|
||||
|
||||
#define ECL_INCLUDE_MATH_H
|
||||
#include <ecl/ecl.h> /* includes ECL_WINDOWS_THREADS */
|
||||
#include <ecl/internal.h>
|
||||
#include <ecl/ecl-inl.h>
|
||||
|
||||
#ifndef __sun__ /* See unixinit.d for this */
|
||||
#define _XOPEN_SOURCE 600 /* For pthread mutex attributes */
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#ifdef ECL_WINDOWS_THREADS
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SCHED_H
|
||||
# include <sched.h>
|
||||
#endif
|
||||
|
||||
/* -- Thread-local variables ------------------------------------------------ */
|
||||
|
||||
#ifdef ECL_THREADS
|
||||
# ifdef ECL_WINDOWS_THREADS
|
||||
# define ecl_process_key_t DWORD
|
||||
# define ecl_process_key_create(key) key = TlsAlloc()
|
||||
# define ecl_process_get_tls(key) TlsGetValue(key)
|
||||
# define ecl_process_set_tls(key,val) (TlsSetValue(key,val)!=0)
|
||||
# else
|
||||
# define ecl_process_key_t static pthread_key_t
|
||||
# define ecl_process_key_create(key) pthread_key_create(&key, NULL)
|
||||
# define ecl_process_get_tls(key) pthread_getspecific(key)
|
||||
# define ecl_process_set_tls(key,val) (pthread_setspecific(key,val)==0)
|
||||
# endif /* ECL_WINDOWS_THREADS */
|
||||
|
||||
/* Accessing a thread-local variable representing the environment. */
|
||||
|
||||
ecl_process_key_t cl_env_key;
|
||||
|
||||
cl_env_ptr
|
||||
ecl_process_env_unsafe(void)
|
||||
{
|
||||
return ecl_process_get_tls(cl_env_key);
|
||||
}
|
||||
|
||||
cl_env_ptr
|
||||
ecl_process_env(void)
|
||||
{
|
||||
cl_env_ptr rv = ecl_process_get_tls(cl_env_key);
|
||||
if(!rv) {
|
||||
ecl_thread_internal_error("pthread_getspecific() failed.");
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
ecl_set_process_env(cl_env_ptr env)
|
||||
{
|
||||
if(!ecl_process_set_tls(cl_env_key, env)) {
|
||||
ecl_thread_internal_error("pthread_setspecific() failed.");
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* The current global environment for single-threaded builds. */
|
||||
cl_env_ptr cl_env_p = NULL;
|
||||
#endif /* ECL_THREADS */
|
||||
|
||||
/* -- Initialiation --------------------------------------------------------- */
|
||||
|
||||
void
|
||||
init_process(void)
|
||||
{
|
||||
cl_env_ptr env = cl_core.first_env;
|
||||
#ifdef ECL_THREADS
|
||||
ecl_process_key_create(cl_env_key);
|
||||
ecl_mutex_init(&cl_core.processes_lock, 1);
|
||||
ecl_mutex_init(&cl_core.global_lock, 1);
|
||||
ecl_mutex_init(&cl_core.error_lock, 1);
|
||||
ecl_rwlock_init(&cl_core.global_env_lock);
|
||||
#endif
|
||||
ecl_set_process_env(env);
|
||||
env->default_sigmask = NULL;
|
||||
env->method_cache = NULL;
|
||||
env->slot_cache = NULL;
|
||||
env->interrupt_struct = NULL;
|
||||
env->disable_interrupts = 1;
|
||||
}
|
||||
0
src/c/threads/atomic.d
Executable file → Normal file
0
src/c/threads/atomic.d
Executable file → Normal file
0
src/c/threads/barrier.d
Executable file → Normal file
0
src/c/threads/barrier.d
Executable file → Normal file
0
src/c/threads/mailbox.d
Executable file → Normal file
0
src/c/threads/mailbox.d
Executable file → Normal file
0
src/c/threads/mutex.d
Executable file → Normal file
0
src/c/threads/mutex.d
Executable file → Normal file
64
src/c/threads/process.d → src/c/threads/thread.d
Executable file → Normal file
64
src/c/threads/process.d → src/c/threads/thread.d
Executable file → Normal file
|
|
@ -2,7 +2,7 @@
|
|||
/* vim: set filetype=c tabstop=2 shiftwidth=2 expandtab: */
|
||||
|
||||
/*
|
||||
* process.d - native threads
|
||||
* thread.d - native threads
|
||||
*
|
||||
* Copyright (c) 2003 Juan Jose Garcia Ripoll
|
||||
*
|
||||
|
|
@ -37,10 +37,6 @@
|
|||
/* -- Macros -------------------------------------------------------- */
|
||||
|
||||
#ifdef ECL_WINDOWS_THREADS
|
||||
# define ecl_process_key_t DWORD
|
||||
# define ecl_process_key_create(key) key = TlsAlloc()
|
||||
# define ecl_process_get_tls(key) TlsGetValue(key)
|
||||
# define ecl_process_set_tls(key,val) (TlsSetValue(key,val)!=0)
|
||||
# define ecl_process_eq(t1, t2) (GetThreadId(t1) == GetThreadId(t2))
|
||||
# define ecl_set_process_self(var) \
|
||||
{ \
|
||||
|
|
@ -54,46 +50,12 @@
|
|||
DUPLICATE_SAME_ACCESS); \
|
||||
}
|
||||
#else
|
||||
# define ecl_process_key_t static pthread_key_t
|
||||
# define ecl_process_key_create(key) pthread_key_create(&key, NULL)
|
||||
# define ecl_process_get_tls(key) pthread_getspecific(key)
|
||||
# define ecl_process_set_tls(key,val) (pthread_setspecific(key,val)==0)
|
||||
# define ecl_process_eq(t1, t2) (t1 == t2)
|
||||
# define ecl_set_process_self(var) (var = pthread_self())
|
||||
#endif /* ECL_WINDOWS_THREADS */
|
||||
|
||||
/* -- Core ---------------------------------------------------------- */
|
||||
|
||||
/* Accessing a thread-local variable representing the environment. */
|
||||
|
||||
ecl_process_key_t cl_env_key;
|
||||
|
||||
cl_env_ptr
|
||||
ecl_process_env_unsafe(void)
|
||||
{
|
||||
return ecl_process_get_tls(cl_env_key);
|
||||
}
|
||||
|
||||
cl_env_ptr
|
||||
ecl_process_env(void)
|
||||
{
|
||||
cl_env_ptr rv = ecl_process_get_tls(cl_env_key);
|
||||
if(!rv) {
|
||||
ecl_thread_internal_error("pthread_getspecific() failed.");
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
ecl_set_process_env(cl_env_ptr env)
|
||||
{
|
||||
if(!ecl_process_set_tls(cl_env_key, env)) {
|
||||
ecl_thread_internal_error("pthread_setspecific() failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Managing the collection of processes. */
|
||||
|
||||
static void
|
||||
extend_process_vector()
|
||||
{
|
||||
|
|
@ -173,18 +135,6 @@ ecl_process_list()
|
|||
return output;
|
||||
}
|
||||
|
||||
/* Initialiation */
|
||||
|
||||
static void
|
||||
init_process(void)
|
||||
{
|
||||
ecl_process_key_create(cl_env_key);
|
||||
ecl_mutex_init(&cl_core.processes_lock, 1);
|
||||
ecl_mutex_init(&cl_core.global_lock, 1);
|
||||
ecl_mutex_init(&cl_core.error_lock, 1);
|
||||
ecl_rwlock_init(&cl_core.global_env_lock);
|
||||
}
|
||||
|
||||
/* -- Environment --------------------------------------------------- */
|
||||
|
||||
extern void ecl_init_env(struct cl_env_struct *env);
|
||||
|
|
@ -372,8 +322,7 @@ ecl_import_current_thread(cl_object name, cl_object bindings)
|
|||
registered = 1;
|
||||
break;
|
||||
case GC_DUPLICATE:
|
||||
/* Thread was probably created using the GC hooks
|
||||
* for thread creation */
|
||||
/* Thread was probably created using the GC hooks for thread creation. */
|
||||
registered = 0;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -797,14 +746,13 @@ mp_restore_signals(cl_object sigmask)
|
|||
/* -- Initialization ------------------------------------------------ */
|
||||
|
||||
void
|
||||
init_threads(cl_env_ptr env)
|
||||
init_threads()
|
||||
{
|
||||
cl_env_ptr the_env = ecl_process_env();
|
||||
cl_object process;
|
||||
ecl_thread_t main_thread;
|
||||
init_process();
|
||||
/* We have to set the environment before any allocation takes place,
|
||||
* so that the interrupt handling code works. */
|
||||
ecl_set_process_env(env);
|
||||
ecl_set_process_self(main_thread);
|
||||
process = ecl_alloc_object(t_process);
|
||||
process->process.phase = ECL_PROCESS_ACTIVE;
|
||||
|
|
@ -812,12 +760,12 @@ init_threads(cl_env_ptr env)
|
|||
process->process.function = ECL_NIL;
|
||||
process->process.args = ECL_NIL;
|
||||
process->process.thread = main_thread;
|
||||
process->process.env = env;
|
||||
process->process.env = the_env;
|
||||
process->process.woken_up = ECL_NIL;
|
||||
ecl_mutex_init(&process->process.start_stop_lock, TRUE);
|
||||
ecl_cond_var_init(&process->process.exit_barrier);
|
||||
|
||||
env->own_process = process;
|
||||
the_env->own_process = process;
|
||||
{
|
||||
cl_object v = si_make_vector(ECL_T, /* Element type */
|
||||
ecl_make_fixnum(256), /* Size */
|
||||
2
src/configure
vendored
2
src/configure
vendored
|
|
@ -6096,7 +6096,7 @@ THREAD_CFLAGS=''
|
|||
THREAD_LIBS=''
|
||||
THREAD_GC_FLAGS='--enable-threads=posix'
|
||||
INSTALL_TARGET='install'
|
||||
THREAD_OBJ="$THREAD_OBJ threads/process threads/mutex threads/condition_variable threads/semaphore threads/barrier threads/mailbox threads/rwlock"
|
||||
THREAD_OBJ="$THREAD_OBJ threads/thread threads/mutex threads/condition_variable threads/semaphore threads/barrier threads/mailbox threads/rwlock"
|
||||
clibs='-lm'
|
||||
SONAME=''
|
||||
SONAME_LDFLAGS=''
|
||||
|
|
|
|||
|
|
@ -161,10 +161,12 @@ struct ecl_interrupt_struct {
|
|||
# define cl_env (*ecl_process_env())
|
||||
extern ECL_API cl_env_ptr ecl_process_env(void) __attribute__((const));
|
||||
extern ECL_API cl_env_ptr ecl_process_env_unsafe(void);
|
||||
extern ECL_API void ecl_set_process_env(cl_env_ptr env);
|
||||
#else
|
||||
# define cl_env (*cl_env_p)
|
||||
# define ecl_process_env() cl_env_p
|
||||
# define ecl_process_env_unsafe() cl_env_p
|
||||
# define ecl_set_process_env(env) cl_env_p = env
|
||||
extern ECL_API cl_env_ptr cl_env_p;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -40,10 +40,9 @@ extern void init_stacks(cl_env_ptr);
|
|||
extern void init_unixint(int pass);
|
||||
extern void init_unixtime(void);
|
||||
extern void init_compiler(void);
|
||||
extern void init_process(void);
|
||||
#ifdef ECL_THREADS
|
||||
extern void init_threads(cl_env_ptr);
|
||||
#else
|
||||
#define init_threads(env) cl_env_p = env
|
||||
extern void init_threads(void);
|
||||
#endif
|
||||
extern void ecl_init_env(cl_env_ptr);
|
||||
extern void init_lib_LSP(cl_object);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue