root/trunk/dep/src/zthread/win32/AtomicFastRecursiveLock.h @ 2

Revision 2, 4.3 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (c) 2005, Eric Crahen
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is furnished
9 * to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 */
22
23#ifndef __ZTFASTRECURSIVELOCK_H__
24#define __ZTFASTRECURSIVELOCK_H__
25
26#include "zthread/NonCopyable.h"
27#include <windows.h>
28#include <assert.h>
29
30namespace ZThread {
31
32
33/**
34 * @class FastRecursiveLock
35 *
36 * @author Eric Crahen <http://www.code-foo.com>
37 * @date <2003-07-16T23:32:34-0400>
38 * @version 2.1.6
39 *
40 * This is the smaller and faster implementation of a RecursiveLock.
41 * A single thread can acquire the mutex any number of times, but it
42 * must perform a release for each acquire(). Other threads are blocked
43 * until a thread has released all of its locks on the mutex.
44 *
45 * This particular implementation performs fewer safety checks. Like
46 * the FastLock implementation, any waiting caused by an acquire() request
47 * is not interruptable. This is so that the mutex can have the fastest
48 * response time for a time critical application while still having a good
49 * degree of reliability.
50 *
51 * TryEnterCriticalSection() does not work at all on some systems, so its
52 * not used.
53 *
54 *
55 * The current Platform SDK defines:
56 *
57 *   LONG InterlockedExchange(LPLONG, LONG)
58 *   LONG InterlockedCompareExchange(LPLONG, LONG, LONG, LONG)
59 *
60 * If your compiler complains about LPLONG not being implicitly casted to
61 * a PVOID, then you should get the SDK update from microsoft or use the
62 * WIN9X implementation of this class.
63 *
64 * ----
65 * Because Windows 95 and earlier can run on processors prior to the 486, they
66 * don't all support the CMPXCHG function, and so Windows 95 an earlier dont support
67 * InterlockedCompareExchange. If you define ZT_WIN9X, you'll get a version of the
68 * FastLock that uses the XCHG instruction
69 */ 
70class FastRecursiveLock : private NonCopyable {
71
72// Add def for mingw32 or other non-ms compiler to align on 64-bit
73// boundary
74#pragma pack(push, 8)
75  LONG volatile _lock;
76#pragma pack(pop)
77  LONG _count;
78 
79  public:
80 
81  /**
82   * Create a new FastRecursiveLock
83   */
84  inline FastRecursiveLock() : _lock(0), _count(0) { }
85
86 
87  /**
88   * Destroy FastLock
89   */
90  inline ~FastRecursiveLock() {
91    assert(_lock == 0);
92  }
93
94  /**
95   * Lock the fast Lock, no error check.
96   *
97   * @exception None
98   */ 
99  inline void acquire() {
100
101    DWORD id = ::GetCurrentThreadId();
102
103    // Take ownership if the lock is free or owned by the calling thread
104    do {
105
106      DWORD owner = (DWORD)::InterlockedCompareExchange(const_cast<LPLONG>(&_lock), id, 0);
107      if(owner == 0 || owner == id)
108        break;
109
110      ::Sleep(0);
111
112    } while(1);
113       
114    _count++;
115
116  }
117
118 
119  /**
120   * Release the fast Lock, no error check.
121   *
122   * @exception None
123   */ 
124  inline void release() {
125
126    if(--_count == 0)
127      ::InterlockedExchange(const_cast<LPLONG>(&_lock), 0);
128
129  }
130   
131  /**
132   * Try to acquire an exclusive lock. No safety or state checks are performed.
133   * This function returns immediately regardless of the value of the timeout
134   *
135   * @param timeout Unused
136   * @return bool
137   * @exception Synchronization_Exception - not thrown
138   */
139  inline bool tryAcquire(unsigned long timeout=0) {
140   
141    DWORD id = ::GetCurrentThreadId();
142    DWORD owner = (DWORD)::InterlockedCompareExchange(const_cast<LPLONG>(&_lock), id, 0);
143   
144    if(owner == 0 || owner == id) {
145      _count++;
146      return true;
147    }
148   
149    return false;
150   
151  }
152 
153 
154}; /* FastRecursiveLock */
155
156
157};
158#endif
Note: See TracBrowser for help on using the browser.