<div dir="ltr">
<div>Hi Marc,</div><div><br></div><div>Below some questions about sequential consistency and critical sections in SMP Gambit.</div><div><br></div><div>
<div>The Sutter slides below illustrate the problematique addressed beautifully.<br></div></div><div><br></div><div> * Please have a look at the below and confirm that this is what Gambit does?<br></div><div><br></div><div> *
 In thread-local code does Gambit internally do any optimizations that 
alters the execution order? In C-compiled code I presume the C compiler 
can make such optimizations, and that in itself pulls Gambit to need to address this problem domain.<br></div><div><br></div><div> * The 
baseline constraint on Gambit's as well as any C compiler's 
optimizations are that optimizations that alter order will not span 
module-external calls, isn't it?</div><div>
<div><br></div><div> * Does Gambit
 offer any low level primitives for (critical sections for) doing low 
level in-module sequentially consistent operations between cores?</div><div><br></div><div>   I.e. anything lower level than thread-send/receive and mutex-lock/unlock.<br></div><div><br></div><div>   What about fence, acquire/read fence, release/write fence.<br></div><div><br></div>

</div><div> * Does Gambit guarantee that newly allocated objects have some initialization when accessed from any CPU core, or if malloc() gave trash then may a Gambit thread see trash?</div><div><br></div><div>   Example:</div><div><br></div><div>   Context: (define x #f) (##fence!)<br></div><div>   Core A: (set! x (vector 1 2))</div><div>   Core B: (let loop () (let ((v x)) (if v (print (##vector-ref v 0))) (loop)))</div><div><br></div><div>   Which are all possible values that may be printed?<br></div><br><div>C/C++ standardized SMP/memory model in the C11/C++11 specs. It's great to see Gambit spec the same now.<br></div><div><br></div><div>Thanks,</div><div>Adam<br></div><div><br></div><div><br></div><div>Re
 critical sections, do you have primitives in SMP Gambit to force the 
compiler to respect them, and then in the code output produce assembly 
instructions that honor them?</div><div><br></div>

<div>Today in SMP Gambit, I presume thread-send/receive and 
mutex-lock/unlock will abstract away the underlying architecture's 
memory model, and ensure that thread-receive will have access to the 
whole structure that thread-send sent.</div><div><br></div><div>Example:<br></div><div style="margin-left:40px"><br></div><div style="margin-left:40px">GVM processor A:<br></div><div style="margin-left:40px"><br></div><div style="margin-left:40px">(thread-send B (list 1 2))</div><div style="margin-left:40px"><br></div><div style="margin-left:40px">(define l (list 3 4))</div><div style="margin-left:40px">(set-car! l 5)</div><div style="margin-left:40px">
(thread-send B (list 1 2))</div><div style="margin-left:40px"><br></div><div style="margin-left:40px"><br></div><div style="margin-left:40px">GVM processor B:<br></div><div style="margin-left:40px">(let loop () (for-each print (thread-receive) (loop))<br></div><div style="margin-left:40px"><br></div><div>This
 is to illustrate that thread-send/receive ensures that the list 
elements will be accessible (= read correctly) at the receiving site. In
 this case on any architecture, four print calls are done, each with the
 respectove argument: 1, 2, 5, 4.<br></div><div><br></div><div><br></div><div>I
 guess that design feature is helped by that the Gambit compiler will 
not do optimizations that garble the code order, over module-external 
procedure calls, and thread-send/receive & mutex-lock/unlock count 
as procedures.</div><div><br></div><div><br></div><div>I presume on strongly ordered architectures the following will make 2 3 go through:</div><div><br></div><div style="margin-left:40px">GVM processor A:</div><div style="margin-left:40px">(define l (list 1 2))</div><div style="margin-left:40px">(thread-send B l)</div><div style="margin-left:40px">(set-car! l 3)</div><br><div style="margin-left:40px">GVM processor B:<br></div><div style="margin-left:40px">(define m (thread-receive))</div><div style="margin-left:40px">(let loop ((i 0)) (if (not (eqv? (expt 3 12) i)) (loop (+ i 1)))<br></div><div style="margin-left:40px">(for-each print m)<br></div><div style="margin-left:40px"><br></div><div>On a weakly ordered architecture the code would not SIGSEGV nor throw exception, but the first value could be 1 or 3.</div><div><br></div><div><br></div><div>Importantly
 on a weakly ordered architecture the code would never cause a SIGSEGV, 
because Gambit's memory management ensures that pending memory bus 
transactions are flushed before it initiates collection of a dead 
object.</div><div><br></div><div>Similarly any allocated object's space is immediately accessible on all cores:</div><div><br></div><div style="margin-left:40px">Common workup:</div><div style="margin-left:40px">(define s #f)</div><div style="margin-left:40px"><br></div><div style="margin-left:40px">GVM processor A:</div><div style="margin-left:40px">(set! s (make-u8vector 5))</div><div style="margin-left:40px"><br></div><div style="margin-left:40px">GVM processor B:<br></div><div style="margin-left:40px">(let loop () (let ((v s)) (if v (##u8vector-ref v 1)) (loop))<br></div><div><br></div><div>The
 promise is limited to that the content is accessible only though - on a
 weakly ordered architecture, it may not have been initialized yet and 
therefore the type and range check in (u8vector-ref v 1) could fail, 
(##u8vector-ref v 1) do not do that though and while it may return junk,
 at least it will not crash.<br></div><div><br></div><div>The above two described behaviors are is in symmetry with any host OS' malloc/free.</div><div><br></div><div><br></div><div>Important references:</div><div><br></div><div>Sutter slides:<a href="https://1drv.ms/b/s!Aq0V7yDPsIZOgcI0y2P8R-VifbnTtw">https://1drv.ms/b/s!Aq0V7yDPsIZOgcI0y2P8R-VifbnTtw</a></div><div><br></div><div>Sutter videos:<br></div><div>
<div><div><a href="https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2" target="_blank">https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2</a> /</div></div><div><a href="https://www.youtube.com/watch?v=A8eCGOqgvH4" target="_blank">https://www.youtube.com/watch?v=A8eCGOqgvH4</a></div><div>and</div><div><a href="https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2" target="_blank">https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2</a> / <br></div><div><a href="https://www.youtube.com/watch?v=KeLBd2EJLOU" target="_blank">https://www.youtube.com/watch?v=KeLBd2EJLOU</a></div>

</div><div><br></div><div><br></div>

</div>