~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/third_party/chromium/src/base/atomicops_internals_mips_gcc.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2
 
// Use of this source code is governed by a BSD-style license that can be
3
 
// found in the LICENSE file.
4
 
 
5
 
// This file is an internal atomic implementation, use base/atomicops.h instead.
6
 
//
7
 
// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.
8
 
 
9
 
#ifndef BASE_ATOMICOPS_INTERNALS_MIPS_GCC_H_
10
 
#define BASE_ATOMICOPS_INTERNALS_MIPS_GCC_H_
11
 
 
12
 
namespace base {
13
 
namespace subtle {
14
 
 
15
 
// Atomically execute:
16
 
//      result = *ptr;
17
 
//      if (*ptr == old_value)
18
 
//        *ptr = new_value;
19
 
//      return result;
20
 
//
21
 
// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
22
 
// Always return the old value of "*ptr"
23
 
//
24
 
// This routine implies no memory barriers.
25
 
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
26
 
                                         Atomic32 old_value,
27
 
                                         Atomic32 new_value) {
28
 
  Atomic32 prev, tmp;
29
 
  __asm__ __volatile__(".set push\n"
30
 
                       ".set noreorder\n"
31
 
                       "1:\n"
32
 
                       "ll %0, %5\n"  // prev = *ptr
33
 
                       "bne %0, %3, 2f\n"  // if (prev != old_value) goto 2
34
 
                       "move %2, %4\n"  // tmp = new_value
35
 
                       "sc %2, %1\n"  // *ptr = tmp (with atomic check)
36
 
                       "beqz %2, 1b\n"  // start again on atomic error
37
 
                       "nop\n"  // delay slot nop
38
 
                       "2:\n"
39
 
                       ".set pop\n"
40
 
                       : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
41
 
                       : "Ir" (old_value), "r" (new_value), "m" (*ptr)
42
 
                       : "memory");
43
 
  return prev;
44
 
}
45
 
 
46
 
// Atomically store new_value into *ptr, returning the previous value held in
47
 
// *ptr.  This routine implies no memory barriers.
48
 
inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
49
 
                                         Atomic32 new_value) {
50
 
  Atomic32 temp, old;
51
 
  __asm__ __volatile__(".set push\n"
52
 
                       ".set noreorder\n"
53
 
                       "1:\n"
54
 
                       "ll %1, %2\n"  // old = *ptr
55
 
                       "move %0, %3\n"  // temp = new_value
56
 
                       "sc %0, %2\n"  // *ptr = temp (with atomic check)
57
 
                       "beqz %0, 1b\n"  // start again on atomic error
58
 
                       "nop\n"  // delay slot nop
59
 
                       ".set pop\n"
60
 
                       : "=&r" (temp), "=&r" (old), "=m" (*ptr)
61
 
                       : "r" (new_value), "m" (*ptr)
62
 
                       : "memory");
63
 
 
64
 
  return old;
65
 
}
66
 
 
67
 
// Atomically increment *ptr by "increment".  Returns the new value of
68
 
// *ptr with the increment applied.  This routine implies no memory barriers.
69
 
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
70
 
                                          Atomic32 increment) {
71
 
  Atomic32 temp, temp2;
72
 
 
73
 
  __asm__ __volatile__(".set push\n"
74
 
                       ".set noreorder\n"
75
 
                       "1:\n"
76
 
                       "ll %0, %2\n"  // temp = *ptr
77
 
                       "addu %1, %0, %3\n"  // temp2 = temp + increment
78
 
                       "sc %1, %2\n"  // *ptr = temp2 (with atomic check)
79
 
                       "beqz %1, 1b\n"  // start again on atomic error
80
 
                       "addu %1, %0, %3\n"  // temp2 = temp + increment
81
 
                       ".set pop\n"
82
 
                       : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
83
 
                       : "Ir" (increment), "m" (*ptr)
84
 
                       : "memory");
85
 
  // temp2 now holds the final value.
86
 
  return temp2;
87
 
}
88
 
 
89
 
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
90
 
                                        Atomic32 increment) {
91
 
  MemoryBarrier();
92
 
  Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment);
93
 
  MemoryBarrier();
94
 
  return res;
95
 
}
96
 
 
97
 
// "Acquire" operations
98
 
// ensure that no later memory access can be reordered ahead of the operation.
99
 
// "Release" operations ensure that no previous memory access can be reordered
100
 
// after the operation.  "Barrier" operations have both "Acquire" and "Release"
101
 
// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
102
 
// access.
103
 
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
104
 
                                       Atomic32 old_value,
105
 
                                       Atomic32 new_value) {
106
 
  Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
107
 
  MemoryBarrier();
108
 
  return res;
109
 
}
110
 
 
111
 
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
112
 
                                       Atomic32 old_value,
113
 
                                       Atomic32 new_value) {
114
 
  MemoryBarrier();
115
 
  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
116
 
}
117
 
 
118
 
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
119
 
  *ptr = value;
120
 
}
121
 
 
122
 
inline void MemoryBarrier() {
123
 
  __asm__ __volatile__("sync" : : : "memory");
124
 
}
125
 
 
126
 
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
127
 
  *ptr = value;
128
 
  MemoryBarrier();
129
 
}
130
 
 
131
 
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
132
 
  MemoryBarrier();
133
 
  *ptr = value;
134
 
}
135
 
 
136
 
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
137
 
  return *ptr;
138
 
}
139
 
 
140
 
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
141
 
  Atomic32 value = *ptr;
142
 
  MemoryBarrier();
143
 
  return value;
144
 
}
145
 
 
146
 
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
147
 
  MemoryBarrier();
148
 
  return *ptr;
149
 
}
150
 
 
151
 
} // namespace base::subtle
152
 
} // namespace base
153
 
 
154
 
#endif  // BASE_ATOMICOPS_INTERNALS_MIPS_GCC_H_