rust3ds / pthread-3ds

PThread implementation for Nintendo 3DS Horizon OS targets. Keep in mind that Horizon OS uses a cooperative, and not preemptive, threading model.
Apache License 2.0
12 stars 7 forks source link

Sketchy RwLock impl #3

Closed AzureMarker closed 2 years ago

AzureMarker commented 2 years ago

I'm a little confused how the RwLock impl works. It doesn't seem to implement a true RwLock, but it does prevent panic from breaking. Maybe we should take a look at Rust3DS's or @vivlim's impl? (they are very similar)

https://github.com/rust3ds/ctru-rs/commit/7b886f48100609756e1d0e46034e4bdc5036ab4d

https://github.com/vivlim/rust/commit/48ae19f843127957499c65afdb5eff41b3755dd5#diff-faaf3057010b60684c982decf1168211dd558b3f5021dd16899382620017ae90

Meziu commented 2 years ago

Yes, i tried copying vivlim's implementation and reworking it into a lower level one. I could't wrap my head around the inclusion of the cvar and for the writer lock/num readers, due to being unable to obtain the kind of unlock. Eg. If the unlock is called by a reader, the code should lower the count, but while this is easy for the std, since it knows what called it, pthread only has one unlock function, and thus I can't know if a reader or the writer want to unlock...

vivlim commented 2 years ago

Unfortunately I don't remember either. IIRC my implementation was just copied from Rust3DS, if I made any changes it was probably to satisfy rustc.

Meziu commented 2 years ago

  /* We distinguish between having acquired a read vs. a write lock by looking
     at the writer TID.  If it's equal to our TID, we must be the writer
     because nobody else can have stored this value.  Also, if we are a
     reader, we will read from the wrunlock store with value 0 by the most
     recent writer because that writer happens-before us.  */
  if (atomic_load_relaxed (&rwlock->__data.__cur_writer)
      == THREAD_GETMEM (THREAD_SELF, tid))
      __pthread_rwlock_wrunlock (rwlock);
  else
    __pthread_rwlock_rdunlock (rwlock);
  return 0;
}

This is the wisdom glibc gives us. I have absolutely no idea what to do.

Edit: if the TID is the thread ID, maybe std::thread::current().id() will give us something? I'm not sure about the specifics since it's called by an extern C function. Worst case scenario: we have to take note of TIDs manually.

Meziu commented 2 years ago

Welp, now my code works perfectly, so I guess it's fixed(?). Should do some more testing (especially in multithreaded environments), but both reading and writing works. https://github.com/Meziu/pthread-3ds/commit/cea081ac27cb173a9addeb5abb632412df6cef85