6    Development Environment Notes

This chapter contains notes about issues and known problems with the development environment software and, whenever possible, provides solutions or ways to avoid the problems. The following topics are discussed:

6.1    General Programming

The following notes apply to general programming.

6.1.1    Change to bcopy, bcmp, and bzero

The argument types for the bcopy, bcmp, and bzero system functions have been changed to conform to the ANSI specification. The new interface prototypes are as follows:

int bcmp __((const void *, const void *, size_t);
int bcopy __((const void *, void *, size_t);
int bzero __((void *, size_t);

You can access the old prototype definitions by compiling applications using the -D__V40_OBJ_COMPAT compile flag. For example:

> cc -D__V40_OBJ_COMPAT test.c

6.1.2    Change to struct utmp, struct utmpx, and struct lastlog

To bring them into compliance with several UNIX and Internet standards, the struct utmp, struct utmpx, and struct lastlog structures were updated in Version 5.0. These changes affect the /usr/include/utmp.h, /usr/include/utmpx.h, and /usr/include/lastlog.h file.

6.1.3    The getaddrinfo() Routine Might Return the Incorrect Return Status

Under the following circumstances, the getaddrinfo() routine returns an incorrect status to the application:

To avoid these problems, check the res pointer to make sure that it is valid.

6.1.4    Time Zone Environment Variable Setting

If the TZ environment variable is set to : (colon), as in TZ=:, either on the command line or via a putenv() call, the data for the default time zone (GMT), used by time-related libc functions (such as tzset(), mktime(), and localtime()), is not loaded as it should be. A setting of TZ=: might result in programs producing empty time zone abbreviations or using time zone data that is erroneously consistent with a previous time zone used by the same program. It might also lead to errors from the mktime() function when valid input is supplied.

The TZ=:pathname syntax and other TZ formats continue to work correctly. Only the TZ=: syntax is affected.

In this release, setting the TZ environment variable to either TZ=:Etc/GMT or TZ=GMT0 produces the same behavior as the TZ=: setting.

6.2    POSIX Threads Library (pthreads)

DECthreads has been renamed the POSIX Threads Library. Compaq has made enhancements to the library to improve the performance of some classes of threaded applications.

The following notes apply to the POSIX Threads Library.

6.2.1    pthread_mutex_destroy() Can Return EBUSY for Unlocked Mutex

One of the possible return status values of the POSIX Threads Library routine pthread_mutex_destroy() is EBUSY. Normally, this indicates that the mutex to be destroyed is currently locked or in use. Attempting to destroy a locked or in-use mutex is an application error.

Under certain timing conditions, pthread_mutex_destroy() can erroneously return EBUSY when the mutex is unlocked or unused. In such cases, the mutex is not destroyed. If the application detects the EBUSY return status, the call can be repeated. Subsequent call may succeed, or may fail with EBUSY again. Eventually the call should succeed. If the call is not successfully repeated, a small amount of memory will be leaked.

6.2.2    Problems with Use of the stackaddr Thread Creation Attribute

Using the stackaddr thread creation attribute, which allows you to allocate your own stack for a thread, is not recommended. The semantics of this attribute are poorly defined by POSIX and the Single UNIX Specification, Version 2. As a result, code using the attribute is unlikely to be portable between implementations. The attribute is difficult to use reliably, because you must, by intimate knowledge of the machine architecture and implementation, know the correct address to specify relative to the allocated stack. The implementation cannot diagnose an incorrect value because the interface does not provide sufficient information. Using an incorrect value might result in program failure, possibly in obscure ways.

Alternatively, if you want to supply your own thread stacks, consider using the pthread_attr_setstackaddr_np() routine. Callers specify the thread stack using a base address and size, which avoids the worst problems with the standard interface.

6.2.3    Memory Alignment Issue

Although older Alpha processors (prior to the 21264 chip) can only access memory in units of at least a quadword (8 bytes), multiple variables, each of which is less than 8 bytes, can occupy the same quadword in memory. In such cases, multithreaded programs might experience a problem if two or more threads read the same quadword, update different parts of it, then independently write their respective copies back to memory. The last thread to write the quadword overwrites any data previously written to other parts of the quadword. This can happen even though each thread protects its part of the quadword with its own mutex.

The Tru64 UNIX C compiler protects scalar variables against this problem by aligning them in memory on quadword (8-byte) boundaries. However, in composite data objects such as structures or arrays, the compiler aligns members on their natural boundaries. For example, a 2-byte member is aligned on a 2-byte boundary. Because of this, any adjacent members of the composite object that total 8 bytes or less could occupy the same quadword in memory.

Inspect your multithreaded application code to determine if you have a composite data object, in which adjacent members could share the same quadword in memory. If you do and if your project allows, it is recommended that you force alignment of each such member variable to a quadword boundary by redefining the variable to be at least 8 bytes, or by defining sufficient padding storage after the variable to total 8 bytes.

Alternatively, you can create one mutex for each composite data object in which adjacent members can share the same quadword in memory. Then use this single mutex to protect all write accesses by all threads to the composite data object. This technique might be less desirable because of performance considerations.

For more information, see the Granularity Considerations section in the Guide to the POSIX Threads Library.

6.2.4    POSIX Threads Library pthread_debug() and pthread_debug_cmd() Routines

In order to allow for the possibility of a more comprehensive and robust threads debugging environment, it has become necessary to remove the pthread_debug() and pthread_debug_cmd() routines. To prevent existing binaries from failing, the routines will continue to be recognized. However, a call to either routine now results in an immediate return to the calling program. The pthread_debug_cmd() routine returns a 0 (zero) indicating success. Debuggers such as Ladebug and TotalView provide functionality formerly provided by these routines.

6.2.5    Process-Shared Synchronization Objects and Debugging

The POSIX Threads Library (pthread) interface now supports the sharing of certain synchronization objects (mutexes, condition variables, and read-write locks) among threads running in multiple cooperating processes. Such objects are termed process-shared objects.

For this release, process-shared objects are not visible to the Ladebug debugger. For example, the show mutex Ladebug command lists process-private mutexes but not process-shared mutexes.

6.2.6    Use of errno

The initial or default thread in a multithreaded application uses the global errno cell instead of a perthread errno.

Starting in Version 5.1, use of the global errno cell by threads other than the initial thread (for example, by calling nonthreadsafe or incorrectly compiled code that uses an errno symbol) will corrupt the initial thread's value.

Properly compiled or existing binaries using the POSIX Threads Library will not be affected by this change.

6.3    Kernel Programming

The following notes apply to kernel programming.

6.3.1    System Call Funneling

If you are a kernel developer who implements or maintains a third-party kernel module that "patches in" its own system call handler, and if that handler needs to be funneled (have its execution restricted to the primary CPU), then you will need to add the funneling hooks into the handler function. Add a call to unix_master() at the start of the handler and a call to unix_release() at the end of the handler.

6.3.2    Changes to the ATM Kernel Programming Interface

To support features needed for point-to-multipoint virtual circuits (VCs) and to provide for future enhancements, the parameters to the atm_cmm_register_cvg() and atm_cmm_register_sig() routines have been changed.

Binary compatibility with previously compiled modules has been maintained. Convergence and signaling modules require minor source code changes when recompiled under Tru64 UNIX Version 5.1A.

See the Asynchronous Transfer Mode manual for more information.

6.3.3    Changes to the Internal Kernel Exception Frame

The kernel's exception frame format has been reduced in size from 264 to 256 bytes by eliminating an unused 8-byte quadword that had been used to save the stack pointer register value. Because this register layout is used solely for exceptions taken on a kernel stack, this change causes no impact to applications. However, if you need to display the contents of an exception frame when debugging a kernel crash dump, you now will need to interpret the data in its new 32-register format.

6.3.4    Changes to the VFS Programming Interface

The VFS namecache is now replicated across processors to provide lower overhead and better scalability. If you are developing third-party file systems, you must be aware of the synchronization requirements with the VFS namecache. Specifically, if you are going to delete or rename files, use the cache_purge() kernel call on the file. The namei() kernel call removes the entry from its own namecache only (when called with the DELETE or RENAME flag). The cache_purge() kernel call invalidates the entry in all namecaches. Additionally, when renaming files, use the cache_purge() kernel call on the existing target entry before you add the new name entry to the directory.