rmalloc(D3) rmalloc(D3)
NAME
rmalloc - allocate space from a private space management map
SYNOPSIS
#include <sys/types.h>
#include <sys/map.h>
#include <sys/ddi.h>
ulong_t rmalloc(struct map *mp, size_t size);
Arguments
mp Pointer to the map from which space is to be
allocated.
size Number of units of space to allocate.
DESCRIPTION
rmalloc allocates space from the private space management map
pointed to by mp.
Return Values
Upon successful completion, rmalloc returns the base of the
allocated space. If size units cannot be allocated, 0 is
returned.
USAGE
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.
Copyright 1994 Novell, Inc. Page 1
rmalloc(D3) rmalloc(D3)
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.
Level
Initialization, Base or Interrupt.
Synchronization Constraints
Does not sleep.
Driver-defined basic locks, read/write locks, and sleep locks
may be held across calls to this function.
Examples
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
Copyright 1994 Novell, Inc. Page 2
rmalloc(D3) rmalloc(D3)
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_PANIC, "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_PANIC, "xx_start: could not allocate map");
REFERENCES
rmalloc_wait(D3), rmallocmap(D3), rmfree(D3), rmfreemap(D3),
rminit(D3), rmsetwant(D3)
Copyright 1994 Novell, Inc. Page 3
rmalloc(D3) rmalloc(D3)
NOTICES
Portability
All processors
Applicability
ddi: 1, 2, 3, 4, 5, 5mp, 6, 6mp, 7, 7mp
Copyright 1994 Novell, Inc. Page 4