LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
| 6 #include "arch.h" |
| 7 |
| 8 static union { |
| 9 Lock l; |
| 10 byte pad [CacheLineSize]; |
| 11 } locktab[57]; |
| 12 |
| 13 #define LOCK(addr) (&locktab[((uintptr)addr>>3)%nelem(locktab)].l) |
6 | 14 |
7 // Atomic add and return new value. | 15 // Atomic add and return new value. |
8 #pragma textflag 7 | 16 #pragma textflag 7 |
9 uint32 | 17 uint32 |
10 runtime·xadd(uint32 volatile *val, int32 delta) | 18 runtime·xadd(uint32 volatile *val, int32 delta) |
11 { | 19 { |
12 uint32 oval, nval; | 20 uint32 oval, nval; |
13 | 21 |
14 for(;;){ | 22 for(;;){ |
15 oval = *val; | 23 oval = *val; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 if(runtime·casp(addr, old, v)) | 75 if(runtime·casp(addr, old, v)) |
68 return; | 76 return; |
69 } | 77 } |
70 } | 78 } |
71 | 79 |
72 #pragma textflag 7 | 80 #pragma textflag 7 |
73 void | 81 void |
74 runtime·atomicstore(uint32 volatile* addr, uint32 v) | 82 runtime·atomicstore(uint32 volatile* addr, uint32 v) |
75 { | 83 { |
76 uint32 old; | 84 uint32 old; |
77 » | 85 |
78 for(;;) { | 86 for(;;) { |
79 old = *addr; | 87 old = *addr; |
80 if(runtime·cas(addr, old, v)) | 88 if(runtime·cas(addr, old, v)) |
81 return; | 89 return; |
82 } | 90 } |
83 } | 91 } |
84 | 92 |
85 #pragma textflag 7 | 93 #pragma textflag 7 |
| 94 bool |
| 95 runtime·cas64(uint64 volatile *addr, uint64 *old, uint64 new) |
| 96 { |
| 97 bool res; |
| 98 ········ |
| 99 runtime·lock(LOCK(addr)); |
| 100 if(*addr == *old) { |
| 101 *addr = new; |
| 102 res = true; |
| 103 } else { |
| 104 *old = *addr; |
| 105 res = false; |
| 106 } |
| 107 runtime·unlock(LOCK(addr)); |
| 108 return res; |
| 109 } |
| 110 |
| 111 #pragma textflag 7 |
86 uint64 | 112 uint64 |
87 runtime·xadd64(uint64 volatile *val, int64 delta) | 113 runtime·xadd64(uint64 volatile *addr, int64 delta) |
88 { | 114 { |
89 » uint64 old; | 115 » uint64 res; |
90 | 116 »······· |
91 » old = *val; | 117 » runtime·lock(LOCK(addr)); |
92 » for(;;) { | 118 » res = *addr + delta; |
93 » » if(runtime·cas64(val, &old, old+v)) | 119 » *addr = res; |
94 » » » return old+v; | 120 » runtime·unlock(LOCK(addr)); |
95 » } | 121 » return res; |
96 } | 122 } |
97 | 123 |
98 #pragma textflag 7 | 124 #pragma textflag 7 |
99 uint64 | 125 uint64 |
100 runtime·atomicload64(uint64 volatile *addr) | 126 runtime·atomicload64(uint64 volatile *addr) |
101 { | 127 { |
102 » uint64 old; | 128 » uint64 res; |
103 ········ | 129 ········ |
104 » old = *val; | 130 » runtime·lock(LOCK(addr)); |
105 » for(;;) { | 131 » res = *addr; |
106 » » if(runtime·cas64(val, &old, old)) | 132 » runtime·unlock(LOCK(addr)); |
107 » » » return old; | 133 » return res; |
108 » } | |
109 } | 134 } |
110 | 135 |
111 #pragma textflag 7 | 136 #pragma textflag 7 |
112 void | 137 void |
113 runtime·atomicstore64(uint64 volatile *addr, uint64 v) | 138 runtime·atomicstore64(uint64 volatile *addr, uint64 v) |
114 { | 139 { |
115 » uint64 old; | 140 » runtime·lock(LOCK(addr)); |
116 »······· | 141 » *addr = v; |
117 » old = *val; | 142 » runtime·unlock(LOCK(addr)); |
118 » for(;;) { | 143 } |
119 » » if(runtime·cas64(val, &old, v)) | |
120 » » » return; | |
121 » } | |
122 } | |
LEFT | RIGHT |