hxmutexlock.h
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:18k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hxmutexlock.h,v 1.3.30.3 2004/07/09 01:45:12 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. /*
  50.  *  Non-reentrant mutexes for various server platforms.
  51.  */
  52. /***********************************************************************
  53.  *  THIS CODE IS HIGHLY CRITICAL TO THE SERVER'S STABILITY!!!
  54.  *  DO NOT MAKE CHANGES TO THE ATOMIC OPERATORS OR TO THE
  55.  *  MUTEX CODE WITHOUT A SERVER TEAM CODE-REVIEW! (dev@helix-server)
  56.  */
  57. /***********************************************************************
  58.  *
  59.  *  Platforms supported:
  60.  *    Windows / x86
  61.  *    Solaris / sparc 
  62.  *    IRIX / MIPS
  63.  *    AIX / PowerPC
  64.  *    Tru64(OSF) / Alpha
  65.  *    HP-UX / PA-RISC
  66.  *    HP-UX / Itanium
  67.  *    Misc. Unix / x86  (Linux, FreeBSD...)
  68.  *
  69.  *  XXXDC: So far, in nearly all cases, native mutexes provided by
  70.  *  OS vendors have been buggy and/or very slow.  Well-written 
  71.  *  assembly-language mutexes are strongly preferred.
  72.  *  Be especially careful about byte-alignment issues.
  73.  *
  74.  */
  75. /***********************************************************************
  76.  *
  77.  * Externally-available routines:
  78.  *
  79.  * inline void HXMutexLock(HX_MUTEX pLock, BOOL bWait = FALSE)
  80.  *     Locks the mutex, blocking until available;  A delay
  81.  *     between attempts to grab the lock is used if bWait is TRUE.
  82.  *     Note that the default is a tight no-delay spinlock, so
  83.  *     always set bWait to TRUE unless you know you should do otherwise.
  84.  *
  85.  * inline BOOL HXMutexTryLock(HX_MUTEX pLock)
  86.  *     Locks the mutex if available, returning TRUE if the lock succeeded,
  87.  *     and returning FALSE otherwise.
  88.  *
  89.  * inline void HXMutexUnlock(HX_MUTEX pLock)
  90.  *     Unlocks the mutex.
  91.  *
  92.  * inline HX_MUTEX HXMutexCreate()
  93.  *     Creates the mutex.
  94.  *
  95.  * inline void HXMutexInit(HX_MUTEX pLock)
  96.  *     Initializes the mutex.
  97.  *
  98.  * inline void HXMutexDestroy(HX_MUTEX pLock)
  99.  *     Destroys the mutex.
  100.  *
  101.  *
  102.  *  Additionally, this file defines IHXMutex, a COM wrapper for the above.
  103.  *
  104.  *
  105.  * NOTES:
  106.  * The older HXxxxMutex variations of the above are depreciated
  107.  * and should be converted over the the above variations for consistancy.
  108.  * HXMutexUnInit() is also depreciated, it never did anything and
  109.  * the purpose of it has been lost.  It appears useless.
  110.  *
  111.  */
  112. /***********************************************************************
  113.  *
  114.  * On most platforms the above are implemented using the
  115.  * following internal routines/#defines (do NOT call these directly!):
  116.  *
  117.  * int _HXMutexSetBit(HX_MUTEX pLock)
  118.  *     Lock the lock and return the old value of the lock
  119.  *     (0 meaning it was unlocked and is now locked, non-zero otherwise)
  120.  *
  121.  * _HXMutexClearBit(pLock)    
  122.  *     Clears the mutex flag.
  123.  *
  124.  * BOOL _HXMutexYieldCPUIfNeeded()
  125.  *     On some platforms we have to explicitly yield the CPU.
  126.  *     This is not needed on most platforms.
  127.  *
  128.  * void _HXMutexInitBit(HX_MUTEX pLock)
  129.  *     Initializes the mutex, typically just calls _HXMutexClearBit().
  130.  *
  131.  * void _HXMutexDestroyBit(HX_MUTEX pLock)
  132.  *     Destroys the mutex, typically does nothing.
  133.  */
  134. #ifndef _HXMUTEXLOCK_H_
  135. #define _HXMUTEXLOCK_H_
  136. /***********************************************************************
  137.  * Common defines/includes
  138.  */
  139. //system
  140. #include  <stdio.h>
  141. //include
  142. #include "hxtypes.h"
  143. #include "hxengin.h"
  144. //hxmisc
  145. #include "microsleep.h"
  146. /***********************************************************************
  147.  * OSF(Tru64) / Alpha defines/includes
  148.  */
  149. #if defined _OSF1
  150. #include <alpha/builtins.h>
  151. typedef struct
  152. {
  153.    char          p;
  154.    unsigned long for_alignment;
  155. } _HXMutexLockType;
  156. #define HX_MUTEX volatile _HXMutexLockType* volatile
  157. #define HX_MUTEX_TYPE volatile _HXMutexLockType
  158. #define HX_MUTEX_BASE_TYPE _HXMutexLockType
  159. /***********************************************************************
  160.  * HP-UX / Itanium defines/includes
  161.  */
  162. #elif defined _HPUX && defined _IA64
  163. #define HX_MUTEX volatile int* volatile
  164. #define HX_MUTEX_TYPE volatile int
  165. #define HX_MUTEX_BASE_TYPE int
  166. /***********************************************************************
  167.  * HP-UX / PA-RISC defines/includes
  168.  */
  169. #elif defined _HPUX
  170. extern "C" {
  171.     int load_and_clear(volatile char* volatile p);
  172. };
  173. typedef struct
  174. {
  175.     char      p;
  176.     long long for_alignment;
  177. } _HXMutexLockType;
  178. #define HX_MUTEX volatile _HXMutexLockType* volatile
  179. #define HX_MUTEX_TYPE volatile _HXMutexLockType  
  180. #define HX_MUTEX_BASE_TYPE _HXMutexLockType  
  181. // for 64-bit or 32-bit
  182. #define alignedaddr(x) (volatile int *)((PTR_INT)(x) + 15 & ~0xf)
  183. #define release_spinlock(LockArea)  if (1) {  
  184.      (*alignedaddr(LockArea) = 1); }
  185. /***********************************************************************
  186.  * AIX / PowerPC defines/includes
  187.  */
  188. #elif defined _AIX
  189. #include <errno.h>
  190. // NATIVE MUTEX
  191. #include <sys/mman.h>
  192. #define HX_MUTEX msemaphore*
  193. #define HX_MUTEX_TYPE msemaphore
  194. #define HX_MUTEX_BASE_TYPE msemaphore
  195. // ASSEMBLY MUTEX
  196. //#define HX_MUTEX volatile int* volatile
  197. //#define HX_MUTEX_TYPE volatile int
  198. //#define HX_MUTEX_BASE_TYPE int
  199. /***********************************************************************
  200.  * IRIX / MIPS defines/includes
  201.  */
  202. #elif defined _IRIX
  203. #include <abi_mutex.h>
  204. #define HX_MUTEX abilock_t*
  205. #define HX_MUTEX_TYPE abilock_t
  206. #define HX_MUTEX_BASE_TYPE abilock_t
  207. /***********************************************************************
  208.  * Windows x86 defines/includes
  209.  */
  210. #elif defined _WIN32
  211. #include <winbase.h>
  212. #define HX_MUTEX volatile int* volatile
  213. #define HX_MUTEX_TYPE volatile int
  214. #define HX_MUTEX_BASE_TYPE int
  215. /***********************************************************************
  216.  * generic defines/includes
  217.  */
  218. #else
  219. #define HX_MUTEX volatile int* volatile
  220. #define HX_MUTEX_TYPE volatile int
  221. #define HX_MUTEX_BASE_TYPE int
  222. #endif
  223. /***********************************************************************
  224.  * misc globals
  225.  *
  226.  * TODO: analyze more closely what the optimal delay is.
  227.  */
  228. #ifndef HX_MUTEX_DELAY
  229. #define HX_MUTEX_DELAY 10000
  230. #endif
  231. // Backoff Configs
  232. // XXXDC - Needs to be fine-tuned on a platform-specific basis!!!
  233. // XXXDC - highly experimental!
  234. #ifdef XXXDC_USE_BACKOFF
  235. #define BACKOFF_THRESHOLD  5     // # failed locks before delay starts
  236. #define BACKOFF_START      100   // usec to initially delay
  237. #define BACKOFF_FACTOR     10    // muliply each delay by this
  238. #define BACKOFF_MAX        15000 // maximum usec to delay
  239. #endif
  240. /***********************************************************************/
  241. /***********************************************************************
  242.  * Windows x86
  243.  *
  244.  * Implementation Notes:
  245.  *   Uses assembly mutex
  246.  */
  247. #if defined _WIN32
  248. #define _HXMutexYieldCPUIfNeeded() /* not needed */
  249. #define _HXMutexInitBit(pLock)     _HXMutexClearBit(pLock)
  250. #define _HXMutexDestroyBit(pLock)  /* not needed */
  251. #define _HXMutexClearBit(pLock)    (*(pLock) = 0)
  252. inline static int
  253. _HXMutexSetBit(HX_MUTEX pLock)
  254. {
  255.     register int nOldBit;
  256.     _asm
  257.     {
  258.         mov eax, 1
  259.         mov ebx, pLock
  260.         xchg dword ptr [ebx], eax
  261.         mov nOldBit, eax
  262.     }
  263.     return nOldBit;
  264. }
  265. /***********************************************************************
  266.  * Solaris / sparc / gcc
  267.  *
  268.  * Implementation Notes:
  269.  *   Uses assembly mutex
  270.  *   GCC inline-assembly syntax
  271.  */
  272. #elif defined _SOLARIS && defined __GNUC__
  273. #define _HXMutexYieldCPUIfNeeded() /* not needed */
  274. #define _HXMutexInitBit(pLock)     _HXMutexClearBit(pLock)
  275. #define _HXMutexDestroyBit(pLock)  /* not needed */
  276. #define _HXMutexClearBit(pLock)    (*(pLock) = 0)
  277. inline static int
  278. _HXMutexSetBit(HX_MUTEX pLock)
  279. {
  280.     volatile int nOldBit;
  281.     __asm__ __volatile__("swap [%0], %1"
  282.                         : "=r" (pLock), "=&r" (nOldBit)
  283.                         : "0" (pLock), "1" (1));
  284.     return nOldBit;
  285. }
  286. /***********************************************************************
  287.  * Solaris / sparc / native compiler
  288.  *
  289.  * Implementation Notes:
  290.  *   Uses assembly mutex
  291.  *   native-compiler syntax
  292.  */
  293. #elif defined _SOLARIS /* native compiler */
  294. extern "C" int _HXMutexSetBitCAS(HX_MUTEX pLock);
  295. extern "C" int _HXMutexSetBitSWAP(HX_MUTEX pLock);
  296. extern "C" int _HXMutexClearBit(HX_MUTEX pLock);
  297. #define _HXMutexSetBit(pLock)      _HXMutexSetBitCAS(pLock)
  298. #define _HXMutexYieldCPUIfNeeded() /* not needed */
  299. #define _HXMutexInitBit(pLock)     _HXMutexClearBit(pLock)
  300. #define _HXMutexDestroyBit(pLock)  /* not needed */
  301. /***********************************************************************
  302.  * IRIX / MIPS
  303.  *
  304.  * Implementation Notes:
  305.  *   Uses native mutex calls acquire_lock/etc.
  306.  *   On this platform we explicitly yield the processor
  307.  */
  308. #elif defined _IRIX
  309. #define _HXMutexYieldCPUIfNeeded() sginap(0)
  310. #define _HXMutexSetBit(pLock)      acquire_lock(pLock)
  311. #define _HXMutexClearBit(pLock)    release_lock(pLock)
  312. #define _HXMutexInitBit(pLock)     init_lock(pLock)
  313. #define _HXMutexDestroyBit(pLock)  /* not needed */
  314. /***********************************************************************
  315.  * AIX / PowerPC
  316.  *
  317.  * Implementation Notes:
  318.  *   Uses native mutex calls msem_lock/etc.
  319.  */
  320. #elif defined _AIX
  321. // NATIVE MUTEX
  322. //this doesn't work cleanly, we had to customize HXMutexLock() for AIX
  323. #define _HXMutexYieldCPUIfNeeded() /* not needed */
  324. #define _HXMutexSetBit(pLock)      msem_lock(pLock, MSEM_IF_NOWAIT)
  325. #define _HXMutexClearBit(pLock)    msem_unlock(pLock, 0)
  326. #define _HXMutexInitBit(pLock)     msem_init(pLock, MSEM_UNLOCKED)
  327. #define _HXMutexDestroyBit(pLock)  msem_remove(pLock)
  328. // ASSEMBLY MUTEX
  329. //#include <sched.h>
  330. //#define _HXMutexYieldCPUIfNeeded() sched_yield()
  331. //extern "C" int _HXMutexSetBit(HX_MUTEX pLock);
  332. //extern "C" int _HXMutexClearBit(HX_MUTEX pLock);
  333. //#define _HXMutexInitBit(pLock)     _HXMutexClearBit(pLock)
  334. //#define _HXMutexDestroyBit(pLock)  /* not needed */
  335. /***********************************************************************
  336.  * HP-UX / Itanium
  337.  *
  338.  * Implementation Notes:
  339.  *   Uses non-inline assembly mutex call _HXMutexSetBit(), defined
  340.  *   in common/util/platform/hpux/spinlock-ia64.s.   XXX: make this inline.
  341.  */
  342. #elif defined _HPUX && defined _IA64
  343. extern "C" int _HXMutexSetBit(HX_MUTEX pLock);
  344. extern "C" int _HXMutexClearBit(HX_MUTEX pLock);
  345. #define _HXMutexYieldCPUIfNeeded() /* not needed */
  346. #define _HXMutexInitBit(pLock)     _HXMutexClearBit(pLock)
  347. #define _HXMutexDestroyBit(pLock)  /* not needed */
  348. /***********************************************************************
  349.  * HP-UX / PA-RISC
  350.  *
  351.  * Implementation Notes:
  352.  *   Uses non-inline assembly mutex call load_and_clear(), defined
  353.  *   in common/util/platform/hpux/spin.s.   XXX: make this inline.
  354.  *   The logic of this mutex is backwards from most of our others,
  355.  *   1 means clear, 0 means set.
  356.  */
  357. #elif defined _HPUX
  358. #define _HXMutexYieldCPUIfNeeded() /* not needed */
  359. #define _HXMutexSetBit(pLock)      (load_and_clear((char* volatile)pLock) == 0)
  360. #define _HXMutexClearBit(pLock)   release_spinlock(pLock)
  361. #define _HXMutexInitBit(pLock)     _HXMutexClearBit(pLock)
  362. #define _HXMutexDestroyBit(pLock)  /* not needed */
  363. /***********************************************************************
  364.  * Tru64 (OSF/1) / Alpha
  365.  *
  366.  * Implementation Notes:
  367.  *   Uses native mutex calls __LOCK_LONG_RETRY/etc.
  368.  *
  369.  * TODO:
  370.  *   This native mutex is much slower than on other platforms.
  371.  *   Change this to use assembly.
  372.  */
  373. #elif defined _OSF1
  374. #define _HXMutexYieldCPUIfNeeded() /* not needed */
  375. #define _HXMutexSetBit(pLock)      (__LOCK_LONG_RETRY(pLock, 1) == 0)
  376. #define _HXMutexClearBit(pLock)    __UNLOCK_LONG(pLock)
  377. #define _HXMutexInitBit(pLock)     _HXMutexClearBit(pLock)
  378. #define _HXMutexDestroyBit(pLock)  /* not needed */
  379. /***********************************************************************
  380.  * Misc. Unix / x86  (Linux, FreeBSD...)
  381.  *
  382.  * Implementation Notes:
  383.  *   Uses assembly mutex
  384.  *   GCC inline-assembly syntax
  385.  *
  386.  * TODO: add non-x86 support for Linux/FreeBSD/etc.
  387.  */
  388. #else
  389. #define _HXMutexYieldCPUIfNeeded() /* not needed */
  390. #define _HXMutexInitBit(pLock)     _HXMutexClearBit(pLock)
  391. #define _HXMutexDestroyBit(pLock)  /* not needed */
  392. #define _HXMutexClearBit(pLock)    (*(pLock) = 0)
  393. /*
  394.  * GCC gets really mad if we use eax / ebx in the assembly below.
  395.  * We use ecx / edx instead (cross your fingers =)
  396.  */
  397. inline static int
  398. _HXMutexSetBit(HX_MUTEX pLock)
  399. {
  400.     volatile int nOldBit;
  401.     __asm__ __volatile__("xchg %%ecx, (%%edx)"
  402. : "=c" (nOldBit)
  403. : "c" (1), "d" (pLock));
  404.     return nOldBit;
  405. }
  406. #endif
  407. /***********************************************************************
  408.  * Common code, shared by multiple platforms
  409.  *
  410.  */
  411. #if !defined(HELIX_FEATURE_SERVER) && !defined(HX_MUTEX_PRIVATE_COLLISION_COUNTERS) && !defined(HX_MUTEX_PRIVATE_COLLISION_COUNTERS)
  412. //default for non-server products is to not use the collision counters
  413. #define HX_MUTEX_NO_COLLISION_COUNTERS
  414. #endif
  415. #if defined HX_MUTEX_NO_COLLISION_COUNTERS
  416. #define HXMutexCollision(p)    /* nothing */
  417. #elif defined HX_MUTEX_PRIVATE_COLLISION_COUNTERS
  418. /* User must define their own HXMutexCollision(p) */
  419. #else
  420. extern HX_MUTEX g_pServerMainLock;
  421. extern UINT32* g_pConcurrentOps;
  422. extern UINT32* g_pConcurrentMemOps;
  423. inline void
  424. HXMutexCollision(HX_MUTEX pLock)
  425. {
  426.     ++(*g_pConcurrentOps);
  427.     if (pLock != g_pServerMainLock)
  428.         ++(*g_pConcurrentMemOps);
  429. }
  430. #endif
  431. #ifndef HX_MUTEX_CUSTOM_COLLISION_DELAY
  432. #define HXMutexCollisionDelay(n) microsleep(n)
  433. #else
  434. /* User must define their own HXMutexCollisionDelay() */
  435. #endif
  436. //will obsolete these old names shortly...
  437. #define HXCreateMutex()   HXMutexCreate()
  438. #define HXInitMutex(p)    HXMutexInit(p)
  439. #define HXUnInitMutex(p)  HXMutexUnInit(p)
  440. #define HXDestroyMutex(p) HXMutexDestroy(p)
  441. #ifdef HX_MUTEX_USE_MANAGED_LOCKS
  442. HX_RESULT AddManagedMutex(HX_MUTEX pMutex);
  443. HX_RESULT RemoveManagedMutex(HX_MUTEX pMutex);
  444. #endif
  445. inline void
  446. HXMutexLock(HX_MUTEX pLock, BOOL bWait = FALSE)
  447. {
  448. #ifdef XXXDC_USE_BACKOFF
  449.     if (_HXMutexSetBit(pLock))
  450.     {
  451.         register int nInitialTries = 1;
  452.   register int nDelay = BACKOFF_START;
  453.    
  454.         //spin on reads for a bit (not writes)
  455.         while (*pLock && nInitialTries < BACKOFF_THRESHOLD)
  456.         {
  457.             HXMutexCollision(pLock);
  458.             ++nInitialTries;
  459.         }
  460.         while(_HXMutexSetBit(pLock))
  461.         {
  462.             _HXMutexYieldCPUIfNeeded();
  463.             if (bWait)
  464.             {
  465. HXMutexCollisionDelay(nDelay);
  466. nDelay = nDelay * BACKOFF_FACTOR;
  467. if (nDelay > BACKOFF_MAX)
  468.     nDelay = BACKOFF_MAX;
  469.             }
  470.             HXMutexCollision(pLock);
  471.         }
  472.     }
  473. #elif defined _AIX
  474.     do
  475.     {
  476.         if (msem_lock(pLock, 0) == 0) break;
  477.     } while (errno == EINTR);
  478. #else
  479.     while(_HXMutexSetBit(pLock))
  480.     {
  481.         _HXMutexYieldCPUIfNeeded();
  482.         if (bWait)
  483.         {
  484.             HXMutexCollisionDelay(HX_MUTEX_DELAY);
  485.         }
  486.         HXMutexCollision(pLock);
  487.     }
  488. #endif
  489. #ifdef HX_MUTEX_USE_MANAGED_LOCKS
  490.     AddManagedMutex(pLock);
  491. #endif
  492. }
  493. inline BOOL
  494. HXMutexTryLock(HX_MUTEX pLock)
  495. {
  496. #ifdef _AIX
  497.     BOOL bRet = (msem_lock(pLock, 0) == 0);
  498. #ifdef HX_MUTEX_USE_MANAGED_LOCKS
  499.     if (bRet)
  500.         AddManagedMutex(pLock);
  501. #endif
  502.     return bRet;
  503. #else
  504.     if (_HXMutexSetBit(pLock))
  505.     {
  506.         HXMutexCollision(pLock);
  507.         return FALSE;
  508.     }
  509. #ifdef HX_MUTEX_USE_MANAGED_LOCKS
  510.     AddManagedMutex(pLock);
  511. #endif
  512.     return TRUE;
  513. #endif
  514. }
  515. inline void
  516. HXMutexUnlock(HX_MUTEX pLock)
  517. {
  518. #ifdef HX_MUTEX_USE_MANAGED_LOCKS
  519.     RemoveManagedMutex(pLock);
  520. #endif
  521.     _HXMutexClearBit(pLock);
  522. }
  523. inline HX_MUTEX
  524. HXMutexCreate()
  525. {
  526.     HX_MUTEX pLock = (HX_MUTEX) new HX_MUTEX_BASE_TYPE;
  527.     _HXMutexInitBit(pLock);
  528.     return pLock;
  529. }
  530. inline void
  531. HXMutexInit(HX_MUTEX pLock)
  532. {
  533.     _HXMutexClearBit(pLock);
  534. }
  535. inline void
  536. HXMutexUnInit(HX_MUTEX pLock)
  537. {
  538.    /* no-op */
  539. }
  540. inline void
  541. HXMutexDestroy(HX_MUTEX pLock)
  542. {
  543.     _HXMutexDestroyBit(pLock);
  544. #if defined _WINDOWS
  545.     delete (void*)pLock;
  546. #else
  547.     delete pLock;
  548. #endif
  549. }
  550. #endif /* _HXMUTEXLOCK_H_ */