@@ -25,24 +25,48 @@ void vexTasksRun();
2525void ser_output_flush ();
2626}
2727
28+ /* *
29+ * @brief lock a sequence of smart ports
30+ *
31+ * For whatever reason, std::lock only compiles if you pass the mutexes like this:
32+ * std::lock(mutex_a, mutex_b, mutex_c);
33+ * You can't pass it an array or iterator or lambda, so we have to use this helper function instead.
34+ */
2835template <std::size_t ... Is>
2936static void lock_ports (std::index_sequence<Is...>) {
3037 std::lock (zest::Brain::ports[Is].mutex ...);
3138}
3239
40+ /* *
41+ * @brief unlock a sequence of smart ports
42+ *
43+ * For whatever reason, std::unlock only compiles if you pass the mutexes like this:
44+ * std::unlock(mutex_a, mutex_b, mutex_c);
45+ * You can't pass it an array or iterator or lambda, so we have to use this helper function instead
46+ */
3347template <std::size_t ... Is>
3448static void unlock_ports (std::index_sequence<Is...>) {
3549 constexpr std::size_t N = sizeof ...(Is);
3650 // Unlock in reverse order (RAII best practice)
3751 (zest::Brain::ports[N - 1 - Is].mutex .unlock (), ...);
3852}
3953
54+ /* *
55+ * @brief lock all smart port mutexes
56+ *
57+ */
4058static void port_mutex_lock_all () {
59+ // this looks weird because of how std::lock is implemented. See lock_ports for details.
4160 constexpr auto num_ports = std::tuple_size<decltype (zest::Brain::ports)>::value;
4261 lock_ports (std::make_index_sequence<num_ports>{});
4362}
4463
64+ /* *
65+ * @brief unlock all smart port mutexes
66+ *
67+ */
4568static void port_mutex_unlock_all () {
69+ // this looks weird because of how std::unlock is implemented. See unlock_ports for details.
4670 constexpr auto num_ports = std::tuple_size<decltype (zest::Brain::ports)>::value;
4771 unlock_ports (std::make_index_sequence<num_ports>{});
4872}
0 commit comments