rwlock.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009, 2010 Université de Bordeaux 1
  4. * Copyright (C) 2010 Centre National de la Recherche Scientifique
  5. *
  6. * StarPU is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation; either version 2.1 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * StarPU is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. *
  15. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  16. */
  17. /**
  18. * A dummy implementation of a rw_lock using spinlocks ...
  19. */
  20. #include "rwlock.h"
  21. static void _take_busy_lock(starpu_rw_lock_t *lock)
  22. {
  23. uint32_t prev;
  24. do {
  25. prev = STARPU_TEST_AND_SET(&lock->busy, 1);
  26. } while (prev);
  27. }
  28. static void _release_busy_lock(starpu_rw_lock_t *lock)
  29. {
  30. STARPU_RELEASE(&lock->busy);
  31. }
  32. void _starpu_init_rw_lock(starpu_rw_lock_t *lock)
  33. {
  34. STARPU_ASSERT(lock);
  35. lock->writer = 0;
  36. lock->readercnt = 0;
  37. lock->busy = 0;
  38. }
  39. int _starpu_take_rw_lock_write_try(starpu_rw_lock_t *lock)
  40. {
  41. _take_busy_lock(lock);
  42. if (lock->readercnt > 0 || lock->writer)
  43. {
  44. /* fail to take the lock */
  45. _release_busy_lock(lock);
  46. return -1;
  47. }
  48. else {
  49. STARPU_ASSERT(lock->readercnt == 0);
  50. STARPU_ASSERT(lock->writer == 0);
  51. /* no one was either writing nor reading */
  52. lock->writer = 1;
  53. _release_busy_lock(lock);
  54. return 0;
  55. }
  56. }
  57. int _starpu_take_rw_lock_read_try(starpu_rw_lock_t *lock)
  58. {
  59. _take_busy_lock(lock);
  60. if (lock->writer)
  61. {
  62. /* there is a writer ... */
  63. _release_busy_lock(lock);
  64. return -1;
  65. }
  66. else {
  67. STARPU_ASSERT(lock->writer == 0);
  68. /* no one is writing */
  69. /* XXX check wrap arounds ... */
  70. lock->readercnt++;
  71. _release_busy_lock(lock);
  72. return 0;
  73. }
  74. }
  75. void _starpu_take_rw_lock_write(starpu_rw_lock_t *lock)
  76. {
  77. do {
  78. _take_busy_lock(lock);
  79. if (lock->readercnt > 0 || lock->writer)
  80. {
  81. /* fail to take the lock */
  82. _release_busy_lock(lock);
  83. }
  84. else {
  85. STARPU_ASSERT(lock->readercnt == 0);
  86. STARPU_ASSERT(lock->writer == 0);
  87. /* no one was either writing nor reading */
  88. lock->writer = 1;
  89. _release_busy_lock(lock);
  90. return;
  91. }
  92. } while (1);
  93. }
  94. void _starpu_take_rw_lock_read(starpu_rw_lock_t *lock)
  95. {
  96. do {
  97. _take_busy_lock(lock);
  98. if (lock->writer)
  99. {
  100. /* there is a writer ... */
  101. _release_busy_lock(lock);
  102. }
  103. else {
  104. STARPU_ASSERT(lock->writer == 0);
  105. /* no one is writing */
  106. /* XXX check wrap arounds ... */
  107. lock->readercnt++;
  108. _release_busy_lock(lock);
  109. return;
  110. }
  111. } while (1);
  112. }
  113. void _starpu_release_rw_lock(starpu_rw_lock_t *lock)
  114. {
  115. _take_busy_lock(lock);
  116. /* either writer or reader (exactly one !) */
  117. if (lock->writer)
  118. {
  119. STARPU_ASSERT(lock->readercnt == 0);
  120. lock->writer = 0;
  121. }
  122. else {
  123. /* reading mode */
  124. STARPU_ASSERT(lock->writer == 0);
  125. lock->readercnt--;
  126. }
  127. _release_busy_lock(lock);
  128. }