<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
p.xmsonormal, li.xmsonormal, div.xmsonormal
{mso-style-name:x_msonormal;
margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
p.xxmsonormal, li.xxmsonormal, div.xxmsonormal
{mso-style-name:x_xmsonormal;
margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle21
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-GB" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Ok thanks, so it seems I should not count too much on those mutexes being movable.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">I was asking because in Thallium I have a C++ mutex class wrapping an ABT_mutex (<a href="https://github.com/mochi-hpc/mochi-thallium/blob/main/include/thallium/mutex.hpp">https://github.com/mochi-hpc/mochi-thallium/blob/main/include/thallium/mutex.hpp</a>).
For now its constructor uses ABT_mutex_create and its destructor ABT_mutex_free. It has move operations but no copy operations. If the ABT_mutex_memory had been movable, I could have replaced the ABT_mutex in this class with an ABT_mutex_memory.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">By the way, do static mutexes have an advantage beyond avoiding an allocation on the heap (which generally is not in the critical path when it comes to mutexes) and shortening code a
bit? (if those are the only advantages, then there is not much reason for me to update my mutex class).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Matthieu<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span style="font-size:12.0pt;color:black">From: </span></b><span style="font-size:12.0pt;color:black">"Iwasaki, Shintaro" <siwasaki@anl.gov><br>
<b>Date: </b>Tuesday, 15 June 2021 at 16:46<br>
<b>To: </b>"Dorier, Matthieu" <mdorier@anl.gov>, "discuss@argobots.org" <discuss@argobots.org>, "discuss@lists.argobots.org" <discuss@lists.argobots.org><br>
<b>Subject: </b>Re: Can I move a static mutex around in memory?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">Hi Matthieu,<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">Thanks.<o:p></o:p></span></p>
</div>
<div>
<blockquote style="border:none #C8C8C8 1.0pt;border-left:solid #C8C8C8 2.25pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:12.0pt;color:#666666">In the example you show, you say “even if you unlock m2, m1 is not unlocked”. That said, if no ULT cares about m1 anymore, and all the ULTs know they should use m2, then why shouldn’t it be fine?<o:p></o:p></span></p>
</blockquote>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">It depends on the implementation. In my understanding, it is fine in the current Argobots implementation, but it can cause an issue in the future update. So far, I do not plan to ensure this
property. For example, a possible Argobots implementation that can break this m1->m2 scenario is using a doubly circular linked list to manage waiters while one of the elements (maybe a head/tail marker of this linked list) is allocated within ABT_mutex_memory
(= the internal mutex entity). If you memory-copy m1 to m2, a waiter of this mutex points to m1's memory address though m1 is no longer valid.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">Even if m1 is unlocked, I am not fully sure if copying m1 to m2 and discarding m1 is okay. In other words, locked-and-then-unlocked ABT_mutex_memory's state can be different from clean ABT_mutex_memory's
state just after <span style="background:white">ABT_MUTEX_INITIALIZER, though I cannot come up with a good example that can cause such.</span><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">Note that if you can guarantee the following, you might want to reinitialize std::vector<ABT_mutex_memory> every time, which should be robust and not affected by the future update.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">1. When std::vector<ABT_mutex_memory> is resized, none of them are "locked" (implied by "no ULT cares about m1 anymore")<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">2. When std::vector<ABT_mutex_memory> is resized, there is no access to the old one: all ULTs can access new ABT_mutex without any data race (implied by "all the ULTs know they should use m2").<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">The code should look like this:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">```<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">std::vector<ABT_mutex_memory> mutex_mems;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">mutex_mems.resize(16);<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">for (int i = 0; i < mutex_mems.size(); i++) {<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"> // Clean up mutex_mems. ABT_mutex_free is not needed to release statically allocated ABT_mutex.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"> const ABT_mutex_memory mutex_mem_init = ABT_MUTEX_INITIALIZER;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"> memcpy(&mutex_mems[i], &<span style="background:white">mutex_mem_init</span>, sizeof(ABT_mutex_memory));<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">}<o:p></o:p></span></p>
</div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">```<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">If this <span style="background:white">memcpy() looks awkward, Argobots can provide a single-line macro.</span><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">I would appreciate any suggestions!<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">Thanks,<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black">Shintaro<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="0" width="100%" align="center">
</div>
<div id="divRplyFwdMsg">
<p class="MsoNormal"><b><span style="color:black">From:</span></b><span style="color:black"> Dorier, Matthieu <mdorier@anl.gov><br>
<b>Sent:</b> Tuesday, June 15, 2021 10:09 AM<br>
<b>To:</b> Iwasaki, Shintaro <siwasaki@anl.gov>; discuss@argobots.org <discuss@argobots.org>; discuss@lists.argobots.org <discuss@lists.argobots.org><br>
<b>Subject:</b> Re: Can I move a static mutex around in memory?</span> <o:p></o:p></p>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="xmsonormal"><span lang="EN-US">Hi Shintaro,</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Thank you for your answer.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">In the example you show, you say “even if you unlock m2, m1 is not unlocked”. That said, if no ULT cares about m1 anymore, and all the ULTs know they should use m2, then why shouldn’t it be fine?</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Maybe other objects in Argobots (such as an ES) are keeping pointers to mutexes, and these pointers would be invalidated?</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Thanks,</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Matthieu</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="xmsonormal"><b><span style="font-size:12.0pt;color:black">From: </span>
</b><span style="font-size:12.0pt;color:black">"Iwasaki, Shintaro" <siwasaki@anl.gov><br>
<b>Date: </b>Tuesday, 15 June 2021 at 14:57<br>
<b>To: </b>"discuss@argobots.org" <discuss@argobots.org>, "discuss@lists.argobots.org" <discuss@lists.argobots.org><br>
<b>Cc: </b>"Dorier, Matthieu" <mdorier@anl.gov><br>
<b>Subject: </b>Re: Can I move a static mutex around in memory?</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"> <o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black">Hi Matthieu,</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black"> </span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black">Thanks for the question! </span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black">ABT_mutex -> Yes, it's internally just a pointer (more specifically, a handle), so you can copy it.</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black">ABT_mutex_memory -> No, it saves it states in this memory (directly used as ABTI_mutex), so if you copy it, you basically corrupt the ABT_mutex structure.</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black"><a href="https://github.com/pmodels/argobots/blob/main/src/include/abt.h.in#L1114-L1115">https://github.com/pmodels/argobots/blob/main/src/include/abt.h.in#L1114-L1115</a></span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black">The same thing goes to ABT_cond_memory: do not move <span style="background:white">ABT_cond_memory around.</span></span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black"> </span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">// Example (THE FOLLOWING IS FORBIDDEN)</span><span style="font-size:12.0pt;color:black">
</span><o:p></o:p></p>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black">ABT_mutex_memory m1 = ABT_MUTEX_INITIALIZER;</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">ABT_mutex_lock(ABT_MUTEX_MEMORY_GET_HANDLE(&m1));</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">ABT_mutex_memory m2;</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">memcpy(&m2, &m1, sizeof(ABT_mutex_memory));</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">// m2 is locked since m1 is locked. The mutex "entity" is copied, so even if you unlock m2, m1 is not unlocked.</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">// It can cause something even worse since this mutex entity may store the waiters or even a pointer to its own memory.</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">// Do not use ABT_mutex_memory in this way.</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">ABT_mutex_lock(ABT_MUTEX_MEMORY_GET_HANDLE(&m2));</span><o:p></o:p></p>
</div>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black"> </span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black">In your case, reallocation on resizing std::vector can break the mutex data (even if ABT_mutex_memory is somehow
<span style="background:white">moved </span>"uniquely" ).</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black">Please dynamically allocate each ABT_mutex_memory individually (std::vector<ABT_mutex_memory *>).</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black"> </span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">Thanks,</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal"><span style="font-size:12.0pt;color:black;background:white">Shintaro</span><o:p></o:p></p>
</div>
<div>
<p class="xmsonormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
</div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="0" width="100%" align="center">
</div>
<div id="x_divRplyFwdMsg">
<p class="xmsonormal"><b><span style="color:black">From:</span></b><span style="color:black"> Dorier, Matthieu via discuss <discuss@lists.argobots.org><br>
<b>Sent:</b> Tuesday, June 15, 2021 7:04 AM<br>
<b>To:</b> discuss@argobots.org <discuss@argobots.org><br>
<b>Cc:</b> Dorier, Matthieu <mdorier@anl.gov><br>
<b>Subject:</b> [argobots-discuss] Can I move a static mutex around in memory?</span>
<o:p></o:p></p>
<div>
<p class="xmsonormal"> <o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="xxmsonormal"><span lang="EN-US">Hi,</span><o:p></o:p></p>
<p class="xxmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xxmsonormal"><span lang="EN-US">I would like to understand statically initialized mutex and condition variables better, in particular: can I move them around in memory (assuming all the ULTs in my code have a consistent way of locating them)?</span><o:p></o:p></p>
<p class="xxmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xxmsonormal"><span lang="EN-US">This would come up in C++ containers, for instance:</span><o:p></o:p></p>
<p class="xxmsonormal"><span lang="EN-US">std::vector<</span>ABT_mutex_memory> <o:p>
</o:p></p>
<p class="xxmsonormal">If I increase the size of the vector, reallocation may take place, and the existing mutexes will be moved somewhere else in memory. Assuming all the ULTs are accessing them by their index in the vector rather than by an ABT_mutex opaque
pointer, then this should be fine as long as I am allowed to move ABT_mutex_memory around (regardless of their state). Is that the case?<o:p></o:p></p>
<p class="xxmsonormal"> <o:p></o:p></p>
<p class="xxmsonormal">Same question for condition variables?<o:p></o:p></p>
<p class="xxmsonormal"> <o:p></o:p></p>
<p class="xxmsonormal">Thanks,<o:p></o:p></p>
<p class="xxmsonormal"> <o:p></o:p></p>
<p class="xxmsonormal">Matthieu<o:p></o:p></p>
<p class="xxmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>