What Is a Resource Manager?

In general terms, a resource manager is a process that registers a name in the filesystem name space. Other processes use that path to communicate with the resource manager.

To give the QNX Neutrino RTOS a great degree of flexibility, to minimize the runtime memory requirements of the final system, and to cope with the wide variety of devices that may be found in a custom embedded system, the OS allows user-written processes to act as resource managers that can be started and stopped dynamically.

Resource managers are typically responsible for presenting an interface to various types of devices. This may involve managing actual hardware devices (like serial ports, parallel ports, network cards, and disk drives) or virtual devices (like /dev/null, a network filesystem, and pseudo-ttys).

In other operating systems, this functionality is traditionally associated with device drivers. But unlike device drivers, resource managers don't require any special arrangements with the kernel. In fact, a resource manager runs as a process that's separate from the kernel and looks just like any other user-level program.

The kernel (procnto) is itself a resource manager; it handles /dev/null, /proc, and several other resources in the same way any other process handles them.

A resource manager accepts messages from other programs and, optionally, communicates with hardware. It registers a pathname prefix in the pathname space (e.g., /dev/ser1), and other processes can open that name using the standard C library open() function, and then read() from, and write() to, the resulting file descriptor. When this happens, the resource manager receives an open request, followed by read and write requests.

A resource manager isn't restricted to handling just open(), read(), and write() calls; it can support any functions that are based on a file descriptor or file pointer, as well as other forms of IPC.

Adding resource managers in QNX Neutrino won't affect any other part of the OS—the drivers are developed and debugged like any other application. And since the resource managers are in their own protected address space, a bug in a device driver won't cause the entire OS to shut down.

If you've written device drivers in most UNIX variants, you're used to being restricted in what you can do within a device driver; but since a device driver in QNX Neutrino is just a regular process, you aren't restricted in what you can do (except for the restrictions that exist inside an ISR).

Note: In order to register a prefix in the pathname space, a resource manager must have the PROCMGR_AID_PATHSPACE ability enabled. In order to create a public channel (i.e., without _NTO_CHF_PRIVATE set), your process must have the PROCMGR_AID_PUBLIC_CHANNEL ability enabled. For more information, see procmgr_ability() in the QNX Neutrino C Library Reference.

For example, a serial port may be managed by a resource manager called devc-ser8250, although the actual resource may be called /dev/ser1 in the pathname space. When a process requests serial port services, it does so by opening a serial port (in this case /dev/ser1).

fd = open("/dev/ser1", O_RDWR);
for (packet = 0; packet < npackets; packet++)
{
    write(fd, packets[packet], PACKET_SIZE);
}
close(fd);

Because resource managers execute as processes, their use isn't restricted to device drivers; any server can be written as a resource manager. For example, a server that's given DVD files to display in a GUI interface wouldn't be classified as a driver, yet it could be written as a resource manager. It can register the name /dev/dvd and as a result, clients can do the following:

fd = open("/dev/dvd", O_WRONLY);
while (data = get_dvd_data(handle, &nbytes))
{
    bytes_written = write(fd, data, nbytes);
    if (bytes_written != nbytes)
    {
        perror ("Error writing the DVD data");
    }
}
close(fd);