[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/2] libc: sleep_ns() rausgeplittet und gefixt



+ libc: sleep() rechnet als erstes sowieso alles in Nanosekunden um,
  dann kann man genauso gut ein sleep_ns() anbieten, das die Zeit direkt
  in Nanosekunden nimmt.

! libc: Theoretisch gibt es in sleep() zwischen der Timeout-Prüfung und
  wait_for_rpc() ein Race, und wenn man es verliert, landet man in einem
  Deadlock (falls nicht irgendjemand anderes zufällig einen RPC schickt,
  dann wartet man nur zu lang). Ich habe es zwar in der Praxis nie
  gesehen, aber wenn man die Funktion schon anfasst, kann man es ja auch
  gleich fixen.

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/modules/include/sleep.h |  4 ++++
 src/modules/lib/msleep.c    | 19 +++++++++++++------
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/src/modules/include/sleep.h b/src/modules/include/sleep.h
index 9b0b9e099..e3dc4f6b7 100644
--- a/src/modules/include/sleep.h
+++ b/src/modules/include/sleep.h
@@ -32,8 +32,12 @@
 extern "C" {
 #endif
 
+// Benutzt eine Busyloop zum Warten
 void msleep(unsigned long msec);
 
+// Schedult einen Timer und yieldet
+void sleep_ns(uint64_t nsec);
+
 #ifdef __cplusplus
 }; // extern "C"
 #endif
diff --git a/src/modules/lib/msleep.c b/src/modules/lib/msleep.c
index 38dd32a1a..04356b3f3 100644
--- a/src/modules/lib/msleep.c
+++ b/src/modules/lib/msleep.c
@@ -42,15 +42,22 @@ void msleep(unsigned long msec)
 
 static void do_nothing(void) {}
 
-unsigned int sleep(unsigned int sec)
+void sleep_ns(uint64_t nsec)
 {
-    uint64_t timeout = get_tick_count() + sec * 1000 * 1000;
-    timer_register(do_nothing, sec * 1000 * 1000);
+    uint64_t timeout = get_tick_count() + nsec;
 
-    while(timeout > get_tick_count())
-    {
-        wait_for_rpc();
+    timer_register(do_nothing, nsec);
+
+    p();
+    while (timeout > get_tick_count()) {
+        v_and_wait_for_rpc();
+        p();
     }
+    v();
+}
 
+unsigned int sleep(unsigned int sec)
+{
+    sleep_ns(sec * 1000 * 1000);
     return 0;
 }
-- 
2.26.2