The Kernel Kit: Areas Concepts

The Kernel Kit Table of Contents | The Kernel Kit Index

# Areas Concepts

An area is a chunk of virtual memory. As such, it has all the expected properties of virtual memory: It has a starting address, a size, the addresses it comprises are contiguous, and it maps to (possibly non-contiguous) physical memory. The features that an area provides that you don't get with "standard" memory are these:

- Areas can be shared. Different areas can refer to the same physical memory. Put another way, different virtual memory addresses can map to the same physical locations. Furthermore, the different areas needn't belong to the same application. By creating and "cloning" areas, applications can easily share the same data.

- Areas can be locked into RAM. You can specify that the area's physical memory be locked into RAM when it's created, locked on a page-by-page basis as pages are swapped in, or that it be swapped in and out as needed.

- Areas can be read- and write-protected.

- Areas are page-aligned. Areas always start on a page boundary, and are allocated in integer multiples of the size of a page. (A page is 4096 bytes, as represented by the `B_PAGE_SIZE` constant.)

- You can specify the starting address of the area's virtual memory. The specification can require that the area start precisely at a certain address, anywhere above a certain address, or anywhere at all.

Because areas are large—one page, minimum—you don't create them arbitrarily. The two most compelling reasons to create an area are the two first points listed above: To share data among different applications, and to lock memory into RAM.

In all particulars (but one) you treat the memory that an area gives you exactly as you would treat any allocated memory: You can read and write it through pointer manipulation, or through standard functions such as `memcpy()` and `strcpy()`. The one difference is between areas and malloc'd memory is...

- You never `free()` the memory that an area allocates for you. If you want to get rid of an area, use the `delete_area()` function, instead.

### Area IDs and Area Names

Each area that you create is tagged with an `area_id` number:

- An `area_id` number is a positive integer that's global and unique within the scope of the computer. They're not unique across the network, nor are they persistent across boots.

- The `area_id` numbers are generated and assigned automatically by the `create_area()` and `clone_area()` functions. The other area functions operate on these `area_id` numbers (they're required as arguments).

- Although they are global, `area_id` numbers have little meaning outside of the address space (application) in which they were created.

- Once assigned, the `area_id` number doesn't change; the number is invalidated when `delete_area()` is called or when the application (team) that created it dies.

- Don't worry about recycled `area_id` numbers. When an area is deleted, it's `area_id` goes with it. (`area_id` values are recycled, but the turnover is at 2^31.)

Areas can also be (loosely) identified by name:

- When you create an area (through `create_area()` or `clone_area()`), you get to name it.

- Area names are not unique—any number of areas can be assigned the same name.

- To look up an area by name, use the `FindArea()` function.

### Sharing an Area Between Applications

For multiple applications to share a common area, one of the applications has to create the area, and the other applications clone the area. You clone an area by calling `clone_area()`. The function takes, as its last argument, the `area_id` of the source area and returns a new (unique) `area_id` number. All further references to the cloned area (in the cloning application) must be based on the area_id that's returned by `clone_area()`.

So how does a cloner find a source `area_id` in the first place?

- The source application can pass the "original" `area_id` number to the cloners.

- The cloners can find the area by name, by calling `find_area()`.

Keep in mind that area names are not forced to be unique, so the `find_area()` method has some amount of uncertainty. But this can be minimized through clever name creation.

#### Cloned Memory

The physical memory that lies beneath an area is never implicitly copied—for example, the area mechanism doesn't perform a "copy-on-write." If two areas refer to the same memory because of cloning, a data modification that's affected through one area will be seen by the other area.

### Locking an Area

When you're working with moderately large amounts of data, it's often the case that you would prefer that the data remain in RAM, even if the rest of your application needs to be swapped out. An argument to `create_area()` lets you declare, through the use of one of the following constants, the locking scheme that you wish to apply to your area:

Constant | Meaning
--- | ---
`B_FULL_LOCK` | The area's memory is locked into RAM when the area is created, and won't be swapped out.
`B_CONTIGUOUS` | Not only is the area's memory locked into RAM, it's also guaranteed to be contiguous. This is particularly—and perhaps exclusively—useful to designers of certain types of device drivers.
`B_LAZY_LOCK` | Allows individual pages of memory to be brought into RAM through the natural order of things and then locks them.
`B_NO_LOCK` | Pages are never locked, they're swapped in and out as needed.
`B_LOMEM` | This is a special constant that's used for for areas that need to be locked, contiguous, and that fit within the first 16MB of physical memory. The folks that need this constant know who they are.

Keep in mind that locking an area essentially reduces the amount of RAM that can be used by other applications, and so increases the likelihood of swapping. So you shouldn't lock simply because you're greedy. But if the area that you're locking is going to be shared among some number of other applications, or if you're writing a real-time application that processes large chunks of data, then locking can be a justifiable excess.

The locking scheme is set by the `create_area()` function and is thereafter immutable. You can't re-declare the lock when you clone an area.

### Area Info

Ultimately, you use an area for the virtual memory that it represents: You create an area because you want some memory to which you can write and from which you can read data. These acts are performed in the usual manner, through references to specific addresses. Setting a pointer to a location within the area, and checking that you haven't exceeded the area's memory bounds as you increment the pointer (while reading or writing) are your own responsibility. To do this properly, you need to know the area's starting address and its extent:

- An area's starting address is maintained as the `address` field in its `area_info` structure; you retrieve the `area_info` for a particular area through the `get_area_info()` function.

- The size of the area (in bytes) is given as the `size` field of its `area_info` structure.

An important point, with regard to `area_info`, is that the `address` field is only valid for the application that created or cloned the area (in other words, the application that created the `area_id` that was passed to `get_area_info()`). Although the memory that underlies an area is global, the address that you get from an `area_info` structure refers to a specific address space.

If there's any question about whether a particular `area_id` is "local" or "foreign," you can compare the `area_info.team` field to your thread's team.

### Deleting an Area

When your application quits, the areas (the `area_id` numbers) that it created through `create_area()` or `clone_area()` are automatically rendered invalid. The memory underlying these areas, however, isn't necessarily freed. An area's memory is freed only when (and as soon as) there are no more areas that refer to it.

You can force the invalidation of an `area_id` by passing it to the `delete_area()` function. Again, the underlying memory is only freed if yours is the last area to refer to the memory.

Deleting an area, whether explicitly through `delete_area()`, or because your application quit, never affects the status of other areas that were cloned from it.

The Kernel Kit Table of Contents | The Kernel Kit Index

The Be Book,
...in lovely HTML...
for BeOS Release 5.

Copyright © 2000 Be, Inc. All rights reserved..