diff --git a/arch/at91sam3x8e/CMakeLists.txt b/arch/at91sam3x8e/CMakeLists.txt index e41a8ab..83cf961 100644 --- a/arch/at91sam3x8e/CMakeLists.txt +++ b/arch/at91sam3x8e/CMakeLists.txt @@ -19,6 +19,7 @@ target_sources(ardix_arch PRIVATE interrupt.c irq_pend_sv.S irq_svc.S + mutex.S sched.c serial.c startup.c diff --git a/arch/at91sam3x8e/mutex.S b/arch/at91sam3x8e/mutex.S new file mode 100644 index 0000000..2c29a32 --- /dev/null +++ b/arch/at91sam3x8e/mutex.S @@ -0,0 +1,47 @@ +/* See the end of this file for copyright, license, and warranty information. */ + +.include "asm.S" + +.text + +/* int _mutex_lock(int *lock); */ +func_begin _mutex_lock + + mov r1, #1 + +1: ldrex r2, [r0] + cmp r2, #0 + itt eq + strexeq r2, r1, [r0] + cmpeq r2, #0 + + bne 1b + + dmb + eor r0, r0 + bx lr + +func_end _mutex_lock + +/* int _mutex_unlock(int *lock); */ +func_begin _mutex_unlock + + mov r1, #0 + str r1, [r0] + dmb + bx lr + +func_end _mutex_unlock + +/* + * This file is part of Ardix. + * Copyright (c) 2020, 2021 Felix Kopp <owo@fef.moe>. + * + * Ardix is non-violent software: you may only use, redistribute, + * and/or modify it under the terms of the CNPLv6+ as found in + * the LICENSE file in the source code root directory or at + * <https://git.pixie.town/thufie/CNPL>. + * + * Ardix comes with ABSOLUTELY NO WARRANTY, to the extent + * permitted by applicable law. See the CNPLv6+ for details. + */ diff --git a/include/ardix/mutex.h b/include/ardix/mutex.h new file mode 100644 index 0000000..eebdd7a --- /dev/null +++ b/include/ardix/mutex.h @@ -0,0 +1,48 @@ +/* See the end of this file for copyright, license, and warranty information. */ + +#pragma once + +#include <toolchain.h> + +struct mutex { + int lock; +}; + +extern int _mutex_lock(int *lock); +extern int _mutex_trylock(int *lock); +extern void _mutex_unlock(int *lock); + +__always_inline void mutex_init(struct mutex *mutex) +{ + mutex->lock = 0; +} + +__always_inline int mutex_lock(struct mutex *mutex) +{ + return _mutex_lock(&mutex->lock); +} + +__always_inline void mutex_unlock(struct mutex *mutex) +{ + _mutex_unlock(&mutex->lock); +} + +__always_inline int mutex_trylock(struct mutex *mutex) +{ + return _mutex_trylock(&mutex->lock); +} + +#define MUTEX(name) struct mutex name = { .lock = 0 } + +/* + * This file is part of Ardix. + * Copyright (c) 2020, 2021 Felix Kopp <owo@fef.moe>. + * + * Ardix is non-violent software: you may only use, redistribute, + * and/or modify it under the terms of the CNPLv6+ as found in + * the LICENSE file in the source code root directory or at + * <https://git.pixie.town/thufie/CNPL>. + * + * Ardix comes with ABSOLUTELY NO WARRANTY, to the extent + * permitted by applicable law. See the CNPLv6+ for details. + */