Kernel and process manager
Interrupt handling
Interrupt Service Routines (ISRs) are no longer supported. Instead, QNX has a new mechanism for attaching threads to interrupts: Interrupt Service Threads (ISTs).
If you are using events, there is currently no need for you to update your code to use ISTs. However, to increase efficiency and control, you should consider migrating to explicit threads in the future.
- InterruptAttachEvent()
- InterruptAttachEventPriority()
- InterruptDetach()
- InterruptDisable()
- InterruptEnable()
- InterruptLock()
- InterruptMask()
- InterruptUnlock()
- InterruptUnmask()
- InterruptWait()
- InterruptAttach()
- InterruptAttachArray()
- InterruptHookIdle2()
- InterruptHookTrace()
The new InterruptAttachThread() function allows you to attach a thread to an interrupt source.
Processes only need the PROCMGR_AID_INTERRUPT ability to attach to interrupts. The PROCMGR_AID_INTERRUPTEVENT ability is discontinued.
For more information, see InterruptAttachEvent()
and related entries in the
QNX OS
C Library Reference.
procnto*
Specifying locked abilities
By default, calls to procmgr_ability() that specify locked abilities do not fail. This behavior prevents processes from failing because abilities are being controlled outside of a process (e.g., using a security policy). In previous releases, you had to specify -bl to set this behavior. Specify -b~l to revert to the previous behavior.
Changing the clock period
Changing the clock period at runtime using ClockPeriod() is no longer supported. Instead, use the new procnto-smp-instr option -C.
Superlocking
The kernel is now superlocked by default. Don't use any of the proctno -m options that relate to superlocking. For more information, go to the procnto* entry in the QNX OS Utilities Reference.
Lazy stack allocation
On-demand lazy stack allocation is disabled: the procnto -n option is now ignored.
Reserved higher priority levels
- Priority 255 is reserved explicitly for interprocessor interrupts (IPIs).
- Priority 254 is, by default, reserved for the clock Interrupt Service Thread(IST) but can be configured via the procnto -C option.
SIGDOOM signal
A new procnto signal notifies processes when they have exhausted resources. When a process cannot allocate the required memory to respond to an event (page fault, timer, etc.), procnto sends it a SIGDOOM. By default, this signal causes the process to terminate, but it can be ignored instead. If a signal handler is allowed to be associated with this signal, then the kernel must ensure that a recursive delivery always terminates the target process.
PROCMGR_AID_XTHREAD_THREADCTL ability
The PROCMGR_AID_XTHREAD_THREADCTL ability is discontinued. ThreadCtlExt() and ThreadCtlExt_r() no longer need it.
Clocks and timers
Clock tick and granularity
The procnto system process is now tickless by design, with per-CPU hardware timers firing on demand at the next event of interest.
System clocks (e.g., CLOCK_MONOTONIC and CLOCK_REALTIME) now report time at hardware-level granularity rather than at system-tick granularity. There is no periodic clock tick interrupt on CPU 0.
The qtime data structure nsec field is now obsolete. New APIs are provided to read hardware-level granularity: clock_gettime_ns(), clock_gettime_mon_ns(), clock_gettime_rt_ns().
Per-core timers
The system now uses hardware timers on each core. Software timers fire on the core on which they were running when they were armed.
Timer precedence
High-resolution timers (HRTs) now have precedence over standard timers that are set to fire at the same time.
Event tracing
For tracing, events are captured independently on each CPU. A program that captures trace
events must have a thread bound to each CPU calling
TraceEvent(_NTO_TRACE_WAITBUFFER)
to capture all events. The set of calls
that must be made to initiate event capture has changed. To capture trace events, programs
only need the TRACE ability; the MEM_PHYS, INTERRUPT and
IO abilities are not required.
ThreadCreate()
ThreadCreate() now must be passed a pre-allocated stack. The pthread_create() function is not affected because it allocates a stack on behalf of the caller, if needed.
libmq
Because message queues are now implemented by the kernel, libmq is no longer supported.
pthread_rwlockattr_getclock(), pthread_rwlockattr_setclock()
The pthread_rwlockattr_getclock() and pthread_rwlockattr_setclock() functions have been replaced with POSIX functions pthread_rwlock_clockrdlock() and pthread_rwlock_clockwrlock().
MsgKeyData()
The MsgKeyData() function is no longer supported.
Persistent threads
Persistent threads are no longer supported.
Receive ID data type
Receive IDs are of type rcvid_t (64-bit signed), instead of int (32-bit signed). Anything that saves or otherwise deals with a receive ID for later comparison needs to save it as rcvid_t.
Save and compare (e.g., in the case of an io_funcs.unblock handler) does not work if you compare a saved 32-bit rcvid to a 64-bit ctp->rcvid value.
For code that needs to compile for QNX SDP 8.0 as well as for previous versions, you can integrate this change by changing the variables that deal with receive IDs to type rcvid_t, and adding the following directive prior to making use of the rcvid_t type.
#ifndef __RCVID_T_SIZE
typedef int rcvid_t;
#endif
Thread runmasks
Updating the runmask or inherit mask is permitted only on the active thread.
A runmask must match a cluster that represents one or more processors. You define clusters at boot time.
- A single cluster that encompasses all processors.
- A per-processor cluster (i.e., a cluster with just one participating processor).
You can define additional clusters using the new startup program option -c.
Unregistered events
Events that are delivered to a process by a different process must be registered. QNX SDP 8.0 does not support the delivery of unregistered events by other processes, either through the _NTO_COF_UNREGEVENTS connection flag, or through the procnto-* option -U.
Synchronization primitives sharing
Shared synchronization primitives such as mutexes, semaphores, condvars, barriers, and read-write locks are no longer shareable among processes by default. To be shareable, they must be initialized explicitly with PTHREAD_PROCESS_SHARED. To share a synchronization object, processes must also share the memory in which it resides.