atom: Replace spinlocks with atoms

This commit is contained in:
Felix Kopp 2020-12-08 12:55:23 +01:00
parent 589e9330da
commit cc00a7a1ea
No known key found for this signature in database
GPG key ID: C478BA0A85F75728
13 changed files with 42 additions and 259 deletions

View file

@ -26,11 +26,11 @@
ARDIX_ARCH_PWD = $(PWD)/arch/at91sam3x8e
ARDIX_SOURCES += \
$(ARDIX_ARCH_PWD)/atom.c \
$(ARDIX_ARCH_PWD)/atomic.c \
$(ARDIX_ARCH_PWD)/interrupt.c \
$(ARDIX_ARCH_PWD)/sched.c \
$(ARDIX_ARCH_PWD)/serial.c \
$(ARDIX_ARCH_PWD)/spinlock.c \
$(ARDIX_ARCH_PWD)/startup.c \
$(ARDIX_ARCH_PWD)/sys.c \
$(ARDIX_ARCH_PWD)/watchdog.c

View file

@ -1,58 +1,56 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#include <arch/at91sam3x8e/spinlock.h>
#include <ardix/atom.h>
/* This code is basically stolen from arch/arm/include/asm/spinlock.h in Linux 5.9 */
void arch_spinlock_init(spinlock_t *lock)
void atom_init(atom_t *atom)
{
lock->lock = 0;
atom->count = 0;
}
int arch_spin_lock(spinlock_t *lock)
int atom_get(atom_t *atom)
{
int tmp;
int newval;
spinlock_t lockval;
atom_t atom_val;
__asm__ volatile(
"1: ldrex %0, [%3] \n" /* lockval = *lock */
" add %1, %0, #1 \n" /* newval = lockval.lock + 1 */
" strex %2, %1, [%3] \n" /* *lock = newval */
"1: ldrex %0, [%3] \n" /* atom_val = *atom */
" add %1, %0, #1 \n" /* newval = atom_val.count + 1 */
" strex %2, %1, [%3] \n" /* *atom = newval */
" teq %2, #0 \n" /* store successful? */
" bne 1b \n" /* -> goto 1 if not */
" dmb " /* memory barrier */
: "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
: "r" (lock)
: "=&r" (atom_val), "=&r" (newval), "=&r" (tmp)
: "r" (atom)
: "cc");
return newval;
}
int arch_spin_unlock(spinlock_t *lock)
int atom_put(atom_t *atom)
{
int tmp;
int newval;
spinlock_t lockval;
atom_t atom_val;
__asm__ volatile(
"1: ldrex %0, [%3] \n"
" sub %1, %0, #1 \n"
" strex %2, %1, [%3] \n"
" teq %2, #0 \n"
" bne 1b \n"
" dmb "
: "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
: "r" (lock)
"1: ldrex %0, [%3] \n" /* atom_val = *atom */
" sub %1, %0, #1 \n" /* newval = atom_val.count - 1 */
" strex %2, %1, [%3] \n" /* *atom = newval */
" teq %2, #0 \n" /* store successful? */
" bne 1b \n" /* -> goto 1 if not */
" dmb " /* memory barrier */
: "=&r" (atom_val), "=&r" (newval), "=&r" (tmp)
: "r" (atom)
: "cc");
return newval;
}
int arch_spinlock_count(spinlock_t *lock)
int atom_count(atom_t *atom)
{
return lock->lock;
return atom->count;
}
/*

View file

@ -1,24 +1,24 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#include <arch/at91sam3x8e/spinlock.h>
#include <ardix/atomic.h>
#include <ardix/atom.h>
static SPINLOCK_DEFINE(atomic_context);
static ATOM_DEFINE(atomic_context);
void atomic_enter(void)
{
arch_spin_lock(&atomic_context);
atom_get(&atomic_context);
}
void atomic_leave(void)
{
arch_spin_unlock(&atomic_context);
atom_put(&atomic_context);
}
int is_atomic_context(void)
{
return arch_spinlock_count(&atomic_context);
return atom_count(&atomic_context);
}
/*

View file

@ -9,11 +9,6 @@
#include <ardix/string.h>
#include <ardix/sched.h>
#include <stdbool.h>
#include <toolchain.h>
#include <ardix/spinlock.h>
void irq_sys_tick(void)
{
/*

View file

@ -1,67 +0,0 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#pragma once
#include <arch/at91sam3x8e/spinlock_type.h>
#include <toolchain.h>
/* This code is basically stolen from arch/arm/include/asm/spinlock.h in Linux 5.9 */
#define SPINLOCK_DEFINE(name) spinlock_t name = { .lock = 0 }
/**
* Initialize a spinlock.
*
* @param lock: Pointer to the spinlock.
*/
void arch_spinlock_init(spinlock_t *lock);
/**
* Increment the lock count on a spinlock.
*
* @param lock: Pointer to the spinlock.
* @returns The new lock count.
*/
int arch_spin_lock(spinlock_t *lock);
/**
* Decrement the lock count on a spinlock.
*
* @param lock: Pointer to the spinlock.
* @returns The new lock count.
*/
int arch_spin_unlock(spinlock_t *lock);
/**
* Get the lock count on a spinlock.
*
* @param lock: Pointer to the spinlock.
*/
int arch_spinlock_count(spinlock_t *lock);
/*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the copyright holder nor the names of its 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 OR
* CONTRIBUTORS 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.
*/

View file

@ -1,33 +0,0 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#pragma once
typedef struct spinlock {
int lock;
} spinlock_t;
/*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the copyright holder nor the names of its 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 OR
* CONTRIBUTORS 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.
*/

View file

@ -1,32 +0,0 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#pragma once
#include <arch/arch_include.h>
#include ARCH_INCLUDE(spinlock_type.h)
/*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the copyright holder nor the names of its 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 OR
* CONTRIBUTORS 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.
*/

View file

@ -3,9 +3,15 @@
#pragma once
#include <arch/arch_include.h>
#include <ardix/types.h>
#include ARCH_INCLUDE(spinlock.h)
#define ATOM_DEFINE(name) atom_t name = { .count = 0, }
int atom_get(atom_t *atom);
int atom_put(atom_t *atom);
int atom_count(atom_t *atom);
/*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>

View file

@ -3,12 +3,10 @@
#pragma once
#include <ardix/list.h>
#include <ardix/spinlock.h>
#include <ardix/types.h>
#include <arch/hardware.h>
#include <stdbool.h>
#include <ardix/list.h>
#include <ardix/types.h>
#ifndef CONFIG_SCHED_MAXPROC
/** The maximum number of processes. */

View file

@ -1,83 +0,0 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#pragma once
/*
* Spinlocks in Ardix work pretty much the same as they do on Linux
* (this is basically just a ripoff). See The Linux Kernel documentation
* for details.
*/
#include <arch/spinlock.h>
#include <toolchain.h>
/**
* Initialize a spinlock.
*
* @param lock: Pointer to the spinlock.
*/
__always_inline void spinlock_init(spinlock_t *lock)
{
arch_spinlock_init(lock);
}
/**
* Increment the lock count on a spinlock.
* If required, block until we have exclusive access to the memory.
*
* @param lock: Pointer to the spinlock.
* @returns The new lock count.
*/
__always_inline int spin_lock(spinlock_t *lock)
{
return arch_spin_lock(lock);
}
/**
* Decrement the lock count on a spinlock.
* If required, block until we have exclusive access to the memory.
*
* @param lock: Pointer to the spinlock.
* @returns The new lock count.
*/
__always_inline int spin_unlock(spinlock_t *lock)
{
return arch_spin_unlock(lock);
}
/**
* Get the lock count of a spinlock.
*
* @param lock: Pointer to the spinlock.
* @returns The current lock count.
*/
__always_inline int spinlock_count(spinlock_t *lock)
{
return arch_spinlock_count(lock);
}
/*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the copyright holder nor the names of its 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 OR
* CONTRIBUTORS 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.
*/

View file

@ -30,9 +30,10 @@ typedef _PID_TYPE_ pid_t;
#define __SIG_ATOMIC_TYPE__ int
#endif /* __SIG_ATOMIC_TYPE__ */
/** Simple atomic reference counter */
typedef struct {
_Atomic __SIG_ATOMIC_TYPE__ lock;
} atomic_t;
int count;
} atom_t;
/*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>

View file

@ -3,7 +3,6 @@
#include <arch/hardware.h>
#include <ardix/spinlock.h>
#include <ardix/io.h>
#include <ardix/printk.h>
#include <ardix/sched.h>

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* See the end of this file for copyright, licensing, and warranty information. */
#include <ardix/atomic.h>
#include <ardix/list.h>
#include <ardix/malloc.h>
#include <ardix/string.h>