SGI IRIX to Compaq Tru64 UNIX Porting Guide
Tru64 UNIX Version 5.0 or higher, October 1999

© Compaq Computer Corporation 1999. All rights reserved.


This book presents information about porting applications from IRIX® to the Compaq Tru64(TM) UNIX® (formerly DIGITAL UNIX) operating system.

Part Number: 1129-1199A-WWEE


COMPAQ, the Compaq logo, and the Digital logo are registered in the U.S. Patent and Trademark Office.

Microsoft and Windows NT are registered trademarks of Microsoft Corporation. Intel, Pentium, Intel Inside, and IA-64 are registered trademarks of Intel Corporation. The following are third-party trademarks: Sun, Solaris, Java, and NFS are trademarks, registered trademarks, or service marks of Sun Microsystems, Inc., in the United States and other countries. SPARC is a trademark or registered trademark of SPARC International, Inc., in the United States and other countries. HP, HP-UX, and PA-RISC are registered trademarks of Hewlett-Packard Company. AIX, IBM, RISC System/6000, and RS/6000 are trademarks or registered trademarks of International Business Machines Corporation. IRIX is a registered trademark and SGI is a trademark of Silicon Graphics, Inc., in the United States and other countries. MIPS is a trademark or registered trademark of MIPS Technologies, Inc., in the United States and other countries. OpenServer, UnixWare, and SCO are trademarks or registered trademarks of The Santa Cruz Operation, Inc, in the United States and other countries. Open Software Foundation, OSF, OSF/1, OSF/Motif, and Motif are trademarks of the Open Software Foundation, Inc. UNIX is a registered trademark in the United States and other countries, exclusively licensed through X/Open Company, Ltd. Other product names mentioned herein may be the trademarks of their respective companies.

Possession, use, or copying of the software described in this publication is authorized only pursuant to a valid written license from Compaq Computer Corporation or an authorized sublicensor.

Compaq Computer Corporation shall not be liable for technical or editorial errors or omissions contained herein. The information in this document is subject to change without notice.


Table of Contents

  1. Introduction
    1. Porting Overview
    2. IRIX Software Version
    3. Porting and Coding Practices
    4. Porting Tools
    5. Porting Services
  2. Comparing IRIX and Tru64 UNIX
    1. Overview of Tru64 UNIX
    2. Directories and Defines
      1. Directory Hierarchies
      2. Defines for Numeric Values
    3. 64-Bit Considerations
      1. C Language Data Types
        1. Data Access
        2. Data Access Synchronization
      2. Pointers
      3. Constants
        1. Truncation of Longs
        2. Bit Shifts
      4. Variables
      5. Structures
        1. Size
        2. Member Alignment
        3. Structure Alignment
        4. Unions
        5. Bit Fields
      6. Library Calls and Operators
    4. File System
    5. Endian Issues
      1. Unions
      2. Initializing Multiword Entities in 32-Bit Chunks
      3. Unused Bytes
      4. Hex Constants Used as Byte Arrays
      5. Data Transfer
    6. Write-to-Memory Operations and Memory Barriers
  3. The Porting Process
    1. Porting Guidelines
    2. Porting Procedures
      1. Look for Potential Problems
        1. Use the grep Command
        2. Use lint -Q
      2. Compile the Code and Save Compiler Messages
      3. Fix Problems Identified at Compile Time
      4. Fix Alignment and Padding
    3. Porting Suggestions
      1. Techniques for Finding Problems in Partially Working Code
      2. Hints for dbx
    4. Porting Assistant
  4. Application Development Environment
    1. Software
    2. C Preprocessor
    3. C Compiler
      1. Features of the DIGITAL UNIX C Compiler
      2. Support for Interfaces and Definitions
      3. Compilation Flags for Hardware Architectures
      4. Compilation Flags for Checking Code Portability
      5. Compilation Flag for 32-Bit Pointers
      6. Call Conventions for Passing Arguments
    4. Linker (ld)
    5. C++
    6. The lint Program Checker
    7. Debugging Tools
    8. System V Compatibility
      1. System V Habitat
      2. Extended System V Compatibility
        1. System V Environment
        2. Extended System V Compatibility In Tru64 UNIX Version 5.0
    9. Other Programming Tools
    10. The make Command
      1. The makefile Search Path
      2. Flags
      3. Implementation of make Rules
      4. Pseudotargets and make Directives
      5. Dynamic Macros
    11. Header Files
    12. Shared Libraries Provided by Tru64 UNIX
      1. DIGITAL UNIX Archive Libraries
      2. Using Shared Libraries
  5. Porting Assistant
    1. What It Does
      1. Code Checking
      2. Diagnostic Messages
      3. HyperHelp on Porting
      4. Code Correction
      5. Linker Assistance
    2. How to Use It
      1. Getting Started
      2. Performing Checks
        1. Run the Check
        2. Step Through the Source Code
        3. Make the Correction
        4. Repeat the Process
    3. Possible Limitations
  6. Porting Threaded Applications
    1. Porting Applications That Use POSIX Threads
      1. Porting Applications That Use Read-write Locks
    2. Programming Notes
      1. Assumptions About Deadlock Conditions
      2. Memory Alignment Considerations
      3. DECthreads Extensions
    3. Files
      1. Include Files
      2. Shared Libraries
    4. Linking
    5. Compiling
    6. Debugging
      1. Ladebug Debugger
      2. Visual Threads
  1. Transferring Data
  2. Resources on the Internet

Figures

Figure 2-1 Tru64 UNIX Directory Hierarchy

Figure 2-2 Byte and Bit Ordering on Alpha Systems

Tables

Table 2-1 Contents of the Tru64 UNIX Directories

Table 2-2 Defines from limits.h and float.h

Table 2-3 C Language Data Types

Table 2-4 Natural Data Alignment

Table 2-5 32-Bit and 64-Bit Values of Constants

Table 2-6 Structure Alignments

Table 4-1 Software Subsets

Table 4-2 Call Conventions for Argument Passing

Table 4-3 Software for System V Environments

Table 4-4 DIGITAL UNIX Programming Tools

Table 4-5 The makefile Search Path

Table 4-6 Flags to the make Command

Table 4-7 Directives and Pseudotargets

Table 4-8 DIGITAL UNIX Standard Header File Directories

Table 4-9 Shared Libraries in /usr/shlib

Table 4-10 Shared Libraries in /usr/shlib/X11

Table 6-1 IRIX and Tru64 UNIX pthread Routines

Table Table A-1 Data Conversion Keywords


Preface

Back to Table of Contents

This guide provides information about porting applications from the IRIX® operating system to the Compaq Tru64(TM) UNIX® (formerly DIGITAL UNIX) operating system. This guide also describes differences between Tru64 UNIX Version 5.0 and IRIX.

Audience

This guide is for software engineers, application developers, and system managers who are considering moving software applications from IRIX to Tru64 UNIX.

The guide assumes that you have software development experience and are familiar with the UNIX operating system and the IRIX operating system.

Structure of This Guide

This guide contains the following chapters and appendices:
 
Chapter 1 Presents the advantages of porting and summarizes the porting process. 
Chapter 2 Gives an overview of Tru64 UNIX and compares the general features of IRIX and Tru64 UNIX. It also discusses issues to consider when porting from IRIX to Tru64 UNIX.
Chapter 3 Discusses the porting process.
Chapter 4 Describes the development environment on the Tru64 UNIX system.
Chapter 5 Describes Porting Assistant, a development environment for programmers porting applications to Tru64 UNIX.
Chapter 6 Presents information on porting threaded applications.
Appendix A Provides information about transferring data between big-endian and little-endian systems.
Appendix B Lists porting resources available on the Internet.
 

Conventions

This document uses the following conventions:
 
% A percent sign represents the Tru64 UNIX system prompt.
% cat Boldface type in interactive examples indicates typed user input.
# A number sign represents the Tru64 UNIX superuser prompt.
File Italic (slanted) type indicates variable values, placeholders, and function 
argument names for Tru64 UNIX commands and functions.
cat UNIX command names are shown in a constant-width typeface.
cat(1) A cross-reference to a reference page includes the appropriate section number in parentheses. For example, cat(1) indicates that you can find information on the cat command in Section 1 of the reference pages.
Ctrl/X This symbol indicates that you hold down the first named key while pressing the key or mouse button that follows the slash.
... In syntax definitions, a horizontal ellipsis indicates that the preceding item can be repeated one or more times.
[] In syntax definitions, items enclosed in square brackets are optional.

Related Documents

The Programmer's Guide is a must for anyone writing or porting applications to Tru64 UNIX.

Other books of particular interest in the Tru64 UNIX documentation set include:

  • Guide to DECthreads

  • Guide to Realtime Programming

  • DEC C Language Reference Manual

  • Compaq Portable Mathematics Library

  • Programmer's Guide: STREAMS (UNIX Press)

  • Programming Support Tools

  • Calling Standard for Alpha Systems

  • Ladebug Debugger Manual

For more information, refer to the following technical publications:
  • Tru64 UNIX Documentation Set

  • Tru64 UNIX SPD (Software Product Description)

  • IRIX Documentation Set

Information on the Internet

You can access Tru64 UNIX documentation and other information on Tru64 UNIX on the web at:

http://www.unix.digital.com/faqs/publications/pub_page/pubs_page.html

The Tru64 UNIX Software Product Description is at:

http://www.digital.com/info/SP7070/

These and other Internet resources for Tru64 UNIX and IRIX can be found in Appendix B.


1 Introduction

Back to Table of Contents

Porting doesn't have to be painful. The process of porting programs from one operating system to another inevitably involves some debugging and recompiling. But programs that adhere to language definitions, avoid nonstandard extensions, and have a minimum of architectural dependencies can run on Tru64 UNIX with few modifications.

Migration Software Systems, Ltd. of San Jose, California, has ported millions of lines of code to Tru64 UNIX on the Alpha architecture. Their comment on the process is instructive: "Porting to DIGITAL UNIX [Tru64 UNIX] can be done with a minimal amount of effort if that code was developed with proper software engineering practices."

This view is echoed in a white paper from the consulting firm D. H. Brown Associates, Inc. In The Uneven Migration to 64-bit UNIX, they write, "Yet, a well structured C or C++ application can be readily ported if it adheres to a few basic principles. These principles mirror generic tenets of good programming style."

When a program does require modifications, it is usually a straightforward process to identify and correct the problems. Almost all such effort involves making the code comply more closely with industry standards.

Code ported to Tru64 UNIX on the Alpha architecture enjoys several advantages:

  • The ported code will run in the mature 64-bit environment that Tru64 UNIX has been providing for more than half a decade.
  • The ported code will run on Alpha systems, which offer the world's fastest processors.
  • In the future, you will have the option of easily migrating the ported code to Tru64 UNIX on Intel's IA-64 architecture.
  • The ported code will adhere closely to industry standards, making it more portable to other architectures and easier to maintain.

1.1 Porting Overview

The porting process is reasonably simple:
  1. Clean up code, removing architectural dependencies and nonstandard practices.
  2. Compile code.
  3. Fix problems found at compile time.
  4. Fix segment faults and unaligned accesses.
    Unaligned accesses are almost always an indication that something is incorrect in the code.
  5. Recompile the code and repeat the process, if necessary.

1.2 IRIX Software Version

The information in this book is based on IRIX 6.5 and earlier versions of IRIX. Even if the application you are porting is based on a newer version of IRIX, most of the content of this book still applies.

1.3 Porting and Coding Practices

Much of the material in this book is not specific to any one vendor, nor is it specific to Tru64 UNIX. It is simply good, standard coding practices. A number of books are available that cover similar ground. Some of the good ones (but certainly not the only good ones) include:
  • The C Programming Language, Second Edition, by Brian W. Kernighan and Dennis M. Ritchie; Prentice-Hall Software Series, Prentice-Hall, Inc.
  • Portable C and UNIX System Programming, by J.E.Lapin; Prentice-Hall Software Series, Prentice-Hall, Inc.
  • C Traps and Pit Falls, by Andrew Koenig; Addison-Wesley Publishing Company

1.4 Porting Tools

Compaq Porting Assistant is a set of integrated software tools designed to help port applications to Tru64 UNIX. It checks for things that are likely to cause porting problems, and it simplifies the process of making needed changes.

See Chapter 5, Porting Assistant, for more information.

1.5 Porting Services

If you do not want to take on the task of porting your application yourself, there are resources to help you get the job done.
  • Compaq Computer Corporation has Global Partner Solutions Centers around the world. Contact them at:

    1-800-332-4786

    alpha-developer@digital.com

    Information about the Global Partner Solutions Centers can be found at:

    http://www.partner.digital.com/www-swdev/pages/Home/TEAM/team.html

    The Compaq Solutions Alliance (CSA) program provides services that can be of significant help in migrating software and in using Tru64 UNIX. You can reach them on the web at:

    http://www.compaq.com/csa/Flash_No.html

  • Third-party consulting sources

    Companies such as Migration Software Systems, Ltd. of San Jose, California, can help you to port your existing applications and systems to the Tru64 UNIX environment. Contact Migration Software Systems at 408-452-0527.


2 Comparing IRIX and Tru64 UNIX

Back to Table of Contents

This chapter compares major features of IRIX and Tru64 UNIX. It also describes features available only on Tru64 UNIX. It presents porting issues involving the Alpha architecture and the 64-bit environment. If you are already familiar with Tru64 UNIX, you can skip this material.

2.1 Overview of Tru64 UNIX

The Tru64 UNIX operating system is a 64-bit advanced kernel architecture based on Carnegie-Mellon University's Mach V2.5 kernel design, with components from Berkeley Software Distribution (BSD) 4.3 and 4.4, UNIX System V, and other sources. Tru64 UNIX implements the Open Software Foundation (OSF) OSF/1 R1.0, R1.1, and R1.2 technology, and the Motif graphical user interface and programming environment. Under the X/Open UNIX branding program, Compaq Computer Corporation has received the UNIX 95 brand for the Tru64 UNIX operating system.

Tru64 UNIX provides symmetric multiprocessing (SMP), realtime support, and numerous features to assist programmers in developing applications that use shared libraries, multithread support, and memory-mapped files. All features of the X Window System, Version 11, Release 6.3 (X11R6.3) from the Open Group are fully supported. POSIX standard 1003.1c pthreads are supported.

The Tru64 UNIX operating system complies with numerous other standards and industry specifications, including the X/Open XPG4 and XTI, POSIX, FIPS, and System V Interface Definition (SVID). Tru64 UNIX is compatible with Berkeley 4.3 and System V programming interfaces and conforms with the OSF Application Environment Specification (AES), which specifies an interface for developing portable applications that will run on a variety of hardware platforms.

Familiar User Interfaces and Tools

Tru64 UNIX provides user interfaces familiar to UNIX developers:

GUI:

  • Common Desktop Environment (CDE)
  • X11R6
  • Motif 1.2.5
 

Shells:

  • POSIX shell
  • C shell (csh)
  • Bourne shell
  • Korn shell (ksh)
Editors:
  • vi
  • GNU emacs
  • ed
  • ex
Development Tools

The Developers' Toolkit for Tru64 UNIX provides the following tools:

  • DEC C compiler for Tru64 UNIX

    The DEC C compiler is NIST-validated, conforms to the ANSI X3J11/88-159 C Language Standard (equivalent to ANSI X3.159-1989 and ISO/IEC 9899:1990), and provides IEEE floating-point support conformant with ANSI/IEEE Standard 754.

    It provides support for ANSI, strict ANSI, and Kernighan and Ritchie (K&R)-style programming.

  • C macro preprocessor, cpp

  • Standard C Libraries

  • dbx

  • Ladebug

The following are separately packaged products:

  • Compaq C++

  • Compaq Visual Fortran

  • Compaq Pascal

  • Compaq COBOL

  • Compaq Ada

  • DIGITAL Extended Math Library (DXML)

  • Compaq Portable Math Library (CPML)

  • COHESIONworX

  • DIGITAL KAP preprocessors

Java

  • JDK for Tru64 UNIX

  • Java SDK for Tru64 UNIX

  • Java Runtime Environment for Tru64 UNIX

  • Compaq Fast Virtual Machine (Fast VM) for Tru64 UNIX

Networking

Tru64 UNIX supports a wide range of industry-standard networks:
TCP/IP SysV R4 STREAMS XTI
BSD Sockets DLI BIND
NTP SNMP FDDI
ONC ATM DLB
DCE screend Packetfilter
Fast Ethernet ATM Token Ring
IP Multicast NetWare DNS
TSP LAT LAT/Telnet gateway
PATHWORKS LAN Manager AppleTalk
DECnet    

Data Interoperability

Support for common data formats provides data interoperability:

  • NFS V2 and V3
  • Interchangeable tar formats
  • ISO 9600 CD-ROM file system
  • CDA
For more information about Tru64 UNIX features, see the Technical Overview and the Software Product Description.

The Technical Overview is at:

http://www.unix.digital.com/faqs/publications/pub_page/V50_DOCS.HTM

The Software Product Description is at:

http://www.digital.com/info/SP7070/

2.2 Directories and Defines

Among the differences between IRIX and Tru64 UNIX are the layout of the directories and the values associated with some of the standard defines.

2.2.1 Directory Hierarchies

The hierarchies of system directories differ between IRIX and Tru64 UNIX. Figure 2-1 shows the Tru64 UNIX directory structure.

Figure 2-1 Tru64 UNIX Directory Hierarchy

Figure of Tru64 UNIX Directory Hierarchy

Table 2-1 describes the contents of the Tru64 UNIX directories.

Table 2-1 Contents of the Tru64 UNIX Directories

Directory Description
/ The root directory of the file system
/dev Block and character device files
/etc System configuration files and databases; nonexecutable files
/sbin Commands essential to boot the system; these commands do not depend on shared libraries or on the loader and can have other versions in /usr/bin or /usr/sbin
/sbin/init.d System initialization files
/sbin/rc0.d The run control files executed for system-state 0 (single-user state)
/sbin/rc2.d The run control files executed for system-state 2 (nonnetworked multiuser state)
/sbin/rc3.d The run control files executed for system-state 3 (networked multiuser state)
/sbin/subsys Loadable kernel modules required in single-user mode
/lost+found Files recovered by fsck
/usr Most user utilities and applications

Most commands in /usr/bin, /usr/sbin, and
/usr/lbin have been built with the shared version of libc and will not work unless /usr is mounted.

/usr/.smdb. Subset installation control files used by setld
/usr/bin Common utilities and applications
/usr/ccs C compilation system; tools and libraries used to generate C programs
/usr/examples Source code for example programs
/usr/opt Optional application packages, such as layered products
/usr/include Program header (include) files

For more information, see Chapter 4, Application Development Environment.

/usr/lib Libraries, data files, and symbolic links to library files located elsewhere; included for compatibility
/usr/lbin Back-end executable files
/usr/sbin System administration utilities and system utilities
/usr/share Architecture-independent ASCII text files

This directory includes word lists, various libraries, and online reference pages.

/usr/sys Directories that contain system configuration files
/usr/shlib Binary loadable shared libraries; shared versions of libraries in /usr/ccs/lib
/opt Optional application packages, such as layered products
/var Multipurpose log, temporary, transient, varying, and spool files
/var/adm Common administrative files and databases

This directory includes the crash area, files for the cron daemon, configuration and database files for sendmail, and files generated by syslog.

/var/spool Miscellaneous printer and mail system spooling directories
/tmp System-generated temporary files that are usually not preserved across a system reboot
/vmunix Pure kernel executable file (the operating system loaded into memory at boot time)
/genvmunix Generic kernel executable file built with most options and device support (useful if vmunix becomes corrupted)
/subsys Files used by the sysconfig utility

2.2.2 Defines for Numeric Values

Some maximum and minimum values assigned to standard defines vary according to system architecture. Table 2-2 shows values for defines in /usr/include/alpha/machlimits.h (Tru64 UNIX) and /usr/include/limits.h (IRIX).

IRIX defines for LONG and ULONG values vary according to whether the code is compiled _MIPS_SZLONG == 32 or _MIPS_SZLONG == 64. Compiling with _MIPS_SZLONG == 64 results in defines with the same values as those in Tru64 UNIX. IRIX code that depends on LONG or ULONG values defined when _MIPS_SZLONG == 32 must be modified.

Table 2-2 Defines from limits.h and float.h

Define

IRIX

Tru64 UNIX

CHAR_MAX

UCHAR_MAX (255U)

127

CHAR_MIN

0

-128

MB_LEN_MAX

5

4

LONG_MAX

2147483647

(_MIPS_SZLONG == 32)

9223372036854775807

LONG_MIN

-2147483647-1

(_MIPS_SZLONG == 32)

(-LONG_MAX-1)

(-9223372036854775807-1)

ULONG_MAX

4294967295U

(_MIPS_SZLONG == 32)

18446744073709551615U

Defines for floating-point values for both IRIX and Tru64 UNIX appear in /usr/include/float.h. By default, the IRIX defines for floating-point values for LDBL (long double) values are defined in terms of the corresponding DBL (double) values. By default, Tru64 UNIX uses different values for long doubles. IRIX code that assumes the IRIX default values for long doubles must be modified, or you can compile the Tru64 UNIX code with the option __X_FLOAT == 1.

2.3 64-Bit Considerations

The

The Alpha architecture is based on a 64-bit microprocessor, and Tru64 UNIX is a 64-bit operating system. These facts introduce a number of extended capabilities beyond 32-bit architectures. For example, 64-bit addressing allows Tru64 UNIX to support file system sizes greater than 2 gigabytes.

When porting a 32-bit application to the 64-bit environment of Tru64 UNIX, you face the same issues you would in porting that application to 64-bit IRIX. This section describes these issues. See SGI's MIPSpro 64-Bit Porting and Transition Guide for a discussion of 64-bit porting issues from the IRIX perspective.

The SGI 64-bit environment supports the LP64 model for native 64-bit programs. This model was pioneered in 1993 by Tru64 UNIX, so if your application is written for a 64-bit environment and follows the LP64 data model, then the only 64-bit considerations in porting the application to Tru64 UNIX might be issues of data and structure alignments. These topics are covered later in this section.

Most porting concerns for applications written for a 32-bit environment are caused by three facts about the 64-bit environment:

  • Pointers are 64 bit, not 32 bit.
  • Long values (long) are 64 bit, not 32 bit.
  • Integer values (int) are 32 bits and not the same size as longs and pointers, as is the case in a 32-bit environment.
Chances are that most code you end up changing incorrectly assumes the following:

     sizeof(int) == sizeof(pointer) == sizeof(long)

2.3.1 C Language Data Types

In the Tru64 UNIX 64-bit environment, long and pointer data types are 64 bits.

Table 2-3 presents Tru64 UNIX data types.

Table 2-3 C Language Data Types

Type

Tru64 UNIX Bits

char

8

short

16

int

32

float

32

pointer

64

long

64

long long

64

double

64

long double

128

Table 2-4 shows the alignment of various Tru64 UNIX data types. Note that long and pointer data types are aligned on 8-byte boundaries.

Table 2-4 Natural Data Alignment

Data Type Alignment (Byte Multiple)
char 4
short 4
int 4
float 4
long 8
pointer 8
long long 8
double 8

With high-level languages, such as C, the compiler automatically attempts to align data and variables to their natural boundaries. In some situations the compiler might lack the information needed to make the correct alignment. Alignment errors can result from misuse of long and pointer data types in structure definitions that are shared between 32-bit and 64-bit systems.

2.3.1.1 Data Access

Older Alpha processors (EV4 and EV5) support only memory access of longwords (32 bits) and quadwords (64 bits). Byte and word accesses are accomplished by multiple instructions that load a longword or quadword, mask, and shift to get the desired entity. The lack of a single, uninterruptible operation for byte and word access has implications both for the performance and the correctness of an application.

Beginning with the 21164a Alpha chip (EV56), the Alpha processor supports direct access of byte and word data types, as well as direct access of longword and quadword data types.

In Tru64 UNIX Version 4.0 and higher, the operating system kernel includes an instruction emulator that allows any Alpha chip to execute and produce correct results from Alpha instructions, even if some of the instructions are not implemented on the chip. Applications that use emulated instructions will run correctly, but might incur significant emulation overhead at run time.

To learn the type of Alpha processor on your system, use the command /usr/sbin/psrinfo -v.

2.3.1.2 Data Access Synchronization

Independently executing applications that access common data must synchronize access to that data. The Alpha architecture mandates that for naturally aligned longwords and quadwords, independent access to adjacent longwords or quadwords produces the same results regardless of the order of instruction execution. No such guarantee exists for char, byte, or word data.

A multithreaded application or multiple processes that access adjacent char, byte, or word data through a common address space must use either thread mutex locking functions or semaphore locks to ensure that access to the data is deterministic. Similarly, such processes using shared memory-mapped files are restricted to semaphore locks to avoid conflicts with access operations to adjacent data items of type char, byte, or word.

A simpler alternative to locking functions or semaphores is to expand byte- or word-length items to longwords.

Longword and quadword data items that are not naturally aligned (low-order 2 bits set to zero for longwords, and low-order 3 bits set to zero for quadwords) incur access penalties similar to those for byte and word access. But typically the compiler takes care of correct alignment for longword and quadword data.

For more information on data alignment and threads, see 6.2.2 Memory Alignment Considerations.

2.3.2 Pointers

Pointers are 64 bits long. Treating pointers as though they are the same size as int values will likely cause unwanted results.

Code to be ported that casts a pointer or quadword (type long or u_long) to an int value results in the upper 32 bits being truncated. If that int value is then cast back to 64 bits, the resulting value is incorrect.

The following summarizes the behavior of 64-bit pointers:

  • Truncation of pointers

    Pointers assigned to int variables are truncated to 32-bit values. Similarly, pointers passed to functions expecting int values are truncated to 32 bits.

  • Assigning integer values to pointers

    Assigning a pointer to an int variable, then assigning the int back to the pointer and dereferencing the pointer can result in a segmentation fault.

  • Subtraction of pointers

    In Tru64 UNIX, the length of the integer required to hold the difference between two pointers to members of the same array is a signed long. This value, ptrdiff_t, is defined in stddef.h.

  • Passing zero to a pointer argument

    Passing zero to a pointer argument when no function prototype is visible results in the use of a 4-byte zero instead of an 8-byte zero (0L). Passing NULL (defined in stdio.h ) results in the desired 8-byte zero (0L).

    Similarly, comparing a pointer to zero does not work. Compare a pointer to NULL instead.

    In cases where the correct function prototype is in scope, standard C promotion rules are in effect, and correct values are assigned in a comparison, an assignment, or a function call.

2.3.3 Constants

Constants can have different values on 32-bit and 64-bit systems. Table 2-5 lists some constants and their values.

Table 2-5 Values of 64-Bit Constants

C Constant Value 32-Bit Value 64-Bit Value
0xFFFFFFFF (232 -1) -1 4,294,967,295
4294967296 232 0 4,294,967,296
0x100000000 232 0 4,294,967,296
0xFFFFFFFFFFFFFFF (264-1) -1 -1

In the following code segment, the expression in the if statement is true in a 32-bit environment but false in Tru64 UNIX:


	long long_val = 0XFFFFFFFF;
	if(long_val < 0)

In Tru64 UNIX, long and unsigned long constants are 64 bit, quadword values. For example:


	sizeof(543210) = 4 bytes
	sizeof(543210L) = 8 bytes
	sizeof(543210UL) = 8 bytes

2.3.3.1 Truncation of Longs

Because longs are 64-bit values, truncation can occur if a long is assigned to an int variable. For example:


	int int_val;
	.
	.
	.
	int_val = 2147483660;

Because of truncation, the value of int_val is -2147483636.

Truncation can also occur if a long value is passed as an argument to a function expecting an int value. For example:


	abs(2147483660) = 2147483636

2.3.3.2 Bit Shifts

A bit-shift operation on an integer constant always yields a 32-bit constant. For example, even though long_val is declared a long, the results of the following operations are 32-bit values:


long_val = 1 << 31 results in long_val = -2147483648

If you need a result of type long, you must use the L or UL suffix for long integer constants. The top 32 bits of value depend on the type of the value shifted. Signed values are sign extended; unsigned values are zero extended. If you want a 64-bit constant, be sure to use the L or the UL suffix. (Note that only the left operand of a shift operator determines the result type. The type of shift count operand is irrelevant.)


long_val = 1L << 31 results in long_val = 2147483648


long_val = 1L << 32 results in long_val = 4294967296

You get similar results by casting to a long. For example, when shifting bytes into a long value, cast each byte to a long; otherwise, the result is only a 32-bit value. The following example results in a 64-bit value. (Assume long_val is a long data type and bp is a pointer to bytes.)


long_val = (((u_long)bp[0] << 56) | ((u_long)bp[1] << 48));

2.3.4 Variables

Variables declared as int are 32-bit entities on both 32-bit systems and in the 64-bit environment of Tru64 UNIX. A variable declared as long (and as pointer) is 64 bits in Tru64 UNIX.

If you have specific variables that need to be 32 bits in size on both Tru64 UNIX and 32-bit systems, define the type to be int. If the variable should be 32 bits on 32-bit systems but 64 bits on Tru64 UNIX systems, define the variable to be long.

2.3.5 Structures

The 64-bit environment can affect both the size and alignment of structures, as described in the following sections.

2.3.5.1 Size

Because pointers and longs are 64-bit values, structures and unions that include pointer or long data types are bigger in size than the same structures and unions on 32-bit systems.

For example, the following structure, TextNode, doubles in size on a 64-bit system because the pointer types are doubled in size from 4 bytes to 8 bytes:


	struct TextNode
	{
	char *text;
	struct TextNode *left;
	struct TextNode *right;
	};

If you are sharing data defined in structures between 32-bit and 64-bit systems, avoid using longs and pointers as members in shared structures.

2.3.5.2 Member Alignment

The compiler ensures that members of structures and unions are aligned on their natural boundaries. Table 2-6 shows the alignments of various data types.

Table 2-6 Structure Alignments

Data Type Alignment
char byte
short word
int longword
long quadword
pointer quadword

This means that the compiler sometimes inserts padding to provide member alignment in structures and unions. On 64-bit Alpha systems, the size of the following structure is 32 bytes--8 bytes for each pointer and 4 bytes of padding after the int member size, so that the pointer left, which follows size, is aligned on a 64-bit boundary:


	struct TextCountNode
	{
	char *text;
	int size;
	struct TextCountNode *left;
	struct TextCountNode *right;
	};

2.3.5.3 Structure Alignment

The compiler aligns structures according to the strictest aligned member. This aids in aligning structure members on their required boundaries. The compiler pads structures to ensure proper alignment. Padding can be added within the structure or at the end of the structure to terminate the structure on the same alignment boundary on which it started.

Because of padding, do not assume that the size of a structure is simply the accumulated size of all of the objects defined in it. The sizeof operator is a safer method for determining structure size.

In some cases, you can minimize the amount of padding needed in a structure by reordering the members.

The following structure is 40 bytes; the compiler adds 4 bytes of padding after each of the members size and count, to maintain alignment of the pointers on 64-bit boundaries:


	struct TextCountNode
	{
	char *text;
	int size;
	struct TextCountNode *left;
	int count;
	struct TextCountNode *right;
	};

By putting the two int members together, the padding is eliminated, and the size of the structure is reduced to 32 bytes:


	struct TextCountNode
	{
	char *text;
	int size;
	int count;
	struct TextCountNode *left;
	struct TextCountNode *right;
	};

2.3.5.4 Unions

Problems arise when the use of a union is based on assumptions such as the following:


sizeof(double) == 2*sizeof(long) or sizeof(long) == 4*sizeof(char)

The following code fragment assumes that an array of two longs overlays a double:


	union double_union {
		double d;
		unsigned long ul[2];
	};

Changing the long to an int fixes the problem:


	union double_union {
		double d;
		unsigned int ul[2];
	};

2.3.5.5 Bit Fields

Bit fields are allowed on any integral type on Alpha systems. (ANSI C requires only bit fields with int, signed int, and unsigned int types.)

In a C declaration, if one bit field immediately follows another in a structure declaration, the second bit field is packed into adjacent bits of the former unit. Because long is 64 bits in length on Alpha systems, consecutive declarations of bit fields of type long might contain multiple bit field definitions in cases that previously did not on 32-bit systems. This change might cause different results in operations on these bit fields.

To ensure the same behavior in operations on bit fields, change bit field definitions of type long to int.

2.3.6 Library Calls and Operators

The 64-bit data types also affect the following library calls and operator:

  • printf() and scanf()

    The conversion specifications for printf() and scanf() have been modified to accommodate the fact that longs and unsigned longs are 64-bit values. There is now a length modifier, l (lowercase letter L), for use with the d, u, o, and x conversion characters to specify assignment of type long or unsigned long.

    For example, %ld prints a long as a signed decimal, and %lu prints a long as an unsigned decimal. If the length modifier is not used, the type is assumed to be int, or unsigned int, depending upon the conversion character.

    The format code %Lf (capital L followed by f) specifies a 128-bit long double type.

  • malloc() and calloc()

    Memory allocation library functions such as malloc() guarantee to return data aligned to the maximum alignment of any object. In the 64-bit Tru64 UNIX environment, malloc() returns a pointer to memory that is at least quadword aligned.

  • lseek()

    The lseek() call takes an argument of type long (off_t) to specify the file offset.

  • fsetpos() and fgetpos()

    The fsetpos() and fgetpos() calls take an argument of type long (fpos_t) to specify the file position.

  • varargs()

    In Tru64 UNIX, va_list is not a char pointer. The formal declaration of va_list is given in va_list.h. See varargs(3) for more information on the use of these macros.

  • sizeof operator

    The result of the sizeof operator is size_t, an unsigned long.

2.4 File System

The 64-bit Tru64 UNIX operating system allows you to build very large files and file systems. The off_t file offset is defined to be a long on Alpha systems (64 bits). Given this extended capability, you can build files and file systems that cannot be fully accessed by 32-bit systems. Consider this when working in a distributed environment in which file systems are shared between 32- and 64-bit systems.

2.5 Endian Issues

IRIX on the MIPS architecture is big endian it has forward byte ordering. Bit 0 is the least significant bit and byte 0 is the most significant byte. Alpha and Intel x86 architectures are little endian byte 0 is the least significant byte. Table 2-2 shows the byte and bit order for Alpha systems.

Figure 2-2 Byte and Bit Ordering on Alpha Systems

Figure of Little-Endian Bit and Byte Order

For well-constructed code, the endianism of a system is almost always transparent. Those few cases where endianism is a concern typically are caused by coding practices that mix types in unions or casts.

2.5.1 Unions

Unions like the following can result in an endian portability problem:


        union int_byte {
                        int int_val;
                        char byte[4];
                };
        union int_byte my_var;
        my_var.int_val = 1000000;
        if(my_var.byte[3] == 0)
                printf("The number is divisible by 256\n");

On a big-endian machine, this code works correctly. Byte[3] is zero only when the number is divisible by 256. However, on a little-endian machine, byte[3] is the most significant byte. Either of the following methods fix this problem:

  • Use a constant to represent the least significant byte. On a big-endian machine, ensure that the constant is 3. On a little-endian machine, ensure that the constant is 0:
    
            if(my_var.byte[INT_LEAST_SIGNIFICANT_BYTE] == 0)
                printf("The number is divisible by 256\n");
    
  • Use code that is not sensitive to endian issues:
    
            if((my_var.int_val & 0xff) == 0)
                printf("The number is divisible by 256\n");
    

2.5.2 Initializing Multiword Entities in 32-Bit Chunks

Use care when porting code that initializes quadword and other multiword entities with 32-bit entities. For example, on a big-endian system, an array of two 32-bit integer values is used to initialize a 64-bit double:


        u.ul[1] = 0x7fffffff;
        u.ul[0] = 0xffffffff;

To produce the correct results on a little-endian system like Alpha, the subscripts must be reversed:


        u.ul[0] = 0x7fffffff;
        u.ul[1] = 0xffffffff;

2.5.3 Unused Bytes

Sometimes code that is trying to make very efficient use of memory takes advantage of the fact that often not all 4 bytes in an integer are used. For example, if a particular int field in a record will hold only values in the range 0 to 10,000,000, the most significant byte will always be zero. A 1-byte field could be stored in that byte to make the record 1 byte smaller.

If the most significant byte is accessed by means of a character array or by casting and dereferencing a pointer, then the code will not be portable and slightly different versions will be needed on big-endian and little-endian machines. However, if bitwise operators are used to mask, merge, and shift bytes, then the code will be portable.

2.5.4 Hex Constants Used As Byte Arrays

An endian problem occurs when a 32-bit value is treated sometimes as a 32-bit value (an integer) and sometimes as an array of 4 characters. For example, the following array is equivalent to the number 0x11223344 on big-endian machines and the number 0x44332211 on little-endian machines:


        char a[4] = {0x11, 0x22, 0x33, 0x44};

2.5.5 Data Transfer

If data with multibyte values is being transferred between big-endian and little-endian systems, then it is a simple matter to provide code that swaps the bytes. Suggestions for doing this are presented in Appendix A, Transferring Data.

2.6 Write-to-Memory Operations and Memory Barriers

The Alpha architecture guarantees coherency of a processor's view of memory (that is, cache is updated, or the contents marked invalid and good data fetched elsewhere). The architecture has a shared-memory model that specifies no implicit ordering between the reads and writes issued on one processor, as viewed by a different processor. This approach allows a wide variety of high-performance implementation techniques. For example, it makes possible such implementations as the use of multibank caches, bypassed write buffers, write merging, and pipelined writes with retry on error.

When required, specify strict ordering of reads and writes by using explicit memory barrier (MB) instructions. Low-level hardware operations such as device drivers often make use of memory barrier instructions to ensure the order in which data are written to memory.

The following code fragment illustrates the use of a memory barrier:


	device_intr()
	{
		mb();
		bcopy (DMA_buffer, data, nbytes);
		/* If we need to update a device register, do: */
	mb();
		device->csr = DONE;
		mb();
	}

See the Tru64 UNIX book Writing Device Drivers: Tutorial for more information.


3 The Porting Process

Back to Table of Contents

This chapter consists of general porting guidelines followed by ordered steps you can follow to port code to the Tru64 UNIX operating system.

3.1 Porting Guidelines

The following suggestions are not the only way to port a 32-bit application to a 64-bit environment. However, each step is based on the lessons learned by people who have already ported code; so at least consider them before creating your own approach.

  • Get copies of each system's commonly used .h files (for example, limits.h, types.h, param.h, and so on) and use them for reference. Use predefined types whenever possible. Use *io.h, common.h, and iotypes.h for driver/kernel typedefs.

  • Take the time to create and use function prototypes. The time invested doing this will be repaid later. Be aware of function arguments that are not explicitly declared and typed. Argument sizes of such functions might not match those of the calling program.

    Also note that int is the default size for untyped registers and unsigned variables.

  • Check all code with lint. Use the -Q option, which turns on checking for potential migration issues when moving from a 32-bit to a 64-bit architecture.

  • When declaring constants, use L or UL as appropriate; when necessary, use the unsigned UL to prevent sign extension.

  • When checking/converting long declarations, check calls to printf() and appropriately change format strings to %ld, %lu, %lx, or vice versa. (Most people miss these changes during their porting.)

  • Check (int *) and (long *) types of casts.

  • Use NULL, defined as 0L, for zero or (char *) comparisons.

  • Declare variables as int or long for alignment and performance. Do not worry about trying to save bytes by using a char or a short.

  • Generate appropriate typedef for portability. For example:

    
    	typedef int boolean_t;
    

  • Look out for longs in unions (extra space allocated), or the storing of pointers or double values in a union whose maximum size is int.

  • Beware of rounding pointers for alignment (for example, & 0x03). To avoid truncating addresses use appropriate castings, and for size, use the following:

    
    (sizeof(long) - 1)
    
    For example:
    
    	#define round(a,b) ((((ulong)(a)+(b))-1)&~(ulong)((b)-1)) 	.
    	.
    	.
    	rndstak = (uchar_t *)round(staktop, BYTESPERWORD); 

  • Avoid storing structures that contain pointers in data files. These files then become nonportable between 32-bit and 64-bit systems.

  • Declare character pointers and character bytes as unsigned char to avoid sign extension problems with 8-bit characters.

  • The signal() function returns a pointer (64 bits) to the previous signal handler.

    
    	void (*signal(int signal, void (*function)( int ))) (int); 

    Do not store the pointer in an int or the address will be truncated.

  • Use variable argument lists instead of declaring extra int arguments.

    Note: The Alpha va_list is not a char pointer as it is with many other varargs implementations. See va_list.h for the formal declaration of va_list.

  • When shifting bytes into a long value, ensure that each byte is cast to a long Otherwise, the result is only a 32-bit value (not 64 bits as expected).

    When shifting bits on an integer constant, specify the constant with L or UL if you want a result of type long or unsigned long, respectively. Otherwise the results will be an integer.

  • Beware of compiler optimizations. Declare as volatile any variable used in a loop that is updated by an external function (for example, signal handler). Otherwise, no changes will be detected by the loops.

  • In driver ioctl() functions, ensure that the cmd argument is an unsigned int to avoid sign extension and comparison problems. Any command defined with IOC_IN (0x80000000) will sign extend.

  • Network Internet addresses are 32 bits. Most network code uses longs for network addresses (16-bit leftover necessary to force 32 bits).

  • When data alignment cannot change (for example, network packets), use #pragma pack(1) to avoid compiler structure padding.

  • Change only what you know is broken. This approach has the following advantages:

    • It minimizes the number of changes, making them more understandable, more manageable, and easier to propagate.

    • It minimizes the number of new problems created during the port.

    • Every change fixes something that is known to be a problem. There are none of the open questions that accompany global replacements.

3.2 Porting Procedures

The following procedures will help in the porting process.

3.2.1 Look for Potential Problems

Use the following methods to locate potential problem areas:

  • Use grep to search for regular expressions that might indicate problem areas.
  • Use lint -Q , which checks for common programming techniques that can cause problems when moving from 32-bit systems to 64-bit systems.

3.2.1.1 Use the grep Command

Search for the following regular expressions to find constructions that are likely to cause porting problems. (It is usually more time effective to find these problems with grep rather than dbx.)

  • memcpy

    Byte counts that work on a 32-bit machine might be incorrect on a 64-bit machine.

  • union

    Any union with a long is likely to be a problem; a union with an int might be a problem.

  • 0[xXl[0-9a-fA-F]

    Hexadecimal constants, especially when mixed with longs or pointers, can be problems.

  • %[dDxX]

    The printf()/scanf() format codes will need to be fixed if the parameter is a long. For example:

    printf("%ld", a_long);

  • sizeof(long)

    In Tru64 UNIX this is not the same as sizeof(int).

  • extern

    If an external variable is used, make sure that all declarations of the variable match.

  • long.*32

    Examine lines like the following:

    
    *typedef long INT32;
    
    It is a good idea to check all long declarations; many of these can be converted to int to save space. For network addresses, replace an unsigned long with an unsigned int.

  • <<, >>, and ~

    Add L to values acted on by shift operators or complements when those values are long constants. This avoids a zero result.

  • &

    Check the address of & to make sure it is not stored in an int.

It is recommended that you check all lines of code that have the regular expressions mentioned in this section. However, if the code contains too many occurrences for you to check them all, it is a good idea to look at a sampling of these constructs. You might determine that for some constructs you should check all the code. You might decide to refine the search characteristics. For example, you could check all the unions in a particular directory.

3.2.1.2 Use lint -Q

Tru64 UNIX provides an option to lint, -Q, whose sole purpose is to search for programming techniques that might cause problems when moving code from a 32-bit system to a 64-bit system.

You can use a number of suboptions to -Q to refine your checking by selectively suppressing checking for specific problem areas. For example, lint -Qc suppresses checking for problematic type casts.

For a description of the -Q suboptions, see the reference page for lint(1).

3.2.2 Compile the Code and Save Compiler Messages

When you compile the code with cc:

  • You can use the -proto flag to generate function prototypes. Then use -warnprotos to check that all functions have prototypes.

    The cc compiler creates function prototypes automatically when the option -proto[is] is used. The -proto option extracts prototype declarations for function definitions into a file with a .H suffix. The i option includes identifiers in the prototype, and the s option generates prototypes for static functions as well.

  • Use the -std1 flag to enforce ANSI C standard.

  • Use the -w0 flag to display all levels of compiler messages.

  • You can deliberately bind addresses to the first 2 gigabytes of address space by specifying the -taso flag to cc or ld. Under this option, the high 33 bits of all pointers are always zero. The -taso option also causes the run-time loader to dynamically relocate shared libraries, such as libc.so, into the first 2 gigabytes of address space. (Also look at the -xtaso flag.)

    The -taso flag might simplify the porting process for applications that assume the size of pointers and variables is always 32 bits.

3.2.3 Fix Problems Identified at Compile Time

For each error, the C compiler identifies, as best it can, the line where the error occurs and the nature of the error.

3.2.4 Fix Alignment and Padding

The Alpha architecture requires that 64-bit quantities (longs and pointers) be 64-bit (8-byte) aligned. The Tru64 UNIX operating system corrects unaligned accesses on the fly, but you should remove unaligned accesses from the code for the following reasons:

  • On-the-fly correction of unaligned accesses is substantially slower than normal accesses.
  • Unaligned access probably indicates a bug in the program. (In almost all cases, if the code is working correctly, the compiler will arrange things to avoid unaligned accesses.)
The unaligned access message includes the program counter of the offending instruction. Set a breakpoint on that instruction to find the offending line of code (and the cause of the problem).

3.3 Porting Suggestions

The following suggestions can help you chase down problems in ported code.

3.3.1 Techniques for Finding Problems in Partially Working Code

When you find something wrong and you are done correcting the code and testing the fix, ask yourself, "Could there be similar bugs in similar code elsewhere in the application? What's the best way to find them?" Then use your tool set to find and fix those bugs.

  • On tough-to-find problems, a reference platform can be very helpful. On a platform where the application works, run the application in the debugger. Trace through both platforms in parallel and determine where the two diverge.

  • Use dbx to get a memory dump. For example, you get a zero returned where you expected to get a reasonable value, and you see a pattern in memory that looks like the following:

    
    	<32-bit value> <32-bit ZERO> <32-bit value> <32-bit ZERO>
    

    You might have an array that was created as an array of longs, but then accessed as an array of ints. This makes every other value a zero.

3.3.2 Hints for dbx

The following example shows how to find a line of code that caused an unaligned access:


    Unaligned access pid=3488 <a.out> va=1400001f4
    pc=120001178 ra=1200010d8 type=ldq
    (dbx) stopi at 0x120001178 (dbx) run [2] stopped at >*[main:7,
    0x120001178] ldq rl7, 4(rl) (dbx) where main(0x3ff800f934,
    0x3ffcOOa5840, 0x11ffff788, 0x120001010,
          0x1200010d8) ["t.c":7,0x120001178]

The argument passing is handled in the following registers:

  • r0 Return value from a function (nonfloating point)
  • rl6 Function argument 1
  • rl7 Function argument 2
  • rl8 Function argument 3
  • rl9 Function argument 4
  • r20 Function argument 5
  • $f16-$f20 are used for floating-point arguments
  • r31 Hardwired to contain a zero; you cannot move to r31.

The first five function arguments are always passed in registers r16-r20. If a function has more than five arguments, the extra arguments are passed on the stack.

Most functions, on entry, store the arguments onto the stack. However, simple leaf functions (no calls to other functions) do not store arguments on the stack. Because the dbx where command looks on the stack for argument values, the information displayed by the where command is incorrect for simple leaf functions.

The following example shows how to dump memory for 20 items, starting at address 0x3000000. The dbx assign command is used to alter the values of variables.


    (dbx) 0x3000000/20 X longs (64-bit ints)
        x ints (32-bit ints)
        c chars
        i disassembled instructions
    (dbx) print *(long *)0x11fffff20
    0x632f73756c70322e
    (dbx) assign 0x11fffff20 = 17
    0x11
    (dbx) print *(long *)0x11fffff20
    0x11

Note: 64 bits are changed.

The following example shows how to print a string that starts at address 0x11fffff20:


     (dbx) print (char *)0x11fffff20

3.4 Porting Assistant

Compaq Porting Assistant is a set of integrated software tools designed to help port applications to Tru64 UNIX. It checks for code that is likely to cause porting problems, and it simplifies the process of making needed changes.

See Chapter 5, Porting Assistant, for more information.


4 Application Development Environment

Back to Table of Contents

The development environment in Tru64 UNIX Version 5.0 is fully ANSI C/ISO C compliant. It offers the programming features of both BSD and System V UNIX and is compliant with most standards, including POSIX, XPG4, and XPG4-UNIX. Tru64 UNIX features debuggers that support C, Assembler, Fortran (F77 and F90), C++, Ada, and connection to /proc. It also supports shared libraries, threads, and versioning, and has a fully optimized C compiler that produces extremely efficient code to exploit the 64-bit address space of the Alpha architecture.

4.1 Software

To port or develop applications for Tru64 UNIX, you need the Developers' Toolkit for Tru64 UNIX.

Table 4-1 lists the software subsets for the Tru64 UNIX software development tools and related software. With the exception of OSFCMPLRSnnn, which is part of the base Tru64 UNIX operating system, all the other subsets are part of the Developers' Toolkit for Tru64 UNIX.

Table 4-1 Software Subsets

Subset Name Contents
OSFCMPLRSnnn Compiler Back End C Language Compiler (This is a mandatory subset.)
OSFSDEnnn  Software Development Tools and Utilities
OSFLIBAnnn Static Libraries
OSFPGMRnnn Standard Programmer Commands
OSFINCLUDEnnn Standard Header Files
OSFSDECDEnnn Software Development Desktop Environment
OSFRTDEVnnn Realtime Software Development Tools
OSFXINCLUDEnnn X Window and X/Motif Header Files
OSFXDEVnnn X Window and X/Motif Software Development
OSFXLIBAnnn X Window and X/Motif Static Libraries
OSFRCSnnn GNU Revision Control System (RCS)
OSFSCCSnnn Source Code Control System (SCCS)
OSFLDBBASEnnn Ladebug Debugger
OSFLDBGUInnn  Ladebug Debugger Window Interface
OSFCDAPGMRnnn  CDA Software Development
OSFXCDADEVnnn CDA for X/Motif Development

In subset names, the sequence nnn indicates the version number of the software; for example, OSFBASE425. The version number depends on the release of Tru64 UNIX you are running. For information about software subsets and loading softare, see the Installation Guide and the reference page for setld(1).

4.2 C Preprocessor

The C preprocessor (cpp) on Tru64 UNIX systems is similar to the preprocessor (cpp) on IRIX systems. Like the IRIX preprocessor, the Tru64 UNIX preprocessor interprets directives, such as #include and #define. The syntax for specifying directives is the same as the syntax on IRIX systems. The Tru64 UNIX C preprocessor supports additional processor-specific conditions (specified by the #pragma directive) and ANSI C preprocessor definitions.

4.3 C Compiler

The Tru64 UNIX system provides an ANSI C-compliant compiler. In addition to compiling ANSI C programs, the compiler provides a compilation mode that allows you to compile programs written in Kernighan and Ritchie (K&R) C.

The Tru64 UNIX Version 5.0 C compiler supports 64-bit data types and is NIST-validated for compliance with the ANSI Standard for C. The C front end supports both 64-bit addressing and the interfaces to the System V shared libraries.

This section highlights the features of the Tru64 UNIX C compilers, and gives some comparisons to the IRIX C compiler.

4.3.1 Features of the DEC C Compiler

The C compiler offers the following features:

  • Compiles the C dialect of the user's choice, including:
    • K&R C (-std0 mode)
    • Strict ANSI C (-std1 mode)
    • ANSI C with extensions (-std mode)

    • This mode allows certain extensions to the ANSI standard, such as C++ style comments and casting of the left side of an assignment operator.
  • Supports the XPG4-UNIX standard:
    • By default, under the c89 command
    • With the -D_XOPEN_SOURCE_EXTENDED option to cc
  • Supports floating-point and double-precision operations in the following two modes:
    • IEEE support (including proper handling for exceptional conditions like NaN, INF, and so forth)
    • Fast Math mode (INF, NaN, and so forth, translated to avoid exception handling)
  • Supports the following language extensions:
    • C++ style structured exception handling by using try...except and termination handling by using try...finally
    • User-defined assembly language sequences by using asm sequences
    • 32-bit pointers to help reduce the amount of memory used by dynamically allocated pointers, and to facilitate the porting of 64-bit hostile programs
    • Linking programs in 32-bit address space to facilitate the porting of 64-bit hostile programs (the ld -taso option)
    • Pragmas for controlling alignment of structures

4.3.2 Support for Interfaces and Definitions

Tru64 UNIX is written using a hierarchy of interfaces and definitions. Using the default interface, D_OSF_SOURCE, applications are able to make use of all the features specified by the OSF Application Environment Specification (AES). If other specific operating system environments are needed, you can use the following symbols:

  • D_POSIX_SOURCE (for maximum portability of your application)
  • D_AES_SOURCE
  • D_XOPEN_SOURCE
  • D_ANSI_C_SOURCE
  • D_BSD
For example, applications needing a fully POSIX-conforming environment should be compiled with the D_POSIX_SOURCE compiler switch. Applications needing a strict ANSI-conforming environment should be compiled with the D_ANSI_ SOURCE and -std1 compiler switches.

4.3.3 Compilation Flags for Hardware Architectures

The Tru64 UNIX C compiler supports the -arch flag for specifying the version of the Alpha architecture for which the instructions are to be generated.

4.3.4 Compilation Flags for Checking Code Portability

The Tru64 UNIX C compiler supports a number of flags that can assist you in porting applications:

  • -check

    Performs compile-time code checking. With this flag, the compiler checks for code that exhibits nonportable behavior, represents a possible unintended code sequence, or possibly affects operation of the program because of a quiet change in the ANSI C Standard. This flag is available for -newc and -migrate only.

  • -isoc94

    Causes the macro STDC_VERSION to be passed to the preprocessor and enables recognition of the digraph forms of various operators.

  • -portable

    Enables the issuance of diagnostics that warn about any nonportable usages encountered. This flag is not available when you use the -oldc flag.

  • -std[n]

    Directs the compiler to produce warnings for language constructs that are not standard in the language. The default is -std0.

    Use -std1 to enforce ANSI C standard.

  • -warnprotos

    Produces warning messages when a function is not declared with a full prototype.

  • -proto[is]

    Extracts prototype declarations for function definitions and puts them in a .H suffixed file. The suboption i includes identifiers in the prototype, and the suboption s generates prototypes for static functions as well.

For more information on the Tru64 UNIX C compiler, see the cc(1) reference page.

4.3.5 Compilation Flag for 32-Bit Pointers

The -xtaso and -xtaso_short compiler flags support the use of 32-bit pointers in the 64-bit Tru64 UNIX environment. In addition to simplifying the process of porting applications that make assumptions about the sizes of pointers, the 32-bit pointer data type can help developers reduce the amount of memory used by dynamically allocated pointers.

When you use the -xtaso flag, all pointer types default to 64-bit pointers. You can declare 32-bit pointers by using pointer_size pragmas. Place pragmas where appropriate in your program. Images built with the -xtaso flag must be linked with the -taso flag in order to run correctly.

When you use the -xtaso_short flag, all pointer types default to 32-bit pointers. You can still declare 64-bit pointers by using the pointer_size pragmas. Because all system routines continue to use 64-bit pointers, most applications require source changes when used in this way.

All pointer_size pragmas in a program are ignored unless the program is compiled with either the -xtaso or -xtaso_short compiler flag.

The syntax for the pointer_size pragma is as follows:


#pragma pointer_size specifier
The specifier must be one of the following keywords:
  • long

    All pointers following this pragma are 64 bits in length until an overriding pointer_size pragma is encountered.

  • short

    All pointers following this pragma are 32 bits in length until an overriding pointer_size pragma is encountered.

  • save

    The current pointer size is saved such that a corresponding #pragma pointer_size restore will set the pointer size to the current value. The model for pointer size preservation is a last-in, first-out stack such that a save is analogous to a push, and a restore is analogous to a pop.

  • restore

    The opposite of save. The uppermost saved pointer size is restored and deleted from the save/restore stack. For more information about using 32-bit pointers, see Appendix A in the Programmer's Guide.

4.3.6 Call Conventions for Passing Arguments

On Tru64 UNIX, the first five function arguments are always passed in registers r16 to r20, with additional arguments passed on the stack. Table 4-2 shows the registers used for argument passing.

Table 4-2 Call Conventions for Argument Passing

Register Description
r0 Return value from a function
r16 Function argument 1
r17 Function argument 2
r18 Function argument 3
r19 Function argument 4
r20 Function argument 5
$f16-$f20 Floating-point registers
r31 Hardwired to contain the value 0

4.4 Linker (ld)

The linker (ld) by default loads the program text and data in the high 64-bit virtual address space of the process (between 0xFFFFFFFFFFFFFFFF and 0x0000000100000000). This means no addresses are accessible with a 32-bit address.

If your source code contains any unintended pointer truncations, they will trap into the kernel and cause a run-time error. You can change the default behavior of the linker by using the -T or -D options to change the text and data segment origin, respectively.

The ld Option for Porting Code

The -taso option causes the linker to load the executable in the lower 31-bit addressable virtual address range. In addition to setting default addresses for text and data segments, the option causes shared libraries linked outside the 31-bit address space to be appropriately relocated by the loader. The -T and -D options, when used in addition to the -taso option, override the -taso default addresses.

4.5 C++

Compaq C++ Version 6.2 for Tru64 UNIX is based on the ANSI/ISO C++ International Standard, reference designation number ISO/IEC 14882:1998.

To enhance compatibility with other C++ compilers, Compaq C++ supports options that direct the compiler to interpret the source program according to certain rules followed by other C++ compilers. Supported options include:

  • -cfront

    Improves compatibility with C++ compilers based on the "cfront" C++ translator from AT&T.

  • -ms

    Improves compatibility with C++ compilers based on Microsoft's Visual C++.

For more information about porting C++ applications, see the Tru64 UNIX manual Using Compaq C++.

4.6 The lint Program Checker

The lint command checks C programs for bugs, nonportable code, and inefficient code. >From a porting perspective, the most useful option may be -Q, which turns on checking for programming practices that might cause problems when code is moved from 32-bit systems to 64-bit systems. Checks the -Q option makes include:

  • Pointer alignment
  • Pointer and integer data type combinations
  • Assignments that cause a truncation of long data types
  • Assignments of long data types to another type
  • Structure and pointer combinations
  • Type castings
  • Format control strings in scanf and printf calls

4.7 Debugging Tools

Tru64 UNIX provides three debugging tools:

  • dbx

    A source-level debugger for programs written in C, Fortran, Pascal, assembly language, and machine code.

  • Ladebug

    A symbolic source code debugger for programs compiled by the DEC C, ACC, Compaq C++, DIGITAL Fortran (DIGITAL Fortran 90 and DIGITAL Fortran 77), Compaq Ada, and Compaq COBOL compilers.

    Both a graphical interface and command-line interface are available.

  • kdbx

    A crash analysis and kernel debugging tool. It serves as an interactive front end to the dbx debugger. The kdbx debugger is extensible, customizable, and insensitive to changes of offsets and sizes of fields in structures.

4.8 System V Compatibility

Tru64 UNIX provides users, programmers, and administrators with System V functionality.

4.8.1 System V Habitat

Developers who want a System V development environment can use the System V Habitat. The habitat provides source-code compatibility for C-language programs. The habitat is part the the base operating system.

The System V habitat consists of alternate versions of commands, subroutines, and system calls that support the source code interfaces and runtime behavior for all components of the Base System and Kernel Extension as defined in the System V Interface Definition (SVID). This implementation of the System V habitat supports all SVID 2 functions and SVID 3 functions. The System V habitat does not contain alternate versions of default system commands, subroutines, and system calls that already meet the SVID requirement.

For directions on making the System V Habitat your default environment, see the chapter titled "Using the System V Habitat" in the Tru64 UNIX Command and Shell Users Guide. The System V Habitat is described in detail in Appendix B of the Programmers Guide.

4.8.2 Extended System V Compatibility

Prior to Tru64 UNIX Version 5.0, the System V Environment, layered software, extended the functionality provided by the System V Habitat by supporting a more complete System V Release 4 (SVR4) environment for general users, application programmers, and system administrators. Starting with Tru64 UNIX Version 5.0, extended System V compatibility is being built into the base operating system.

4.8.2.1 System V Environment

The System V Environment was an extension to the operating system that contained a separate System V Release 4.0 binary license from UNIX Software Laboratories. A special license and a Product Authorization Key (PAK) were required.

The System V Environment added compliance with the following SVID 3 volumes:

  • Volume 2: Utilities and Administration
  • Volume 3: Software Development, Terminal Interface, Realtime and Memory Management, Remote Services

Table 4-3 lists the additional software required for the System V Environment.

Table 4-3 Software for System V Environments

Subset Name

Contents

SVEENVnnn

System V Environment Setup Files Package

SVEADMnnn

System V Environment System Management Package

SVEBCPnnn

System V Environment Base Compatibility Package

SVEDEVnnn

System V Environment API and Development Tools Package

SVEMANnnn

System V Environment Reference Pages Package

SVEPRINTnnn

System V Environment Print Package

The System V Environment is described in the Technical Overview.

4.8.2.2 Extended System V Compatibility In Tru64 UNIX Version 5.0

Starting with Tru64 UNIX Version 5.0, the features of the System V Environment are integrated into the base operating system. Tru64 UNIX provides 80% of the System V Interface Definition (SVID) standard, as verified by the SVVS 3 and SVVS 4 test suites. As a result, Tru64 UNIX contains a substantial number of System V Release 4 (SVR4) features and delivers the highest composite SVR4 conformance of any implementation.

SVR4 functionality will be further expanded in future releases.

4.9 Other Programming Tools

Tru64 UNIX provides other programming tools that are also available on HP-UX. Each tool has been modified to support the ANSI C language dialect, shared libraries, and 64-bit data types. Otherwise, its use is the same as its HP-UX equivalent, when one exists.

Table 4-4 gives a brief description of each Tru64 UNIX tool. For more information about the tools, see the respective reference pages.

Table 4-4 Tru64 UNIX Programming Tools

Tool Function
ar Creates and maintains archive libraries. (You cannot use the ar command to create shared libraries.)
atom

hiprof

pixie

third

Profiling tools.

Produces flat and hierarchical profile of execution times.

Produces profile by procedure, source line, or instruction.

Performs memory access checks and detects leaks.

cflow Analyzes C application files (as well as yacc, lex, and assembler files) and builds a graph that charts the external references made in the application.
ctags Creates a tags file that you can use with the ex editor. The tags file specifies the location of functions and typedef declarations in the specified set of C application files.
cxref Analyzes a set of C application files and builds a cross-reference table. The table lists all symbols used in the application.
dis Disassembles object files into machine instructions.
gprof Produces an execution profile.
lex Generates a C language source file that matches patterns for simple lexical analysis of an input stream.
nm Displays symbol table information for object files and archive files and shared libraries.
file Reads one or more files as input, performs a series of tests on the files, and determines their types.
odump Displays information about an object file, archive file, or executable file. You can use odump options to display an object file's header, defined symbols, or program regions.
prof Analyzes profile data.
pixstats Analyzes the output from pixie; supported only with archive libraries and cannot be used with shared libraries.
rcs Revision Control System (RCS).
sccs Source Code Control System (SCCS).
size Displays number of bytes required by each section of an object file, as well as total number of bytes required by an object file.
stdump Displays detailed symbol table information for an application or object.
strip Strips symbolic debugger information from an executable file.
trace Monitors variable accesses.
uprofile

kprofile

Profiles a program (uprofile) or the kernel (kprofile) by using built-in performance counters on the Alpha processor.
yacc Converts a context-free grammar specification into a set of tables that a simple parsing program can use.

4.10 The make Command

Tru64 UNIX provides three versions of the make command:

  • /bin/make

    The default. For a detailed description, see the make(1) reference page.

  • /usr/bin/posix/make

    The XPG4-UNIX version. For a detailed description, see the make(1p) reference page.

  • /usr/opt/ultrix/usr/bin/make

    The SYSTEM V version with some Berkeley compatibility added. For a detailed description, see the make(1u) reference page.

In addition to the appropriate reference page, you can find information about the make command in the Tru64 UNIX book Programming Support Tools.

Within the Tru64 UNIX Workstation Development Environment, the imake and makedepend tools are available as a make preprocessor utility and a make dependency tool.

The description of make that follows applies to the default version of the command, /bin/make.

4.10.1 The makefile Search Path

If the make -f option is not used, then make looks for makefiles in the locations indicated in Table 4-5. Note that Tru64 UNIX assumes RCS, not SCCS, as the default for file archiving.

Table 4-5 The makefile Search Path

IRIX make

Tru64 UNIX make

makefile

makefile

Makefile

Makefile

SCCS/s.makefile

makefile,v

SCCS/s.Makefile

Makefile,v

 

RCS/makefile,v

If the RCS file is present, Tru64 UNIX attempts to perform a checkout.

 

RCS/Makefile,v

If the RCS file is present, Tru64 UNIX attempts to perform a checkout.

4.10.2 Flags

Table 4-6 shows differences between IRIX make options and those in Tru64 UNIX.

Table 4-6 Flags to the make Command

Flag

IRIX Function

Tru64 UNIX Equivalent

-O

Turns off compatibility mode for old makefiles.

No equivalent.

-u

Unconditionally makes the target, regardless of timestamps.

No equivalent.

The -u flag in Tru64 UNIX performs a different function.

-g

Auto get. If a file does not exist, attempts to get it from SCCS.

-C

If a file does not exist, attempts to get it from RCS.This flag is on by default.

-d

Prints reasons targets are updated.

No equivalent.

-D

Prints verbose debug information.

No equivalent.

-N

Permits targets with dependencies to be candidates for application of the NULL suffix transformation rules.

No equivalent.

-M

Turns off -N.

No equivalent.

-P

Updates multiple targets in parallel.

No equivalent.

-B

Arranges the output of parallel make in appropriate blocks.

No equivalent.

4.10.3 Implementation of make Rules

Tru64 UNIX has the default rule implementation in the make binary, and uses a Makeconf file to supersede the default rules with any compilation-specific changes. Tru64 UNIX automatically searches for a Makeconf file in the current directory.

4.10.4 Pseudo Targets and make Directives

Table 4-7 summarizes the behavior of pseudotargets in Tru64 UNIX.

Table 4-7 Pseudotargets

Pseudotargets

Behavior in Tru64 UNIX

.SUFFIXES

Work similarly to those in IRIX, but the suffixes list is different.

The default suffixes list in DIGITAL UNIX:

.out .o .s .c .a .F .f .e .r .y .yr .ye .l .p .sh .csh .h .f~ .f90~

.DEFAULT, .IGNORE, .PRECIOUS, .SILENT

Equivalent on both systems.

.MAKEOPTS

No equivalent.

4.10.5 Dynamic Macros

The DIGITAL UNIX make command recognizes the built-in macros $@, $$@, $?, $<, and $*. It does not recognize the $% built-in macro. That macro is available in the XPG4-UNIX version of make:


	/usr/bin/posix/make

4.11 Header Files

The locations and contents of header files differ among the various UNIX operating systems. These differences can appear in a number of ways. For example, the interface to a service might be slightly different, structure definitions might be located in different header files, values might have changed to reflect the 64-bit Alpha architecture, or nearly identical structures or constants might have different names.

The Tru64 UNIX header files are accessible in the /usr/include directory. Some subdirectories in /usr/include are links to subdirectories in /usr/sys/include.

Table 4-8 describes the Tru64 UNIX directories that contain standard header files.

Table 4-8 Tru64 UNIX Standard Header File Directories

Directory Description
dec Header files specific to Tru64 UNIX
DPS Display PostScript System C header files
DXm Header files with Tru64 UNIX extensions to Motif C
lvm C header files for Logical Volume Manager (LVM)
mach Mach-specific C include files
Mrm Motif resource manager C header files
net Miscellaneous network C header files
netimp C header files for IMP protocols
netinet C header files for Internet standard protocols
netns C header files for XNS standard protocols
nfs C header files for Network File System (NFS)
protocols C header files for Berkeley service protocols
rpc C header files for remote procedure calls
servers C header files for servers
sys System C header files (kernel data structures)
tli C header files for Transport Layer Interface (TLI)
ufs C header files for UNIX File System (UFS)
uil Header files for the User Interface Language (UIL) Compiler
X11 X Toolkit header files
Xm Motif C header files

The compiler can help you port your application by finding inconsistencies in the application's use of a symbol, a function, or a declaration in a header file. The Tru64 UNIX C compiler issues error messages for the following conditions:

  • Header file not found
    
    	cfe: Error: file.c: 1: Cannot open file cursesX.h for
    	#include
    
  • Undefined symbol (a symbol that is not defined before its use)

    This message helps you to find references to header file symbols that have moved or are no longer available.

    
    	cfe: Error: file.c, line 8: 'ENOSYSTEM' undefined,
    	reoccurrences will not be reported
    
  • Multiply defined symbol (a local definition that conflicts with a header file definition)
    
    	cfe: Warning: file.c:4: Tried to redefine the macro
    	EDEADLK, this macro keeps the old definition in
    	std/std1 mode, otherwise the macro is redefined
    
  • Redeclared function (a local function declaration that conflicts with a header file declaration)
    
    	cfe: Error: t.c, line 7: redeclaration of 'openlog';
    	previous declaration at line 120 in file
    	'/usr/include/syslog.h'
    		int openlog(char*, int);
    		----^
    
  • Mismatched function use and prototype (failure of a function usage to provide the number of arguments declared by the prototype declaration)
    
    	cfe: Error: file.c, line 12: Number of arguments
    	doesn't agree with number in declaration
    
  • Incompatible function arguments (an attempt to provide incompatible arguments to a function)
    
    	cfe: Warning: file.c, line 12: Incompatible pointer
    	type assignment
    

Because function declarations or prototypes are not required by the C language before a function call, the compiler cannot detect misuse of functions that did not have a preceding prototype declared. You might need to find differences in these cases by first determining which header files your application depends on, generating a list of the function declarations these header files contain, and then using this list of functions to generate a cross-reference for the needed header files on a Tru64 UNIX system. Then you can cross-check the actual declarations for changes in the function interfaces and modify your source code where necessary. You can use shell scripts to search for the appropriate definitions in the list of header files.

4.12 Shared Libraries Provided by Tru64 UNIX

Table 4-9 describes the shared libraries that Tru64 UNIX provides in the /usr/shlib directory.

Table 4-9 Shared Libraries in /usr/shlib

Library /usr/shlib Description
libDXm.so Motif Extensions library.
libDXterm.so DECterm widget library, used by dxterm.
libDtHelp.so CDE online help routines.
libDtMail.so Shared library support for the dtmail CDE mail utility.
libDtSvc.so CDE service routines for desktop management.
libDtTerm.so Shared library support for the CDE ddterm terminal emulator utility.
libDtWidget.so Shared library of CDE widgets to supplement Motif widget.
libICE.so Inter-Client Exchange library, which enables the building of protocols.
libMrm.so Motif Resource Manager library.
libSM.so The X Session Management Protocol (XSMP), which provides a uniform mechanism for users to save and restore their sessions using the services of a network-based session manager. It is built on ICE and is the C interface to the protocol.
libUil.so The callable Motif UIL (User Interface Language) compiler used by applications that want to compile UIL at run time.
libX11.so Xlib library.
libXETrap.so X Extension library.
libXaw.so X Athena Widgets run-time library.
libXext.so X Extension client-side library.
libXi.so X Input Extension client-side library.
libXIE.so X Imaging Extension client-side run-time library (V5).
libXie.so X Imaging Extension client-side run-time library (V3).
libXm.so Motif Widgets library.
libXmu.so X Miscellaneous utilities run-time library.
libXt.so X Intrinsics library.
libXtst.so A library of routines for X clients to make use of the XTEST Extension.
libXv.so X video Extension client-side run-time library.
libaio.so POSIX realtime asynchronous I/O functions.
libaio_raw.so POSIX realtime asynchronous I/O functions (raw disk and tape only).
libaud.so C2 security auditing library.
libbkr.so Motif Help System library.
libc.so C library.
libc_r.so Threadsafe libc (link to libc.so).
libcda.so CDA run-time library.
libcdrom.so Rock Ridge Extensions to CDFS library.
libchf.so CDA/Imaging signal-handling routines.
libcmalib.so CMA threads library.
libcsa.so Shared library portion of the CDE dtcm calendar manager utility.
libcurses.so Curses screen control library.
libcxx.so C++ run-time support library.
libdb.so Database routines.
libdnet_stub.so DECnet library.
libdps.so Adobe Display PostScript client-side run-time libraries.
libdpstk.so Adobe Display PostScript toolkit.
libdvr.so CDA run-time viewer library.
libdvs.so CDA run-time layout library.
libesnmp.so Extensible SNMP library.
libexc.so Library that provides support for exception handling.
libiconv.so Internationalization codeset conversion routines.
libids.so Image-display services library.
libids_nox.so Image-display services not dependent on X.
libimg.so Image-processing routines.
libips.so Image-processing routines.
libm.so Compaq Portable Mathematics Library (CPML).
libmach.so Mach library.
libmxr.so Library used by mxr, the ULTRIX binary interpreter for OSF/1.
libndb.so Database routines.
libots.so Compiler run-time support.
libpacl.so POSIX Access Control List library.
libproplist.so VFS Extended File Attributes library.
libpset.so Processor set routines.
libpsres.so Adobe Display PostScript resource utilities.
libpthread.so Application Programming Interface for Tru64 UNIX threads.
libpthreads.so DECthreads library.
libsecurity.so C2 security library.
libsm_x.so Systems Management Graphical support library; no user-level interfaces available.
libtcl.so Base Tool Command Language (TCL) support library.
libtclx.so Extended TCL support library.
libtk.so Graphical TCL (TK) Extensions library.
libtkx.so Graphical Extended TCL support library.
libtli.so XTI library.
libtt.so SunSoft Tooltalk routines.
libvxvm.so LSM utility library.
libmsfs.so AdvFS system call interface library.
libfilsys.so File system utility library.
libxnet.so X/Open networking interface library.
libxti.so XTI library.

Table 4-10 describes the shared libraries that Tru64 UNIX provides in the /usr/shlib/X11 directory.

Table 4-10 Shared Libraries in /usr/shlib/X11

Library /usr/shlib/X11 Description
libXau.so X Authorization library
libXdmDecGreet.so Motif loadable greeter library
libXdmGreet.so Athena-style loadable greeter library
libXdmcp.so X Display Manager control program library
lib_adobe_dps.so Adobe Display PostScript Extension library
lib_dec_cirrus.so Device support for the Cirrus VGA graphics card
lib_dec_ffb.so Support for the sfb+ graphics accelerator for 2D and 3D drawing operations
lib_dec_sfb.so Device support for the smart frame buffer (HX)
lib_dec_smt.so Shared memory transport library
lib_dec_tx.so Device support for the TX graphic adapter
lib_dec_ws.so Low-layer operating system interface for the X server
lib_dec_xi_pcm.so Dynamically loadable X Input Extension library that supports the dial and box
lib_dec_xi_serial_mouse.so Support library for the serial mouse
lib_dec_xv_tx.so X Video Extension support for the TX graphic option
libcfb.so Color frame buffer library
libcfb16.so 16-bit visual support for the color frame buffer
libcfb32.so 32-bit visual support for the color frame buffer
libdbe.so DOUBLE-BUFFER Extension library
libdix.so Device-independent portion of the X Server
libdixie.so With libmixie.so, supports the X Image Extensions (XIE) Extension library
libextMITMisc.so MIT-SUNDRY-NONSTANDARD Extension library
libextMultibuf.so MultiBuffering Extension library
libextScrnSvr.so MIT-SCREEN-SAVER Extension library
libextSync.so SYNC Extension library
libextXCMisc.so XC-MISC Extension library
libextbigreq.so BIG-REQUESTS Extension library
libextkme.so Keyboard-Management-Extension
libextshape.so SHAPE Extension library
libextshm.so MIT-SHM Extension library
libextxtest.so XTEST Extension library
libextxtrap.so DEC-XTRAP Extension library
libfont.so Font access library
libfr_Speedo.so Loadable font renderer library
libfr_Type1.so Loadable font renderer library
libfr_fs.so Loadable X Server font renderer for using a font server
libmfb.so Monochrome frame buffer support
libmi.so Machine-independent portion of the X Server
libmixie.so With libdixie.so, supports the X Image Extensions (XIE) Extension library
libos.so Operating system-dependent portion of the X Server
libxinput.so X Input Extension server-side library
libxkb.so XKEYBOARD Extension library

4.12.1 Tru64 UNIX Archive Libraries

In addition to shared libraries, the Tru64 UNIX system provides archive libraries. When you link your application with them, the image for library routines you call is included in your application image. You can link Tru64 UNIX applications to either shared libraries or archive libraries.

Use of shared libraries, rather than archive libraries, is encouraged. Normally, you can use shared libraries in any application and create any library as a shared library. In most cases, the effect of using shared libraries instead of archive libraries is transparent.

4.12.2 Using Shared Libraries

The use of shared libraries is transparent to the user.

The -non_shared option turns off the use of shared libraries. The following example creates a nonshared executable on Tru64 UNIX by using the /usr/lib/libc.a static archive library:


	% cc -non_shared -o hello hello.c

5 Porting Assistant

Back to Table of Contents

This chapter describes Porting Assistant, a tool designed specifically to help you port source code to Tru64 UNIX from other UNIX and non-UNIX platforms.

5.1 What It Does

Porting Assistant can check C, C++, and Fortran code to identify segments that might not compile or run properly on Tru64 UNIX. It generates diagnostic messages indicating the potential problems. The specific code in question is displayed in an editor along with the corresponding diagnostic message. HyperHelp is available to explain why changes need to be made. Tools are provided to simplify the process of making corrections. Porting Assistant also makes it easier to link code by helping to resolve undefined symbols.

5.1.1 Code Checking

Porting Assistant checks for the following potential porting problems:

  • Conditional code (#ifdef) that might need a Tru64 UNIX branch

    If the application already uses conditional code that applies to one or more platforms, Porting Assistant can locate this conditional code. You can then decide how to handle that code for Tru64 UNIX.

  • Includes (#include) of files that do not exist in the specified directories

    Porting Assistant identifies include files that are not found in the specified location. If possible, it reports locations where the file does exist.

  • Calls to library functions that do not match Tru64 UNIX definitions

    Porting Assistant checks for functions that do not have function definitions in Tru64 UNIX. For many of these functions, mappings to equivalent Tru64 UNIX functions are provided.

    Porting Assistant also flags functions that have calls that are inconsistent with their definition. This may occur if a function has a different signature on Tru64 UNIX than on another platform.

  • Calls to library functions with different semantics on Tru64 UNIX

    Porting Assistant provides a list of functions that have different semantics on Tru64 UNIX than on other platforms. Categories of function differences include platform differences and 32/64 bit differences. For each such function, Porting Assistant provides access to the function's reference page and to a special reference page that describes how this function is different on Tru64 UNIX. Porting Assistant searches your code to find calls to these functions.

  • Code with 32-bit dependencies

    Porting Assistant locates code that assumes it is running on a 32-bit architecture. This includes operations such as assigning or casting pointers to integers, assigning longs to other types, and sign-extension problems.

  • Commands in makefiles that might not run correctly on Tru64 UNIX

    Porting Assistant can check a makefile to ensure that all specified actions exist on the user's path. If Porting Assistant cannot find an action, it suggests locations of a program with the same name. Porting Assistant checks the arguments and options to common build commands (cc, ld, ar, and rm). It reports when the Tru64 UNIX option is different from that on the source platform and gives the equivalent Tru64 UNIX option.

5.1.2 Diagnostic Messages

A Porting Assistant diagnostic message reports the name of the file and the line number where the potential problem was found, the severity of the problem, and brief text describing the nature of the problem.

Examples of diagnostic text include:

  • Assignment of longs to other types
  • Illegal combinations of pointer and data
  • Shift operator yields zero
  • Truncation of longs in assignments
  • Function calls with no prototype
  • Function name is incorrectly called with n arguments
If you find the meaning of a diagnostic message unclear, you can use HyperHelp to obtain an explanation of the message and a suggested course of action.

5.1.3 HyperHelp on Porting

Porting Assistant includes online HyperHelp that explains how to use Porting Assistant and its checks. You can navigate through HyperHelp by task or by the index, or you can perform a search for the information.

The HyperHelp also includes porting tips that cover topics such as byte ordering, data alignment, and shared libraries. The extensive Help for the diagnostic messages is particularly useful because it is directly linked to specific messages with a description of the problem and suggestions on how to fix it. In addition to HyperHelp, you can access reference pages from Porting Assistant.

5.1.4 Code Correction

Porting Assistant displays the code in question in the editor of your choice: vi, emacs, or a bundled Motif editor. The associated diagnostic message is also displayed. An editor option lets you compile the code in the editor buffer to test changes quickly.

To speed the task of changing function names, variable names, or type names in source files, Porting Assistant lets you change a specified string to a different string in a set of files. Porting Assistant offers the option of performing substitution with or without confirmation. If you want to confirm each substitution, Porting Assistant brings each file into an editor, with the cursor positioned on each occurrence of the specified string. You can then choose to change that occurrence of the string.

5.1.5 Linker Assistance

Porting Assistant helps resolve undefined symbols reported by the linker. It includes a facility to look up a function to see what library defines it. It reports the library name and the linker options that are needed to link the library with the application.

5.2 How to Use It

This section is intended as an introduction to using Porting Assistant. After you have Porting Assistant running, you will likely find it intuitive to use. In those instances where you have questions, you can access HyperHelp by clicking on the Help button available on all Porting Assistant windows.

5.2.1 Getting Started

Porting Assistant ships with the Developers' Toolkit for Tru64 UNIX Version 4.0 and later. The subset name for Porting Assistant Version 3.0 is PRTBASE300.

You can download Porting Assistant from:

http://www.digital.com/info/porting_assistant/

To function, Porting Assistant requires that the Developers' Toolkit for Tru64 UNIX be installed on the system.

After you install Porting Assistant, you can start it from the command line as follows:

%port &

The Porting Assistant Control Panel appears. From the File pulldown menu you can choose to work on a new project or to open an existing project.

If you select New, you are presented with the Project Manager window, where you specify:

  • Project name
  • Working directory for the project
  • Directory for the executable target
  • Directory for data files
  • Directory for the current source to be ported
  • Directory for the ported source
After you have supplied the needed information and dismissed the Project Manager window, you are returned to the Porting Assistant Control Panel. If the name for your project is not already highlighted, select it by placing the cursor on the name and clicking MB1.

Go to the Tools pulldown menu and select Porting Assistant. The Application Information dialog box appears. Provide the requested information. Indicate whether you are using an existing makefile or creating a new one. If you are creating a new makefile, the Application Information dialog box assists you in the process.

When you finish with the Application Information dialog box, the Porting Assistant window appears. This window is central to using Porting Assistant. From it, you will select and run the various checks that will help you to port your source code.

5.2.2 Performing Checks

Regardless of which check you want, you perform the following actions:

  1. Run the check.
  2. Step through the source code corresponding to each diagnostic message.
  3. Make any needed corrections.

5.2.2.1 Run the Check

Select the type of check you want and run it:

  • Ifdef Code
  • Include Files
  • 32-Bit Dependencies
  • Function Calls
  • Parallel Directives
  • Platform-Specific Assumptions
  • Makefile
Porting Assistant uses a tool called the builder to run the check .

The main area of the builder is a transcript of the check. You can see the builder progressing through the files being ported. Any diagnostic messages are reported first in the builder.

5.2.2.2 Step Through the Source Code

When the check finishes, you walk through the list of diagnostic messages by using First, Next, Previous, and Last buttons.

When you click on First, the builder launches the editor to display the source code corresponding to the first diagnostic message.

Porting Assistant offers you a choice of a Motif-based editor, emacs, or vi. The left margin of the Motif-based editor is the annotations area. A "B" in this area indicates a line of source code corresponding to a diagnostic message.

Markings that can appear in the annotations area include:

  • An exclamation point on a green background, which indicates that the diagnostic message is informational rather than an error
  • An exclamation point on a yellow background, which indicates that the diagnostic message refers to an error
  • A square or hexagon indicating a break point
The editor displays these annotations only if it is already running when the user starts the check.

The editor provides a "Find Annotation" to let you move quickly through code to annotations of interest.

You can use the Editor Filter function to filter out unwanted diagnostic messages. For example:

  • If after assessing the source code flagged with a diagnostic message, you determine that you do not need to view future occurrences of that same message, you can use the "Filter Instance" function to filter the message in that context from future builds.
  • If you determine that you do not need to view occurrences of that message as applied anywhere in the current file, you can use the "Filter File" function.
  • If you determine that you do not need to view future occurrences of that message in any of your files, you can use the "Filter Everywhere" function.

5.2.2.3 Make the Correction

The Motif-based FUSE editor is a fully functional editor. In addition to the Find feature, available on the editor window Buffer pulldown menu, Porting Assistant offers a Search option on the Tools pulldown menu on the editor window and on the other major Porting Assistant windows. The Search window allows multifile search and replace.

5.2.2.4 Repeat the Process

After you have completed making corrections for one of the code checks, return to the Porting Assistant window. Select the next code check appropriate to your porting job, and repeat the process of making corrections.

5.3 Possible Limitations

Some functions in Porting Assistant depend on information in Porting Assistant databases. Follow-on releases of a vendor's product might make such information out of date: for example, the reference pages that show differences between a routine as implemented in Tru64 UNIX and another vendor's UNIX.

The following functions in Porting Assistant might be rendered outdated or incomplete because of changes in a vendor's UNIX after Porting Assistant shipped:

  • Find Function on Tru64 UNIX (from the editor Utilities pulldown menu)

    The Function Finder locates functions on Tru64 UNIX that are equivalent to functions on the platform from which the code is being ported. The introduction of new functions by a vendor would result in the Function Finder failing to find an equivalent function in Tru64 UNIX.

  • Code Check for Platform-Specific Assumptions

    The list of possible functions to check for would be incomplete if a vendor introduced new functions that involve assumptions about the hardware platform they run on.

Despite the possible limitations previously described, Porting Assistant provides a number of features that will speed the porting process. Even assuming the worst case--a port from an implementation of UNIX about which Porting Assistant databases have no specific information--Porting Assistant retains most of its functionality.


6 Porting Threaded Applications

Back to Table of Contents

This chapter is intended to help you get started with the process of porting threaded applications to Tru64 UNIX. For detailed information about pthreads in Tru64 UNIX, see the Guide to DECthreads and the reference pages for specific pthread functions.

A number of good books on pthreads programming are available. Among them are Programming with POSIX Threads by David R. Butenhof; Addison-Wesley Publishing Company, and Pthreads Programming by Bradford Nichols, Dick Buttlar, and Jacqueline Proulx Farrell; OReilly & Associates, Inc.

The DECthreads pthread interface is an implementation of the POSIX standard 1003.1c-1995 (part of 1003.1-1996). DECthreads adds extensions specified in The Open Group's Single UNIX Specification, Version 2 (SUSV2), also known as XSH5, part of the UNIX 98 brand. Although DECthreads provides nearly all of the threads-related extensions specified by SUSV2, technically it is not SUSV2 compliant.

SGI first offered threads support in IRIX 6.2, when it provided the IRIX 6.2 POSIX Patch Set. Threads support is integral in IRIX 6.4. The IRIX 6.4 threads API is the same POSIX 1003. 1c-1995 pthreads standard in DECthreads. IRIX 6.5 complies with SUSV2.

6.1 Porting Applications That Use POSIX Threads

Because of the strong similarities between IRIX pthreads and DECthreads, porting IRIX threaded applications to Tru64 UNIX should prove relatively straightforward.

Of the IRIX POSIX threads routines, six (all of which are optional under POSIX 1003.1c) are not currently supported in Tru64 UNIX:

pthread_mutex_getprioceiling()

pthread_mutex_setprioceiling()

pthread_mutexattr_getprioceiling()

pthread_mutexattr_setprioceiling()

pthread_mutexattr_getprotocol()

pthread_mutexattr_setprotocol()

Table 6-1 maps IRIX pthreads routines to those in Tru64 UNIX.

Table 6-1 IRIX and Tru64 UNIX pthread Routines

pthread Routine IRIX Tru64 UNIX Comments
pthread_atfork() yes yes  
pthread_attr_destroy() yes yes  
pthread_attr_getdetachstate() yes yes  
pthread_attr_getguardsize() yes yes  
pthread_attr_getinheritsched() yes yes  
pthread_attr_getschedparam() yes yes  
pthread_attr_getschedpolicy() yes yes  
pthread_attr_getscope() yes yes  
pthread_attr_getstackaddr() yes yes  
pthread_attr_getstacksize() yes yes  
pthread_attr_init() yes yes  
pthread_attr_setdetachstate() yes yes  
pthread_attr_setguardsize() yes yes  
pthread_attr_setinheritsched() yes yes  
pthread_attr_setschedparam() yes yes  
pthread_attr_setschedpolicy() yes yes Tru64 UNIX supports SCHED_OTHER, SCHED_FIFO, and SCHED_RR.
pthread_attr_setscope() yes yes  
pthread_attr_setstackaddr() yes yes  
pthread_attr_setstacksize() yes yes  
pthread_cancel() yes yes  
pthread_cleanup_pop() yes yes  
pthread_cleanup_push() yes yes  
pthread_cond_broadcast() yes yes  
pthread_cond_destroy() yes yes  
pthread_cond_init() yes yes  
pthread_cond_signal() yes yes  
pthread_cond_timedwait() yes yes  
pthread_cond_wait() yes yes  
pthread_condattr_destroy() yes yes  
pthread_condattr_getpshared() yes yes  
pthread_condattr_init() yes yes  
pthread_condattr_setpshared() yes yes  
pthread_create() yes yes  
pthread_detach() yes yes  
pthread_equal() yes yes  
pthread_exit() yes yes  
pthread_getconcurrency() yes yes Not needed in DECthreads. Provided for Single UNIX Specification, Version 2 source code compatibility.
pthread_getschedparam() yes yes  
pthread_getspecific() yes yes  
pthread_join() yes yes  
pthread_key_create() yes yes  
pthread_key_delete() yes yes  
pthread_kill() yes yes  
pthread_mutex_destroy() yes yes  
pthread_mutex_getprioceiling() yes no Not provided in Tru64 UNIX Version 5.0
pthread_mutex_init() yes yes  
pthread_mutex_lock() yes yes  
pthread_mutex_setprioceiling() yes no Not provided in Tru64 UNIX Version 5.0
pthread_mutex_trylock() yes yes  
pthread_mutex_unlock() yes yes  
pthread_mutexattr_destroy() yes yes  
pthread_mutexattr_getprioceiling() yes no Not provided in Tru64 UNIX Version 5.0
pthread_mutexattr_getprotocol() yes no Not provided in Tru64 UNIX Version 5.0
pthread_mutexattr_getpshared() yes yes  
pthread_mutexattr_gettype() yes yes  
pthread_mutexattr_init() yes yes  
pthread_mutexattr_setprioceiling() yes no Not provided in Tru64 UNIX Version 5.0
pthread_mutexattr_setprotocol() yes no Not provided in Tru64 UNIX Version 5.0
pthread_mutexattr_setpshared() yes yes  
pthread_mutexattr_settype() yes yes  
pthread_once() yes yes  
pthread_rwlock_destroy() yes yes  
pthread_rwlock_init() yes yes  
pthread_rwlock()_rdlock yes yes  
pthread_rwlock_tryrdlock() yes yes  
pthread_rwlock_trywrlock() yes yes  
pthread_rwlock_unlock() yes yes  
pthread_rwlock_wrlock() yes yes  
pthread_rwlockattr_destroy() yes yes  
pthread_rwlockattr_getpshared() yes yes  
pthread_rwlockattr_init() yes yes  
pthread_rwlockattr_setpshared() yes yes  
pthread_self() yes yes  
pthread_setcancelstate() yes yes  
pthread_setcanceltype() yes yes  
pthread_setconcurrency() yes yes Not needed in DECthreads. Provided for Single UNIX Specification, Version 2 source code compatibility.
pthread_setschedparam() yes yes  
pthread_setspecific() yes yes  
pthread_sigmask() yes yes  
pthread_testcancel() yes yes  
sched_yield() yes yes  

6.1.2 Porting Applications That Use Read-write Locks

Starting with Tru64 UNIX Version 4.0F, DECthreads implements read-write locks using the following routines. This implementation conforms to the UNIX 98 specification.

pthread_rwlock_destroy()

pthread_rwlock_init()

pthread_rwlock_rdlock()

pthread_rwlock_tryrdlock()

pthread_rwlock_trywrlock()

pthread_rwlock_unlock()

pthread_rwlock_wrlock()

pthread_rwlockattr_destroy()

pthread_rwlockattr_getpshared()

pthread_rwlockattr_init()

pthread_rwlockattr_setpshared()

6.2 Programming Notes

This section presents issues related to programming DECthreads.

6.2.1 Assumptions About Deadlock Conditions

Although DECthreads does not currently detect deadlock conditions involving more than one mutex, it might in the future. Therefore, avoid writing code that depends on DECthreads not reporting a particular error condition.

6.2.2 Memory Alignment Considerations

Alpha processors prior to EV56 (EV4 and EV5) can access memory only in units of at least a longword (4 bytes). A longword in memory can contain multiple variables, each of which is less than 4 bytes. For these older processors, when a program accesses any part of a longword that contains more than one variable, it actually retrieves and writes the entire longword. In such cases, multithreaded programs may experience a problem if two or more threads read the same longword, update different parts of it, then independently write their respective copies back to memory. The last thread to write the longword overwrites any data previously written to other parts of the longword. This can happen even though each thread protects its part of the longword with its own mutex.

The Tru64 UNIX C compiler protects scalar variables against this problem by aligning them in memory on longword (4-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 4 bytes or less could occupy the same longword in memory.

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

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

To learn the type of Alpha processor on your system, use the command /usr/sbin/psrinfo -v.

For more information on threads and memory alignment, see the Granularity Considerations section of the Guide to DECthreads.

6.2.3 DECthreads Extensions

In general, pthread routines ending in _np are not portable. The following Tru64 UNIX pthread routines are nonportable extensions and are not found in IRIX. The object naming routines, pthread_*name_np(), are available in Tru64 UNIX Version 4.0F and later releases. In the following list, they are marked with an asterisk.

  • pthread_attr_getguardsize_np()
  • pthread_attr_getname_np()*
  • pthread_attr_setguardsize_np()
  • pthread_attr_setname_np()*
  • pthread_cond_getname_np()*
  • pthread_cond_setname_np()*
  • pthread_cond_signal_int_np()
  • pthread_delay_np()
  • pthread_exc_get_status_np()
  • pthread_exc_matches_np()
  • pthread_exc_report_np()
  • pthread_exc_set_status_np()
  • pthread_get_expiration_np()
  • pthread_getname_np()*
  • pthread_getsequence_np()
  • pthread_key_getname_np()*
  • pthread_key_setname_np()*
  • pthread_lock_global_np()
  • pthread_mutex_getname_np()*
  • pthread_mutex_setname_np()*
  • pthread_mutexattr_gettype_np()
  • pthread_mutexattr_settype_np()
  • pthread_rwlock_getname_np()*
  • pthread_rwlock_setname_np()*
  • pthread_setname_np()*
  • pthread_unlock_global_np()

6.3 Files

Threads on Tru64 UNIX use the include files and shared libraries described in this section.

6.3.1 Include Files

Threads on Tru64 UNIX use the following include files:

  • pthread.h

    Provides the POSIX 1003.1c-1995 API. Include pthread.h in your program.

  • pthread_exception.h

    Supports pthread exception handling. Each C module that utiltizes DECthreads exceptions must include the pthread_exception.h header file. The Guide to DECthreads describes the use of DECthreads exceptions.

6.3.2 Shared Libraries

Threads on Tru64 UNIX use the following shared libraries:
 
libmach.so Shared version of threads support library. Direct use of mach interfaces is not supported.
libpthread.s Requires libmach.so, libexc.so, and libc.so.
libexc.so Shared version of Tru64 UNIX exception support package.
libc.so Shared version of libc (C language runtime) package.

The libexc, libmach, libpthread, and libc libraries are available to code compiled with the -pthread option to the C compiler command. For example:

% cc -o myprog myprog.c -pthread

6.4 Linking

The ld command does not support the -pthread switch or -threads switch. Instead, you must list the individual libraries in the proper order. For example:


	ld <...> -lpthread -lmach -lexc -lc

More generally, link a multithreaded application with the following switches:


	-lpthread -lmach -lexc -lc

6.5 Compiling

Compile a multithreaded application by using shared versions of libmach and libpthread as follows:


% cc -o myprog myprog.c -pthread
If you use a compiler front end or a language environment that does not support the -pthread compilation switch, you must use the -D_THREAD_SAFE compilation switch.

6.6 Debugging

Tru64 UNIX offerw two threads debugging tools:

  • Ladebug Debugger
  • Visual Threads

6.6.1 Ladebug Debugger

The Ladebug debugger provides commands to display the state of threads, mutexes, and condition variables, without using the builtin DECthreads debug facility. Using the Ladebug commands, you can examine core files and remote debug sessions, as well as run processes.

The following list is a summary of Ladebug threads commands:

  • Set breakpoints:

    
    stop [variable] [thread ID_list] [at line_number] [if expression]
    
    stop [variable] [thread ID_list] [in function] [if expression]
    

    ID_listis a list of thread IDs. If you omit ID_list, the breakpoint is set at the process level.

  • Set tracepoints:

    
    trace [variable] [thread ID_list] [at line_number] [if expression]
    
    trace [variable] [thread ID_list] [in function] [if expression]
    
    when [variable] [thread ID_list] [at line_number] [if expression]{command [; . . .]}
    
    when [variable] [thread ID_list] [at line_number] [in function]{command [; . . .]}
    

    If no ID_list is specified, the tracepoint is set at the process level.

  • Step through the current thread:

    
    	step
    	stepi
    	next
    	nexti
    

  • Resume execution of a thread put on hold, for example, at a breakpoint:

    
    cont [signal]
    

    As the current thread resumes, all other threads also continue.

    If you specify a signal, the program continues execution with that signal. The signal value can be either a signal number or a string name (for example, SIGSEGV).

  • Show threads known to the debugger:

    
    show thread [ID_list][with state == state_specification]
    

    If you do not specify any thread identifiers, the debugger displays information for all known threads.

    Use the option show thread with state == to list threads in a specific state, such as threads that are currently blocked. For example:

    
    show thread [ID_list] with state == blocked
    

    The following are valid values for state_specification:

    
    	ready
    	blocked
    	running
    	terminated
    	detached
    
  • Display the stack trace of current thread:

    
    where [number] [thread ID_list | all | *]
    

    where [number] displays the stack trace of the currently active functions for the current thread.

    where [thread] displays the stack traces of the specified threads.

    The keywords all and * are equivalent.

  • Show the registers for the current thread:

    
    printreg
    

  • Evaluate an expression in the context of the current thread:

    
    print expression
    

  • Evaluate an expression in the context of the current thread and make a call in that context:

    
    call expression
    

  • Show information about mutexes:

    
    show mutex [mutex_identifier_list] [with state == locked]
    

    Use the optional state == locked to display information only for locked mutexes.

  • Show information about condition variables:

    
    show condition [condition_ID_list] [with state == wait]
    

    If you supply one or more condition variable IDs, the debugger displays information about those condition variables that you specify, provided that the list matches the identity of currently available condition variables. If you omit the condition variable identifier specification, the debugger displays information about all condition variables currently available. For details and examples, see the chapter on debugging multithreaded applications in the Ladebug Debugger Manual.

6.6.2 Visual Threads

The Visual Threads tool lets you debug and analyze Tru64 UNIX multithreaded applications that use DECthreads or are written in Java. You can use it to debug potential thread-related logic problems, including deadlock, data protection errors, and thread usage errors. You can also use its rule-based analysis and statistics capabilities to monitor the thread-related performance of an application. It can help you identify problem areas even though the application does not show any specific problem symptoms.

Visual Threads is available on the Associated Products CD-ROM for Tru64 UNIX and is licensed as part of the Developers' Toolkit. You can also download Visual Threads from the Visual Threads web site, http://www.unix.digital.com/visualthreads/. This site also contains information about installing, licensing, starting, and using Visual Threads. Visual Threads is documented in online help.


A Transferring Data

Back to Table of Contents

If data with multibyte values is being transferred between big-endian and little-endian systems, then you must provide code that swaps the byte order. This is a simple matter. For 32-bit data, code to convert big-endian to little-endian data might look as follows:


#define SWAP4(N)        (       (( (N) & 0x00FF)     << 24) | \
                                (( (N) & 0xFF00)     << 8)  | \
                                (( (N) & 0xFF0000)   >> 8)  | \
                                (( (N) & 0xFF000000) >> 24)   \

                        )

The following I/O is transparent to endianism:

  • Data that is read and written by the framework classes

    The framework classes always store data on disk in a type-tagged, compressed binary format. The processing is such that either machine kind can read or write data. The on-disk format is the same for both types of machines.

  • Temporary files that are written then read by the same invocation of an application and that are deleted before the application terminates

If you have big-endian applications that have direct written persistent data, you can update the readers/writers in LITTLE_ENDIAN conditionally compiled code to do the byte reversal on read/write.

Suggestion: If your data file has a versioning indicator, define the existing version to be big-endian. Invent a new version value to mean little-endian. Make the READER able to recognize/read both kinds of files. The big-endian WRITER is unchanged, and the little-endian WRITER writes the little-endian version. This approach has the following advantages:

  • A write takes minimal time
  • Reads on the same machine type take (near) minimal time
  • Only cross-endian reads take more time (assumed to be the rare case)
Using Fortran to Convert Unformatted Numeric Data

DIGITAL Fortran enables programs to read and write unformatted data (originally written using unformatted I/O statements) in several nonnative floating-point formats and in big-endian INTEGER or floating-point format. This facilitates sharing a common source of unformatted data among big-endian and little-endian systems.

Converting unformatted data rather than formatted data is generally faster and is less likely to lose precision of floating-point numbers. If a converted nonnative value is outside the range of the native data type, a run-time message appears. (See the DIGITAL Fortran user manual for a list of run-time messages.)

Table A-1 lists the keywords for some of the supported unformatted file data formats. (See the DIGITAL Fortran documentation for information on other keywords you can use.)

Table A-1 Data Conversion Keywords

Keyword Results
little_endian Native little-endian integers of the appropriate INTEGER size (1, 2, 4, or 8-bytes) and native little-endian IEEE floating-point data for REAL and COMPLEX single- and double-precision numbers. These are the same formats as stored in memory.
big_endian Big-endian integer data of the appropriate INTEGER size (1, 2, or 4-bytes) and big-endian IEEE floating-point formats for REAL and COMPLEX single and double-precision numbers. INTEGER (KIND=1) or INTEGER*1 data is the same for little endian and big endian.
native No conversion occurs between memory and disk. This is the default for unformatted files. 

You can use the following methods to specify the type of nonnative (or native) format:

  • Set an environment variable for a specific unit number before the file is opened. The environment variable is named FORT_CONVERTn, where n is the unit number.

    You can use environment variables to specify multiple formats in a single program, usually one format for each specified unit number. Specify the numeric format at run time by setting the appropriate environment variable before you open that unit number.

    When you open a file, the appropriate environment variable is set. That environment variable is always used. For instance, you might use this method to specify that a unit number will use a particular format instead of the format specified in the program (perhaps in a script file that sets the environment variable before running the program).

    Suppose you have previously compiled a program that reads numeric data from unit 28. The following Korn shell command sequence sets the appropriate environment variables before running the program:

    
    	% FORT_CONVERT28 = little_endian
    	% export FORT_CONVERT28
    

  • Specify the CONVERT specifier in the OPEN statement for a specific unit number.

    For example, the following source code shows how the OPEN statement would be coded to read nonnative big-endian (IEEE floating-point) numeric data from unit 15. This data might be processed and written in native little-endian format to unit 20 (the absence of the CONVERT specifier or environment variable FORT_CONVERT20 indicates native Alpha little-endian data for unit 20):

    
    	OPEN (CONVERT='big_endian', FILE='graph3.dat',
     	FORM='UNFORMATTED', UNIT=15)
    	.
    	.
    	.
    	OPEN (FILE='graph3_axp.dat', FORM='UNFORMATTED', UNIT=20)
    

  • Compile the program with the f77 -convert command. This method affects all unit numbers that use unformatted data specified by the program.

    Specify the numeric format at compile time. You must compile all routines under the same -convert flag. You could use the same source program and compile it using different f77 commands to create multiple executable programs, each of which reads and writes different formats.

    For example, the following shell commands compile program file.f to use big-endian integer data and big-endian IEEE floating-point formats. Data is converted between the big-endian format and the little-endian memory format (little-endian integers, S_float and T_float little-endian IEEE floating-point format).

    
         % f77 -convert big_endian -o big_endian.out file.f
         % big_endian.out
    

    Because this method affects all unit numbers, you cannot read data in one format and write it in another file format unless you also use it in combination with the environment variable method or the OPEN statement CONVERT specifier method to specify a different format for a particular unit number.

If you specify more than one method, the order of precedence when you open a file with unformatted data is to check for an environment variable first, then for the OPEN statement CONVERT specifier, and then whether the f77 -convert command was used when the program was compiled.

Nonnative Data

When porting source code along with the unformatted data, note that vendors might use different units for specifying the record length (RECL specifier) of unformatted files. Whereas formatted files are specified in units of characters (bytes), unformatted files are specified in longword units for DIGITAL Fortran and some other vendors.


B Resources on the Internet

Back to Table of Contents

The following porting-related resources are available on the Internet:



Back to Table of Contents