January 24, 1995 Technical note on configuring the QNX 4.22 Process manager ========================================================== (A special note of thanks to Andrew Edgar for his contibutions to this technical note.) Currently QNX 4.22 has a hard limit on the number of processes, proxies and virtual circuits that may be allocated at one time on a given node (CPU). In QNX 4, process slots are consumed by real processes (executable programs) and also by proxies (asynchronous messenger processes), remote proxies (proxies connected to another node), and by virtual-circuits (virtual process ids). Hence, a system, which in its fully configured state required 160 processes, 30 proxies and 140 virtual-circuits, would require 330 process slots. As a direct result of the fact that the QNX 4.22 32bit process manager is actually a small model 16bit program (64K code and 64K data), the number of processes it can manage is limited. The rule the process manager uses is as follows: ------------------------------------------------ You are not allowed more than 400 process slots. You are not allowed more than 250 executables (real processes). If you are configured for more than 300 process slots and also for 250 executables then the number of executables is reduced by the number of process slots less 300. The code fragment within the process manager is: if (num_slots > 400) num_slots = 400; if (num_procs > 250) num_procs = 250; if (num_slots > 300 && num_procs == 250) num_procs -= num_slots - 300; If you execute the "sin info" command you will see three heap values: heapp, heapf and heapl. The heapp value is the process manager's process heap (the amount of memory remaining in its primary data segment). The process heap is the most precious resource in a large QNX 4.2x system. The heapf value is the amount of file-descriptor (FD) space remaining. The FD heap has a memory segment to itself (up to a maximum of 64K). Each FD consumes 16 bytes, hence the maximum number of FDs allowed by QNX is 4096 (16 * 4096 = 65536). The heapl value is the amount of LDT space remaining. The LDT heap also has a memory segment to itself, each LDT entry consumes 8 bytes of LDT heap (heapl) and 4 bytes of process heap (heapp) at runtime. The process manager knows the maximum number of LDT entries at initialization time and allocates the appropriate amount of LDT heap, 8 bytes per LDT entry at initialization time (you would need 8192 LDT entries to max out the LDT heap). Curiously the LDT heap is also used by GDT entries (sort of). The process manager allocates 8 bytes per GDT entry out of the LDT heap at initialization time. If this would starve the LDT heap, then some more system memory is allocated to the LDT heap (in 4K chunks). Each GDT entry uses 12 bytes of process heap at runtime. Processes: ---------- Using the Proc command line syntax of "-p SSS,PPP" lets us specify the total number of process slots and the number of processes allowed in the system. Where is total number of process slots (processes, proxies, virtual-circuits and remote proxies) and is the maximum number of real processes (executables) allowed. Each process slot () consumes 110 bytes of process heap at init time. Each real process slot () consumes 134 bytes of process heap at init time. For example specifying "-p 200" would allocate 200 process slots of 134 bytes each, consuming a total of 26800 bytes of process heap. Specifying "-p 300,200" would allocate 200 real process slots of 134 bytes each and 300-200 process slots of 110 bytes each, for a total heap consumption of 200 * 134 + 100 * 110 = 37800 bytes. Registered names: ----------------- Each registered name requires 6 bytes of process heap at init time and 8 + ((nameLength / 4) * 4) bytes of process heap space (heapp) at runtime. Name length Bytes required 4-7 12 8-11 16 12-15 20 ... 28-31 36 So 50, 16 byte registered names would consume (50 * 6) + (50 * (8 + 16)) bytes of heap, which equals 1500 bytes. Timers: ------- Timers use 26 bytes of heap at init time and none at run time. So 50 timers would consume 1300 bytes. How to tune your QNX 4.22B OS image for maximum heapp availability: ------------------------------------------------------------------- 1> Reduce the amount of prefix space being allocated (use filesystem hard or symbolic links wherever possible). 2> Reduce process slots to the minimum acceptable value "-p " (each saves 134 bytes). 3> Reduce real processes to the minimum acceptable value "-p ," (each saves an additional 24 bytes and strlen(process_path) per process). 4> Reduce maximum number of names (each saves 6 + 8 + strlen(name) bytes). 5> Reduce maximum number of sessions. 6> Reduce maximum number of timers. 7> Don't use lots of GDT entries and if you have a very large 16 bit program, port it to 32bit. Other factors of which to take note: ------------------------------------ The prefix space (option -r) cannot be set to more than 2048 bytes (2K), the OS will limit it to 2K without notice. Each virtual-circuit (VC) created in the system will use a minimum of 4K of system memory, one page (in the 32bit version of the OS only). As a final note, a further 16 * num_procs bytes of system memory can be saved by disabling process time accounting with the "-a" option. This option does not save any process heap so for the 4 or 8 K of space it might save, it is of dubious value. An example Proc32 configuration could be : ------------------------------------------ Proc32 -l1 -b -d32 -f 8 256 4096 -m300 -n50 -p100 -r2048 -s32 -t50 -T20 Uses 32*2 + 300*2 + 50*6 + 100*134 + 2048 + 32*51 + 50*26 = 19344 bytes of heapp at init time. The 20K of trace buffer is allocated out of system memory, not out of the heap. The "sin info" command reported 36756 bytes of heapp available after booting and running these commands: sys/Proc32 sys/Slib32 /bin/Fsys /bin/Fsys.aha4scsi idle //63/bin/Dev //63/bin/Dev.con //63/bin/Dev.ser These commands used the following runtime resources: Name LDTs GDTs Proxies Timers Names(bytes) (bytes) Proc32 10 4 8 1 Slib32 10 2 1 1(10) Fsys 9 14 2 1 1(8) Fsys.aha4scsi 18 8 2 1 idle 4 1 Dev 12 22 2 Dev.con 16 12 1 Dev.ser 16 6 sin 12 2 --- --- --- --- --- ------ total 107 71 9 8 2 2 bytes 107 284 108 128 0 18 Total runtime heapp utilization: 661 Thus the total heapp utilization at this point is 19344 + 661 = 20005 bytes. The process manager was configured with a 64K heap, hence, 65536 - 20005 (used) - 35756 (free) = 8775 bytes used internally by the process manager itself.