TEXT   25

mtx lock

Guest on 24th January 2023 02:00:35 PM


  1. mtx_lock(unsigned long *lock) {
  2.         unsigned long l;
  3.  
  4. retry:
  5.         l = *lock;
  6.         if (l == 0) {
  7.                 if (cmpxchg(lock, 0, 1)) // cmpxchg returns 1 on failure
  8.                                          // cmpxchg(addr, old, new)
  9.                         goto retry;
  10.                 return;
  11.         }
  12.        
  13.         current->next = l & MASK;
  14.         if (cmpxchg(lock, l, current | 1))
  15.                 goto retry;
  16.  
  17.         sleep_on_queue(current);
  18. }
  19.  
  20. mtx_unlock(unsigned long *lock) {
  21.         unsigned long l;
  22.         struct thread *head, *p;
  23.  
  24. retry:
  25.         l = *lock;
  26.         if (l == 1) {
  27.                 if (cmpxchg(lock, 1, 0))
  28.                         goto retry;
  29.                 return;
  30.         }
  31.         head = (struct thread *)(l & MASK);
  32.  
  33.         // remove current from queue
  34.         list_for_each(p, head) {
  35.                 if (p->next == current) {
  36.                         p->next = current->next;
  37.                         break;
  38.                 }
  39.         }
  40.  
  41.         if (cmpxchg(lock, head | 1, head->next))
  42.                 goto retry;
  43.  
  44.         wake_up_one(head);
  45. }

Raw Paste


Login or Register to edit or fork this paste. It's free.

">