[libbus] Add thread ownership functions
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Mon, 3 Jan 2011 13:30:37 +0000 (08:30 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Mon, 3 Jan 2011 13:32:05 +0000 (08:32 -0500)
WvlBusRegisterOwnerThread() and WvlBusNotOwned().

src/include/bus.h
src/winvblock/libbus/libbus.c

index e15b72b..fdad308 100644 (file)
@@ -80,6 +80,7 @@ typedef struct WVL_BUS_T {
         USHORT NodeCount;
         LIST_ENTRY WorkItems;
         KSPIN_LOCK WorkItemsLock;
+        PETHREAD Thread;
       } BusPrivate_;
   } WVL_S_BUS_T, * WVL_SP_BUS_T;
 
@@ -161,5 +162,7 @@ extern WVL_M_LIB PDEVICE_OBJECT STDCALL WvlBusGetNodePdo(
 extern WVL_M_LIB UINT32 STDCALL WvlBusGetNodeCount(
     WVL_SP_BUS_T
   );
+extern WVL_M_LIB BOOLEAN STDCALL WvlBusRegisterOwnerThread(IN WVL_SP_BUS_T);
+extern WVL_M_LIB BOOLEAN STDCALL WvlBusNotOwned(IN WVL_SP_BUS_T);
 
 #endif  /* WVL_M_BUS_H_ */
index 8c8683a..36df957 100644 (file)
@@ -647,3 +647,38 @@ WVL_M_LIB UINT32 STDCALL WvlBusGetNodeCount(
   ) {
     return Bus->BusPrivate_.NodeCount;
   }
+
+/**
+ * Register an owning thread for a bus.
+ *
+ * @v Bus               The bus to take ownership of with the current thread.
+ * @ret BOOLEAN         FALSE if the bus is already owned, else TRUE.
+ *
+ * Some operations, such as manipulations of the child node list,
+ * are best carried out serialized on a single, owning thread.
+ * This is to avoid race conditions but without holding an
+ * expensive lock.
+ */
+WVL_M_LIB BOOLEAN STDCALL WvlBusRegisterOwnerThread(IN WVL_SP_BUS_T Bus) {
+    if (Bus->BusPrivate_.Thread)
+      return FALSE;
+    Bus->BusPrivate_.Thread = PsGetCurrentThread();
+    return TRUE;
+  }
+
+/**
+ * Check if the current thread owns a bus.
+ *
+ * @v Bus               The bus to check ownership of.
+ * @ret BOOLEAN         FALSE if the bus is owned or ownerless, else TRUE.
+ *
+ * If a bus doesn't have an owning thread, this returns FALSE.
+ */
+WVL_M_LIB BOOLEAN STDCALL WvlBusNotOwned(IN WVL_SP_BUS_T Bus) {
+    if (
+        !Bus->BusPrivate_.Thread ||
+        (Bus->BusPrivate_.Thread == PsGetCurrentThread())
+      )
+      return FALSE;
+    return TRUE;
+  }