1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr_arch_atomic.h" 18 19#ifdef USE_ATOMICS_IA32 20 21APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p) 22{ 23 return APR_SUCCESS; 24} 25 26APR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem) 27{ 28 return *mem; 29} 30 31APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val) 32{ 33 *mem = val; 34} 35 36APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val) 37{ 38 asm volatile ("lock; xaddl %0,%1" 39 : "=r" (val), "=m" (*mem) 40 : "0" (val), "m" (*mem) 41 : "memory", "cc"); 42 return val; 43} 44 45APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val) 46{ 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