snRuntime/src/sync.h
Functions
Name | |
---|---|
volatile uint32_t * | snrt_mutex() |
void | snrt_mutex_acquire(volatile uint32_t * pmtx) lock a mutex, blocking |
void | snrt_mutex_ttas_acquire(volatile uint32_t * pmtx) lock a mutex, blocking |
void | snrt_mutex_release(volatile uint32_t * pmtx) Release the mutex. |
void | snrt_cluster_hw_barrier() Synchronize cores in a cluster with a hardware barrier. |
void | snrt_global_barrier() Synchronize clusters globally with a global software barrier. |
void | snrt_partial_barrier(snrt_barrier_t * barr, uint32_t n) Generic barrier. |
Functions Documentation
function snrt_mutex
inline volatile uint32_t * snrt_mutex()
function snrt_mutex_acquire
inline void snrt_mutex_acquire(
volatile uint32_t * pmtx
)
lock a mutex, blocking
declare mutex with static volatile uint32_t mtx = 0;
function snrt_mutex_ttas_acquire
inline void snrt_mutex_ttas_acquire(
volatile uint32_t * pmtx
)
lock a mutex, blocking
test and test-and-set (ttas) implementation of a lock. Declare mutex with static volatile uint32_t mtx = 0;
function snrt_mutex_release
inline void snrt_mutex_release(
volatile uint32_t * pmtx
)
Release the mutex.
function snrt_cluster_hw_barrier
inline void snrt_cluster_hw_barrier()
Synchronize cores in a cluster with a hardware barrier.
function snrt_global_barrier
inline void snrt_global_barrier()
Synchronize clusters globally with a global software barrier.
function snrt_partial_barrier
inline void snrt_partial_barrier(
snrt_barrier_t * barr,
uint32_t n
)
Generic barrier.
Parameters:
- barr pointer to a barrier
- n number of harts that have to enter before released
Source code
// Copyright 2023 ETH Zurich and University of Bologna.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//================================================================================
// Mutex functions
//================================================================================
inline volatile uint32_t *snrt_mutex() { return &_snrt_mutex; }
inline void snrt_mutex_acquire(volatile uint32_t *pmtx) {
asm volatile(
"li t0,1 # t0 = 1\n"
"1:\n"
" amoswap.w.aq t0,t0,(%0) # t0 = oldlock & lock = 1\n"
" bnez t0,1b # Retry if previously set)\n"
: "+r"(pmtx)
:
: "t0");
}
inline void snrt_mutex_ttas_acquire(volatile uint32_t *pmtx) {
asm volatile(
"1:\n"
" lw t0, 0(%0)\n"
" bnez t0, 1b\n"
" li t0,1 # t0 = 1\n"
"2:\n"
" amoswap.w.aq t0,t0,(%0) # t0 = oldlock & lock = 1\n"
" bnez t0,2b # Retry if previously set)\n"
: "+r"(pmtx)
:
: "t0");
}
inline void snrt_mutex_release(volatile uint32_t *pmtx) {
asm volatile("amoswap.w.rl x0,x0,(%0) # Release lock by storing 0\n"
: "+r"(pmtx));
}
//================================================================================
// Barrier functions
//================================================================================
inline void snrt_cluster_hw_barrier() {
uint32_t register r;
asm volatile("lw %0, 0(%1)"
: "=r"(r)
: "r"((uint32_t)snrt_cluster_hw_barrier_addr())
: "memory");
}
inline void snrt_global_barrier() {
// Synchronize all DM cores in software
if (snrt_is_dm_core()) {
// Remember previous iteration
uint32_t prev_barrier_iteration = _snrt_barrier.iteration;
uint32_t cnt =
__atomic_add_fetch(&(_snrt_barrier.cnt), 1, __ATOMIC_RELAXED);
// Increment the barrier counter
if (cnt == snrt_cluster_num()) {
_snrt_barrier.cnt = 0;
__atomic_add_fetch(&(_snrt_barrier.iteration), 1, __ATOMIC_RELAXED);
} else {
while (prev_barrier_iteration == _snrt_barrier.iteration)
;
}
}
// Synchronize cores in a cluster with the HW barrier
snrt_cluster_hw_barrier();
}
inline void snrt_partial_barrier(snrt_barrier_t *barr, uint32_t n) {
// Remember previous iteration
uint32_t prev_it = barr->iteration;
uint32_t cnt = __atomic_add_fetch(&barr->cnt, 1, __ATOMIC_RELAXED);
// Increment the barrier counter
if (cnt == n) {
barr->cnt = 0;
__atomic_add_fetch(&barr->iteration, 1, __ATOMIC_RELAXED);
} else {
// Some threads have not reached the barrier --> Let's wait
while (prev_it == barr->iteration)
;
}
}
Updated on 2023-06-19 at 09:43:56 +0000