sync0ipm.ic
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. A fast mutex for interprocess synchronization.
  3. mutex_t can be used only within single process,
  4. but ip_mutex_t also between processes.
  5. (c) 1995 Innobase Oy
  6. Created 9/30/1995 Heikki Tuuri
  7. *******************************************************/
  8. /* An extra structure created in the private address space of each process
  9. which creates or opens the ip mutex. */
  10. struct ip_mutex_hdl_struct {
  11. ip_mutex_t* ip_mutex; /* pointer to ip mutex */
  12. os_event_t released; /* event which signals that the mutex
  13. is released; this is obtained from
  14. create or open of an ip mutex */
  15. os_mutex_t exclude; /* os mutex obtained when ip mutex is
  16. created or opened */
  17. };
  18. UNIV_INLINE
  19. ulint
  20. ip_mutex_get_waiters(
  21. volatile ip_mutex_t* ipm);
  22. UNIV_INLINE
  23. void
  24. ip_mutex_set_waiters(
  25. volatile ip_mutex_t* ipm,
  26. ulint flag);
  27. UNIV_INLINE
  28. mutex_t*
  29. ip_mutex_get_mutex(
  30. ip_mutex_t* ipm);
  31. /******************************************************************
  32. Accessor functions for ip mutex. */
  33. UNIV_INLINE
  34. ulint
  35. ip_mutex_get_waiters(
  36. volatile ip_mutex_t* ipm)
  37. {
  38. return(ipm->waiters);
  39. }
  40. UNIV_INLINE
  41. void
  42. ip_mutex_set_waiters(
  43. volatile ip_mutex_t* ipm,
  44. ulint flag)
  45. {
  46. ipm->waiters = flag;
  47. }
  48. UNIV_INLINE
  49. mutex_t*
  50. ip_mutex_get_mutex(
  51. ip_mutex_t* ipm)
  52. {
  53. return(&(ipm->mutex));
  54. }
  55. /******************************************************************
  56. Reserves an ip mutex. */
  57. UNIV_INLINE
  58. ulint
  59. ip_mutex_enter(
  60. /*===========*/
  61. /* out: 0 if success, 
  62. SYNC_TIME_EXCEEDED if timeout */
  63. ip_mutex_hdl_t* ip_mutex_hdl, /* in: pointer to ip mutex handle */
  64. ulint time) /* in: maximum time to wait, in
  65. microseconds, or 
  66. SYNC_INFINITE_TIME */
  67. {
  68. mutex_t* mutex;
  69. os_event_t released;
  70. os_mutex_t exclude;
  71. ip_mutex_t* ip_mutex;
  72. ulint loop_count;
  73. ulint ret;
  74. ip_mutex = ip_mutex_hdl->ip_mutex;
  75. released = ip_mutex_hdl->released;
  76. exclude = ip_mutex_hdl->exclude;
  77. mutex = ip_mutex_get_mutex(ip_mutex);
  78. loop_count = 0;
  79. loop:
  80. loop_count++;
  81. ut_ad(loop_count < 15);
  82. if (mutex_enter_nowait(mutex) == 0) {
  83. /* Succeeded! */
  84. return(0);
  85. }
  86. ip_mutex_system_call_count++;
  87. os_event_reset(released);
  88. /* Order is important here: FIRST reset event, then set waiters */
  89. ip_mutex_set_waiters(ip_mutex, 1);
  90. if (mutex_enter_nowait(mutex) == 0) {
  91. /* Succeeded! */
  92. return(0);
  93. }
  94. if (time == SYNC_INFINITE_TIME) {
  95. time = OS_SYNC_INFINITE_TIME;
  96. }
  97. /* Suspend to wait for release */
  98. ip_mutex_system_call_count++;
  99. ret = os_event_wait_time(released, time);
  100. ip_mutex_system_call_count++;
  101. os_mutex_enter(exclude);
  102. ip_mutex_system_call_count++;
  103. os_mutex_exit(exclude);
  104. if (ret != 0) {
  105. ut_a(ret == OS_SYNC_TIME_EXCEEDED);
  106. return(SYNC_TIME_EXCEEDED);
  107. }
  108. goto loop;
  109. }
  110. /******************************************************************
  111. Releases an ip mutex. */
  112. UNIV_INLINE
  113. void
  114. ip_mutex_exit(
  115. /*==========*/
  116. ip_mutex_hdl_t* ip_mutex_hdl) /* in: pointer to ip mutex handle */
  117. {
  118. mutex_t* mutex;
  119. os_event_t released;
  120. os_mutex_t exclude;
  121. ip_mutex_t* ip_mutex;
  122. ip_mutex = ip_mutex_hdl->ip_mutex;
  123. released = ip_mutex_hdl->released;
  124. exclude = ip_mutex_hdl->exclude;
  125. mutex = ip_mutex_get_mutex(ip_mutex);
  126. mutex_exit(mutex);
  127. if (ip_mutex_get_waiters(ip_mutex) != 0) {
  128. ip_mutex_set_waiters(ip_mutex, 0);
  129. /* Order is important here: FIRST reset waiters, 
  130. then set event */
  131. ip_mutex_system_call_count++;
  132. os_mutex_enter(exclude);
  133. /* The use of the exclude mutex seems to prevent some
  134. kind of a convoy problem in the test tsproc.c. We do
  135. not know why. */
  136. ip_mutex_system_call_count++;
  137. os_event_set(released);
  138. ip_mutex_system_call_count++;
  139. os_mutex_exit(exclude);
  140. }
  141. }