ifnet: Add ifnet_serialize_array_{enter,exit,try,assert}()
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 12 Jun 2012 03:08:09 +0000 (11:08 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 12 Jun 2012 03:48:33 +0000 (11:48 +0800)
Ease network device driver development

sys/net/if_var.h

index 4b352bf..288d9a5 100644 (file)
@@ -594,6 +594,10 @@ struct ifmultiaddr {
 
 #ifdef _KERNEL
 
+#ifndef _SYS_SERIALIZE2_H_
+#include <sys/serialize2.h>
+#endif
+
 enum ifaddr_event {
        IFADDR_EVENT_ADD,
        IFADDR_EVENT_DELETE,
@@ -720,10 +724,104 @@ ifa_forwardmsg(struct lwkt_msg *_lmsg, int _nextcpu)
        ifnet_forwardmsg(_lmsg, _nextcpu);
 }
 
+static __inline int
+ifnet_serialize_array_index(int _arrcnt, int _txoff, int _rxoff,
+    enum ifnet_serialize _slz)
+{
+       int _off;
+
+       if (_slz == IFNET_SERIALIZE_MAIN) {
+               _off = 0;
+       } else if (_slz & IFNET_SERIALIZE_TX_BASE) {
+               _off = (_slz & ~IFNET_SERIALIZE_TX_BASE) + _txoff;
+               KASSERT(_off < _arrcnt,
+                   ("invalid TX serializer %#x", _slz));
+       } else if (_slz & IFNET_SERIALIZE_RX_BASE) {
+               _off = (_slz & ~IFNET_SERIALIZE_RX_BASE) + _rxoff;
+               KASSERT(_off < _arrcnt,
+                   ("invalid RX serializer %#x", _slz));
+       } else {
+               panic("unknown serializer %#x", _slz);
+       }
+       return _off;
+}
+
+static __inline void
+ifnet_serialize_array_enter(lwkt_serialize_t *_arr, int _arrcnt,
+    int _txoff, int _rxoff, enum ifnet_serialize _slz)
+{
+       int _off;
+
+       if (_slz == IFNET_SERIALIZE_ALL) {
+               lwkt_serialize_array_enter(_arr, _arrcnt, 0);
+               return;
+       }
+
+       _off = ifnet_serialize_array_index(_arrcnt, _txoff, _rxoff, _slz);
+       lwkt_serialize_enter(_arr[_off]);
+}
+
+static __inline void
+ifnet_serialize_array_exit(lwkt_serialize_t *_arr, int _arrcnt,
+    int _txoff, int _rxoff, enum ifnet_serialize _slz)
+{
+       int _off;
+
+       if (_slz == IFNET_SERIALIZE_ALL) {
+               lwkt_serialize_array_exit(_arr, _arrcnt, 0);
+               return;
+       }
+
+       _off = ifnet_serialize_array_index(_arrcnt, _txoff, _rxoff, _slz);
+       lwkt_serialize_exit(_arr[_off]);
+}
+
+static __inline int
+ifnet_serialize_array_try(lwkt_serialize_t *_arr, int _arrcnt,
+    int _txoff, int _rxoff, enum ifnet_serialize _slz)
+{
+       int _off;
+
+       if (_slz == IFNET_SERIALIZE_ALL)
+               return lwkt_serialize_array_try(_arr, _arrcnt, 0);
+
+       _off = ifnet_serialize_array_index(_arrcnt, _txoff, _rxoff, _slz);
+       return lwkt_serialize_try(_arr[_off]);
+}
+
+#ifdef INVARIANTS
+
+static __inline void
+ifnet_serialize_array_assert(lwkt_serialize_t *_arr, int _arrcnt,
+    int _txoff, int _rxoff, enum ifnet_serialize _slz, boolean_t _serialized)
+{
+       int _off;
+
+       if (_slz == IFNET_SERIALIZE_ALL) {
+               int _i;
+
+               if (_serialized) {
+                       for (_i = 0; _i < _arrcnt; ++_i)
+                               ASSERT_SERIALIZED(_arr[_i]);
+               } else {
+                       for (_i = 0; _i < _arrcnt; ++_i)
+                               ASSERT_NOT_SERIALIZED(_arr[_i]);
+               }
+               return;
+       }
+
+       _off = ifnet_serialize_array_index(_arrcnt, _txoff, _rxoff, _slz);
+       if (_serialized)
+               ASSERT_SERIALIZED(_arr[_off]);
+       else
+               ASSERT_NOT_SERIALIZED(_arr[_off]);
+}
+
+#endif /* INVARIANTS */
+
 #define REINPUT_KEEPRCVIF      0x0001  /* ether_reinput_oncpu() */
 #define REINPUT_RUNBPF                 0x0002  /* ether_reinput_oncpu() */
 
-
 extern struct ifnethead ifnet;
 extern struct  ifnet   **ifindex2ifnet;
 extern int ifqmaxlen;