From: Vladimir Tzankov <vtzankov@gm...> - 2008-07-29 18:33:48
Here are my thoughts on the LISP heap management with multithreading.
I am still not aware of many internal details and possible pitfalls -
so advices are welcomed.
The GC will be protected with spinlock (possibly more efficient than mutex).
During GC all thread will be suspended at "safe" points (described below).
Suspension will be through mutex or spinlock - per thread.
The suspension and GC will be performed in the context of the thread
that caused the GC.
Is it ok to delay the suspension after the mark phase?
Still no objects are moved. All other threads may continue to run
(unless they do not try to allocate something and do not care about
the mark bit(s)).
Are there non-local exits from the GC?
What happens with signals during GC - looks like they are "disabled"?
(Pascal Bourguignon posted this interesting paper:
I would like to have spinlock per heap type. In this way the
allocations on a single heap will not block allocation on other types
(unless GC is invoked). I am not sure that this is possible for all
memory models but SVPW_PURE ones are good candidates.
Implementing this requires changes to mem structure, spvw_allocate.d
and other places that rely on accessing members of mem different than
heap specific ones. Currently I do not feel I am aware of all the
details in order to implement it quickly - so it will remain as TODO
However as a beginning:
1. single spinlock protects the whole mem structure (all heaps).
2. every thread should acqiure it in order to allocate anything
3. the thread that causes the GC will suspend all others before invoking it.
4. every thread should define so called "safe" points at which it can
be suspended with no risk. these places will be:
4.1. any call to allocate_xxxxxx()
4.2. begin_system_call (what happens if pointers to LISP heap are passed?)
4.3. (*) we need some other place in order to be able to suspend
forms like: (loop). Probably the interrupt() macro is good candidate?
"safe" points concept is similar to the cancellation points
(pthread_testcancel()) in pthreads.