Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.3 KiB

  1. //+------------------------------------------------------------
  2. //
  3. // Copyright (C) 1998, Microsoft Corporation
  4. //
  5. // File: spinlock.cpp
  6. //
  7. // Contents: Simple Spinlock package used by CLdapConnection
  8. //
  9. // Classes:
  10. //
  11. // Functions:
  12. // AcquireSpinLockSingleProc
  13. // AcquireSpinLockMultiProc
  14. // InitializeSpinLock
  15. // ReleaseSpinLock
  16. //
  17. // History:
  18. // jstamerj 980511 17:26:26: Created.
  19. //
  20. //-------------------------------------------------------------
  21. #include "smtpinc.h"
  22. #include "spinlock.h"
  23. PFN_ACQUIRESPINLOCK g_AcquireSpinLock;
  24. //+----------------------------------------------------------------------------
  25. //
  26. // Function: InitializeSpinLock
  27. //
  28. // Synopsis: Initializes a SPIN_LOCK
  29. //
  30. // Arguments: [psl] -- Pointer to SPIN_LOCK to initialize
  31. //
  32. // Returns: Nothing. *psl is in released state when this functionr returns
  33. //
  34. //-----------------------------------------------------------------------------
  35. VOID InitializeSpinLock(
  36. PSPIN_LOCK psl)
  37. {
  38. *psl = 0;
  39. if(g_AcquireSpinLock == NULL) {
  40. // Determine multi or single proc
  41. SYSTEM_INFO si;
  42. GetSystemInfo(&si);
  43. if(si.dwNumberOfProcessors > 1) {
  44. g_AcquireSpinLock = AcquireSpinLockMultipleProc;
  45. } else {
  46. g_AcquireSpinLock = AcquireSpinLockSingleProc;
  47. }
  48. }
  49. }
  50. //+----------------------------------------------------------------------------
  51. //
  52. // Function: AcquireSpinLockMultiProc
  53. //
  54. // Synopsis: Acquire a lock, spinning while it is unavailable.
  55. // Optimized for multi proc machines
  56. //
  57. // Arguments: [psl] -- Pointer to SPIN_LOCK to acquire
  58. //
  59. // Returns: Nothing. *psl is in acquired state when this function returns
  60. //
  61. //-----------------------------------------------------------------------------
  62. VOID AcquireSpinLockMultipleProc(
  63. volatile PSPIN_LOCK psl)
  64. {
  65. do {
  66. //
  67. // Spin while the lock is unavailable
  68. //
  69. while (*psl > 0) {
  70. ;
  71. }
  72. //
  73. // Lock just became available, try to grab it
  74. //
  75. } while ( InterlockedIncrement(psl) != 1 );
  76. }
  77. //+----------------------------------------------------------------------------
  78. //
  79. // Function: AcquireSpinLockSingleProc
  80. //
  81. // Synopsis: Acquire a lock, spinning while it is unavailable.
  82. // Optimized for single proc machines
  83. //
  84. // Arguments: [psl] -- Pointer to SPIN_LOCK to acquire
  85. //
  86. // Returns: Nothing. *psl is in acquired state when this function returns
  87. //
  88. //-----------------------------------------------------------------------------
  89. VOID AcquireSpinLockSingleProc(
  90. volatile PSPIN_LOCK psl)
  91. {
  92. do {
  93. //
  94. // Spin while the lock is unavailable
  95. //
  96. while (*psl > 0) {
  97. Sleep(0);
  98. }
  99. //
  100. // Lock just became available, try to grab it
  101. //
  102. } while ( InterlockedIncrement(psl) != 1 );
  103. }
  104. //+----------------------------------------------------------------------------
  105. //
  106. // Function: ReleaseSpinLock
  107. //
  108. // Synopsis: Releases an acquired spin lock
  109. //
  110. // Arguments: [psl] -- Pointer to SPIN_LOCK to release.
  111. //
  112. // Returns: Nothing. *psl is in released state when this function returns
  113. //
  114. //-----------------------------------------------------------------------------
  115. VOID ReleaseSpinLock(
  116. PSPIN_LOCK psl)
  117. {
  118. _ASSERT( *psl > 0 );
  119. InterlockedExchange( psl, 0 );
  120. }