Allocating and Using Shared Memory Blocks



next up previous
Next: Choosing a GUI Up: A Real-Time Phase Vocoder Previous: Choosing a Paradigm

Allocating and Using Shared Memory Blocks

Upon startup, Prism has to allocate and set up a shared memory block, then fork off the process to generate the audio output. The routines it uses are documented in the shmop(2) manual pages. Enough memory is allocate to hold a control structure and all of the spectral data produced by the analysis program (Figure 2).

  
Figure 2: Allocating shared memory blocks

Prism calls shmget(2) to allocate the required amount of memory, which returns a handle to the memory block for subsequent use. The other parameters specify the access permissions in the normal chmod(1) format, and that the block should be created if it does not yet exist. The process then forks, with the child being responsible for synthesis, and the parent for control functions.

After the fork(2) call, both the parent and the child processes must attached to the shared memory block and cause it to appear in their respective memory spaces. The appropriate system call is shmat(2). The parameters indicate the handle of the shared memory block, and the desired target address. Passing NULL as the latter tells the system to make the choice of address for itself: in Linux running on an i386 architecture, the blocks are allocated downwards in memory starting at an address of 1.5GB. This call can be made once before the fork system call, as the shared block will then appear in both the child's and parent's memory space.

There is one easy trap to catch the unwary programmer using shared memory blocks: shared memory blocks are persistent! If your application crashes without tidying up shared memory blocks properly, memory will leak like a sieve. The user can check for any undeleted memory blocks using the ipcs(1) command, and remove them with ipcrm(1). Prism does its best to cope with any unexpected events by catching the SEGV signal, and shuts down any shared memory activity before exiting. However, the best safeguard against memory leaks is to mark the shared memory block for deletion as soon as it is created. Counter-intuitively, the way to do this is to mark the block as transient using the shmctl(2) call, and then detach the process from the shared memory block. The shared memory block will persist until all the processes using it detach using the shmdt(2) call, so the block will disappear automatically when the parent and child processes exit.



next up previous
Next: Choosing a GUI Up: A Real-Time Phase Vocoder Previous: Choosing a Paradigm



N J Bailey
Tue Oct 13 17:55:45 BST 1998