Commit 2fec96d6 authored by Ben Avison's avatar Ben Avison
Browse files

Initial import of SyncLib

Detail:
  SyncLib is a library containing architecture-independent synchronisation
  primitives. It supports uniprocessor and SMP systems, even though RISC OS
  itself does not (yet) support SMP - but it allows individual modules to
  start to be modified in preparation for any such future support. The
  library adjusts itself according to the architecture targeted by your
  chosen build, so in particular when used in ROM builds, only supported for
  the appropriate CPU(s) will be included.
Admin:
  SyncLib is used heavily by SDIODriver and SDFS - they have acted as a test
  bed for the library and also as a proof of concept for SMP-ready modules.
parents
hdr/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
c/** gitlab-language=c linguist-language=c linguist-detectable=true
h/** gitlab-language=c linguist-language=c linguist-detectable=true
Copyright (c) 2011-2012, Ben Avison
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of their
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Makefile for SyncLib
COMPONENT = SyncLib
HDRS = atomic barrier cpuevent mutex spin spinrw synclib
OBJS = atomic barrier cpuevent init mutex spin spinrw
include CLibrary
# Dynamic dependencies:
Dir <Obey$Dir>
amu all_libs THROWBACK=-throwback
Dir <Obey$Dir>
amu clean
stripdepnd
Dir <Obey$Dir>
amu export_hdrs
amu export_libs THROWBACK=-throwback
/* (0.01)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.01
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 29 May 2012
#define Module_MajorVersion "0.01"
#define Module_Version 1
#define Module_MinorVersion ""
#define Module_Date "29 May 2012"
#define Module_ApplicationDate "29-May-12"
#define Module_ComponentName "SyncLib"
#define Module_ComponentPath "bsd/RiscOS/Sources/Lib/SyncLib"
#define Module_FullVersion "0.01"
#define Module_HelpVersion "0.01 (29 May 2012)"
#define Module_LibraryVersionInfo "0:1"
/*
* Copyright (c) 2012, Ben Avison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \file mutex.c
* An implementation of a simple mutex. Does not disable interrupts while the
* mutex is held, so is suitable for mutexes that are held for an extended
* period, but is not appropriate if you need it to always be possible to lock
* the mutex from the background (e.g. in an interrupt handler).
*/
#include "swis.h"
#include "SyncLib/synclib.h"
bool mutex_try_lock(mutex_t *mutex)
{
if (atomic_update(MUTEX_LOCKED, (uint32_t *) mutex) == MUTEX_LOCKED)
return false;
barrier();
return true;
}
void mutex_lock(mutex_t *mutex)
{
while (atomic_update(MUTEX_LOCKED, (uint32_t *) mutex) == MUTEX_LOCKED)
cpuevent_wait();
barrier();
}
void mutex_sleep_lock(mutex_t *mutex)
{
while (atomic_update(MUTEX_LOCKED, (uint32_t *) mutex) == MUTEX_LOCKED)
_swix(OS_UpCall, _INR(0,1), 6, mutex);
barrier();
}
void mutex_unlock(mutex_t *mutex)
{
barrier();
*mutex = MUTEX_UNLOCKED;
barrier_sync();
cpuevent_send();
}
/*
* Copyright (c) 2012, Ben Avison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ATOMIC_H
#define ATOMIC_H
#include <stdint.h>
/** \file atomic.h
* An implementation of atomic memory accesses that uses ARM's favoured
* instructions, dependent upon the current CPU.
*/
/** Atomic read/write of a 32-bit value.
* Can be entered in any processor mode.
* \arg new_value Value to write.
* \arg address Memory location at which to perform the read/write.
* \return Value that was read.
*/
uint32_t atomic_update(uint32_t new_value, volatile uint32_t *address);
/** User-defined atomic operation on a 32-bit value.
* Can be entered in any processor mode unless you need to support
* architecture 5 or earlier, in which case must be entered in privileged mode.
* \arg callback Routine to change the value (may be called more than once).
* \arg argument Value to pass to callback as its second argument.
* \arg address Memory location at which to operate.
* \return Value that was at location before operation.
*/
uint32_t atomic_process(uint32_t (*callback)(uint32_t, uint32_t), uint32_t argument, volatile uint32_t *address);
#endif
/*
* Copyright (c) 2012, Ben Avison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BARRIER_H
#define BARRIER_H
/** \file barrier.h
* An implementation of CPU data barriers.
*/
/** Call this to enforce the order of memory accesses as viewed by other CPUs
* in the system. Can be entered in any processor mode.
*/
void barrier(void);
/** Call this to enforce the order of memory accesses as viewed by other CPUs
* in the system, but also synchronise non-data transfer instructions for the
* present CPU with respect to its memory accesses. Can be entered in any
* processor mode.
*/
void barrier_sync(void);
#endif
/*
* Copyright (c) 2012, Ben Avison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CPUEVENT_H
#define CPUEVENT_H
/** \file cpuevent.h
* An implementation of CPU synchronisation events.
*/
/** Wake up any other sleeping CPUs. Can be entered in any processor mode.
*/
void cpuevent_send(void);
/** Sleep the present CPU. Can be entered in any processor mode.
*/
void cpuevent_wait(void);
#endif
/*
* Copyright (c) 2012, Ben Avison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MUTEX_H
#define MUTEX_H
#include <stdbool.h>
#include <stdint.h>
/** \file mutex.h
* An implementation of a simple mutex. Does not disable interrupts while the
* mutex is held, so is suitable for mutexes that are held for an extended
* period, but is not appropriate if you need it to always be possible to lock
* the mutex from the background (e.g. in an interrupt handler).
*/
/** The data block used to hold the state of a mutex. */
typedef enum
{
MUTEX_LOCKED,
MUTEX_UNLOCKED
} mutex_t;
/** Attempt to lock a mutex.
* Can be entered in any processor mode.
* \arg mutex Pointer to mutex.
* \return Whether the lock succeeded.
*/
bool mutex_try_lock(mutex_t *mutex);
/** Lock a mutex, waiting (forever if necessary) for it to become available.
* Can be entered in any processor mode.
* \arg mutex Pointer to mutex.
*/
void mutex_lock(mutex_t *mutex);
/** Lock a mutex, waiting (forever if necessary) for it to become available, sleeping the current task if necessary.
* Can be entered in any processor mode.
* \arg mutex Pointer to mutex.
*/
void mutex_sleep_lock(mutex_t *mutex);
/** Unlock a mutex.
* Can be entered in any processor mode.
* \arg mutex Pointer to mutex.
*/
void mutex_unlock(mutex_t *mutex);
#endif
/*
* Copyright (c) 2011, Ben Avison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SPIN_H
#define SPIN_H
#include <stdint.h>
/** \file spin.h
* An implementation of a simple SVC-mode spin lock. Only one CPU can hold it
* at a time, and interrupts are disabled on the CPU that holds it, to avoid
* any re-entrancy concerns.
*/
/** The data block used to hold the state of a spinlock. */
typedef struct
{
uint32_t opaque[2];
} spinlock_t;
/** Use this to initialise any new spin locks you create. */
#define SPIN_INITIALISER { 1, 0 }
/** Disable IRQs and, if on a SMP system, wait (forever if necessary) for any
* other CPU using this lock to release it, and claim it ourselves.
* Must be entered in privileged mode.
* \arg lock Pointer to spinlock block.
*/
void spin_lock(spinlock_t *lock);
/** Release the lock and restore the IRQ disable state to how it was when the
* lock was claimed.
* Must be entered in privileged mode.
* \arg lock Pointer to spinlock block.
*/
void spin_unlock(spinlock_t *lock);
#endif
/*
* Copyright (c) 2012, Ben Avison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SPINRW_H
#define SPINRW_H
#include <stdbool.h>
#include <stdint.h>
/** \file spinrw.h
* An implementation of an SVC-mode read-write spin lock.
*
* The lock can be held only once for writing, but multiple times for reading.
* It can only be held for reading or writing, not both at the same time.
*
* While the lock is held for writing, interrupts are disabled on the CPU
* holding the lock, so it is always possible to claim a read lock from
* interrupt context.
*
* Interrupts are *not* disabled while one or more read locks are held. This
* allows read locks to be held for extended periods, but means that claiming a
* write lock from interrupt context can fail. For this reason, you may wish to
* design your software such that write locks are only ever claimed from the
* foreground.
*/
/** The data block used to hold the state of a spinlock. */
typedef struct
{
uint32_t opaque[4];
} spinrwlock_t;
/** Use this to initialise any new read-write spin locks you create. */
#define SPINRW_INITIALISER { 1, 0, 0, 1 }
/** Attempt to claim a write lock. Will fail if the lock is already held for
* either reading or writing. If it succeeds, IRQs are disabled.
* Must be entered in privileged mode.
* \arg lock Pointer to spinrwlock block.
* \return Whether the lock succeeded.
*/
bool spinrw_try_write_lock(spinrwlock_t *lock);
/** Wait (forever if necessary) until the lock is not held for reading or
* writing, then claim a write lock and disable IRQs.
* Must be entered in privileged mode.
* \arg lock Pointer to spinrwlock block.
*/
void spinrw_write_lock(spinrwlock_t *lock);
/** Wait (forever if necessary) until the lock is not held for reading or
* writing, sleeping the current task if necessary, then claim a write lock and
* disable IRQs.
* Must be entered in privileged mode.
* \arg lock Pointer to spinrwlock block.
*/
void spinrw_sleep_write_lock(spinrwlock_t *lock);
/** Release a write lock and restore the IRQ disable state to how it was when
* the write lock was claimed.
* Must be entered in privileged mode.
* \arg lock Pointer to spinrwlock block.
*/
void spinrw_write_unlock(spinrwlock_t *lock);
/** Wait (forever if necessary) for any other CPU that holds the lock for
* writing to release it, then increment the number of times the lock is held
* for reading.
* Must be entered in privileged mode.
* \arg lock Pointer to spinrwlock block.
*/
void spinrw_read_lock(spinrwlock_t *lock);
/** Decrement the number of times the lock is held for reading.
* Must be entered in privileged mode.
* \arg lock Pointer to spinrwlock block.
*/
void spinrw_read_unlock(spinrwlock_t *lock);
#endif
/*
* Copyright (c) 2012, Ben Avison
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SYNCLIB_H
#define SYNCLIB_H
/** \file synclib.h
* A library containing architecture-independent synchronisation primitives.
* Supports uniprocessor and SMP systems.
*/
#include "SyncLib/atomic.h"
#include "SyncLib/barrier.h"
#include "SyncLib/cpuevent.h"
#include "SyncLib/mutex.h"
#include "SyncLib/spin.h"
#include "SyncLib/spinrw.h"
/** Library initialisation routine.
* Call this before any of the other functions in this library.
* Must be entered in privileged mode.
*/
void synclib_init(void);
#endif
;
; Copyright (c) 2012, Ben Avison
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the copyright holder nor the names of their
; contributors may be used to endorse or promote products derived from
; this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
; Inline assembler version of the barrier routine
EXTERN barrier
EXTERN barrier_sync
MACRO
$label Barrier$cc
IF :LNOT: SupportARMv6
$label ; nothing
ELIF :LNOT: NoARMv7
$label
[ "$cc" <> "" :LAND: "$cc" <> "AL"
LCLS not
not SETS :REVERSE_CC: "$cc"
B$not %FT00
]
DMB ; can't be done conditionally
00
ELSE
$label Push "a4,ip,lr", $cc
BL$cc barrier ; preseves flags
Pull "a4,ip,lr", $cc
ENDIF
MEND
MACRO
$label BarrierSync$cc
IF :LNOT: SupportARMv6
$label ; nothing