We also remove conditionalization for garbage collector inclusion in autotools.
When we propose an alternative gc, then we may decide to put them back, or to
add necessary ifdef statements directly in files.
Moreover untangle c-stack from the gc code and assign the stack base with a
rough guess only when it is not initialized yet (GC will always fill it).
Finally remove a kludge from ecl_adopt_cpu and disable colleciton until the cpu
is fully initialized.
I've also renamed *HANDLER-CLUSTERS* to a more appropriate *SIGNAL-HANDLERS*.
Currently this symbol is imported to the SYSTEM package, although this may be
revised in the future to cater to multiple global environments. Alternatively
the SYSTEM package may be common to all runtimes.
Both tags have a special meaning to the low-level runtime (most notably the
frame stack). Extracting them from "all symbols" is a step towards multiple
runtimes.
Objects have a well defind extent so there is no need to rely on GC for
them. This change allows us to move stack initialization before garbage
collector is introduced into the system (or even without any GC).
This commit removes initial bindings array from the process and allocates it
only in the bds stack. To make fields in the structure less confusing we rename
initial_bindings slot to inherit_bindings_p.
On observable behavior change is that bindings are inherited when the process is
enabled, not when it is created. That was not specified in documentation so it
should be fine to change this behavior. Moreover it makes more sense from the
programmer perspective -- we want to inherit bindings of the process that starts
our thread, not the one that creates it.
When we don't use mprotect (nor guard page), we allocate the memory manually.
This simplifies some code and makes the booting process less intervened with GC.
The function ecl_fdefinition checks also for lamdbas and whatnot, while all we
need is a lookup in the global namespace for the function name.
This commit also changes how we store SETF function definition -- instead of
maintaining them in a global environment, it is stored along with the symbol.
That saves us from taking a global lock repeatedly.
The previous function call sequence for ordinary global functions
looked as follows.
1. check whether the function is defined, i.e. whether
symbol->symbol.gfdef is not NULL
2. set the_env->function to symbol->symbol.gfdef
3. call the function pointer symbol->symbol.gfdef->cfun.entry
This commit implements a performance optimization that enables us to
skip the first step. The basic idea is to replace symbol->symbol.gfdef
with a closure that signals an undefined-function condition.
However, straightforwardly implementing this would have the
disadvantage that it would consume a larger amount of memory for each
symbol without a function definition. To get around this, we reorder
the fields of the ecl_symbol struct such that the symbol can serve as
the function object itself, introducing an entry point that is only
used for undefined functions.
Benchmarking shows an improvement of about 10% in thight loops
compared to the old method.
- Spinlocks have been replaced by ordinary locks. Without access to
the underyling scheduler, spinlocks provide no performace benefit
and may even be harmful in case of high contention.
- Synchronization of process creation and exiting has been simplified.
Instead of a spinlock, a barrier and atomic operations we now use
only a single lock protecting the shared process state and a
condition variable for implementing process joins.
- Some locks which were implemented using Lisp objects now directly
use a native mutex.
- Our own mutex implementation has been removed as it is now unused.
On Unix, pathnames are converted into the default encoding specified
by ext:*default-external-format* and back. On Windows, the operating
system already gives us utf16 encoded pathnames, so we use those.
ecl_namestring with ECL_NAMESTRING_FORCE_BASE_STRING encodes with the
specified encoding. Decoding is handled individually in the filesystem
functions.
Includes a minor refactor of list_directory, changing the
PARSE_DIRECTORY_ENTRY macro into an inline function.
Closes#609, #549.
Always use the byte sized input/output operations ReadConsoleA/WriteConsoleA
and do all the conversion to unicode by ourself.
Moreover, expand the set of known encodings for Windows codepages and print
a warning if we encounter an unsupported codepage.
Fixes#582.
Due to the fact that the thread local environment is allocated with
mmap, the garbage collector is only aware of it after the thread is
listed in cl_core.processes. Therefore, we have to list the thread
before we allocate any memory in its environment. We were doing this
previously, however a bit earlier than needed which had the
unfortunate side effect that not all threads listed in
cl_core.processes had valid environment associated to them. Now, we
delay the listing until immediately before allocating the contents of
environment, ensuring that all listed threads have valid environments.