ia32.c revision 253734
1169689Skan/* Licensed to the Apache Software Foundation (ASF) under one or more 2169689Skan * contributor license agreements. See the NOTICE file distributed with 3169689Skan * this work for additional information regarding copyright ownership. 4169689Skan * The ASF licenses this file to You under the Apache License, Version 2.0 5169689Skan * (the "License"); you may not use this file except in compliance with 6169689Skan * the License. You may obtain a copy of the License at 7169689Skan * 8169689Skan * http://www.apache.org/licenses/LICENSE-2.0 9169689Skan * 10169689Skan * Unless required by applicable law or agreed to in writing, software 11169689Skan * distributed under the License is distributed on an "AS IS" BASIS, 12169689Skan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13169689Skan * See the License for the specific language governing permissions and 14169689Skan * limitations under the License. 15169689Skan */ 16169689Skan 17169689Skan#include "apr_arch_atomic.h" 18169689Skan 19169689Skan#ifdef USE_ATOMICS_IA32 20169689Skan 21169689SkanAPR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p) 22169689Skan{ 23169689Skan return APR_SUCCESS; 24169689Skan} 25169689Skan 26169689SkanAPR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem) 27169689Skan{ 28169689Skan return *mem; 29169689Skan} 30169689Skan 3118334SpeterAPR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val) 3218334Speter{ 3318334Speter *mem = val; 3418334Speter} 3518334Speter 3618334SpeterAPR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val) 3718334Speter{ 3818334Speter asm volatile ("lock; xaddl %0,%1" 3918334Speter : "=r" (val), "=m" (*mem) 4018334Speter : "0" (val), "m" (*mem) 4118334Speter : "memory", "cc"); 42169689Skan return val; 4318334Speter} 4418334Speter 45169689SkanAPR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val) 46169689Skan{ 47 asm volatile ("lock; subl %1, %0" 48 : /* no output */ 49 : "m" (*(mem)), "r" (val) 50 : "memory", "cc"); 51} 52 53APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem) 54{ 55 return apr_atomic_add32(mem, 1); 56} 57 58APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem) 59{ 60 unsigned char prev; 61 62 asm volatile ("lock; decl %0; setnz %1" 63 : "=m" (*mem), "=qm" (prev) 64 : "m" (*mem) 65 : "memory"); 66 67 return prev; 68} 69 70APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with, 71 apr_uint32_t cmp) 72{ 73 apr_uint32_t prev; 74 75 asm volatile ("lock; cmpxchgl %1, %2" 76 : "=a" (prev) 77 : "r" (with), "m" (*(mem)), "0"(cmp) 78 : "memory", "cc"); 79 return prev; 80} 81 82APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val) 83{ 84 apr_uint32_t prev = val; 85 86 asm volatile ("xchgl %0, %1" 87 : "=r" (prev), "+m" (*mem) 88 : "0" (prev)); 89 return prev; 90} 91 92APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp) 93{ 94 void *prev; 95#if APR_SIZEOF_VOIDP == 4 96 asm volatile ("lock; cmpxchgl %2, %1" 97 : "=a" (prev), "=m" (*mem) 98 : "r" (with), "m" (*mem), "0" (cmp)); 99#elif APR_SIZEOF_VOIDP == 8 100 asm volatile ("lock; cmpxchgq %q2, %1" 101 : "=a" (prev), "=m" (*mem) 102 : "r" ((unsigned long)with), "m" (*mem), 103 "0" ((unsigned long)cmp)); 104#else 105#error APR_SIZEOF_VOIDP value not supported 106#endif 107 return prev; 108} 109 110APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with) 111{ 112 void *prev; 113#if APR_SIZEOF_VOIDP == 4 114 asm volatile ("xchgl %2, %1" 115 : "=a" (prev), "+m" (*mem) 116 : "0" (with)); 117#elif APR_SIZEOF_VOIDP == 8 118 asm volatile ("xchgq %q2, %1" 119 : "=a" (prev), "+m" (*mem) 120 : "0" (with)); 121#else 122#error APR_SIZEOF_VOIDP value not supported 123#endif 124 return prev; 125} 126 127#endif /* USE_ATOMICS_IA32 */ 128