~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WTF/wtf/TCSpinLock.h

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2005, 2006, Google Inc.
 
2
// Copyright (c) 2010, Patrick Gansterer <paroga@paroga.com>
 
3
// All rights reserved.
 
4
// 
 
5
// Redistribution and use in source and binary forms, with or without
 
6
// modification, are permitted provided that the following conditions are
 
7
// met:
 
8
// 
 
9
//     * Redistributions of source code must retain the above copyright
 
10
// notice, this list of conditions and the following disclaimer.
 
11
//     * Redistributions in binary form must reproduce the above
 
12
// copyright notice, this list of conditions and the following disclaimer
 
13
// in the documentation and/or other materials provided with the
 
14
// distribution.
 
15
//     * Neither the name of Google Inc. nor the names of its
 
16
// contributors may be used to endorse or promote products derived from
 
17
// this software without specific prior written permission.
 
18
// 
 
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
20
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
21
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
22
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
23
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
26
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
27
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
28
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
29
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
30
 
 
31
// ---
 
32
// Author: Sanjay Ghemawat <opensource@google.com>
 
33
 
 
34
#ifndef TCMALLOC_INTERNAL_SPINLOCK_H__
 
35
#define TCMALLOC_INTERNAL_SPINLOCK_H__
 
36
 
 
37
#include <wtf/Atomics.h>
 
38
#if OS(UNIX)
 
39
#include <sched.h>
 
40
#endif
 
41
 
 
42
#if ENABLE(COMPARE_AND_SWAP)
 
43
 
 
44
static void TCMalloc_SlowLock(unsigned* lockword);
 
45
 
 
46
// The following is a struct so that it can be initialized at compile time
 
47
struct TCMalloc_SpinLock {
 
48
    void Lock() {
 
49
      if (!WTF::weakCompareAndSwap(&lockword_, 0, 1))
 
50
        TCMalloc_SlowLock(&lockword_);
 
51
      WTF::memoryBarrierAfterLock();
 
52
    }
 
53
 
 
54
    void Unlock() {
 
55
      WTF::memoryBarrierBeforeUnlock();
 
56
      lockword_ = 0;
 
57
    }
 
58
 
 
59
    // Report if we think the lock can be held by this thread.
 
60
    // When the lock is truly held by the invoking thread
 
61
    // we will always return true.
 
62
    // Indended to be used as CHECK(lock.IsHeld());
 
63
    bool IsHeld() const {
 
64
        return lockword_ != 0;
 
65
    }
 
66
 
 
67
    void Init() { lockword_ = 0; }
 
68
    void Finalize() { }
 
69
 
 
70
    unsigned lockword_;
 
71
};
 
72
 
 
73
#define SPINLOCK_INITIALIZER { 0 }
 
74
 
 
75
static void TCMalloc_SlowLock(unsigned* lockword) {
 
76
  do {
 
77
#if OS(WINDOWS)
 
78
    Sleep(0);
 
79
#else
 
80
    sched_yield();
 
81
#endif
 
82
  } while (!WTF::weakCompareAndSwap(lockword, 0, 1));
 
83
}
 
84
 
 
85
#else
 
86
 
 
87
#include <pthread.h>
 
88
 
 
89
// Portable version
 
90
struct TCMalloc_SpinLock {
 
91
  pthread_mutex_t private_lock_;
 
92
 
 
93
  inline void Init() {
 
94
    if (pthread_mutex_init(&private_lock_, NULL) != 0) CRASH();
 
95
  }
 
96
  inline void Finalize() {
 
97
    if (pthread_mutex_destroy(&private_lock_) != 0) CRASH();
 
98
  }
 
99
  inline void Lock() {
 
100
    if (pthread_mutex_lock(&private_lock_) != 0) CRASH();
 
101
  }
 
102
  inline void Unlock() {
 
103
    if (pthread_mutex_unlock(&private_lock_) != 0) CRASH();
 
104
  }
 
105
  bool IsHeld() {
 
106
    if (pthread_mutex_trylock(&private_lock_))
 
107
      return true;
 
108
 
 
109
    Unlock();
 
110
    return false;
 
111
  }
 
112
};
 
113
 
 
114
#define SPINLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
 
115
 
 
116
#endif
 
117
 
 
118
// Corresponding locker object that arranges to acquire a spinlock for
 
119
// the duration of a C++ scope.
 
120
class TCMalloc_SpinLockHolder {
 
121
 private:
 
122
  TCMalloc_SpinLock* lock_;
 
123
 public:
 
124
  inline explicit TCMalloc_SpinLockHolder(TCMalloc_SpinLock* l)
 
125
    : lock_(l) { l->Lock(); }
 
126
  inline ~TCMalloc_SpinLockHolder() { lock_->Unlock(); }
 
127
};
 
128
 
 
129
// Short-hands for convenient use by tcmalloc.cc
 
130
typedef TCMalloc_SpinLock SpinLock;
 
131
typedef TCMalloc_SpinLockHolder SpinLockHolder;
 
132
 
 
133
#endif  // TCMALLOC_INTERNAL_SPINLOCK_H__