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

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: mut_tas.c,v 11.18 2000/11/30 00:58:41 ubell Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16. #endif
  17. /*
  18.  * This is where we load in the actual test-and-set mutex code.
  19.  */
  20. #define LOAD_ACTUAL_MUTEX_CODE
  21. #include "db_int.h"
  22. #ifdef DIAGNOSTIC
  23. #undef MSG1
  24. #define MSG1 "mutex_lock: ERROR: lock currently in use: pid: %lu.n"
  25. #undef MSG2
  26. #define MSG2 "mutex_unlock: ERROR: lock already unlockedn"
  27. #ifndef STDERR_FILENO
  28. #define STDERR_FILENO 2
  29. #endif
  30. #endif
  31. /*
  32.  * __db_tas_mutex_init --
  33.  * Initialize a MUTEX.
  34.  *
  35.  * PUBLIC: int __db_tas_mutex_init __P((DB_ENV *, MUTEX *, u_int32_t));
  36.  */
  37. int
  38. __db_tas_mutex_init(dbenv, mutexp, flags)
  39. DB_ENV *dbenv;
  40. MUTEX *mutexp;
  41. u_int32_t flags;
  42. {
  43. /* Check alignment. */
  44. DB_ASSERT(((db_alignp_t)mutexp & (MUTEX_ALIGN - 1)) == 0);
  45. memset(mutexp, 0, sizeof(*mutexp));
  46. /*
  47.  * If this is a thread lock or the process has told us that there are
  48.  * no other processes in the environment, use thread-only locks, they
  49.  * are faster in some cases.
  50.  *
  51.  * This is where we decide to ignore locks we don't need to set -- if
  52.  * the application isn't threaded, there aren't any threads to block.
  53.  */
  54. if (LF_ISSET(MUTEX_THREAD) || F_ISSET(dbenv, DB_ENV_PRIVATE)) {
  55. if (!F_ISSET(dbenv, DB_ENV_THREAD)) {
  56. F_SET(mutexp, MUTEX_IGNORE);
  57. return (0);
  58. }
  59. F_SET(mutexp, MUTEX_THREAD);
  60. }
  61. /* Initialize the lock. */
  62. if (MUTEX_INIT(&mutexp->tas))
  63. return (__os_get_errno());
  64. mutexp->spins = __os_spin();
  65. #ifdef MUTEX_SYSTEM_RESOURCES
  66. mutexp->reg_off = INVALID_ROFF;
  67. #endif
  68. F_SET(mutexp, MUTEX_INITED);
  69. return (0);
  70. }
  71. /*
  72.  * __db_tas_mutex_lock
  73.  * Lock on a mutex, logically blocking if necessary.
  74.  *
  75.  * PUBLIC: int __db_tas_mutex_lock __P((DB_ENV *, MUTEX *));
  76.  */
  77. int
  78. __db_tas_mutex_lock(dbenv, mutexp)
  79. DB_ENV *dbenv;
  80. MUTEX *mutexp;
  81. {
  82. u_long ms;
  83. int nspins;
  84. if (!dbenv->db_mutexlocks || F_ISSET(mutexp, MUTEX_IGNORE))
  85. return (0);
  86. ms = 1;
  87. loop: /* Attempt to acquire the resource for N spins. */
  88. for (nspins = mutexp->spins; nspins > 0; --nspins) {
  89. #ifdef HAVE_MUTEX_HPPA_MSEM_INIT
  90. relock:
  91. #endif
  92. if (!MUTEX_SET(&mutexp->tas))
  93. continue;
  94. #ifdef HAVE_MUTEX_HPPA_MSEM_INIT
  95. /*
  96.  * HP semaphores are unlocked automatically when a holding
  97.  * process exits.  If the mutex appears to be locked
  98.  * (mutexp->locked != 0) but we got here, assume this has
  99.  * happened.  Stick our own pid into mutexp->locked and
  100.  * lock again.  (The default state of the mutexes used to
  101.  * block in __lock_get_internal is locked, so exiting with
  102.  * a locked mutex is reasonable behavior for a process that
  103.  * happened to initialize or use one of them.)
  104.  */
  105. if (mutexp->locked != 0) {
  106. mutexp->locked = (u_int32_t)getpid();
  107. goto relock;
  108. }
  109. /*
  110.  * If we make it here, locked == 0, the diagnostic won't fire,
  111.  * and we were really unlocked by someone calling the
  112.  * DB mutex unlock function.
  113.  */
  114. #endif
  115. #ifdef DIAGNOSTIC
  116. if (mutexp->locked != 0) {
  117. char msgbuf[128];
  118. (void)snprintf(msgbuf,
  119.     sizeof(msgbuf), MSG1, (u_long)mutexp->locked);
  120. (void)write(STDERR_FILENO, msgbuf, strlen(msgbuf));
  121. }
  122. #endif
  123. #if defined(DIAGNOSTIC) || defined(HAVE_MUTEX_HPPA_MSEM_INIT)
  124. mutexp->locked = (u_int32_t)getpid();
  125. #endif
  126. if (ms == 1)
  127. ++mutexp->mutex_set_nowait;
  128. else
  129. ++mutexp->mutex_set_wait;
  130. return (0);
  131. }
  132. /* Yield the processor; wait 1ms initially, up to 1 second. */
  133. __os_yield(NULL, ms * USEC_PER_MS);
  134. if ((ms <<= 1) > MS_PER_SEC)
  135. ms = MS_PER_SEC;
  136. goto loop;
  137. }
  138. /*
  139.  * __db_tas_mutex_unlock --
  140.  * Release a lock.
  141.  *
  142.  * PUBLIC: int __db_tas_mutex_unlock __P((DB_ENV *, MUTEX *));
  143.  */
  144. int
  145. __db_tas_mutex_unlock(dbenv, mutexp)
  146. DB_ENV *dbenv;
  147. MUTEX *mutexp;
  148. {
  149. if (!dbenv->db_mutexlocks || F_ISSET(mutexp, MUTEX_IGNORE))
  150. return (0);
  151. #ifdef DIAGNOSTIC
  152. if (!mutexp->locked)
  153. (void)write(STDERR_FILENO, MSG2, sizeof(MSG2) - 1);
  154. #endif
  155. #if defined(DIAGNOSTIC) || defined(HAVE_MUTEX_HPPA_MSEM_INIT)
  156. mutexp->locked = 0;
  157. #endif
  158. MUTEX_UNSET(&mutexp->tas);
  159. return (0);
  160. }
  161. /*
  162.  * __db_tas_mutex_destroy --
  163.  * Destroy a MUTEX.
  164.  *
  165.  * PUBLIC: int __db_tas_mutex_destroy __P((MUTEX *));
  166.  */
  167. int
  168. __db_tas_mutex_destroy(mutexp)
  169. MUTEX *mutexp;
  170. {
  171. if (F_ISSET(mutexp, MUTEX_IGNORE))
  172. return (0);
  173. MUTEX_DESTROY(&mutexp->tas);
  174. return (0);
  175. }