generalizing fd allocation code to id allocation

Andriy Gapon avg at icyb.net.ua
Wed Feb 11 04:53:59 PST 2009


Guys,

anybody has ideas (or code) for generalizing code in
sys/kern/kern_descrip.c for managing fd-s ("small" integer numbers)?

I mean divorcing that code from filedesc and making it re-usable
wherever we need some (constrained) id allocation.
By constrained I mean that either ids are allocated from a sufficiently
small limited pool or it is desirable to keep ids at small values.

I needed this in a small driver that I am slowly writing and here's some
bits from it:

#define NDSLOTTYPE      uint64_t
#define NDSLOTSIZE      sizeof(NDSLOTTYPE)
#define NDENTRIES       (NDSLOTSIZE * __CHAR_BIT)
#define NDSLOT(x)       ((x) / NDENTRIES)
#define NDBIT(x)        ((NDSLOTTYPE)1 << ((x) % NDENTRIES))
#define NDSLOTS(x)      (((x) + NDENTRIES - 1) / NDENTRIES)
...
/* XXX ugly */
NDSLOTTYPE host_addr_map[NDSLOTS(sizeof(uint8_t) * __CHAR_BIT)];
...
static uint8_t alloc_host_addr(struct heci_softc *sc)
{
        static const int maxoff = sizeof(sc->host_addr_map) /
sizeof(sc->host_addr_map[0]);
        NDSLOTTYPE *map = sc->host_addr_map;
        int off;

        for (off = 0; off < maxoff; ++off) {
                if (map[off] != ~0UL) {
                        uint8_t addr = off * NDENTRIES + ffsl(~map[off])
- 1;
                        map[NDSLOT(addr)] |= NDBIT(addr);
                        return (addr);
                }
        }

        /* XXX what to return if all addresses are in use? */
        /* use the fact that zero is a reserved address */
        return 0;
}

static void
release_host_addr(struct heci_softc *sc, uint8_t addr)
{
        NDSLOTTYPE *map = sc->host_addr_map;
        if (!(map[NDSLOT(addr)] & NDBIT(addr))) /* XXX make KASSERT? */
                device_printf(sc->dev, "release for unused host addr
0x%02x\n", addr);
        map[NDSLOT(addr)] &= ~NDBIT(addr);
}


Essentially this is almost a copy/paste.


-- 
Andriy Gapon


More information about the freebsd-hackers mailing list