From ab28a5e612cc4706aacf53c54fffc46dec38b3b7 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 26 Nov 2013 09:15:43 +0100 Subject: [PATCH] add a basic spinlock, which based on a ticket lock --- arch/x86/include/asm/processor.h | 2 + include/eduos/spinlock.h | 132 +++++++++++++++++++++++++++++++ include/eduos/spinlock_types.h | 64 +++++++++++++++ 3 files changed, 198 insertions(+) create mode 100644 include/eduos/spinlock.h create mode 100644 include/eduos/spinlock_types.h diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 64a3a15..751daef 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -125,6 +125,8 @@ static inline size_t lsb(size_t i) #define NOP4 asm volatile ("nop;nop;nop;nop") /// A eight-instruction-do-nothing #define NOP8 asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop") +/// The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop. +#define PAUSE asm volatile ("pause") #ifdef __cplusplus } diff --git a/include/eduos/spinlock.h b/include/eduos/spinlock.h new file mode 100644 index 0000000..878d0fe --- /dev/null +++ b/include/eduos/spinlock.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011, Stefan Lankes, RWTH Aachen University + * 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 University 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 REGENTS 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. + */ + +/** + * @author Stefan Lankes + * @file include/eduos/spinlock.h + * @brief Spinlock functions + */ + +#ifndef __SPINLOCK_H__ +#define __SPINLOCK_H__ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Initialization of a spinlock + * + * Initialize each spinlock before use! + * + * @param s Pointer to the spinlock structure to initialize. + * @return + * - 0 on success + * - -EINVAL (-22) on failure + */ +inline static int spinlock_init(spinlock_t* s) { + if (BUILTIN_EXPECT(!s, 0)) + return -EINVAL; + + atomic_int32_set(&s->queue, 0); + atomic_int32_set(&s->dequeue, 1); + s->owner = MAX_TASKS; + s->counter = 0; + + return 0; +} + +/** @brief Destroy spinlock after use + * @return + * - 0 on success + * - -EINVAL (-22) on failure + */ +inline static int spinlock_destroy(spinlock_t* s) { + if (BUILTIN_EXPECT(!s, 0)) + return -EINVAL; + + s->owner = MAX_TASKS; + s->counter = 0; + + return 0; +} + +/** @brief Lock spinlock at entry of critical section + * @return + * - 0 on success + * - -EINVAL (-22) on failure + */ +inline static int spinlock_lock(spinlock_t* s) { + int32_t ticket; + + if (BUILTIN_EXPECT(!s, 0)) + return -EINVAL; + + if (s->owner == current_task->id) { + s->counter++; + return 0; + } + + ticket = atomic_int32_add(&s->queue, 1); + while(atomic_int32_read(&s->dequeue) != ticket) { + PAUSE; + } + s->owner = current_task->id; + s->counter = 1; + + return 0; +} + +/** @brief Unlock spinlock on exit of critical section + * @return + * - 0 on success + * - -EINVAL (-22) on failure + */ +inline static int spinlock_unlock(spinlock_t* s) { + if (BUILTIN_EXPECT(!s, 0)) + return -EINVAL; + + s->counter--; + if (!s->counter) { + s->owner = MAX_TASKS; + atomic_int32_inc(&s->dequeue); + } + + return 0; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/eduos/spinlock_types.h b/include/eduos/spinlock_types.h new file mode 100644 index 0000000..e8fc389 --- /dev/null +++ b/include/eduos/spinlock_types.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011, Stefan Lankes, RWTH Aachen University + * 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 University 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 REGENTS 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. + */ + +/** + * @author Stefan Lankes + * @file include/eduos/spinlock_types.h + * @brief Spinlock type definition + */ + +#ifndef __SPINLOCK_TYPES_H__ +#define __SPINLOCK_TYPES_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Spinlock structure */ +typedef struct spinlock { + /// Internal queue + atomic_int32_t queue; + /// Internal dequeue + atomic_int32_t dequeue; + /// Owner of this spinlock structure + tid_t owner; + /// Internal counter var + uint32_t counter; +} spinlock_t; + +/// Macro for spinlock initialization +#define SPINLOCK_INIT { ATOMIC_INIT(0), ATOMIC_INIT(1), MAX_TASKS, 0} + +#ifdef __cplusplus +} +#endif + +#endif