blob: f7936bce8b77830b2d1d6f9bb1386a103a01721d [file]
/*
* Copyright 2014, NICTA
*
* This software may be distributed and modified according to the terms of
* the BSD 2-Clause license. Note that NO WARRANTY is provided.
* See "LICENSE_BSD2.txt" for details.
*
* @TAG(NICTA_BSD)
*/
#include <assert.h>
#include <sel4/sel4.h>
#include <stddef.h>
#include <sync/atomic.h>
#include <sync/bin_sem_bare.h>
int sync_bin_sem_bare_wait(seL4_CPtr aep, volatile int *value) {
int oldval;
int result = sync_atomic_decrement_safe(value, &oldval, __ATOMIC_ACQUIRE);
if (result != 0) {
/* Failed decrement; too many outstanding lock holders. */
return -1;
}
if (oldval <= 0) {
seL4_Wait(aep, NULL);
/* Even though we performed an acquire barrier during the atomic
* decrement we did not actually have the lock yet, so we have
* to do another one now */
__atomic_thread_fence(__ATOMIC_ACQUIRE);
}
return 0;
}
int sync_bin_sem_bare_post(seL4_CPtr aep, volatile int *value) {
/* We can do an "unsafe" increment here because we know we are the only
* lock holder.
*/
int val = sync_atomic_increment(value, __ATOMIC_RELEASE);
assert(*value <= 1);
if (val <= 0) {
seL4_Signal(aep);
}
return 0;
}