aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/lock.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-07-04 17:47:11 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-07-04 17:47:11 +0100
commitce5c899f22106926ca50c153a600b537d08970bc (patch)
treee23cbd3e5901a3178957ee36b22f1277832858b2 /extras/mini-os/lock.c
parent355b0469a8d017b80d9ce1078c90fe628c8b3bbe (diff)
downloadxen-ce5c899f22106926ca50c153a600b537d08970bc.tar.gz
xen-ce5c899f22106926ca50c153a600b537d08970bc.tar.bz2
xen-ce5c899f22106926ca50c153a600b537d08970bc.zip
stubdom: use host's gcc
This makes stubdom use the host's gcc instead of downloading/compiling binutils+gcc. That requires a bunch of changes and even uncovered a few bugs, but saves a lot of time. Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/lock.c')
-rw-r--r--extras/mini-os/lock.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/extras/mini-os/lock.c b/extras/mini-os/lock.c
new file mode 100644
index 0000000000..71a4971015
--- /dev/null
+++ b/extras/mini-os/lock.c
@@ -0,0 +1,111 @@
+/*
+ * locks for newlib
+ *
+ * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, July 20008
+ */
+
+#ifdef HAVE_LIBC
+
+#include <sys/lock.h>
+#include <sched.h>
+#include <wait.h>
+
+int ___lock_init(_LOCK_T *lock)
+{
+ lock->busy = 0;
+ init_waitqueue_head(&lock->wait);
+ return 0;
+}
+
+int ___lock_acquire(_LOCK_T *lock)
+{
+ unsigned long flags;
+ while(1) {
+ wait_event(lock->wait, !lock->busy);
+ local_irq_save(flags);
+ if (!lock->busy)
+ break;
+ local_irq_restore(flags);
+ }
+ lock->busy = 1;
+ local_irq_restore(flags);
+ return 0;
+}
+
+int ___lock_try_acquire(_LOCK_T *lock)
+{
+ unsigned long flags;
+ int ret = -1;
+ local_irq_save(flags);
+ if (!lock->busy) {
+ lock->busy = 1;
+ ret = 0;
+ }
+ local_irq_restore(flags);
+ return ret;
+}
+
+int ___lock_release(_LOCK_T *lock)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ lock->busy = 0;
+ wake_up(&lock->wait);
+ local_irq_restore(flags);
+ return 0;
+}
+
+
+int ___lock_init_recursive(_LOCK_RECURSIVE_T *lock)
+{
+ lock->owner = NULL;
+ init_waitqueue_head(&lock->wait);
+ return 0;
+}
+
+int ___lock_acquire_recursive(_LOCK_RECURSIVE_T *lock)
+{
+ unsigned long flags;
+ if (lock->owner != get_current()) {
+ while (1) {
+ wait_event(lock->wait, lock->owner == NULL);
+ local_irq_save(flags);
+ if (lock->owner == NULL)
+ break;
+ local_irq_restore(flags);
+ }
+ lock->owner = get_current();
+ local_irq_restore(flags);
+ }
+ lock->count++;
+ return 0;
+}
+
+int ___lock_try_acquire_recursive(_LOCK_RECURSIVE_T *lock)
+{
+ unsigned long flags;
+ int ret = -1;
+ local_irq_save(flags);
+ if (!lock->owner) {
+ ret = 0;
+ lock->owner = get_current();
+ lock->count++;
+ }
+ local_irq_restore(flags);
+ return ret;
+}
+
+int ___lock_release_recursive(_LOCK_RECURSIVE_T *lock)
+{
+ unsigned long flags;
+ BUG_ON(lock->owner != get_current());
+ if (--lock->count)
+ return 0;
+ local_irq_save(flags);
+ lock->owner = NULL;
+ wake_up(&lock->wait);
+ local_irq_restore(flags);
+ return 0;
+}
+
+#endif