MTasker

"A computer is a state machine. Threads are for people who can't program state machines."
-- Alan Cox

Copyright and License

MTasker is © 2004 by bert hubert <ahu@ds9a.nl>.
It is licensed under the terms of the General Public License (GPL) version 2 (and no other).

News

2004-02-08Version 0.4 was released. A theoretically damaging bug was fixed involving delete[] vs delete, spotted by Valgrind. There is tentative Solaris support, not heavily tested. Furthermore, a new method called numProcesses() was added so the kernel can query how many processes are running, and perhaps acting on that.
2003-01-20Version 0.3 was released. This should compile under more versions of gcc, has a new method called getTid() so contexts can print a numerical presentation of their identity. It also fixes a tid accounting bug which may have affected stability.

This version powers the PowerDNS Recursing Nameserver!

Downloading

Latest release: Version 0.4 (8 February 2004)
Online documentation, Change log.

High level overview

MTasker is a two-file C++ library designed to support very simple cooperative multitasking to facilitate writing code that would ordinarily require a statemachine, for which the author does not consider himself smart enough.

This class does not perform any magic it only makes calls to makecontext() and swapcontext(). Getting the details right however is complicated and MTasker does that for you.

If preemptive multitasking or more advanced concepts such as semaphores, locks or mutexes are required, the use of POSIX threads is advised.

MTasker is designed to offer the performance of statemachines while maintaining simple thread semantics. It is not a replacement for a full threading system.

Canonical example

This implements the canonical multitasking example, alternately printing an 'A' and a 'B'. The Linux kernel started this way too.
MTasker<> MT;

void printer(void *p)
{
  char c=(char)p;
  for(;;) {
    cout<<c<<endl;
    MT.yield();
  }

}

int main()
{
  MT.makeThread(printer,(void*)'a');
  MT.makeThread(printer,(void*)'b');

  for(;;) {               // kernel loop
    while(MT.schedule()); // do everything we can do

    if(MT.noProcesses())  // exit if no processes are left
      break;
  }
}