
2 changed files with 0 additions and 199 deletions
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin |
||||
* Copyright (C) 2015 Eistec AB |
||||
* |
||||
* This file is subject to the terms and conditions of the GNU Lesser General |
||||
* Public License v2.1. See the file LICENSE in the top level directory for more |
||||
* details. |
||||
*/ |
||||
|
||||
|
||||
/**
|
||||
* @ingroup core_util |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief Generic implementation of the kernel's atomic interface |
||||
* |
||||
* @author Kaspar Schleiser <kaspar@schleiser.de> |
||||
* @author Oliver Hahm <oliver.hahm@inria.fr> |
||||
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se> |
||||
* |
||||
* @} |
||||
*/ |
||||
|
||||
#include "irq.h" |
||||
#include "cpu.h" |
||||
#include "atomic.h" |
||||
|
||||
/* Set ARCH_HAS_ATOMIC_COMPARE_AND_SWAP within cpu.h to override this function */ |
||||
#if (ARCH_HAS_ATOMIC_COMPARE_AND_SWAP == 0) |
||||
|
||||
int atomic_cas(atomic_int_t *var, int old, int now) |
||||
{ |
||||
unsigned int mask = irq_disable(); |
||||
|
||||
if (ATOMIC_VALUE(*var) != old) { |
||||
irq_restore(mask); |
||||
return 0; |
||||
} |
||||
|
||||
ATOMIC_VALUE(*var) = now; |
||||
irq_restore(mask); |
||||
return 1; |
||||
} |
||||
|
||||
#endif |
@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin |
||||
* Copyright (C) 2015 Eistec AB |
||||
* |
||||
* This file is subject to the terms and conditions of the GNU Lesser |
||||
* General Public License v2.1. See the file LICENSE in the top level |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @addtogroup core_util |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief Functions for atomic handling of variables |
||||
* |
||||
* @author Kaspar Schleiser <kaspar@schleiser.de> |
||||
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se> |
||||
*/ |
||||
|
||||
#ifndef ATOMIC_H |
||||
#define ATOMIC_H |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/**
|
||||
* @brief Integer variable for use in atomic counters. |
||||
* |
||||
* @note This type is a struct for hard type checking (let the compiler warn |
||||
* if int is assigned regularly). |
||||
*/ |
||||
typedef struct { |
||||
volatile int value; /**< the actual value */ |
||||
} atomic_int_t; |
||||
|
||||
/**
|
||||
* @brief Initializer for atomic variables |
||||
* |
||||
* @param[in] val initial value for the atomic integer |
||||
*/ |
||||
#define ATOMIC_INIT(val) {(val)} |
||||
|
||||
/**
|
||||
* @brief Atomic Compare and Swap |
||||
* |
||||
* Updates the value in var iff the current value of var is equal to old. |
||||
* |
||||
* @param[inout] var Atomic variable to update |
||||
* @param[in] old The old value to compare against |
||||
* @param[in] now The new value to write to var |
||||
* |
||||
* @return 1 if the write completed successfully |
||||
* @return 0 if the write failed. |
||||
*/ |
||||
int atomic_cas(atomic_int_t *var, int old, int now); |
||||
|
||||
/**
|
||||
* @brief Increment a counter variable by one atomically and return the old value. |
||||
* |
||||
* @param[inout] var Pointer to a counter variable. |
||||
* |
||||
* @return The value of *val* before the increment. |
||||
*/ |
||||
static inline int atomic_inc(atomic_int_t *var) |
||||
{ |
||||
int old; |
||||
|
||||
do { |
||||
old = var->value; |
||||
} while (!atomic_cas(var, old, old + 1)); |
||||
|
||||
return old; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Decrement a counter variable by one atomically and return the old value. |
||||
* |
||||
* @param[inout] var Pointer to a counter variable. |
||||
* |
||||
* @return The value of *val* before the decrement. |
||||
*/ |
||||
static inline int atomic_dec(atomic_int_t *var) |
||||
{ |
||||
int old; |
||||
|
||||
do { |
||||
old = var->value; |
||||
} while (!atomic_cas(var, old, old - 1)); |
||||
|
||||
return old; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set an atomic variable to 1. |
||||
* |
||||
* @param[inout] var Pointer to an atomic variable to update |
||||
* |
||||
* @return 1 if the old value was 0 and the variable was successfully updated |
||||
* @return 0 if the variable was already set |
||||
*/ |
||||
static inline int atomic_set_to_one(atomic_int_t *var) |
||||
{ |
||||
do { |
||||
if (var->value != 0) { |
||||
return 0; |
||||
} |
||||
} while (!atomic_cas(var, 0, 1)); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set an atomic variable to 0. |
||||
* |
||||
* @param[inout] var Pointer to an atomic variable to update |
||||
* |
||||
* @return 1 if the old value was not 0 and the variable was successfully updated |
||||
* @return 0 if the variable was already cleared |
||||
*/ |
||||
static inline int atomic_set_to_zero(atomic_int_t *var) |
||||
{ |
||||
int old; |
||||
|
||||
do { |
||||
old = var->value; |
||||
|
||||
if (old == 0) { |
||||
return 0; |
||||
} |
||||
} while (!atomic_cas(var, old, 0)); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Get the value of an atomic int |
||||
* |
||||
* @param[in] var Atomic variable |
||||
* |
||||
* @return the value of the atomic integer |
||||
* |
||||
* @note This can be used for non-thread-safe assignment of the atomic integer |
||||
*/ |
||||
#define ATOMIC_VALUE(var) ((var).value) |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* ATOMIC_H */ |
||||
/** @} */ |
Loading…
Reference in new issue