Writing drivers in C++

Local static variables with dynamic initialization

Do not use local static variables that have dynamic initialization expressions within a C++ device driver, especially for SCO SVR5 2.X. This refers to constructs such as the following, where the initializing expression must be computed at runtime.

   int f();        /* DO NOT USE IN C++ DEVICE DRIVERS */

void g() { static int i = f(); }

An initial expression of a constant, such as 22 is, however, acceptable.

This restriction is necessary because such constructs need protection in multithreaded contexts; the second thread through the function must not be allowed to read the variable until the first thread through has initialized it, and the kernel environment in which device drivers operate is a multithreaded context. However, if you are sure that a function will only be executed within a single-threaded context, such as when a lock always protects calls to the function, it is safe to use this construct.

In SCO SVR5 2.X, the compiled code for this construct is not thread-safe and so cannot be used in a driver context.

In SVR5, the compiled code is thread-safe if compiled with CC -Kthread, but it uses a runtime interface in that relies on the user-level threads library, which is not available to kernel-level code. Drivers that must use this construct can code a replacement for the following C++ runtime support routine:

   extern "C" int __static_init_wait(int* addr_guard_variable)
           The generated code sets up a guard variable for a local static
           object, with two bits defined:  the low-order 'done bit' and the
           and the next-low-order 'busy bit'.

This routine is passed the address of the guard variable. It then loops on the decision table shown below. ... }

Done Busy Decision Notes
0 0 return 1 in %eax reset due to exception in initialization;
will not happen in driver
1 1 return 0 in %eax no longer busy
0 1 continue to wait still busy
1 0 internal error should not happen

© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005