]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/race.go
496e3725bf9712f41d2760de461433cb5ea883cd
[gostls13.git] / src / runtime / race.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //go:build race
6
7 package runtime
8
9 import (
10         "internal/abi"
11         "unsafe"
12 )
13
14 // Public race detection API, present iff build with -race.
15
16 func RaceRead(addr unsafe.Pointer)
17 func RaceWrite(addr unsafe.Pointer)
18 func RaceReadRange(addr unsafe.Pointer, len int)
19 func RaceWriteRange(addr unsafe.Pointer, len int)
20
21 func RaceErrors() int {
22         var n uint64
23         racecall(&__tsan_report_count, uintptr(unsafe.Pointer(&n)), 0, 0, 0)
24         return int(n)
25 }
26
27 // RaceAcquire/RaceRelease/RaceReleaseMerge establish happens-before relations
28 // between goroutines. These inform the race detector about actual synchronization
29 // that it can't see for some reason (e.g. synchronization within RaceDisable/RaceEnable
30 // sections of code).
31 // RaceAcquire establishes a happens-before relation with the preceding
32 // RaceReleaseMerge on addr up to and including the last RaceRelease on addr.
33 // In terms of the C memory model (C11 §5.1.2.4, §7.17.3),
34 // RaceAcquire is equivalent to atomic_load(memory_order_acquire).
35 //
36 //go:nosplit
37 func RaceAcquire(addr unsafe.Pointer) {
38         raceacquire(addr)
39 }
40
41 // RaceRelease performs a release operation on addr that
42 // can synchronize with a later RaceAcquire on addr.
43 //
44 // In terms of the C memory model, RaceRelease is equivalent to
45 // atomic_store(memory_order_release).
46 //
47 //go:nosplit
48 func RaceRelease(addr unsafe.Pointer) {
49         racerelease(addr)
50 }
51
52 // RaceReleaseMerge is like RaceRelease, but also establishes a happens-before
53 // relation with the preceding RaceRelease or RaceReleaseMerge on addr.
54 //
55 // In terms of the C memory model, RaceReleaseMerge is equivalent to
56 // atomic_exchange(memory_order_release).
57 //
58 //go:nosplit
59 func RaceReleaseMerge(addr unsafe.Pointer) {
60         racereleasemerge(addr)
61 }
62
63 // RaceDisable disables handling of race synchronization events in the current goroutine.
64 // Handling is re-enabled with RaceEnable. RaceDisable/RaceEnable can be nested.
65 // Non-synchronization events (memory accesses, function entry/exit) still affect
66 // the race detector.
67 //
68 //go:nosplit
69 func RaceDisable() {
70         gp := getg()
71         if gp.raceignore == 0 {
72                 racecall(&__tsan_go_ignore_sync_begin, gp.racectx, 0, 0, 0)
73         }
74         gp.raceignore++
75 }
76
77 // RaceEnable re-enables handling of race events in the current goroutine.
78 //
79 //go:nosplit
80 func RaceEnable() {
81         gp := getg()
82         gp.raceignore--
83         if gp.raceignore == 0 {
84                 racecall(&__tsan_go_ignore_sync_end, gp.racectx, 0, 0, 0)
85         }
86 }
87
88 // Private interface for the runtime.
89
90 const raceenabled = true
91
92 // For all functions accepting callerpc and pc,
93 // callerpc is a return PC of the function that calls this function,
94 // pc is start PC of the function that calls this function.
95 func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
96         kind := t.Kind_ & kindMask
97         if kind == kindArray || kind == kindStruct {
98                 // for composite objects we have to read every address
99                 // because a write might happen to any subobject.
100                 racereadrangepc(addr, t.Size_, callerpc, pc)
101         } else {
102                 // for non-composite objects we can read just the start
103                 // address, as any write must write the first byte.
104                 racereadpc(addr, callerpc, pc)
105         }
106 }
107
108 func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
109         kind := t.Kind_ & kindMask
110         if kind == kindArray || kind == kindStruct {
111                 // for composite objects we have to write every address
112                 // because a write might happen to any subobject.
113                 racewriterangepc(addr, t.Size_, callerpc, pc)
114         } else {
115                 // for non-composite objects we can write just the start
116                 // address, as any write must write the first byte.
117                 racewritepc(addr, callerpc, pc)
118         }
119 }
120
121 //go:noescape
122 func racereadpc(addr unsafe.Pointer, callpc, pc uintptr)
123
124 //go:noescape
125 func racewritepc(addr unsafe.Pointer, callpc, pc uintptr)
126
127 type symbolizeCodeContext struct {
128         pc   uintptr
129         fn   *byte
130         file *byte
131         line uintptr
132         off  uintptr
133         res  uintptr
134 }
135
136 var qq = [...]byte{'?', '?', 0}
137 var dash = [...]byte{'-', 0}
138
139 const (
140         raceGetProcCmd = iota
141         raceSymbolizeCodeCmd
142         raceSymbolizeDataCmd
143 )
144
145 // Callback from C into Go, runs on g0.
146 func racecallback(cmd uintptr, ctx unsafe.Pointer) {
147         switch cmd {
148         case raceGetProcCmd:
149                 throw("should have been handled by racecallbackthunk")
150         case raceSymbolizeCodeCmd:
151                 raceSymbolizeCode((*symbolizeCodeContext)(ctx))
152         case raceSymbolizeDataCmd:
153                 raceSymbolizeData((*symbolizeDataContext)(ctx))
154         default:
155                 throw("unknown command")
156         }
157 }
158
159 // raceSymbolizeCode reads ctx.pc and populates the rest of *ctx with
160 // information about the code at that pc.
161 //
162 // The race detector has already subtracted 1 from pcs, so they point to the last
163 // byte of call instructions (including calls to runtime.racewrite and friends).
164 //
165 // If the incoming pc is part of an inlined function, *ctx is populated
166 // with information about the inlined function, and on return ctx.pc is set
167 // to a pc in the logically containing function. (The race detector should call this
168 // function again with that pc.)
169 //
170 // If the incoming pc is not part of an inlined function, the return pc is unchanged.
171 func raceSymbolizeCode(ctx *symbolizeCodeContext) {
172         pc := ctx.pc
173         fi := findfunc(pc)
174         if fi.valid() {
175                 u, uf := newInlineUnwinder(fi, pc)
176                 for ; uf.valid(); uf = u.next(uf) {
177                         sf := u.srcFunc(uf)
178                         if sf.funcID == abi.FuncIDWrapper && u.isInlined(uf) {
179                                 // Ignore wrappers, unless we're at the outermost frame of u.
180                                 // A non-inlined wrapper frame always means we have a physical
181                                 // frame consisting entirely of wrappers, in which case we'll
182                                 // take a outermost wrapper over nothing.
183                                 continue
184                         }
185
186                         name := sf.name()
187                         file, line := u.fileLine(uf)
188                         if line == 0 {
189                                 // Failure to symbolize
190                                 continue
191                         }
192                         ctx.fn = &bytes(name)[0] // assume NUL-terminated
193                         ctx.line = uintptr(line)
194                         ctx.file = &bytes(file)[0] // assume NUL-terminated
195                         ctx.off = pc - fi.entry()
196                         ctx.res = 1
197                         if u.isInlined(uf) {
198                                 // Set ctx.pc to the "caller" so the race detector calls this again
199                                 // to further unwind.
200                                 uf = u.next(uf)
201                                 ctx.pc = uf.pc
202                         }
203                         return
204                 }
205         }
206         ctx.fn = &qq[0]
207         ctx.file = &dash[0]
208         ctx.line = 0
209         ctx.off = ctx.pc
210         ctx.res = 1
211 }
212
213 type symbolizeDataContext struct {
214         addr  uintptr
215         heap  uintptr
216         start uintptr
217         size  uintptr
218         name  *byte
219         file  *byte
220         line  uintptr
221         res   uintptr
222 }
223
224 func raceSymbolizeData(ctx *symbolizeDataContext) {
225         if base, span, _ := findObject(ctx.addr, 0, 0); base != 0 {
226                 ctx.heap = 1
227                 ctx.start = base
228                 ctx.size = span.elemsize
229                 ctx.res = 1
230         }
231 }
232
233 // Race runtime functions called via runtime·racecall.
234 //
235 //go:linkname __tsan_init __tsan_init
236 var __tsan_init byte
237
238 //go:linkname __tsan_fini __tsan_fini
239 var __tsan_fini byte
240
241 //go:linkname __tsan_proc_create __tsan_proc_create
242 var __tsan_proc_create byte
243
244 //go:linkname __tsan_proc_destroy __tsan_proc_destroy
245 var __tsan_proc_destroy byte
246
247 //go:linkname __tsan_map_shadow __tsan_map_shadow
248 var __tsan_map_shadow byte
249
250 //go:linkname __tsan_finalizer_goroutine __tsan_finalizer_goroutine
251 var __tsan_finalizer_goroutine byte
252
253 //go:linkname __tsan_go_start __tsan_go_start
254 var __tsan_go_start byte
255
256 //go:linkname __tsan_go_end __tsan_go_end
257 var __tsan_go_end byte
258
259 //go:linkname __tsan_malloc __tsan_malloc
260 var __tsan_malloc byte
261
262 //go:linkname __tsan_free __tsan_free
263 var __tsan_free byte
264
265 //go:linkname __tsan_acquire __tsan_acquire
266 var __tsan_acquire byte
267
268 //go:linkname __tsan_release __tsan_release
269 var __tsan_release byte
270
271 //go:linkname __tsan_release_acquire __tsan_release_acquire
272 var __tsan_release_acquire byte
273
274 //go:linkname __tsan_release_merge __tsan_release_merge
275 var __tsan_release_merge byte
276
277 //go:linkname __tsan_go_ignore_sync_begin __tsan_go_ignore_sync_begin
278 var __tsan_go_ignore_sync_begin byte
279
280 //go:linkname __tsan_go_ignore_sync_end __tsan_go_ignore_sync_end
281 var __tsan_go_ignore_sync_end byte
282
283 //go:linkname __tsan_report_count __tsan_report_count
284 var __tsan_report_count byte
285
286 // Mimic what cmd/cgo would do.
287 //
288 //go:cgo_import_static __tsan_init
289 //go:cgo_import_static __tsan_fini
290 //go:cgo_import_static __tsan_proc_create
291 //go:cgo_import_static __tsan_proc_destroy
292 //go:cgo_import_static __tsan_map_shadow
293 //go:cgo_import_static __tsan_finalizer_goroutine
294 //go:cgo_import_static __tsan_go_start
295 //go:cgo_import_static __tsan_go_end
296 //go:cgo_import_static __tsan_malloc
297 //go:cgo_import_static __tsan_free
298 //go:cgo_import_static __tsan_acquire
299 //go:cgo_import_static __tsan_release
300 //go:cgo_import_static __tsan_release_acquire
301 //go:cgo_import_static __tsan_release_merge
302 //go:cgo_import_static __tsan_go_ignore_sync_begin
303 //go:cgo_import_static __tsan_go_ignore_sync_end
304 //go:cgo_import_static __tsan_report_count
305
306 // These are called from race_amd64.s.
307 //
308 //go:cgo_import_static __tsan_read
309 //go:cgo_import_static __tsan_read_pc
310 //go:cgo_import_static __tsan_read_range
311 //go:cgo_import_static __tsan_write
312 //go:cgo_import_static __tsan_write_pc
313 //go:cgo_import_static __tsan_write_range
314 //go:cgo_import_static __tsan_func_enter
315 //go:cgo_import_static __tsan_func_exit
316
317 //go:cgo_import_static __tsan_go_atomic32_load
318 //go:cgo_import_static __tsan_go_atomic64_load
319 //go:cgo_import_static __tsan_go_atomic32_store
320 //go:cgo_import_static __tsan_go_atomic64_store
321 //go:cgo_import_static __tsan_go_atomic32_exchange
322 //go:cgo_import_static __tsan_go_atomic64_exchange
323 //go:cgo_import_static __tsan_go_atomic32_fetch_add
324 //go:cgo_import_static __tsan_go_atomic64_fetch_add
325 //go:cgo_import_static __tsan_go_atomic32_compare_exchange
326 //go:cgo_import_static __tsan_go_atomic64_compare_exchange
327
328 // start/end of global data (data+bss).
329 var racedatastart uintptr
330 var racedataend uintptr
331
332 // start/end of heap for race_amd64.s
333 var racearenastart uintptr
334 var racearenaend uintptr
335
336 func racefuncenter(callpc uintptr)
337 func racefuncenterfp(fp uintptr)
338 func racefuncexit()
339 func raceread(addr uintptr)
340 func racewrite(addr uintptr)
341 func racereadrange(addr, size uintptr)
342 func racewriterange(addr, size uintptr)
343 func racereadrangepc1(addr, size, pc uintptr)
344 func racewriterangepc1(addr, size, pc uintptr)
345 func racecallbackthunk(uintptr)
346
347 // racecall allows calling an arbitrary function fn from C race runtime
348 // with up to 4 uintptr arguments.
349 func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr)
350
351 // checks if the address has shadow (i.e. heap or data/bss).
352 //
353 //go:nosplit
354 func isvalidaddr(addr unsafe.Pointer) bool {
355         return racearenastart <= uintptr(addr) && uintptr(addr) < racearenaend ||
356                 racedatastart <= uintptr(addr) && uintptr(addr) < racedataend
357 }
358
359 //go:nosplit
360 func raceinit() (gctx, pctx uintptr) {
361         lockInit(&raceFiniLock, lockRankRaceFini)
362
363         // On most machines, cgo is required to initialize libc, which is used by race runtime.
364         if !iscgo && GOOS != "darwin" {
365                 throw("raceinit: race build must use cgo")
366         }
367
368         racecall(&__tsan_init, uintptr(unsafe.Pointer(&gctx)), uintptr(unsafe.Pointer(&pctx)), abi.FuncPCABI0(racecallbackthunk), 0)
369
370         // Round data segment to page boundaries, because it's used in mmap().
371         start := ^uintptr(0)
372         end := uintptr(0)
373         if start > firstmoduledata.noptrdata {
374                 start = firstmoduledata.noptrdata
375         }
376         if start > firstmoduledata.data {
377                 start = firstmoduledata.data
378         }
379         if start > firstmoduledata.noptrbss {
380                 start = firstmoduledata.noptrbss
381         }
382         if start > firstmoduledata.bss {
383                 start = firstmoduledata.bss
384         }
385         if end < firstmoduledata.enoptrdata {
386                 end = firstmoduledata.enoptrdata
387         }
388         if end < firstmoduledata.edata {
389                 end = firstmoduledata.edata
390         }
391         if end < firstmoduledata.enoptrbss {
392                 end = firstmoduledata.enoptrbss
393         }
394         if end < firstmoduledata.ebss {
395                 end = firstmoduledata.ebss
396         }
397         size := alignUp(end-start, _PageSize)
398         racecall(&__tsan_map_shadow, start, size, 0, 0)
399         racedatastart = start
400         racedataend = start + size
401
402         return
403 }
404
405 //go:nosplit
406 func racefini() {
407         // racefini() can only be called once to avoid races.
408         // This eventually (via __tsan_fini) calls C.exit which has
409         // undefined behavior if called more than once. If the lock is
410         // already held it's assumed that the first caller exits the program
411         // so other calls can hang forever without an issue.
412         lock(&raceFiniLock)
413
414         // __tsan_fini will run C atexit functions and C++ destructors,
415         // which can theoretically call back into Go.
416         // Tell the scheduler we entering external code.
417         entersyscall()
418
419         // We're entering external code that may call ExitProcess on
420         // Windows.
421         osPreemptExtEnter(getg().m)
422
423         racecall(&__tsan_fini, 0, 0, 0, 0)
424 }
425
426 //go:nosplit
427 func raceproccreate() uintptr {
428         var ctx uintptr
429         racecall(&__tsan_proc_create, uintptr(unsafe.Pointer(&ctx)), 0, 0, 0)
430         return ctx
431 }
432
433 //go:nosplit
434 func raceprocdestroy(ctx uintptr) {
435         racecall(&__tsan_proc_destroy, ctx, 0, 0, 0)
436 }
437
438 //go:nosplit
439 func racemapshadow(addr unsafe.Pointer, size uintptr) {
440         if racearenastart == 0 {
441                 racearenastart = uintptr(addr)
442         }
443         if racearenaend < uintptr(addr)+size {
444                 racearenaend = uintptr(addr) + size
445         }
446         racecall(&__tsan_map_shadow, uintptr(addr), size, 0, 0)
447 }
448
449 //go:nosplit
450 func racemalloc(p unsafe.Pointer, sz uintptr) {
451         racecall(&__tsan_malloc, 0, 0, uintptr(p), sz)
452 }
453
454 //go:nosplit
455 func racefree(p unsafe.Pointer, sz uintptr) {
456         racecall(&__tsan_free, uintptr(p), sz, 0, 0)
457 }
458
459 //go:nosplit
460 func racegostart(pc uintptr) uintptr {
461         gp := getg()
462         var spawng *g
463         if gp.m.curg != nil {
464                 spawng = gp.m.curg
465         } else {
466                 spawng = gp
467         }
468
469         var racectx uintptr
470         racecall(&__tsan_go_start, spawng.racectx, uintptr(unsafe.Pointer(&racectx)), pc, 0)
471         return racectx
472 }
473
474 //go:nosplit
475 func racegoend() {
476         racecall(&__tsan_go_end, getg().racectx, 0, 0, 0)
477 }
478
479 //go:nosplit
480 func racectxend(racectx uintptr) {
481         racecall(&__tsan_go_end, racectx, 0, 0, 0)
482 }
483
484 //go:nosplit
485 func racewriterangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
486         gp := getg()
487         if gp != gp.m.curg {
488                 // The call is coming from manual instrumentation of Go code running on g0/gsignal.
489                 // Not interesting.
490                 return
491         }
492         if callpc != 0 {
493                 racefuncenter(callpc)
494         }
495         racewriterangepc1(uintptr(addr), sz, pc)
496         if callpc != 0 {
497                 racefuncexit()
498         }
499 }
500
501 //go:nosplit
502 func racereadrangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
503         gp := getg()
504         if gp != gp.m.curg {
505                 // The call is coming from manual instrumentation of Go code running on g0/gsignal.
506                 // Not interesting.
507                 return
508         }
509         if callpc != 0 {
510                 racefuncenter(callpc)
511         }
512         racereadrangepc1(uintptr(addr), sz, pc)
513         if callpc != 0 {
514                 racefuncexit()
515         }
516 }
517
518 //go:nosplit
519 func raceacquire(addr unsafe.Pointer) {
520         raceacquireg(getg(), addr)
521 }
522
523 //go:nosplit
524 func raceacquireg(gp *g, addr unsafe.Pointer) {
525         if getg().raceignore != 0 || !isvalidaddr(addr) {
526                 return
527         }
528         racecall(&__tsan_acquire, gp.racectx, uintptr(addr), 0, 0)
529 }
530
531 //go:nosplit
532 func raceacquirectx(racectx uintptr, addr unsafe.Pointer) {
533         if !isvalidaddr(addr) {
534                 return
535         }
536         racecall(&__tsan_acquire, racectx, uintptr(addr), 0, 0)
537 }
538
539 //go:nosplit
540 func racerelease(addr unsafe.Pointer) {
541         racereleaseg(getg(), addr)
542 }
543
544 //go:nosplit
545 func racereleaseg(gp *g, addr unsafe.Pointer) {
546         if getg().raceignore != 0 || !isvalidaddr(addr) {
547                 return
548         }
549         racecall(&__tsan_release, gp.racectx, uintptr(addr), 0, 0)
550 }
551
552 //go:nosplit
553 func racereleaseacquire(addr unsafe.Pointer) {
554         racereleaseacquireg(getg(), addr)
555 }
556
557 //go:nosplit
558 func racereleaseacquireg(gp *g, addr unsafe.Pointer) {
559         if getg().raceignore != 0 || !isvalidaddr(addr) {
560                 return
561         }
562         racecall(&__tsan_release_acquire, gp.racectx, uintptr(addr), 0, 0)
563 }
564
565 //go:nosplit
566 func racereleasemerge(addr unsafe.Pointer) {
567         racereleasemergeg(getg(), addr)
568 }
569
570 //go:nosplit
571 func racereleasemergeg(gp *g, addr unsafe.Pointer) {
572         if getg().raceignore != 0 || !isvalidaddr(addr) {
573                 return
574         }
575         racecall(&__tsan_release_merge, gp.racectx, uintptr(addr), 0, 0)
576 }
577
578 //go:nosplit
579 func racefingo() {
580         racecall(&__tsan_finalizer_goroutine, getg().racectx, 0, 0, 0)
581 }
582
583 // The declarations below generate ABI wrappers for functions
584 // implemented in assembly in this package but declared in another
585 // package.
586
587 //go:linkname abigen_sync_atomic_LoadInt32 sync/atomic.LoadInt32
588 func abigen_sync_atomic_LoadInt32(addr *int32) (val int32)
589
590 //go:linkname abigen_sync_atomic_LoadInt64 sync/atomic.LoadInt64
591 func abigen_sync_atomic_LoadInt64(addr *int64) (val int64)
592
593 //go:linkname abigen_sync_atomic_LoadUint32 sync/atomic.LoadUint32
594 func abigen_sync_atomic_LoadUint32(addr *uint32) (val uint32)
595
596 //go:linkname abigen_sync_atomic_LoadUint64 sync/atomic.LoadUint64
597 func abigen_sync_atomic_LoadUint64(addr *uint64) (val uint64)
598
599 //go:linkname abigen_sync_atomic_LoadUintptr sync/atomic.LoadUintptr
600 func abigen_sync_atomic_LoadUintptr(addr *uintptr) (val uintptr)
601
602 //go:linkname abigen_sync_atomic_LoadPointer sync/atomic.LoadPointer
603 func abigen_sync_atomic_LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
604
605 //go:linkname abigen_sync_atomic_StoreInt32 sync/atomic.StoreInt32
606 func abigen_sync_atomic_StoreInt32(addr *int32, val int32)
607
608 //go:linkname abigen_sync_atomic_StoreInt64 sync/atomic.StoreInt64
609 func abigen_sync_atomic_StoreInt64(addr *int64, val int64)
610
611 //go:linkname abigen_sync_atomic_StoreUint32 sync/atomic.StoreUint32
612 func abigen_sync_atomic_StoreUint32(addr *uint32, val uint32)
613
614 //go:linkname abigen_sync_atomic_StoreUint64 sync/atomic.StoreUint64
615 func abigen_sync_atomic_StoreUint64(addr *uint64, val uint64)
616
617 //go:linkname abigen_sync_atomic_SwapInt32 sync/atomic.SwapInt32
618 func abigen_sync_atomic_SwapInt32(addr *int32, new int32) (old int32)
619
620 //go:linkname abigen_sync_atomic_SwapInt64 sync/atomic.SwapInt64
621 func abigen_sync_atomic_SwapInt64(addr *int64, new int64) (old int64)
622
623 //go:linkname abigen_sync_atomic_SwapUint32 sync/atomic.SwapUint32
624 func abigen_sync_atomic_SwapUint32(addr *uint32, new uint32) (old uint32)
625
626 //go:linkname abigen_sync_atomic_SwapUint64 sync/atomic.SwapUint64
627 func abigen_sync_atomic_SwapUint64(addr *uint64, new uint64) (old uint64)
628
629 //go:linkname abigen_sync_atomic_AddInt32 sync/atomic.AddInt32
630 func abigen_sync_atomic_AddInt32(addr *int32, delta int32) (new int32)
631
632 //go:linkname abigen_sync_atomic_AddUint32 sync/atomic.AddUint32
633 func abigen_sync_atomic_AddUint32(addr *uint32, delta uint32) (new uint32)
634
635 //go:linkname abigen_sync_atomic_AddInt64 sync/atomic.AddInt64
636 func abigen_sync_atomic_AddInt64(addr *int64, delta int64) (new int64)
637
638 //go:linkname abigen_sync_atomic_AddUint64 sync/atomic.AddUint64
639 func abigen_sync_atomic_AddUint64(addr *uint64, delta uint64) (new uint64)
640
641 //go:linkname abigen_sync_atomic_AddUintptr sync/atomic.AddUintptr
642 func abigen_sync_atomic_AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
643
644 //go:linkname abigen_sync_atomic_CompareAndSwapInt32 sync/atomic.CompareAndSwapInt32
645 func abigen_sync_atomic_CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
646
647 //go:linkname abigen_sync_atomic_CompareAndSwapInt64 sync/atomic.CompareAndSwapInt64
648 func abigen_sync_atomic_CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
649
650 //go:linkname abigen_sync_atomic_CompareAndSwapUint32 sync/atomic.CompareAndSwapUint32
651 func abigen_sync_atomic_CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
652
653 //go:linkname abigen_sync_atomic_CompareAndSwapUint64 sync/atomic.CompareAndSwapUint64
654 func abigen_sync_atomic_CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)