diff --git a/include/semaphore.h b/include/semaphore.h new file mode 100644 index 00000000..5393235e --- /dev/null +++ b/include/semaphore.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 Amazon.com, Inc. or its affiliates. + * All Rights Reserved. + * + * 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. + * + * 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 OWNER 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. + */ +#ifndef KTF_SEMAPHORE_H +#define KTF_SEMAPHORE_H + +#include +#include + +struct sem { + atomic_t v; +}; +typedef struct sem sem_t; + +#define MAX_SEMAPHORE_VALUE (_U32(-1) / 2) +#define SEM_INIT(value) \ + { \ + .v = {(value) } \ + } + +extern void sem_init(sem_t *sem, uint32_t value); +extern bool sem_trywait(sem_t *sem); +extern void sem_wait(sem_t *sem); +extern void sem_post(sem_t *sem); + +#endif \ No newline at end of file diff --git a/lib/semaphore.c b/lib/semaphore.c new file mode 100644 index 00000000..399e7df2 --- /dev/null +++ b/lib/semaphore.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 Amazon.com, Inc. or its affiliates. + * All Rights Reserved. + * + * 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. + * + * 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 OWNER 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. + */ + +#include +#include + +void sem_init(sem_t *sem, uint32_t value) { + /* Do not allow more than 2^31-1 threads to access this semaphore */ + BUG_ON(value > MAX_SEMAPHORE_VALUE); + + atomic_set(&(sem->v), value); +} + +bool sem_trywait(sem_t *sem) { + int64_t val; + + if (atomic_read(&(sem->v)) > 0) { + val = atomic_dec_return(&(sem->v)); + if (val >= 0) { + return true; + } + else { + atomic_inc(&(sem->v)); + } + } + + return false; +} + +void sem_wait(sem_t *sem) { + while (!sem_trywait(sem)) { + cpu_relax(); + } +} + +void sem_post(sem_t *sem) { atomic_inc(&(sem->v)); }