Advertisement
Guest User

Untitled

a guest
Aug 26th, 2016
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.66 KB | None | 0 0
  1.  
  2. struct ConceptualBlock
  3. {
  4. struct ConceptualBlock* next;
  5. };
  6.  
  7.  
  8. struct scond
  9. {
  10. #ifdef USE_WIN32_THREADS
  11. HANDLE event, atomic_lock;
  12. volatile int waiters;
  13. volatile bool waiting_ack;
  14. volatile struct ConceptualBlock* volatile root;
  15. HANDLE ack;
  16. #else
  17. pthread_cond_t cond;
  18. #endif
  19. };
  20.  
  21. void scond_wait(scond_t *cond, slock_t *lock)
  22. {
  23. #ifdef USE_WIN32_THREADS
  24.  
  25. printf("SCW B %p\n",cond);
  26.  
  27. //setup a queue (linked list) of blocked threads
  28. volatile struct ConceptualBlock myblock;
  29. myblock.next = NULL;
  30. volatile struct ConceptualBlock* volatile * ptr = &cond->root;
  31. while(*ptr != NULL)
  32. ptr = &((*ptr)->next);
  33. *ptr = &myblock;
  34.  
  35. //now the conceptual lock release and condition block are supposed to be atomic.
  36. //we can't do that in windows, but we can simulate the effects by using the queue, by the following analysis:
  37. //What happens if they aren't atomic?
  38. //1. a signaller can rush in and signal, expecting a waiter to get it; but the waiter wouldn't, because he isn't blocked yet
  39. //solution: win32 events make this easy. the event will sit there enabled
  40. //2. a signaller can rush in and signal, and then turn right around and wait
  41. //solution: the signaller will get queued behind the waiter, who's enqueued before he releases the mutex
  42.  
  43. for(;;)
  44. {
  45. ReleaseMutex(lock->lock);
  46. bool myturn = (cond->root == &myblock);
  47. ReleaseMutex(lock->lock);
  48.  
  49. if(myturn)
  50. {
  51. WaitForSingleObject(cond->event, INFINITE);
  52. break;
  53. }
  54. else
  55. {
  56. //otherwise, go to sleep (TODO: do something better than that)
  57. Sleep(1);
  58. }
  59. }
  60.  
  61. //re-acquire mutex
  62. WaitForSingleObject(lock->lock, INFINITE);
  63.  
  64. //remove ourselves from the queue
  65. cond->root = myblock.next;
  66.  
  67. #else
  68. pthread_cond_wait(&cond->cond, &lock->lock);
  69. #endif
  70. }
  71.  
  72. /**
  73. * scond_signal:
  74. * @cond : pointer to condition variable object
  75. *
  76. * Signal a condition. Unblocks at least one of the threads currently blocked
  77. * on the specified condition variable @cond.
  78. **/
  79. void scond_signal(scond_t *cond)
  80. {
  81. #ifdef USE_WIN32_THREADS
  82. //printf("DOOBOO %p\n",cond);
  83.  
  84. printf("SCS A %p\n",cond);
  85. /* remember: we currently have mutex */
  86. if(cond->root == NULL) return;
  87.  
  88. printf("SCS B %p\n",cond);
  89. /* OK, someone is waiting for a signal */
  90. /* We're supposed to wake up someone--anyone. It could even be ourselves, if we scond_wait() again in a minute. No guarantees. */
  91.  
  92. SetEvent(cond->event);
  93.  
  94. printf("SCS C %p\n",cond);
  95. //printf("DOOBOO %p\n",cond);
  96. #else
  97. pthread_cond_signal(&cond->cond);
  98. #endif
  99. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement