init
This commit is contained in:
82
lib_locks/lib_locks/api/hwlock.h
Normal file
82
lib_locks/lib_locks/api/hwlock.h
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2014-2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
#ifndef __hwlock_h_
|
||||
#define __hwlock_h_
|
||||
|
||||
#include <xs1.h>
|
||||
|
||||
#define QUOTEAUX(x) #x
|
||||
#define QUOTE(x) QUOTEAUX(x)
|
||||
|
||||
/** This type represents a hardware lock. */
|
||||
typedef unsigned hwlock_t;
|
||||
|
||||
enum {
|
||||
HWLOCK_NOT_ALLOCATED = 0
|
||||
};
|
||||
|
||||
/** Allocate a hardware lock.
|
||||
*
|
||||
* This function will allocate a new hardware lock from the pool of hardware
|
||||
* locks available on the xCORE. The hardware has a limited number of hardware
|
||||
* locks (for example, current L and S series devices have 4 locks per tile).
|
||||
*
|
||||
* \returns the allocated lock if allocation is successful or the value
|
||||
* ``HWLOCK_NOT_ALLOCATED`` if not.
|
||||
*/
|
||||
inline hwlock_t hwlock_alloc(void)
|
||||
{
|
||||
hwlock_t lock;
|
||||
asm volatile ("getr %0, " QUOTE(XS1_RES_TYPE_LOCK)
|
||||
: "=r" (lock));
|
||||
return lock;
|
||||
}
|
||||
|
||||
/** Free a hardware lock.
|
||||
*
|
||||
* This function frees a given hardware lock and returns it to the
|
||||
* hardware pool to be reallocated elsewhere.
|
||||
*
|
||||
* \param lock the hardware lock to be freed. If this is an invalid lock id or
|
||||
* not an currently allocated lock then the function will trap.
|
||||
*/
|
||||
inline void hwlock_free(hwlock_t lock)
|
||||
{
|
||||
asm volatile ("freer res[%0]"
|
||||
: /* no output */
|
||||
: "r" (lock));
|
||||
}
|
||||
|
||||
/** Acquire a hardware lock.
|
||||
*
|
||||
* This function acquires a lock for the current logical core. If
|
||||
* another core holds the lock the function will pause until the
|
||||
* lock is released.
|
||||
*
|
||||
* \param lock the hardware lock to acquire
|
||||
*/
|
||||
inline void hwlock_acquire(hwlock_t lock)
|
||||
{
|
||||
asm volatile ("in %0, res[%0]"
|
||||
: /* no output */
|
||||
: "r" (lock)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/** Release a hardware lock.
|
||||
*
|
||||
* This function releases a lock from the current logical core. The lock should
|
||||
* have been previously claimed by hwlock_acquire().
|
||||
*
|
||||
* \param lock the hardware lock to release
|
||||
*/
|
||||
inline void hwlock_release(hwlock_t lock)
|
||||
{
|
||||
asm volatile ("out res[%0], %0"
|
||||
: /* no output */
|
||||
: "r" (lock)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif // __hwlock_h_
|
||||
67
lib_locks/lib_locks/api/swlock.h
Normal file
67
lib_locks/lib_locks/api/swlock.h
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2014-2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
#ifndef __swlock_h_
|
||||
#define __swlock_h_
|
||||
#include <xccompat.h>
|
||||
|
||||
/** Type that represents a software lock */
|
||||
typedef unsigned swlock_t;
|
||||
|
||||
/** This define should be used to initialize a software lock e.g.
|
||||
|
||||
\code
|
||||
swlock_t my_lock = SWLOCK_INITIAL_VALUE;
|
||||
\endcode
|
||||
|
||||
If you intialize this way there is no need to call swlock_init().
|
||||
*/
|
||||
#define SWLOCK_INITIAL_VALUE 0
|
||||
|
||||
enum {
|
||||
SWLOCK_NOT_ACQUIRED = 0
|
||||
};
|
||||
|
||||
/** Initialize a software lock.
|
||||
*
|
||||
* This function will initialize a software lock for use. Note that unlike
|
||||
* hardware locks, there is no need to allocate or free a software lock from a
|
||||
* limited pool.
|
||||
*/
|
||||
void swlock_init(REFERENCE_PARAM(swlock_t, lock));
|
||||
|
||||
/** Try and acquire a software lock.
|
||||
*
|
||||
* This function tries to acquire a lock for the current logical core.
|
||||
* If another core holds the lock then the function will fail and return.
|
||||
*
|
||||
* \param lock the software lock to acquire.
|
||||
*
|
||||
* \returns a value that is equal to ``SWLOCK_NOT_ACQUIRED`` if
|
||||
* the attempt fails. Any other value indicates that the
|
||||
* acquisition has succeeded.
|
||||
*/
|
||||
int swlock_try_acquire(REFERENCE_PARAM(swlock_t, lock));
|
||||
|
||||
/** Acquire a software lock.
|
||||
*
|
||||
* This function acquires a lock for the current logical core.
|
||||
* If another core holds the lock then the function will wait until
|
||||
* it becomes available.
|
||||
*
|
||||
* \param lock the software lock to acquire.
|
||||
*
|
||||
*/
|
||||
void swlock_acquire(REFERENCE_PARAM(swlock_t, lock));
|
||||
|
||||
/** Release a software lock.
|
||||
*
|
||||
* This function releases a previously acquired software lock for other cores
|
||||
* to use.
|
||||
*
|
||||
* \param lock the software lock to release.
|
||||
*
|
||||
*/
|
||||
void swlock_release(REFERENCE_PARAM(swlock_t, lock));
|
||||
|
||||
#endif // __swlock_h_
|
||||
6
lib_locks/lib_locks/lib_build_info.cmake
Normal file
6
lib_locks/lib_locks/lib_build_info.cmake
Normal file
@@ -0,0 +1,6 @@
|
||||
set(LIB_NAME lib_locks)
|
||||
set(LIB_VERSION 2.3.1)
|
||||
set(LIB_INCLUDES api)
|
||||
set(LIB_DEPENDENT_MODULES "")
|
||||
|
||||
XMOS_REGISTER_MODULE()
|
||||
12
lib_locks/lib_locks/module_build_info
Normal file
12
lib_locks/lib_locks/module_build_info
Normal file
@@ -0,0 +1,12 @@
|
||||
# You can set flags specifically for your module by using the MODULE_XCC_FLAGS
|
||||
# variable. So the following
|
||||
#
|
||||
# MODULE_XCC_FLAGS = $(XCC_FLAGS) -O3
|
||||
#
|
||||
# specifies that everything in the modules should have the application
|
||||
# build flags with -O3 appended (so the files will build at
|
||||
# optimization level -O3).
|
||||
#
|
||||
# You can also set MODULE_XCC_C_FLAGS, MODULE_XCC_XC_FLAGS etc..
|
||||
|
||||
VERSION = 2.3.1
|
||||
8
lib_locks/lib_locks/src/hwlock.c
Normal file
8
lib_locks/lib_locks/src/hwlock.c
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright 2014-2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include "hwlock.h"
|
||||
|
||||
extern inline hwlock_t hwlock_alloc(void);
|
||||
extern inline void hwlock_free(hwlock_t lock);
|
||||
extern inline void hwlock_acquire(hwlock_t lock);
|
||||
extern inline void hwlock_release(hwlock_t lock);
|
||||
28
lib_locks/lib_locks/src/swlock.c
Normal file
28
lib_locks/lib_locks/src/swlock.c
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2014-2024 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
#include "swlock.h"
|
||||
|
||||
void swlock_init(swlock_t *_lock)
|
||||
{
|
||||
volatile swlock_t *lock = _lock;
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
extern int swlock_try_acquire(swlock_t *lock);
|
||||
|
||||
void swlock_acquire(swlock_t *lock)
|
||||
{
|
||||
int value;
|
||||
do {
|
||||
value = swlock_try_acquire(lock);
|
||||
}
|
||||
while (value == SWLOCK_NOT_ACQUIRED);
|
||||
}
|
||||
|
||||
void swlock_release(swlock_t *lock)
|
||||
{
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
|
||||
44
lib_locks/lib_locks/src/swlock_asm.S
Normal file
44
lib_locks/lib_locks/src/swlock_asm.S
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2014-2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
.file "swlock_asm.S"
|
||||
.text
|
||||
.cc_top swlock_try_acquire.function
|
||||
.align 4
|
||||
.globl swlock_try_acquire
|
||||
.globl swlock_try_acquire.nstackwords
|
||||
.globl swlock_try_acquire.maxthreads
|
||||
.globl swlock_try_acquire.maxtimers
|
||||
.globl swlock_try_acquire.maxchanends
|
||||
.type swlock_try_acquire, @function
|
||||
.set swlock_try_acquire.locnochandec, 1
|
||||
.set swlock_try_acquire.nstackwords, 0
|
||||
swlock_try_acquire:
|
||||
ENTSP_lu6 0
|
||||
get r11, id
|
||||
add r11, r11, 1
|
||||
ldw r1, r0[0] // Get the current mutex value.
|
||||
bt r1, .Lfailed // Check if it is already claimed.
|
||||
stw r11, r0[0] // Claim it.
|
||||
#if !defined(__XS1B__)
|
||||
// On XS2 a high priority core needs to ensure that a low priority core
|
||||
// has executed the store before we load
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
#endif
|
||||
nop
|
||||
ldw r2, r0[0] // Reload the mutex.
|
||||
eq r0, r11, r2 // If the value hasn't changed we've claimed the
|
||||
retsp 0 // mutex.
|
||||
.Lfailed:
|
||||
ldc r0, 0
|
||||
retsp 0
|
||||
.size swlock_try_acquire, .-swlock_try_acquire
|
||||
.cc_bottom swlock_try_acquire.function
|
||||
.set swlock_try_acquire.maxchanends, 0
|
||||
.set swlock_try_acquire.maxtimers, 0
|
||||
.set swlock_try_acquire.maxthreads, 1
|
||||
3
lib_locks/lib_locks/wscript
Normal file
3
lib_locks/lib_locks/wscript
Normal file
@@ -0,0 +1,3 @@
|
||||
def use_module(bld):
|
||||
source = bld.path.ant_glob('src/*')
|
||||
bld.module(source=source, includes=['api'], version='2.0.3')
|
||||
Reference in New Issue
Block a user