atomic.h revision 290001
1/* 2 * Copyright (C) 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17/* $Id: atomic.h,v 1.6 2008/01/24 23:47:00 tbox Exp $ */ 18 19#ifndef ISC_ATOMIC_H 20#define ISC_ATOMIC_H 1 21 22#include <isc/platform.h> 23#include <isc/types.h> 24 25#ifdef ISC_PLATFORM_USEGCCASM 26 27/* We share the gcc-version with x86_32 */ 28#error "impossible case. check build configuration" 29 30#elif defined(ISC_PLATFORM_USESTDASM) 31/* 32 * The followings are "generic" assembly code which implements the same 33 * functionality in case the gcc extension cannot be used. It should be 34 * better to avoid inlining below, since we directly refer to specific 35 * registers for arguments, which would not actually correspond to the 36 * intended address or value in the embedded mnemonic. 37 */ 38#include <isc/util.h> /* for 'UNUSED' macro */ 39 40static isc_int32_t 41isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { 42 UNUSED(p); 43 UNUSED(val); 44 45 __asm ( 46 "movq %rdi, %rdx\n" 47 "movl %esi, %eax\n" 48#ifdef ISC_PLATFORM_USETHREADS 49 "lock;" 50#endif 51 "xadd %eax, (%rdx)\n" 52 /* 53 * XXX: assume %eax will be used as the return value. 54 */ 55 ); 56} 57 58#ifdef ISC_PLATFORM_HAVEXADDQ 59static isc_int64_t 60isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) { 61 UNUSED(p); 62 UNUSED(val); 63 64 __asm ( 65 "movq %rdi, %rdx\n" 66 "movq %rsi, %rax\n" 67#ifdef ISC_PLATFORM_USETHREADS 68 "lock;" 69#endif 70 "xaddq %rax, (%rdx)\n" 71 /* 72 * XXX: assume %rax will be used as the return value. 73 */ 74 ); 75} 76#endif 77 78static void 79isc_atomic_store(isc_int32_t *p, isc_int32_t val) { 80 UNUSED(p); 81 UNUSED(val); 82 83 __asm ( 84 "movq %rdi, %rax\n" 85 "movl %esi, %edx\n" 86#ifdef ISC_PLATFORM_USETHREADS 87 "lock;" 88#endif 89 "xchgl (%rax), %edx\n" 90 /* 91 * XXX: assume %rax will be used as the return value. 92 */ 93 ); 94} 95 96static isc_int32_t 97isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { 98 UNUSED(p); 99 UNUSED(cmpval); 100 UNUSED(val); 101 102 __asm ( 103 "movl %edx, %ecx\n" 104 "movl %esi, %eax\n" 105 "movq %rdi, %rdx\n" 106 107#ifdef ISC_PLATFORM_USETHREADS 108 "lock;" 109#endif 110 /* 111 * If (%rdi) == %eax then (%rdi) := %edx. 112 * %eax is set to old (%ecx), which will be the return value. 113 */ 114 "cmpxchgl %ecx, (%rdx)" 115 ); 116} 117 118#else /* !ISC_PLATFORM_USEGCCASM && !ISC_PLATFORM_USESTDASM */ 119 120#error "unsupported compiler. disable atomic ops by --disable-atomic" 121 122#endif 123#endif /* ISC_ATOMIC_H */ 124