aboutsummaryrefslogtreecommitdiff
path: root/sem.c
diff options
context:
space:
mode:
authorOtto Mattik <otto@mattik.org>2021-07-08 18:10:55 +0200
committerOtto Mattik <otto@mattik.org>2021-07-08 18:10:55 +0200
commitda34d97efb21719b2b332f8c60b2750d11bcde1f (patch)
tree2de9fe89f6d79b8ebfcde64c5e86204e904aedf2 /sem.c
downloadarmen-a861fb554ced7709555d2d1b639c534e3f45a83f.tar.gz
armen-a861fb554ced7709555d2d1b639c534e3f45a83f.zip
git: update to v1.0HEADv1.0master
Diffstat (limited to 'sem.c')
-rw-r--r--sem.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/sem.c b/sem.c
new file mode 100644
index 0000000..c34e798
--- /dev/null
+++ b/sem.c
@@ -0,0 +1,78 @@
+/************************************************************************/
+/* */
+/* File: sem.c */
+/* Description: semaphore P and V operations. */
+/* Version: 1.0 */
+/* Author: Otto Mattik */
+/* */
+/* (C)Copyright Otto Mattik 2014-2021. */
+/* */
+/* This file is a part of 'armen' (a tiny operating system). */
+/* 'armen' is distributed under the CeCILL-V2.1 licence. For more */
+/* details about this licence, please visit the website cecill.info */
+/* */
+/************************************************************************/
+
+#ifdef USE_SEM
+
+#include "core.h"
+
+/*
+ * initialize a semaphore
+ *
+ * input:
+ * sem address of semaphore
+ * value initial value for semaphore
+ * output:
+*/
+void sem_init( sem_t* sem, uint8_t value )
+{
+ ((_sem_t*)sem)->lock = 0;
+ ((_sem_t*)sem)->value =
+ ((_sem_t*)sem)->count = value;
+}
+
+/*
+ * P operation
+ *
+ * input:
+ * sem address of semaphore
+ * output:
+ * O if success, otherwise -1
+*/
+void sem_wait( sem_t* sem )
+{
+ while( test_and_set( sem ) != 0 ) ;
+ if( ((_sem_t*)sem)->count == 0 )
+ {
+ ((_sem_t*)sem)->lock = 0;
+ _threads[_cur_thread].sem = sem;
+ wait_event( EVENT_SEM );
+ }
+ else
+ {
+ --((_sem_t*)sem)->count;
+ ((_sem_t*)sem)->lock = 0;
+ }
+}
+
+/*
+ * V operation
+ *
+ * input:
+ * sem address of semaphore
+ * output:
+ * O if success, otherwise -1
+*/
+void sem_post( sem_t* sem )
+{
+ while( test_and_set( sem ) != 0 ) ;
+ if( ((_sem_t*)sem)->count != ((_sem_t*)sem)->value )
+ {
+ ++((_sem_t*)sem)->count;
+ _wakeup( EVENT_SEM, sem );
+ }
+ ((_sem_t*)sem)->lock = 0;
+}
+
+#endif