From owner-freebsd-hackers@FreeBSD.ORG Wed Feb 11 13:09:49 2009 Return-Path: Delivered-To: freebsd-hackers@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B4EC01065672 for ; Wed, 11 Feb 2009 13:09:49 +0000 (UTC) (envelope-from avg@icyb.net.ua) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id E55218FC21 for ; Wed, 11 Feb 2009 13:09:48 +0000 (UTC) (envelope-from avg@icyb.net.ua) Received: from odyssey.starpoint.kiev.ua (alpha-e.starpoint.kiev.ua [212.40.38.101]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id PAA11867 for ; Wed, 11 Feb 2009 15:09:47 +0200 (EET) (envelope-from avg@icyb.net.ua) Message-ID: <4992CE1A.6060106@icyb.net.ua> Date: Wed, 11 Feb 2009 15:09:46 +0200 From: Andriy Gapon User-Agent: Thunderbird 2.0.0.19 (X11/20090110) MIME-Version: 1.0 To: freebsd-hackers@FreeBSD.org References: <4992CA63.8080601@icyb.net.ua> In-Reply-To: <4992CA63.8080601@icyb.net.ua> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Cc: Subject: Re: generalizing fd allocation code to id allocation X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Feb 2009 13:09:50 -0000 My nose has just been rubbed into alloc_unr(9) :) Thanks, Roman! on 11/02/2009 14:53 Andriy Gapon said the following: > 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