<div dir="ltr">Hi Akturk,<div class="gmail_extra"><br><div class="gmail_quote">On Sun, Mar 1, 2015 at 1:42 AM, Cihangir Akturk <span dir="ltr">&lt;<a href="mailto:cakturk@gmail.com" target="_blank">cakturk@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Reading the lib/llist.c file in the kernel sources, I came across<br>
the llist_add_bach function defined like this;<br>
<br>
bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last,<br>
                     struct llist_head *head)<br>
{<br>
        struct llist_node *first;<br>
<br>
        do {<br>
                new_last-&gt;next = first = ACCESS_ONCE(head-&gt;first);<br>
        } while (cmpxchg(&amp;head-&gt;first, first, new_first) != first);<br>
<br>
        return !first;<br>
}<br>
<br>
One thing bugging my mind is the ACCESS_ONCE macro. Is it really<br>
needed here ? I mean I would write this function with ACCES_ONCE<br>
moved outside the loop like as follows;<br></blockquote><div><br></div><div>ACCESS_ONCE avoids compiler optimization. A kind of compiler optimization can be caching a value in a register and reusing it.</div><div>Why compiler does this? Its his job to create optimized code for speed by default.</div><div><br></div><div>Now llist is lock less linked list, where multiple consumers and producers can work simultaneously.</div><div>Hence during each iteration of the while loop, you want to access the current value of head-&gt;first.</div><div><br></div><div>And if you remove ACCESS_ONCE, compiler can keep a copy of head-&gt;list in a register during first iteration and reuse it from register for the subsequent iterations. </div><div><br></div><div>Thanks,</div><div>Arun</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last,<br>
                     struct llist_head *head)<br>
{<br>
        struct llist_node *first, *old;<br>
<br>
        old = ACCESS_ONCE(head-&gt;first);<br>
        for (;;) {<br>
                first = old;<br>
                new_last-&gt;next = old;<br>
                old = cmpxchg(&amp;head-&gt;first, first, new_first);<br>
                if (old == first)<br>
                        break;<br>
        }<br>
<br>
        return !first;<br>
}<br>
<br>
I think that it may be faster to just use the return value of cmpxchg.<br>
But I am not sure about this.<br>
<br>
Is my understanding correct ?<br>
<br>
_______________________________________________<br>
Kernelnewbies mailing list<br>
<a href="mailto:Kernelnewbies@kernelnewbies.org">Kernelnewbies@kernelnewbies.org</a><br>
<a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" target="_blank">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
</blockquote></div><br></div></div>