github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/runtime/atomic_arm.c (about)

     1  // Copyright 2009 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  #include "runtime.h"
     6  #include "arch_GOARCH.h"
     7  #include "../../cmd/ld/textflag.h"
     8  
     9  static struct {
    10  	Lock l;
    11  	byte pad[CacheLineSize-sizeof(Lock)];
    12  } locktab[57];
    13  
    14  #define LOCK(addr) (&locktab[((uintptr)(addr)>>3)%nelem(locktab)].l)
    15  
    16  // Atomic add and return new value.
    17  #pragma textflag NOSPLIT
    18  uint32
    19  runtime·xadd(uint32 volatile *val, int32 delta)
    20  {
    21  	uint32 oval, nval;
    22  
    23  	for(;;){
    24  		oval = *val;
    25  		nval = oval + delta;
    26  		if(runtime·cas(val, oval, nval))
    27  			return nval;
    28  	}
    29  }
    30  
    31  #pragma textflag NOSPLIT
    32  uint32
    33  runtime·xchg(uint32 volatile* addr, uint32 v)
    34  {
    35  	uint32 old;
    36  
    37  	for(;;) {
    38  		old = *addr;
    39  		if(runtime·cas(addr, old, v))
    40  			return old;
    41  	}
    42  }
    43  
    44  #pragma textflag NOSPLIT
    45  void
    46  runtime·procyield(uint32 cnt)
    47  {
    48  	uint32 volatile i;
    49  
    50  	for(i = 0; i < cnt; i++) {
    51  	}
    52  }
    53  
    54  #pragma textflag NOSPLIT
    55  uint32
    56  runtime·atomicload(uint32 volatile* addr)
    57  {
    58  	return runtime·xadd(addr, 0);
    59  }
    60  
    61  #pragma textflag NOSPLIT
    62  void*
    63  runtime·atomicloadp(void* volatile* addr)
    64  {
    65  	return (void*)runtime·xadd((uint32 volatile*)addr, 0);
    66  }
    67  
    68  #pragma textflag NOSPLIT
    69  void
    70  runtime·atomicstorep(void* volatile* addr, void* v)
    71  {
    72  	void *old;
    73  
    74  	for(;;) {
    75  		old = *addr;
    76  		if(runtime·casp(addr, old, v))
    77  			return;
    78  	}
    79  }
    80  
    81  #pragma textflag NOSPLIT
    82  void
    83  runtime·atomicstore(uint32 volatile* addr, uint32 v)
    84  {
    85  	uint32 old;
    86  	
    87  	for(;;) {
    88  		old = *addr;
    89  		if(runtime·cas(addr, old, v))
    90  			return;
    91  	}
    92  }
    93  
    94  #pragma textflag NOSPLIT
    95  bool
    96  runtime·cas64(uint64 volatile *addr, uint64 old, uint64 new)
    97  {
    98  	bool res;
    99  	
   100  	runtime·lock(LOCK(addr));
   101  	if(*addr == old) {
   102  		*addr = new;
   103  		res = true;
   104  	} else {
   105  		res = false;
   106  	}
   107  	runtime·unlock(LOCK(addr));
   108  	return res;
   109  }
   110  
   111  #pragma textflag NOSPLIT
   112  uint64
   113  runtime·xadd64(uint64 volatile *addr, int64 delta)
   114  {
   115  	uint64 res;
   116  	
   117  	runtime·lock(LOCK(addr));
   118  	res = *addr + delta;
   119  	*addr = res;
   120  	runtime·unlock(LOCK(addr));
   121  	return res;
   122  }
   123  
   124  #pragma textflag NOSPLIT
   125  uint64
   126  runtime·xchg64(uint64 volatile *addr, uint64 v)
   127  {
   128  	uint64 res;
   129  
   130  	runtime·lock(LOCK(addr));
   131  	res = *addr;
   132  	*addr = v;
   133  	runtime·unlock(LOCK(addr));
   134  	return res;
   135  }
   136  
   137  #pragma textflag NOSPLIT
   138  uint64
   139  runtime·atomicload64(uint64 volatile *addr)
   140  {
   141  	uint64 res;
   142  	
   143  	runtime·lock(LOCK(addr));
   144  	res = *addr;
   145  	runtime·unlock(LOCK(addr));
   146  	return res;
   147  }
   148  
   149  #pragma textflag NOSPLIT
   150  void
   151  runtime·atomicstore64(uint64 volatile *addr, uint64 v)
   152  {
   153  	runtime·lock(LOCK(addr));
   154  	*addr = v;
   155  	runtime·unlock(LOCK(addr));
   156  }