rmalloc -- allocate space from a private space management map


   #include <sys/types.h>
   #include <sys/map.h>
   #include <sys/ddi.h>

ulong_t rmalloc(struct map *mp, size_t size);


rmalloc allocates space from the private space management map pointed to by mp.


Pointer to the map from which space is to be allocated.

Number of units of space to allocate.

Return values

Upon successful completion, rmalloc returns the base of the allocated space. If size units cannot be allocated, 0 is returned.


Drivers can use rmalloc to allocate space from a previously allocated and initialized private space management map.

On systems where the rmallocmap function is available, the map must have been allocated by a call to rmallocmap(D3) and the space managed by the map must have been added using rmfree(D3) prior to the first call to rmalloc for the map.

On systems where the rmallocmap function is not available, the map must be initially allocated either as a data array, or by the kmem_alloc(D3) function. The map must have been initialized by a call to rminit(D3) and the space managed by the map must have been added using rmfree(D3) prior to the first call to rmalloc for the map.

size specifies the amount of space to allocate and is in arbitrary units. The driver using the map places whatever semantics on the units are appropriate for the type of space being managed. For example, units may be byte addresses, pages of memory, or blocks on a device.

The system allocates space from the memory map on a first-fit basis and coalesces adjacent space fragments when space is returned to the map by rmfree.

Context and synchronization

All contexts.

Hardware applicability


Version applicability

ddi: 1, 2, 3, 4, 5, 5mp, 6, 6mp, 7, 7mp, 7.1, 7.1mp, 8, 8mp


rmalloc_wait(D3), rmallocmap(D3), rmfree(D3), rmfreemap(D3), rminit(D3), rmsetwant(D3)


The following example is a simple memory map, but it illustrates the principles of map management. A driver declares a map table (line 4) and initializes the map table by calling both the rminit and rmfree functions. There are 35 entries in the map table, 32 of which can be used to represent space allocated. In the driver's start(D2) routine, we allocate 16 Kbytes of memory using kmem_alloc(D3) (line 8). This is the space to be managed. Then we call rminit to establish the number of slots or entries in the map (line 10), and rmfree to populate the map with the space it is to manage (line 11).

In the driver's read(D2) and write(D2) routines, we use rmalloc to allocate buffers for data transfer. This example illustrates the write routine. Assuming the device can only transfer XX_MAXBUFSZ bytes at a time, we calculate the amount of data to copy (line 22) and use rmalloc to allocate some space from the map. The call to rmalloc is protected against interrupts (line 23) from the device that may result in freeing map space. This way, if space is freed, we won't miss the corresponding wakeup(D3).

If the appropriate space cannot be allocated, we use rmsetwant(D3) to indicate that we want space (line 25) and then we sleep until a buffer is available. When a buffer becomes available, rmfree is called to return the space to the map and to wake the sleeping process. Then the call to rmalloc will succeed and the driver can then transfer data.

    1  #define XX_MAPSIZE	35
    2  #define XX_MEMSIZE	(16*1024)
    3  #define XX_MAXBUFSZ	1024

4 struct map xx_map[XX_MAPSIZE]; ... 5 xx_start() 6 { 7 caddr_t bp;

8 if ((bp = kmem_alloc(XX_MEMSIZE, KM_NOSLEEP)) == 0) 9 cmn_err(CE_WARN, "xx_start: could not allocate %d bytes", XX_MEMSIZE); 10 rminit(xx_map, XX_MAPSIZE); 11 rmfree(xx_map, XX_MEMSIZE, bp); 12 } ... 13 xx_write(dev, uiop, crp) 14 dev_t dev; 15 uio_t *uiop; 16 cred_t *crp; 17 { 18 caddr_t addr; 19 size_t size; 20 int s; ... 21 while (uiop->uio_resid > 0) { 22 size = min(uiop->uio_resid, XX_MAXBUFSZ); 23 s = spl4(); 24 while ((addr = (caddr_t)rmalloc(xx_map, size)) == NULL) { 25 rmsetwant(xx_map); 26 sleep((caddr_t)xx_map, PZERO); 27 } 28 splx(s); ... 29 } ...

On systems where the rmallocmap function is available, line 4 could become:

   struct map *xx_map;
and line 10 could become:
   if ((mp=rmallocmap(xx_MAPSIZE) == 0
   	cmn_err (CE_WARN, "xx_start: could not allocate map");

19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005