{"id":157163,"date":"2012-11-02T15:18:06","date_gmt":"2012-11-02T11:18:06","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=157163"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=157163","title":{"rendered":"<span class=\"post_title\">Atomic operations<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t\u0421\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043a\u0430\u043a \u0436\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u2014 \u0434\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043a\u0430\u0442.<br \/>  <a name=\"habracut\"><\/a><\/p>\n<p>  <a href=\"http:\/\/ru.wikipedia.org\/wiki\/%D0%90%D1%82%D0%BE%D0%BC%D0%B0%D1%80%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F\">\u0410\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/a> \u2014 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0435\u0441\u044f \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u043e\u0435 \u0446\u0435\u043b\u043e\u0435 \u043b\u0438\u0431\u043e \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0435\u0441\u044f \u0432\u043e\u0432\u0441\u0435. \u0422. \u0435. \u044d\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f, \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0435, \u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0435\/\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439. \u0415\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0443, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0439. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0441\u0442\u0438: load-link and store-conditional (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Load-Link\/Store-Conditional\">LL\/SC<\/a>), compare-and-swap (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Compare_and_swap\">CAS<\/a>) \u0438 \u0434\u0440\u0443\u0433\u0438\u0435.<\/p>\n<h5>1. LL\/SC<\/h5>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u043c\u0430\u043d\u0434 LL\/SC:<br \/>  ldl_l\/stl_c \u0438 ldq_l\/stq_c (Alpha), lwarx\/stwcx (PowerPC), ll\/sc (MIPS), and ldrex\/strex (ARM version 6 and above). <br \/>  \u041a\u043e\u043c\u0430\u043d\u0434\u044b \u0434\u0430\u043d\u044b \u043f\u0430\u0440\u0430\u043c\u0438, \u0442. \u043a. \u043f\u0435\u0440\u0432\u0430\u044f \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 lock, \u0432\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u0435\u0442. \u0412\u043c\u0435\u0441\u0442\u0435 \u043e\u043d\u0438 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u044e\u0442, \u0447\u0442\u043e \u0432\u0441\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441 \u043e\u0434\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u043f\u0430\u0440\u0443 lwarx\/stwcx (PowerPC):  <\/p>\n<pre><code class=\"cpp\">void atomic_incr(int * operand, int incr) {     asm volatile (         &quot;loop:\\n\\t&quot; \/* repeat until this succeeds *\/         &quot;lwarx  6,0,%0\\n\\t&quot; \/* reserve the operand *\/         &quot;add    6,6,%1\\n\\t&quot; \/* add incr to it *\/         &quot;stwcx. 6,0,%0\\n\\t&quot; \/* put the sum back, and release it *\/         &quot;bne- loop&quot; \/* start-over on failure *\/         :         : &quot;r&quot; (operand), &quot;r&quot; (incr)         : &quot;r6&quot;      ); }<\/code><\/pre>\n<p>  \u041a\u043e\u0434 \u0432\u0437\u044f\u0442 <a href=\"http:\/\/www.memoryhole.net\/kyle\/2007\/05\/atomic_incrementing.html\">\u043e\u0442\u0441\u044e\u0434\u0430.<\/a><br \/>  \u0412 6-\u043e\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0438 \u043e\u043d(\u043e\u043f\u0435\u0440\u0430\u043d\u0434) \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u041f\u043e\u0442\u043e\u043c \u0432 6-\u043e\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0443\u043c\u043c\u0443 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0438 incr. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438\u0437 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u0441\u0443\u043c\u043c\u0443 \u0432 \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0435\u0433\u043e. \u0415\u0441\u043b\u0438 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a \u043c\u0435\u0436\u0434\u0443 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043e \u0433\u0434\u0435-\u0442\u043e \u0435\u0449\u0435 \u043f\u043e\u043c\u0438\u043c\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438(\u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043e \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0443\u0436\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u043e\u0441\u044c \u0432 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0435), \u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443. \u042d\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 5-\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u043d\u043e\u0432\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b gcc<\/b><\/p>\n<div class=\"spoiler_text\">\u041f\u0440\u0438\u043c\u0435\u0440:<br \/>  : &quot;=r&quot; (val), &quot;=m&quot; (*mem)<br \/>  : \u00ab0\u00bb (val), \u00abm\u00bb (*mem)<br \/>  : \u00abmemory\u00bb, \u00abcc\u00bb);<br \/>  \u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u2014 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b.<br \/>  &quot;=r&quot; (val) \u2014 %0 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439 \u0438\u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u043c. gcc \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 \u0434\u043b\u044f %0.<br \/>  &quot;=m&quot; (*mem) \u2014 %1 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e gcc \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 (mem \u2014 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u044d\u0442\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e).<br \/>  \u0412\u0442\u043e\u0440\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u2014 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b.<br \/>  \u00ab0\u00bb (val) \u2014 0 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440, \u0447\u0442\u043e \u0438 \u0432 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u0438 \u0432 \u043d\u0435\u0433\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439.<br \/>  \u00abm\u00bb (*mem) \u2014 \u00abm\u00bb \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0442\u043e \u0436\u0435, \u0447\u0442\u043e \u0438 &quot;=m&quot;, \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0437\u043d\u0430\u043a\u0430 &quot;=&quot; \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0447\u0442\u0435\u043d\u0438\u0435.<br \/>  \u0422\u0440\u0435\u0442\u044c\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u2014 \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438.<br \/>  \u00abmemory\u00bb \u2014 \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0430 \u043f\u0430\u043c\u044f\u0442\u044c.<br \/>  \u00abcc\u00bb \u2014 \u00abcondition code register\u00bb. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b \u0444\u043b\u0430\u0433\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430.<br \/>  \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"http:\/\/www.ibiblio.org\/gferg\/ldp\/GCC-Inline-Assembly-HOWTO.html\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/div>\n<\/div>\n<h5>2. CAS<\/h5>\n<p>  \u041f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u2014 \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0435. \u0415\u0441\u043b\u0438 \u043e\u043d\u043e \u0442\u043e, \u043a\u0430\u043a\u043e\u0435 \u043c\u044b \u043e\u0436\u0438\u0434\u0430\u0435\u043c, \u0442\u043e \u043c\u0435\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043d\u043e\u0432\u043e\u0435.<br \/>  \u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c:  <\/p>\n<pre><code class=\"cpp\">int compare_and_swap (int* reg, int oldval, int newval)  {   int old_reg_val = *reg;   if (old_reg_val == oldval)       *reg = newval;   return old_reg_val; }<\/code><\/pre>\n<p>  \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 CAS \u2014 Double Compare And Swap (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Double_compare-and-swap\">CAS2<\/a>). \u0414\u0430\u044e\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0430 \u0434\u0432\u0435 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0434\u043d\u043e\u0439, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0434\u0432\u0430 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u041f\u0440\u0438\u043c\u0435\u0440:  <\/p>\n<pre><code class=\"cpp\">\/* double-compare-and-swap: atomically sets the two-word data at address @mem  *                          to the two-word value of @new if value at @mem  *                          equals @old  *   @mem: pointer to value  *   @old: old value   *   @new: new value  *  *   returns: 0 on failure, non-zero on success *\/ static inline  char DWCAS(volatile DWORD *mem, DWORD old, DWORD new) { \tchar r = 0; \tunsigned long old_h = old &gt;&gt; SHIFT, old_l = old; \tunsigned long new_h = new &gt;&gt; SHIFT, new_l = new; \t__asm__ __volatile__(&quot;lock; &quot; CMPXCHGxB &quot; (%6);&quot; \t\t     &quot;setz %7; &quot; \t\t     : &quot;=a&quot; (old_l), \t\t       &quot;=d&quot; (old_h) \t\t     : &quot;0&quot; (old_l), \t\t       &quot;1&quot; (old_h), \t\t       &quot;b&quot; (new_l), \t\t       &quot;c&quot; (new_h), \t\t       &quot;r&quot; (mem), \t\t       &quot;m&quot; (r) \t\t     : &quot;cc&quot;, &quot;memory&quot;); \treturn r; }<\/code><\/pre>\n<p>  \u041a\u043e\u0434 \u0432\u0437\u044f\u0442 <a href=\"http:\/\/julien.benoist.name\/lockfree\/atomic-queue\/atomic.h\">\u043e\u0442\u0441\u044e\u0434\u0430.<\/a><br \/>  \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u00ablock;\u00bb \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0448\u0438\u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0437\u0430 \u043d\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439.<br \/>  \u041d\u043e \u044d\u0442\u0430 \u0433\u0440\u0443\u043f\u043f\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u0431\u043e\u043b\u0435\u0435 \u00ab\u0441\u043b\u0430\u0431\u0430\u044f\u00bb, \u0447\u0435\u043c LL\/SC, \u0442. \u043a. \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f:<br \/>  \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f: compare_and_swap( reg, 5, 7 ) \u0438 *reg = 5;<br \/>  1) int old_reg_val = *reg; (old_reg_val = 5)<br \/>  2) \u0434\u0440\u0443\u0433\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u0435\u043b\u0430\u0435\u0442 *reg = 42; funny_stuff; *reg = 5;<br \/>  3) if (old_reg_val == oldval) \u2014 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u043e, \u0445\u043e\u0442\u044f \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0434\u0432\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. \u0422. \u0435. \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435, \u043d\u043e \u043d\u0430\u0448\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0435 \u0437\u043d\u0430\u0435\u0442. \u042d\u0442\u0430 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <a href=\"http:\/\/en.wikipedia.org\/wiki\/ABA_problem\">ABA problem<\/a>.<br \/>  \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043e\u0431\u0445\u043e\u0434\u0430 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u041c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Double-Word Compare-And-Swap (\u0447\u0430\u0441\u0442\u043e \u043f\u0443\u0442\u0430\u0435\u0442\u0441\u044f \u0441 Double Compare And Swap). \u0412 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u043c \u0441\u043b\u043e\u0432\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043f\u0430\u043c\u044f\u0442\u044c \u0441 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0438 ABA \u043d\u043e\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439 (\u0443\u0432\u0438\u0434\u0435\u043b \u044d\u0442\u043e \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 <a href=\"http:\/\/www.google.com\/patents\/US20080228784\">\u043f\u0430\u0442\u0435\u043d\u0442\u043e\u0432<\/a>).<\/p>\n<h5>3. \u041f\u0440\u043e\u0441\u0442\u044b\u0435 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/h5>\n<p>  \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f.<br \/>  \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u043c\u0430\u043d\u0434: addl(i386), xaddl(x86). <br \/>  \u0412\u043e\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0437 <a href=\"http:\/\/en.wikipedia.org\/wiki\/Fetch-and-add\">\u0432\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/a>:  <\/p>\n<pre><code class=\"cpp\">void atomic_add(int * operand, int incr) {     asm volatile (         &quot;lock; xaddl %1, (%0)\\n&quot; \/\/ add incr to operand         : \/\/ no output         : &quot;r&quot; (operand), &quot;r&quot; (incr)     ); }<\/code><\/pre>\n<p>  \u041d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u0445 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u00ablock;\u00bb \u043d\u0435 \u043d\u0443\u0436\u043d\u0430. \u041f\u0440\u0438\u043c\u0435\u0440 \u2014 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0418\u0442\u0430\u043d\u0438\u0443\u043c\u0435 (\u0432\u0437\u044f\u0442 <a href=\"http:\/\/www.memoryhole.net\/kyle\/2007\/05\/atomic_incrementing.html\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>):  <\/p>\n<pre><code class=\"cpp\">void atomic_oneup(int * operand) {     uint64_t res; \/\/ this MUST be 64 bits     asm volatile (         &quot;fetchadd4.rel %0=%1,%2&quot;         : &quot;=r&quot; (res)         : &quot;m&quot; (*operand), &quot;i&quot; (1)         : &quot;memory&quot;     ); }<\/code><\/pre>\n<p>  \u041a\u0441\u0442\u0430\u0442\u0438, \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442, \u0434\u0435\u043a\u0440\u0435\u043c\u0435\u043d\u0442, +=, -= \u0432 \u0421++ \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435 (\u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043d\u0430 \u044586 \u0438 \u044586_64).  <\/p>\n<pre><code class=\"cpp\">int a =0; ++a;<\/code><\/pre>\n<p>  \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432   <\/p>\n<pre><code class=\"cpp\">c7 45 fc 00 00 00 00 \tmovl   $0x0,-0x4(%rbp) 83 45 fc 01          \taddl   $0x1,-0x4(%rbp)<\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0434\u0435\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 subl. <\/p>\n<h5>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h5>\n<p>  Q: \u042d\u0442\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0448\u043a\u043e\u043b\u044c\u043d\u0438\u043a\u0443! \u0417\u0430\u0447\u0435\u043c \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0438\u0441\u0430\u0442\u044c?<br \/>  A: \u041c\u043d\u0435 \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043a\u0430\u043a \u0436\u0435 \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u0442\u043e\u043b\u044c\u043a\u043e, \u0447\u0442\u043e \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e lock&#8217;\u0438. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0435\u0449\u0435 \u043a\u043e\u043c\u0443-\u0442\u043e.<\/p>\n<p>  Q: \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043a\u0443\u0447\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u043d\u0435\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0435\u0439.<br \/>  A: \u041f\u0438\u0448\u0438\u0442\u0435, \u0441 \u0440\u0430\u0434\u043e\u0441\u0442\u044c\u044e \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044e.<\/p>\n<p>  Q: \u0427\u0442\u043e? \u0423\u0436\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435? \u0413\u0434\u0435 \u0441\u0430\u043c\u0430 \u0441\u0442\u0430\u0442\u044c\u044f? \u0413\u0434\u0435 <a href=\"https:\/\/en.wikipedia.org\/wiki\/MSI_protocol\">MSI<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Coherence_protocol\">Cache Coherence<\/a> \u0438 %\u0435\u0449\u0435_\u043a\u0443\u0447\u0430_\u0443\u043c\u043d\u044b\u0445_\u0441\u043b\u043e\u0432%?<br \/>  A: \u042f \u043d\u0435 \u043a\u043e\u043f\u0430\u043b \u0433\u043b\u0443\u0431\u043e\u043a\u043e. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u0438\u0448\u0443\u0442 \u043b\u044e\u0434\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u043d\u0430\u044e\u0442 \u044d\u0442\u0438 \u0442\u0435\u043c\u044b.    \t   \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/157163\/\"> http:\/\/habrahabr.ru\/post\/157163\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t\u0421\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043a\u0430\u043a \u0436\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u2014 \u0434\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043a\u0430\u0442.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-157163","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/157163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=157163"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/157163\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=157163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=157163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=157163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}