1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPC_IMPL_CODEGEN_ATM_H 20 #define GRPC_IMPL_CODEGEN_ATM_H 21 22 /** This interface provides atomic operations and barriers. 23 It is internal to gpr support code and should not be used outside it. 24 25 If an operation with acquire semantics precedes another memory access by the 26 same thread, the operation will precede that other access as seen by other 27 threads. 28 29 If an operation with release semantics follows another memory access by the 30 same thread, the operation will follow that other access as seen by other 31 threads. 32 33 Routines with "acq" or "full" in the name have acquire semantics. Routines 34 with "rel" or "full" in the name have release semantics. Routines with 35 "no_barrier" in the name have neither acquire not release semantics. 36 37 The routines may be implemented as macros. 38 39 // Atomic operations act on an intergral_type gpr_atm that is guaranteed to 40 // be the same size as a pointer. 41 typedef intptr_t gpr_atm; 42 43 // A memory barrier, providing both acquire and release semantics, but not 44 // otherwise acting on memory. 45 void gpr_atm_full_barrier(void); 46 47 // Atomically return *p, with acquire semantics. 48 gpr_atm gpr_atm_acq_load(gpr_atm *p); 49 gpr_atm gpr_atm_no_barrier_load(gpr_atm *p); 50 51 // Atomically set *p = value, with release semantics. 52 void gpr_atm_rel_store(gpr_atm *p, gpr_atm value); 53 54 // Atomically add delta to *p, and return the old value of *p, with 55 // the barriers specified. 56 gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p, gpr_atm delta); 57 gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta); 58 59 // Atomically, if *p==o, set *p=n and return non-zero otherwise return 0, 60 // with the barriers specified if the operation succeeds. 61 int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n); 62 int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n); 63 int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n); 64 int gpr_atm_full_cas(gpr_atm *p, gpr_atm o, gpr_atm n); 65 66 // Atomically, set *p=n and return the old value of *p 67 gpr_atm gpr_atm_full_xchg(gpr_atm *p, gpr_atm n); 68 */ 69 70 #include <grpc/impl/codegen/port_platform.h> 71 72 #if defined(GPR_GCC_ATOMIC) 73 #include <grpc/impl/codegen/atm_gcc_atomic.h> 74 #elif defined(GPR_GCC_SYNC) 75 #include <grpc/impl/codegen/atm_gcc_sync.h> 76 #elif defined(GPR_WINDOWS_ATOMIC) 77 #include <grpc/impl/codegen/atm_windows.h> 78 #else 79 #error could not determine platform for atm 80 #endif 81 82 #ifdef __cplusplus 83 extern "C" { 84 #endif 85 86 /** Adds \a delta to \a *value, clamping the result to the range specified 87 by \a min and \a max. Returns the new value. */ 88 gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm* value, gpr_atm delta, 89 gpr_atm min, gpr_atm max); 90 91 #ifdef __cplusplus 92 } 93 #endif 94 95 #endif /* GRPC_IMPL_CODEGEN_ATM_H */ 96