<html>
    <head>
      <base href="https://bugs.freedesktop.org/">
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Concurrent call to glClientWaitSync results in segfault in one of the waiters."
   href="https://bugs.freedesktop.org/show_bug.cgi?id=98172#c43">Comment # 43</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Concurrent call to glClientWaitSync results in segfault in one of the waiters."
   href="https://bugs.freedesktop.org/show_bug.cgi?id=98172">bug 98172</a>
              from <span class="vcard"><a class="email" href="mailto:michel@daenzer.net" title="Michel Dänzer <michel@daenzer.net>"> <span class="fn">Michel Dänzer</span></a>
</span></b>
        <pre>(In reply to Suzuki, Shinji from <a href="show_bug.cgi?id=98172#c41">comment #41</a>)
<span class="quote">> "screen->fence_reference(screen, &fence, NULL);
> is thread-safe if calls are serialized otherwise not thread safe".</span >

Not quite.

 screen->fence_reference(screen, &fence, NULL);

is always thread-safe with a local variable fence, because each thread has a
separate instance of the local variable, so only one of them will attempt to
destroy the fence object referenced by the pointer stored in the local
variables.


(In reply to Suzuki, Shinji from <a href="show_bug.cgi?id=98172#c42">comment #42</a>)
<span class="quote">> (The use of the shared completion flag seems to have potential
> synchronization problem because a waiter can see a successful wait as a
> result of unsuccessful call to fence_finish() if another thread comes and
> completes a successful fence_finish() call after the first thread completes
> unsuccessful fence_finish() but before returns.)</span >

Since the fence signalled before the first waiter returns, I'd say that's at
least sort of correct. :)


<span class="quote">>    screen->fence_reference(screen, &fence, so->fence);</span >

[...]

<span class="quote">>    if (fence) {
>       if(screen->fence_finish(screen, fence, timeout)) {
>          so->b.StatusFlag = GL_TRUE;
>          if( p_atomic_cmpxchg(&so->fence, fence, NULL) == fence ) {</span >

I'm afraid there's still a race here:

Thread 0                                                            Thread 1
--------                                                            --------

screen->fence_reference(screen, &fence, so->fence);
-> struct r600_multi_fence *rsrc = (struct r600_multi_fence *)src;
   -> rsrc != NULL

                                                                    if
(p_atomic_cmpxchg(&so->fence, fence, NULL) == fence) {
                                                                    -> fence !=
NULL, so->fence == NULL
                                                                       ->
continues to destroy the fence object

=> r600_fence_reference and st_client_wait_sync continue working
   with the fence object memory, which was already freed by thread
   1.


Did you run into any particular problem with my latest patch? Assuming the
shared mutex contention is your only issue with it, have you actually measured
any significant contention with it? If not, I'd like to submit it as the fix
for this bug report. It can always be changed to use a per-fence-object mutex
later if somebody measures significant contention with the shared mutex.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are the QA Contact for the bug.</li>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>