Caution: This version of this document is no longer maintained. For the latest documentation, see http://www.qnx.com/developers/docs.

A Quick Introduction to the Adaptive Partitioning Scheduler

This chapter gives you a quick hands-on introduction to the adaptive partitioning scheduler. It assumes that you're running the Photon microGUI on your Neutrino system.

  1. Log in as root.
  2. Go to the directory that holds the buildfile for your system's boot image (e.g. /boot/build).
  3. Create a copy of the buildfile:
    cp qnxbasedma.build apsdma.build
      
  4. Edit the copy (e.g. apsdma.build).
  5. Search for procnto. The line might look like this:
        PATH=/proc/boot:/bin:/usr/bin:/opt/bin \
    LD_LIBRARY_PATH=/proc/boot:/lib:/usr/lib:/lib/dll:/opt/lib \
    procnto-instr
      

    Note: In a real buildfile, you can't use a backslash (\) to break a long line into shorter pieces, but we've done that here, just to make the command easier to read.

  6. Add [module=aps] to the beginning of the line:
        [module=aps] PATH=/proc/boot:/bin:/usr/bin:/opt/bin \
    LD_LIBRARY_PATH=/proc/boot:/lib:/usr/lib:/lib/dll:/opt/lib \
    procnto-instr
      

    You can add commands to your buildfile to create partitions and start programs in them, but when you're experimenting with adaptive partitioning, it's better to do it at runtime, so that you can easily change things. For more information, see the Setting Up and Using the Adaptive Partitioning Scheduler chapter.

  7. Save your changes to the buildfile.
  8. Generate a new boot image:
    mkifs apsdma.build apsdma.ifs
      
  9. Put the new image in place. We recommend that you copy your current boot image to /.altboot as a backup in case something goes wrong:
    cp /.altboot /.old_altboot
    cp /.boot /.altboot
    cp apsdma.ifs /.boot
      
  10. Reboot your system.
  11. Log in as a normal user.

    Note: You don't have to be root to manipulate the partitions because the security options are initially off. If you use adaptive partitioning in a product, you should choose the level of security that's appropriate. For more information, see the System Considerations chapter in this guide, and the documentation for SchedCtl() in the Neutrino Library Reference.

  12. The adaptive partitioning scheduler automatically creates one partition, called System. Use the aps utility to create another partition:
    aps create -b20 partitionA
      

    Note that the new partition's budget is subtracted from its parent partition's budget (the System partition in this case).

  13. Use the aps utility to list the partitions on your system:
    $ aps show -l
                        +---- CPU Time ----+-- Critical Time --
    Partition name   id | Budget |    Used | Budget |      Used
    --------------------+------------------+-------------------
    System            0 |    80% |  14.14% |  100ms |   0.000ms
    partitionA        1 |    20% |   0.00% |    0ms |   0.000ms
    --------------------+------------------+-------------------
    Total               |   100% |  14.14% |
      

    Note: The -l option makes this command loop until you terminate it (e.g. by pressing Ctrl-C). For this demonstration, leave it running, and start another terminal window to work in.

  14. Use the on command to start a process in the partition:
    on -Xaps=partitionA rebound &
      

    Note: Because rebound is a graphical application, it makes io-graphics (which runs in the System partition) use some CPU time. Don't set rebound to run at its highest speed, or io-graphics will starve the shells that are also running in the System partition.

  15. Create another partition and run rebound in it:
    aps create -b20 partitionB
    on -Xaps=partitionB rebound &
      
  16. To determine which partitions your processes are running in, use the pidin sched command. For adaptive partitioning, the ExtSched column displays the partition name.
  17. Create a program called greedy.c that simply loops forever:
    #include <stdlib.h>
    
    int main( void )
    {
        while (1) {
        }
    
        return EXIT_SUCCESS;
    }
      
  18. Compile it, and then run it in one of the partitions, where it will use as much CPU as possible:
    qcc -o greedy greedy.c
    on -Xaps=partitionB ./greedy &
      

    Note that the instance of rebound that's running in partitionB no longer gets much (if any) CPU time, but the one in partitionA still does, because the adaptive partitioning scheduler guarantees that partition 20% of the CPU time.

  19. Look at the output from aps. It will look something like this:
                        +---- CPU Time ----+-- Critical Time --
    Partition name   id | Budget |    Used | Budget |      Used
    --------------------+------------------+-------------------
    System            0 |    60% |  11.34% |  100ms |   0.000ms
    partitionA        1 |    20% |   2.12% |    0ms |   0.000ms
    partitionB        2 |    20% |  86.50% |    0ms |   0.000ms
    --------------------+------------------+-------------------
    Total               |   100% |  99.96% |
      

    Note that partitionB is using more than its budget of 20%. This happens because the other partitions aren't using their budgets; instead of running an idle thread in the other partitions, the adaptive partitioning scheduler gives their unused time to the partitions that need it.

  20. Start another instance of greedy in partitionA:
    on -Xaps=partitionA ./greedy &
      

    The instance of rebound in that partition grinds to a halt. The output of aps looks something like this:

                        +---- CPU Time ----+-- Critical Time --
    Partition name   id | Budget |    Used | Budget |      Used
    --------------------+------------------+-------------------
    System            0 |    60% |   1.73% |  100ms |   0.000ms
    partitionA        1 |    20% |  48.91% |    0ms |   0.000ms
    partitionB        2 |    20% |  49.32% |    0ms |   0.000ms
    --------------------+------------------+-------------------
    Total               |   100% |  99.96% |
      

    The System partition's unused time is divided between the other two partitions.

  21. Start another instance of greedy in the System partition:
    on -Xaps=System ./greedy &
      

    There's now no free time left in the system, so each partition gets only its minimum guaranteed CPU time. The output of aps looks something like this:

                        +---- CPU Time ----+-- Critical Time --
    Partition name   id | Budget |    Used | Budget |      Used
    --------------------+------------------+-------------------
    System            0 |    60% |  59.99% |  100ms |   0.000ms
    partitionA        1 |    20% |  19.97% |    0ms |   0.000ms
    partitionB        2 |    20% |  19.99% |    0ms |   0.000ms
    --------------------+------------------+-------------------
    Total               |   100% |  99.96% |
      
  22. If you slay the instances of greedy, the instances of rebound come back to life, and the consumption of CPU time drops.

Because you created the partitions at runtime instead of in your OS image, the new partitions will disappear when you restart the system.