atomic.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005, 2007, 2008  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id: atomic.h,v 1.6 2008/01/24 23:47:00 tbox Exp $ */
00018 
00019 #ifndef ISC_ATOMIC_H
00020 #define ISC_ATOMIC_H 1
00021 
00022 #include <isc/platform.h>
00023 #include <isc/types.h>
00024 
00025 #ifdef ISC_PLATFORM_USEGCCASM
00026 
00027 /* We share the gcc-version with x86_32 */
00028 #error "impossible case.  check build configuration"
00029 
00030 #elif defined(ISC_PLATFORM_USESTDASM)
00031 /*
00032  * The followings are "generic" assembly code which implements the same
00033  * functionality in case the gcc extension cannot be used.  It should be
00034  * better to avoid inlining below, since we directly refer to specific
00035  * registers for arguments, which would not actually correspond to the
00036  * intended address or value in the embedded mnemonic.
00037  */
00038 #include <isc/util.h>           /* for 'UNUSED' macro */
00039 
00040 static isc_int32_t
00041 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
00042         UNUSED(p);
00043         UNUSED(val);
00044 
00045         __asm (
00046                 "movq %rdi, %rdx\n"
00047                 "movl %esi, %eax\n"
00048 #ifdef ISC_PLATFORM_USETHREADS
00049                 "lock;"
00050 #endif
00051                 "xadd %eax, (%rdx)\n"
00052                 /*
00053                  * XXX: assume %eax will be used as the return value.
00054                  */
00055                 );
00056 }
00057 
00058 #ifdef ISC_PLATFORM_HAVEXADDQ
00059 static isc_int64_t
00060 isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
00061         UNUSED(p);
00062         UNUSED(val);
00063 
00064         __asm (
00065                 "movq %rdi, %rdx\n"
00066                 "movq %rsi, %rax\n"
00067 #ifdef ISC_PLATFORM_USETHREADS
00068                 "lock;"
00069 #endif
00070                 "xaddq %rax, (%rdx)\n"
00071                 /*
00072                  * XXX: assume %rax will be used as the return value.
00073                  */
00074                 );
00075 }
00076 #endif
00077 
00078 static void
00079 isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
00080         UNUSED(p);
00081         UNUSED(val);
00082 
00083         __asm (
00084                 "movq %rdi, %rax\n"
00085                 "movl %esi, %edx\n"
00086 #ifdef ISC_PLATFORM_USETHREADS
00087                 "lock;"
00088 #endif
00089                 "xchgl (%rax), %edx\n"
00090                 /*
00091                  * XXX: assume %rax will be used as the return value.
00092                  */
00093                 );
00094 }
00095 
00096 static isc_int32_t
00097 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
00098         UNUSED(p);
00099         UNUSED(cmpval);
00100         UNUSED(val);
00101 
00102         __asm (
00103                 "movl %edx, %ecx\n"
00104                 "movl %esi, %eax\n"
00105                 "movq %rdi, %rdx\n"
00106 
00107 #ifdef ISC_PLATFORM_USETHREADS
00108                 "lock;"
00109 #endif
00110                 /*
00111                  * If (%rdi) == %eax then (%rdi) := %edx.
00112                  * %eax is set to old (%ecx), which will be the return value.
00113                  */
00114                 "cmpxchgl %ecx, (%rdx)"
00115                 );
00116 }
00117 
00118 #else /* !ISC_PLATFORM_USEGCCASM && !ISC_PLATFORM_USESTDASM */
00119 
00120 #error "unsupported compiler.  disable atomic ops by --disable-atomic"
00121 
00122 #endif
00123 #endif /* ISC_ATOMIC_H */

Generated on Tue Apr 28 17:41:03 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha