Finding out information about the threads

Even though we can get a lot of information about processes (above), in QNX Neutrino a process doesn't actually do anything on its own — it acts as a container for multiple threads. Therefore, to find out about the threads, we can call devctl() with the following commands:

DCMD_PROC_TIDSTATUS
This command gets most of the information about a thread, and also sets the "current thread" that's used for subsequent operations (except the next two in this list).
DCMD_PROC_GETGREG
This returns the general registers for the current thread.
DCMD_PROC_GETFPREG
This returns the floating-point registers for the current thread.

There are other commands available for manipulating the thread status (such as starting or stopping a thread, etc.), which we won't discuss here.

First we need a way of iterating through all the threads in a process. Earlier in this chapter, we called out to a function do_process(), which was responsible for the "per-process" processing. Let's now see what this function does and how it relates to finding all the threads in the process:

void
do_process (int pid, int fd, char *name)
{
  procfs_status   status;

  printf ("PROCESS ID %d\n", pid);

  // dump out per-process information
  dump_procfs_info (fd, pid);
  dump_procfs_map_info (fd, pid);
  dump_procfs_timer (fd, pid);
  dump_procfs_irq (fd, pid);

  // now iterate through all the threads
  status.tid = 1;
  while (1) {
    if (devctl (fd, DCMD_PROC_TIDSTATUS, &status,
                sizeof (status), 0) != EOK) {
      break;
    } else {
      do_thread (fd, status.tid, &status);
      status.tid++;
    }
  }
}

The do_process() function dumps out all the per-process information that we discussed above, and then iterates through the threads, calling do_thread() for each one. The trick here is to start with thread number 1 and call the devctl() with DCMD_PROC_TIDSTATUS until it returns something other than EOK. (QNX Neutrino starts numbering threads at "1.")

The magic that happens is that the kernel will return information about the thread specified in the tid member of status if it has it; otherwise, it will return information on the next available thread ID (or return something other than EOK to indicate it's done).