Hi Andy, Andy Wingo <wi...@pobox.com> writes: > On Thu 29 Nov 2012 23:42, Mark H Weaver <m...@netris.org> writes: > >> SCM >> scm_local_eval (SCM exp, SCM env) >> { >> static SCM local_eval_var = SCM_BOOL_F; >> >> if (scm_is_false (local_eval_var)) >> local_eval_var = scm_c_public_variable ("ice-9 local-eval", >> "local-eval"); >> >> return scm_call_2 (SCM_VARIABLE_REF (local_eval_var), exp, env); >> } >> >> The problem is that it's possible for a thread to see a non-#f value for >> 'local_eval_var' before it sees the memory it points to properly >> initialized. > > scm_c_public_variable is not idempotent?
It is idempotent as far as I know, but that's not the problem. The problem is that in modern weakly-ordered memory models, there is no guarantee that thread B will see writes in the same order as they were performed by thread A. For example, if (ice-9 local-eval) has not yet been loaded when thread A calls 'scm_local_eval', then thread A will load the (ice-9 local-eval) module, allocate and initialize the associated SCM variable objects, and finally write 'local_eval_var' to point to one of these variable objects. However, in the absence of thread synchronization, thread B may see 'local_eval_var' set to a non-#f value before it sees the writes that initialized the variable object to which 'local_eval_var' points. In other words, thread B may end up reading a SCM variable object that has not yet been initialized in its timeline. For a good introduction to what is needed to write robust multithreaded code on modern weakly-ordered memory architectures, I recommend the following article: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2480.html Regards, Mark