T284: T285: Store RPC recv slots in thread struct
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Thu, 25 Aug 2016 10:19:32 +0000 (12:19 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Wed, 21 Sep 2016 09:48:56 +0000 (11:48 +0200)
Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

include/barrelfish/threads.h
lib/barrelfish/include/threads_priv.h
lib/barrelfish/threads.c
tools/flounder/LMP.hs
tools/flounder/RPCClient.hs

index 97980d5..0978736 100644 (file)
@@ -94,6 +94,9 @@ errval_t thread_get_async_error(void);
 void thread_set_mask_channels(bool m);
 bool thread_get_mask_channels(void);
 
+void thread_store_recv_slot(struct capref recv_slot);
+struct capref thread_get_next_recv_slot(void);
+
 extern __thread thread_once_t thread_once_local_epoch;
 extern void thread_once_internal(thread_once_t *control, void (*func)(void));
 
index 9fb381c..14ab5cc 100644 (file)
@@ -82,6 +82,8 @@ struct thread {
     errval_t    async_error;                ///< RPC async error
     uint32_t    outgoing_token;             ///< Token of outgoing message
     bool    mask_channels;
+    struct capref recv_slots[16];           ///< Queued cap recv slots
+    uint8_t recv_slot_count;                ///< number of currently queued recv slots
 };
 
 void thread_enqueue(struct thread *thread, struct thread **queue);
index 3e0ad29..27892fe 100644 (file)
@@ -694,6 +694,30 @@ bool thread_get_mask_channels(void)
 }
 
 /**
+ * \brief Store receive slot provided by rpc in thread state
+ */
+void thread_store_recv_slot(struct capref recv_slot)
+{
+    struct thread *me = thread_self();
+    assert(me);
+
+    assert(me->recv_slot_count < 15);
+
+    me->recv_slots[me->recv_slot_count++] = recv_slot;
+}
+
+struct capref thread_get_next_recv_slot(void)
+{
+    struct thread *me = thread_self();
+
+    if (me->recv_slot_count == 0) {
+        return NULL_CAP;
+    }
+
+    return me->recv_slots[--me->recv_slot_count];
+}
+
+/**
  * \brief Yield the calling thread
  *
  * Switches to the next runnable thread in this dispatcher, or if none is
index 7ade040..6b3cf00 100644 (file)
@@ -671,15 +671,23 @@ rx_handler arch ifn typedefs msgdefs msgs =
             [],
         C.SBlank,
 
-        C.SComment "allocate a new receive slot if we're not in RPC and used the last one",
-        C.If (need_slot_alloc "cap")
-            [C.Ex $ C.Assignment errvar $
-                C.Call "lmp_chan_alloc_recv_slot" [chanaddr],
-             C.If (C.Call "err_is_fail" [errvar])
-                [report_user_err $
-                    C.Call "err_push" [errvar, C.Variable "LIB_ERR_LMP_ALLOC_RECV_SLOT"]]
-                []
-            ] [],
+        C.SComment "get or allocate a new receive slot if needed",
+        C.If (C.Unary C.Not $ C.Call "capref_is_null" [C.Variable "cap"])
+        [
+            localvar (C.TypeName "struct capref") "nextslot" (Just (
+                C.Call "thread_get_next_recv_slot" []
+            )),
+            C.If (C.Call "capref_is_null" [ C.Variable "nextslot" ]) [
+                 C.Ex $ C.Assignment errvar $
+                    C.Call "lmp_chan_alloc_recv_slot" [chanaddr],
+                 C.If (C.Call "err_is_fail" [errvar])
+                    [report_user_err $
+                        C.Call "err_push" [errvar, C.Variable "LIB_ERR_LMP_ALLOC_RECV_SLOT"]]
+                    []
+            ] [
+                C.Ex $ C.Call "lmp_chan_set_recv_slot" [chanaddr, C.Variable "nextslot" ]
+            ]
+        ] [],
         C.SBlank,
 
         C.SComment "is this the start of a new message?",
@@ -768,19 +776,6 @@ rx_handler arch ifn typedefs msgdefs msgs =
                                  | (afl, word) <- zip wl [0..]],
             case cap of
                 Just (CapFieldTransfer _ af) -> C.StmtList [
-                      C.SComment "Update recv slot if we're in RPC, otherwise we do slot alloc earlier",
-                      C.If in_rpc [
-                          C.If (C.Unary C.Not (C.Call "capref_is_null" [(argfield_expr RX mn af)]))
-                          [
-                              C.Ex $ C.Call "lmp_chan_set_recv_slot"
-                                        [chanaddr, (argfield_expr RX mn af)]
-                          ] [
-                              C.Ex $ C.Call "assert"
-                                    [C.Unary C.Not (C.StringConstant
-                                        "Flounder LMP: cap RX in RPC, but no new recv slot provided")]
-                          ]
-                      ] [],
-                      C.SComment "Store received cap in provided capref",
                       C.Ex $ C.Assignment (argfield_expr RX mn af) (C.Variable "cap")
                      ]
                 Nothing -> C.StmtList [],
index 7330430..5147f75 100644 (file)
@@ -197,7 +197,7 @@ rpc_fn ifn typedefs msg@(RPC n args _) =
         is_cap_arg (Arg _ _) = False
         rx_cap_args = filter is_cap_arg rxargs
         binding_save_rx_slot (Arg tr (Name an)) = C.Ex $
-            C.Assignment (rpc_rx_union_elem n an) (C.DerefPtr $ C.Variable an)
+            C.Call "thread_store_recv_slot" [(C.DerefPtr $ C.Variable an)]
         binding_save_rx_slots = C.StmtList [ binding_save_rx_slot c | c <- rx_cap_args ]
         token_name = "token"
         outgoing_token = bindvar `C.DerefField` "outgoing_token"