mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2025-12-27 21:01:58 -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)" != ""
|
!if "$(ECL_THREADS)" != ""
|
||||||
ECL_THREADS_FLAG=1
|
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
|
semaphore.obj barrier.obj mailbox.obj atomic.obj
|
||||||
!else
|
!else
|
||||||
ECL_THREADS_FLAG=0
|
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 \
|
time.obj unixint.obj memory.obj \
|
||||||
mapfun.obj multival.obj hash.obj format.obj pathname.obj\
|
mapfun.obj multival.obj hash.obj format.obj pathname.obj\
|
||||||
structure.obj load.obj unixfsys.obj unixsys.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)
|
$(ECL_UCD_OBJ) $(ECL_SSE_OBJ)
|
||||||
|
|
||||||
all: $(DPP) ..\eclmin.lib ..\cinit.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_LIBS=''
|
||||||
THREAD_GC_FLAGS='--enable-threads=posix'
|
THREAD_GC_FLAGS='--enable-threads=posix'
|
||||||
INSTALL_TARGET='install'
|
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'
|
clibs='-lm'
|
||||||
SONAME=''
|
SONAME=''
|
||||||
SONAME_LDFLAGS=''
|
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 \
|
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 \
|
multival.o hash.o format.o pathname.o structure.o load.o \
|
||||||
unixfsys.o unixsys.o serialize.o ffi.o sse2.o @EXTRA_OBJS@ \
|
unixfsys.o unixsys.o serialize.o ffi.o sse2.o @EXTRA_OBJS@ \
|
||||||
threads/atomic.o
|
threads/atomic.o process.o
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,7 @@ cl_boot(int argc, char **argv)
|
||||||
setbuf(stdin, stdin_buf);
|
setbuf(stdin, stdin_buf);
|
||||||
setbuf(stdout, stdout_buf);
|
setbuf(stdout, stdout_buf);
|
||||||
#endif
|
#endif
|
||||||
|
init_process();
|
||||||
|
|
||||||
ARGC = argc;
|
ARGC = argc;
|
||||||
ARGV = argv;
|
ARGV = argv;
|
||||||
|
|
@ -492,7 +493,9 @@ cl_boot(int argc, char **argv)
|
||||||
init_alloc();
|
init_alloc();
|
||||||
GC_disable();
|
GC_disable();
|
||||||
env = cl_core.first_env;
|
env = cl_core.first_env;
|
||||||
init_threads(env);
|
#ifdef ECL_THREADS
|
||||||
|
init_threads();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1) Initialize symbols and packages
|
* 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: */
|
/* vim: set filetype=c tabstop=2 shiftwidth=2 expandtab: */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* process.d - native threads
|
* thread.d - native threads
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003 Juan Jose Garcia Ripoll
|
* Copyright (c) 2003 Juan Jose Garcia Ripoll
|
||||||
*
|
*
|
||||||
|
|
@ -37,10 +37,6 @@
|
||||||
/* -- Macros -------------------------------------------------------- */
|
/* -- Macros -------------------------------------------------------- */
|
||||||
|
|
||||||
#ifdef ECL_WINDOWS_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)
|
|
||||||
# define ecl_process_eq(t1, t2) (GetThreadId(t1) == GetThreadId(t2))
|
# define ecl_process_eq(t1, t2) (GetThreadId(t1) == GetThreadId(t2))
|
||||||
# define ecl_set_process_self(var) \
|
# define ecl_set_process_self(var) \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -54,46 +50,12 @@
|
||||||
DUPLICATE_SAME_ACCESS); \
|
DUPLICATE_SAME_ACCESS); \
|
||||||
}
|
}
|
||||||
#else
|
#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_process_eq(t1, t2) (t1 == t2)
|
||||||
# define ecl_set_process_self(var) (var = pthread_self())
|
# define ecl_set_process_self(var) (var = pthread_self())
|
||||||
#endif /* ECL_WINDOWS_THREADS */
|
#endif /* ECL_WINDOWS_THREADS */
|
||||||
|
|
||||||
/* -- Core ---------------------------------------------------------- */
|
/* -- 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
|
static void
|
||||||
extend_process_vector()
|
extend_process_vector()
|
||||||
{
|
{
|
||||||
|
|
@ -173,18 +135,6 @@ ecl_process_list()
|
||||||
return output;
|
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 --------------------------------------------------- */
|
/* -- Environment --------------------------------------------------- */
|
||||||
|
|
||||||
extern void ecl_init_env(struct cl_env_struct *env);
|
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;
|
registered = 1;
|
||||||
break;
|
break;
|
||||||
case GC_DUPLICATE:
|
case GC_DUPLICATE:
|
||||||
/* Thread was probably created using the GC hooks
|
/* Thread was probably created using the GC hooks for thread creation. */
|
||||||
* for thread creation */
|
|
||||||
registered = 0;
|
registered = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -797,14 +746,13 @@ mp_restore_signals(cl_object sigmask)
|
||||||
/* -- Initialization ------------------------------------------------ */
|
/* -- Initialization ------------------------------------------------ */
|
||||||
|
|
||||||
void
|
void
|
||||||
init_threads(cl_env_ptr env)
|
init_threads()
|
||||||
{
|
{
|
||||||
|
cl_env_ptr the_env = ecl_process_env();
|
||||||
cl_object process;
|
cl_object process;
|
||||||
ecl_thread_t main_thread;
|
ecl_thread_t main_thread;
|
||||||
init_process();
|
|
||||||
/* We have to set the environment before any allocation takes place,
|
/* We have to set the environment before any allocation takes place,
|
||||||
* so that the interrupt handling code works. */
|
* so that the interrupt handling code works. */
|
||||||
ecl_set_process_env(env);
|
|
||||||
ecl_set_process_self(main_thread);
|
ecl_set_process_self(main_thread);
|
||||||
process = ecl_alloc_object(t_process);
|
process = ecl_alloc_object(t_process);
|
||||||
process->process.phase = ECL_PROCESS_ACTIVE;
|
process->process.phase = ECL_PROCESS_ACTIVE;
|
||||||
|
|
@ -812,12 +760,12 @@ init_threads(cl_env_ptr env)
|
||||||
process->process.function = ECL_NIL;
|
process->process.function = ECL_NIL;
|
||||||
process->process.args = ECL_NIL;
|
process->process.args = ECL_NIL;
|
||||||
process->process.thread = main_thread;
|
process->process.thread = main_thread;
|
||||||
process->process.env = env;
|
process->process.env = the_env;
|
||||||
process->process.woken_up = ECL_NIL;
|
process->process.woken_up = ECL_NIL;
|
||||||
ecl_mutex_init(&process->process.start_stop_lock, TRUE);
|
ecl_mutex_init(&process->process.start_stop_lock, TRUE);
|
||||||
ecl_cond_var_init(&process->process.exit_barrier);
|
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 */
|
cl_object v = si_make_vector(ECL_T, /* Element type */
|
||||||
ecl_make_fixnum(256), /* Size */
|
ecl_make_fixnum(256), /* Size */
|
||||||
2
src/configure
vendored
2
src/configure
vendored
|
|
@ -6096,7 +6096,7 @@ THREAD_CFLAGS=''
|
||||||
THREAD_LIBS=''
|
THREAD_LIBS=''
|
||||||
THREAD_GC_FLAGS='--enable-threads=posix'
|
THREAD_GC_FLAGS='--enable-threads=posix'
|
||||||
INSTALL_TARGET='install'
|
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'
|
clibs='-lm'
|
||||||
SONAME=''
|
SONAME=''
|
||||||
SONAME_LDFLAGS=''
|
SONAME_LDFLAGS=''
|
||||||
|
|
|
||||||
|
|
@ -161,10 +161,12 @@ struct ecl_interrupt_struct {
|
||||||
# define cl_env (*ecl_process_env())
|
# 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(void) __attribute__((const));
|
||||||
extern ECL_API cl_env_ptr ecl_process_env_unsafe(void);
|
extern ECL_API cl_env_ptr ecl_process_env_unsafe(void);
|
||||||
|
extern ECL_API void ecl_set_process_env(cl_env_ptr env);
|
||||||
#else
|
#else
|
||||||
# define cl_env (*cl_env_p)
|
# define cl_env (*cl_env_p)
|
||||||
# define ecl_process_env() cl_env_p
|
# define ecl_process_env() cl_env_p
|
||||||
# define ecl_process_env_unsafe() 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;
|
extern ECL_API cl_env_ptr cl_env_p;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,9 @@ extern void init_stacks(cl_env_ptr);
|
||||||
extern void init_unixint(int pass);
|
extern void init_unixint(int pass);
|
||||||
extern void init_unixtime(void);
|
extern void init_unixtime(void);
|
||||||
extern void init_compiler(void);
|
extern void init_compiler(void);
|
||||||
|
extern void init_process(void);
|
||||||
#ifdef ECL_THREADS
|
#ifdef ECL_THREADS
|
||||||
extern void init_threads(cl_env_ptr);
|
extern void init_threads(void);
|
||||||
#else
|
|
||||||
#define init_threads(env) cl_env_p = env
|
|
||||||
#endif
|
#endif
|
||||||
extern void ecl_init_env(cl_env_ptr);
|
extern void ecl_init_env(cl_env_ptr);
|
||||||
extern void init_lib_LSP(cl_object);
|
extern void init_lib_LSP(cl_object);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue