Date: Sat, 06 Sep 2008 23:27:09 -0700 From: Julian Elischer <julian@elischer.org> To: Marko Zec <zec@FreeBSD.org>, FreeBSD virtualization mailing list <freebsd-virtualization@freebsd.org> Subject: FOREACH_VNET... Message-ID: <48C3743D.9090503@elischer.org>
next in thread | raw e-mail | index | archive | help
trying to replace VNET_ITERLOOP_{BEGIN,END} looking at an example: static void if_slowtimo(void *arg) { struct ifnet *ifp; IFNET_RLOCK(); VNET_ITERLOOP_BEGIN(); INIT_VNET_NET(curvnet); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_timer == 0 || --ifp->if_timer) continue; if (ifp->if_watchdog) (*ifp->if_watchdog)(ifp); } VNET_ITERLOOP_END(); IFNET_RUNLOCK(); timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); } If we expand this out we get: (reindented for readability) static void if_slowtimo(void *arg) { struct ifnet *ifp; IFNET_RLOCK(); struct vnet *vnet_iter; VNET_LIST_REF(); LIST_FOREACH(vnet_iter, &vnet_head, vnet_le) { struct vnet *saved_vnet = curvnet; curvnet = vnet_iter; INIT_VNET_NET(curvnet); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_timer == 0 || --ifp->if_timer) continue; if (ifp->if_watchdog) (*ifp->if_watchdog)(ifp); } curvnet = saved_vnet; } VNET_LIST_UNREF(); IFNET_RUNLOCK(); timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); } now several things leap out here.. (like, declaring variables in mid block) using different macros to try do this cleanly might lead to: static void if_slowtimo(void *arg) { struct ifnet *ifp; VNET_DECL(vnet_iter); VNET_DECL(saved_vnet); IFNET_RLOCK(); CURVNET_SAVE(saved_vnet); VNET_LIST_REF(); FOREACH_VNET(vnet_iter) { CURVNET_SET_QUIET(vnet_iter); INIT_VNET_NET(vnet_iter); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_timer == 0 || --ifp->if_timer) continue; if (ifp->if_watchdog) (*ifp->if_watchdog)(ifp); } } CURVNET_SET(vnet_hold); VNET_LIST_UNREF(); IFNET_RUNLOCK(); timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); } this adds a lot to the original.. I could see: using bigger macros, getting it back (size wise) to: static void if_slowtimo(void *arg) { struct ifnet *ifp; VNET_ITERATOR_DECL(vnet_iter, saved_vnet); IFNET_RLOCK(); FOREACH_VNET(vnet_iter, saved_vnet) { VNET_SWITCHTO(vnet_iter); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_timer == 0 || --ifp->if_timer) continue; if (ifp->if_watchdog) (*ifp->if_watchdog)(ifp); } } FOREACH_VNET_COMPLETE(saved_vnet); IFNET_RUNLOCK(); timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); } still bigger than the original macros though arguably more "C-like" anyone have better ways to express this? Brook, robert, bz? does this look better? Julian
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?48C3743D.9090503>