Programmer's Guide

[Bookset] [Bookset] [Contents] [About]

About This Book

    Note to Windows users

    Recommended reading

Compiling and Debugging

    Conforming to standards

    Header files in include

    Self-hosted or cross-development

     A simple example

     Self-hosted

     Cross-development with network filesystem

     Cross-development with debugger

      Download/upload facility

     Cross-development, deeply embedded

      Step 1: Build a QNX system image.
      Step 2: Transfer the system image to the target.
      Step 3: Boot the target.

    Using libraries

     Static linking

     Dynamic linking

     Runtime loading

     Static and dynamic libraries

      Static libraries
      Dynamic libraries
      dlopen

     Platform-specific library locations

    Linking your modules

     Creating shared objects

      Specifying an internal name

    Debugging

     Debugging in a self-hosted environment

     Debugging in a cross-development environment

     The GNU debugger (gdb)

      Starting gdb

     The process-level debug agent

      Serial connection
      TCP/IP connection
       TCP/IP static port connection
       TCP/IP dynamic port connection
       Sample boot script for dynamic port sessions

    A simple debug session

     Configure the target

     Compile for debugging

     Start the debug session

     Get help

     Sample boot image

Programming Overview

    Process model

     An application as a set of processes

    Processes and threads

     Some definitions

    Priorities and scheduling

     Priority range

     BLOCKED and READY states

     The ready queue

     Suspending a running thread

     When the thread is blocked

     When the thread is preempted

     When the thread yields

    Scheduling algorithms

     FIFO scheduling

     Round-robin scheduling

    Why threads?

    Summary

Processes

    Starting processes --- two methods

    Process creation

     Concurrency

     Using fork and forkpty

     Inheriting file descriptors

    Process termination

     Normal process termination

     Abnormal process termination

     Affect of parent termination

    Detecting process termination

      Detecting termination from a starter process
      Sample parent process using wait
      Sample parent process using sigwaitinfo
      Detecting dumped processes
      Detecting the termination of daemons
      Detecting client termination

Writing a Resource Manager

    What is a Resource Manager?

      A few examples...

     Why write a Resource Manager?

     Under the covers

      Under the client's covers
      Under the resource manager's covers

     The types of resource managers

      Device resource managers
      Filesystem resource managers

    Components of a Resource Manager

     iofunc layer

     resmgr layer

     dispatch layer

     thread pool layer

    Simple device Resource Manager examples

     Single-threaded device resource manager example

      Initialize the dispatch interface
      Initialize the resource manager attributes
      Initialize functions used to handle messages
      Initialize the attribute structure used by the device
      Put a name into the namespace
      Allocate the context structure
      Start the resource manager message loop

     Multi-threaded device resource manager example

      Define THREAD_POOL_PARAM_T
      Initialize thread pool attributes
      Allocate a thread pool handle
      Start the threads

    Data carrying structures

     The open control block (ocb) structure

     The attribute structure

     The mount structure

    Handling the _IO_READ message

     Sample code for handling _IO_READ messages

     Ways of adding functionality to the resource manager

      Using the default functions
      Using the helper functions
      Writing the entire function yourself

    Handling the _IO_WRITE message

     Sample code for handling _IO_WRITE messages

    Methods of returning and replying

     Returning with an error

     Returning using an IOV array that points to your data

     Returning with a single buffer containing data

     Returning success but with no data

     Getting the resource manager library to do the reply

     Performing the reply in the server

      Leaving the client blocked, replying later

     Returning and telling the library to do the default action

    Handling other read/write details

     Handling the xtype member

      If you're not expecting extended types (xtype)

     Handling pread* and pwrite*

      Sample code for handling _IO_READ messages in pread*
      Sample code for handling _IO_WRITE messages in pwrite

     Handling readcond

    Attribute handling

     Updating the time for reads and writes

    Combine messages

     Where combine messages are used

      Atomic operations
       Using a mutex
       Per-thread files
       The readblock function
      Bandwidth considerations

     The library's combine-message handling

      Component responses
      Component data access
      Locking and unlocking the attribute structure
      Connect message types
      _IO_CONNECT_COMBINE_CLOSE
      _IO_CONNECT_COMBINE

    Extending Data Control Structures (DCS)

     Extending the ocb and attribute structures

     Extending the mount structure

    Handling devctl messages

     Sample code for handling _IO_DEVCTL messages

    Handling ionotify and select

     Sample code for handling _IO_NOTIFY messages

    Handling private messages and pulses

    Handling open, dup, and close messages

    Handling client unblocking due to signals or timeouts

    Handling interrupts

     Sample code for handling interrupts

    Multi-threaded Resource Managers

     Multi-threaded Resource Manager example

     Thread pool attributes

     Thread pool functions

    Filesystem Resource Managers

     Considerations for Filesystem Resource Managers

     Taking over more than one device

     Handling directories

      Matching at or below a mountpoint
      The _IO_OPEN message for filesystems
      Returning directory entries from _IO_READ
       Returning information associated with a directory structure

    Message types

     Connect messages

     I/O messages

    Resource Manager data structures

      _resmgr_attr_t control structure
      _resmgr_connect_funcs_t connect table
      resmgr_io_funcs_t I/O table

Qnet Networking

    Where the programmer lives

    Node descriptors aren't nids!

    How do I pass node descriptors around?

    The sys/netmgr.h header file

      netmgr_strtond
      netmgr_ndtostr
      netmgr_remote_nd

    When node descriptors are valid for a node other than its own

Writing an Interrupt Handler

    Overview

     Attaching and detaching interrupts

     The Interrupt Service Routine (ISR)

      Determining the source of the interrupt
       Edge-triggered IRQ
       Level-sensitive IRQ
      Servicing the hardware
       Safe functions
      Updating common data structures
      Signalling the application code
       Using InterruptAttach
       Using InterruptAttachEvent

    Advanced topics

     Interrupt environment

     Ordering of shared interrupts

     Interrupt latency

     Atomic Operations

Heap Analysis - Making Memory Errors a Thing of the Past

    Abstract

    Dynamic Memory Management

    Problems with Heap Corruption

    Common Errors

     Overrun/Underrun

     Requests to free

     Using Uninitialized/Stale Pointers

    Detecting and Reporting Errors

     Using the malloc_g Library

     What's Checked?

      Memory Allocation
      Reallocating Memory
      Releasing Memory

     Controlling Level of Checking

      mallopt
      MALLOC_CKACCESS
      MALLOC_FILLAREA
      MALLOC_CKCHAIN

     Forcing verification

     Controlling Error Handling

    Manual Checking (Bounds Checking)

     Getting pointer information

      find_malloc_ptr
      _mptr

     Getting the heap buffer size

      _msize
      _musize
      DH_ULEN

    Memory Leaks

     Tracing

     Causing a Trace and Giving Results

      malloc_dump_unreferenced

     Analyzing Dumps

    Compiler Support

     C++ Issues

      Clean C
      C++ Example

     Bounds Checking GCC

    Summary

Freedom from Hardware and Platform Dependencies

    Common problems

     I/O space vs memory-mapped

     Big-endian vs little-endian

      Typecast mangling
      Hardware access
      Network transparency

     Alignment and structure packing

     Atomic operations

    Solutions

     Determining endianness

     Swapping data if required

      ENDIAN_LE16
      ENDIAN_LE32
      ENDIAN_LE64
      ENDIAN_BE16
      ENDIAN_BE32
      ENDIAN_BE64

     Accessing unaligned data

      UNALIGNED_RET16
      UNALIGNED_RET32
      UNALIGNED_RET64
      UNALIGNED_PUT16
      UNALIGNED_PUT32
      UNALIGNED_PUT64

     Examples

      Mixed-endian accesses
      Accessing hardware with dual-ported memory

     Accessing I/O ports

Conventions for Makefiles and Directories

     Structure

      Makefile structure
      The recurse.mk file
      Macros
       The EARLY_DIRS and LATE_DIRS macros
       The LIST macro
      Directory structure
      The project level
      The section level (optional)
      The OS level
      The CPU level
      The variant level

     Specifying options

      The common.mk file
      The variant-level makefile
      Recognized variant names

     Using the standard macros and include files

      The qconfig.mk include file
       The preset macros
       The post-set macros
       qconfig.mk macros
      The qrules.mk include file
      The qtargets.mk include file

     Advanced topics

      Collapsing unnecessary directory levels
      Performing partial builds
      More uses for LIST

Developing SMP Systems

    Introduction

     Building an SMP image

    The impact of SMP

     To SMP or not to SMP

     Processor affinity

     SMP and synchronization primitives

     SMP and FIFO scheduling

     SMP and interrupts

     SMP and atomic operations

    Designing with SMP in mind

     Use the SMP primitives

     Assume that threads really do run concurrently

     Break the problem down

Using GDB

    GDB commands

     Command syntax

     Command completion

     Getting help

    Running programs under GDB

     Compiling for debugging

     Setting the target

     Starting your program

     Your program's arguments

     Your program's environment

     Your program's input and output

     Debugging an already-running process

     Killing the child process

     Debugging programs with multiple threads

     Debugging programs with multiple processes

    Stopping and continuing

     Breakpoints, watchpoints, and exceptions

      Setting breakpoints
      Setting watchpoints
      Breakpoints and exceptions
      Deleting breakpoints
      Disabling breakpoints
      Break conditions
      Breakpoint command lists
      Breakpoint menus

     Continuing and stepping

     Signals

     Stopping and starting multithreaded programs

    Examining the stack

     Stack frames

     Backtraces

     Selecting a frame

     Information about a frame

     MIPS machines and the function stack

    Examining source files

     Printing source lines

     Searching source files

     Specifying source directories

     Source and machine code

     Shared libraries

    Examining data

     Expressions

     Program variables

     Artificial arrays

     Output formats

     Examining memory

     Automatic display

     Print settings

     Value history

     Convenience variables

     Registers

     Floating point hardware

    Examining the symbol table

    Altering execution

     Assignment to variables

     Continuing at a different address

     Giving your program a signal

     Returning from a function

     Calling program functions

     Patching programs

Glossary


[Bookset] [Bookset] [Contents] [About]