github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/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  
     8  static struct {
     9  	Lock l;
    10  	byte pad[CacheLineSize-sizeof(Lock)];
    11  } locktab[57];
    12  
    13  #define LOCK(addr) (&locktab[((uintptr)(addr)>>3)%nelem(locktab)].l)
    14  
    15  // Atomic add and return new value.
    16  #pragma textflag 7
    17  uint32
    18  runtime·xadd(uint32 volatile *val, int32 delta)
    19  {
    20  	uint32 oval, nval;
    21  
    22  	for(;;){
    23  		oval = *val;
    24  		nval = oval + delta;
    25  		if(runtime·cas(val, oval, nval))
    26  			return nval;
    27  	}
    28  }
    29  
    30  #pragma textflag 7
    31  uint32
    32  runtime·xchg(uint32 volatile* addr, uint32 v)
    33  {
    34  	uint32 old;
    35  
    36  	for(;;) {
    37  		old = *addr;
    38  		if(runtime·cas(addr, old, v))
    39  			return old;
    40  	}
    41  }
    42  
    43  #pragma textflag 7
    44  void
    45  runtime·procyield(uint32 cnt)
    46  {
    47  	uint32 volatile i;
    48  
    49  	for(i = 0; i < cnt; i++) {
    50  	}
    51  }
    52  
    53  #pragma textflag 7
    54  uint32
    55  runtime·atomicload(uint32 volatile* addr)
    56  {
    57  	return runtime·xadd(addr, 0);
    58  }
    59  
    60  #pragma textflag 7
    61  void*
    62  runtime·atomicloadp(void* volatile* addr)
    63  {
    64  	return (void*)runtime·xadd((uint32 volatile*)addr, 0);
    65  }
    66  
    67  #pragma textflag 7
    68  void
    69  runtime·atomicstorep(void* volatile* addr, void* v)
    70  {
    71  	void *old;
    72  
    73  	for(;;) {
    74  		old = *addr;
    75  		if(runtime·casp(addr, old, v))
    76  			return;
    77  	}
    78  }
    79  
    80  #pragma textflag 7
    81  void
    82  runtime·atomicstore(uint32 volatile* addr, uint32 v)
    83  {
    84  	uint32 old;
    85  	
    86  	for(;;) {
    87  		old = *addr;
    88  		if(runtime·cas(addr, old, v))
    89  			return;
    90  	}
    91  }
    92  
    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
   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 7
   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 7
   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 7
   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  }