1*a7720a99Skettenis /* $OpenBSD: _atomic_lock.c,v 1.2 2018/05/17 20:28:32 kettenis Exp $ */
27e321ac1Sguenther
37e321ac1Sguenther /*
47e321ac1Sguenther * Copyright (c) 2004 Dale Rahn. All rights reserved.
57e321ac1Sguenther *
67e321ac1Sguenther * Redistribution and use in source and binary forms, with or without
77e321ac1Sguenther * modification, are permitted provided that the following conditions
87e321ac1Sguenther * are met:
97e321ac1Sguenther * 1. Redistributions of source code must retain the above copyright
107e321ac1Sguenther * notice, this list of conditions and the following disclaimer.
117e321ac1Sguenther * 2. Redistributions in binary form must reproduce the above copyright
127e321ac1Sguenther * notice, this list of conditions and the following disclaimer in the
137e321ac1Sguenther * documentation and/or other materials provided with the distribution.
147e321ac1Sguenther *
157e321ac1Sguenther * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
167e321ac1Sguenther * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
177e321ac1Sguenther * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
187e321ac1Sguenther * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
197e321ac1Sguenther * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
207e321ac1Sguenther * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
217e321ac1Sguenther * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
227e321ac1Sguenther * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
237e321ac1Sguenther * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
247e321ac1Sguenther * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
257e321ac1Sguenther */
267e321ac1Sguenther
277e321ac1Sguenther /*
287e321ac1Sguenther * Atomic lock for arm
297e321ac1Sguenther */
307e321ac1Sguenther
317e321ac1Sguenther #include <sys/types.h>
327e321ac1Sguenther #include <machine/spinlock.h>
337e321ac1Sguenther
347e321ac1Sguenther int
_atomic_lock(volatile _atomic_lock_t * lock)357e321ac1Sguenther _atomic_lock(volatile _atomic_lock_t *lock)
367e321ac1Sguenther {
377e321ac1Sguenther _atomic_lock_t old = 0;
387e321ac1Sguenther uint32_t scratch = 0;
397e321ac1Sguenther
407e321ac1Sguenther __asm__("1: ldrex %0, [%1] \n"
417e321ac1Sguenther " strex %2, %3, [%1] \n"
427e321ac1Sguenther " cmp %2, #0 \n"
437e321ac1Sguenther " bne 1b \n"
447e321ac1Sguenther : "+r" (old), "+r" (lock), "+r" (scratch)
457e321ac1Sguenther : "r" (_ATOMIC_LOCK_LOCKED));
467e321ac1Sguenther
477e321ac1Sguenther return (old != _ATOMIC_LOCK_UNLOCKED);
487e321ac1Sguenther }
49