On 22.09.2017 13:31, Dima Pasechnik wrote:
No, we have not done that before, and everything worked on Linux and
OSX, and even on Cygwin (that is to say, we were lucky with threads
implementations on these platforms, depending on some sort of
undefined behaviour). Now I am trying
ecl_import_current_thread/ecl_release_current_thread on FreeBSD, and
it certainly appears to be the right direction, but I have a couple of
questions, at least one of them related to signal handling.

0) any advice on signal flags to be set to certain values?
Namely, ECL_OPT_SIGNAL_HANDLING_THREAD and
ECL_OPT_THREAD_INTERRUPT_SIGNAL? They seem to affect
the setup quite a bit; I had to do some trial and error, setting the
former to 1 and the latter to 67 (probably OS-specific value) seemed
to have done the trick...

1) as ECL must be built with --enable-threads, does it mean
that it will also try to spawn threads on its own?
(so far we always used to --disable-threads; for debugging purposes
I'd rather not let ECL run its own threads)

[I'd say this is a documentation issue, too, as it's not clear what
exactly --enable-threads is doing: enabling own ECL's threads, or
enabling ECL embedding in a multithreaded program, or both?]
--enable-threads gives ECL ability to use threads (i.e programmer may create his own thread in Lisp program). ECL may be embedded in any scenario (having both threads enabled and disabled), but if threads for ECL are disabled, than it is calling program responsibility to assure that ECL is accessed synchronously (i.e no two functions in ECL at the same time are called).

ECL_OPT_SIGNAL_HANDLING_THREAD is a flag, which when set to 1 makes ECL create a separate thread meant for handling signals (so ECL in that case runs two threads). If
ECL has threads disabled, then this flag does nothing.

2) for some reason calling ecl_release_current_thread()
leads to a nasty  crash, with lines like

     frame #299974: 0x0000000883a52463
libecl.so.16.1`FElibc_error(msg="", narg=0) at error.d:490
     frame #299975: 0x0000000883ab3e2c libecl.so.16.1`ecl_process_env
at process.d:70
     frame #299976: 0x0000000883aba9d4
libecl.so.16.1`ecl_alloc_compact_object(t=t_base_string,
extra_space=12) at alloc_2.d:622
     frame #299977: 0x0000000883a8c782
libecl.so.16.1`ecl_alloc_simple_vector(l=11, aet=ecl_aet_bc) at
array.d:585
     frame #299978: 0x0000000883a5331d
libecl.so.16.1`make_base_string_copy(s="No error: 0") at string.d:136
     frame #299979: 0x0000000883a52320
libecl.so.16.1`_ecl_strerror(code=0) at error.d:475
     frame #299980: 0x0000000883a52463

repeating endlessly in the backtrace.
Must it be called at all?
(The test program in examples you pointed at does work for me, with
few makefile changes...)



3) How does one call cl_boot() in such a multithreaded setting? I
tried merely putting the call to

    ecl_import_current_thread()

before the call to

    cl_boot()

but I get an error from GC:

"Threads explicit registering is not previously enabled"
and the program aborts.
Without doing ecl_import_current_thread(), cl_boot() succeeds in "main" thread,
but coredumps if invoked from another thread---this is the behaviour
you mistook for another instance of GC kicking in)

While we probably can live with cl_boot() always being called in the
main thread, this would be an extra burden to implement...
ecl_import_current_thread and ecl_release_current_thread needs to be called
in threads, which call ECL and are different than thread where cl_boot is called. For the thread where cl_boot was called you don't call import/release, they are implicit for cl_boot / cl_shutdown. You may run cl_boot in thread not being main
one, that's not the issue.

4) GC_THREADS is #define'd both in ECL and in GC headers.
This seems wrong to me.
No idea why it is that way. I'll keep in mind investigating that.

Regards,
Daniel

Reply via email to