[cpp-threads] High-level concurrency issues

Peter A. Buhr pabuhr at plg.uwaterloo.ca
Fri Oct 28 17:55:56 BST 2005


   Date: Mon, 17 Oct 2005 12:02:24 -0700
   From: "Boehm, Hans" <hans.boehm at hp.com>

   a) We didn't propose coroutines. I haven't seen much of a desire for
   adding those to the language. 

If all you have is hammer, everything looks like a nail. ;-) Let me push a
little longer on coroutines and then I'll sadly let it die if the Gods are
against me. The killer app for coroutines is device drivers, which are mostly
finite automata that can be coded directly as coroutines with very few errors.
Think of it: working device drivers! Wouldn't that make Windows and Linux
people happy? I'm also starting to believe most "pluggins" would be best
implemented as coroutines, allowing the pluggin to easily retain state and
execution location between calls to it.

   And I think your taxonomy remains as valid if you couple threads and stacks,
   since they're not really orthogonal anyway.

Touche, Hans! But let me argue against myself and show that the thread and
stack can actually be independent or loosely coupled.

1. People have suggested nano-tasks, where a task is an active object that only
   has state in its class variables. After the nano-task is created, a thread
   starts in one of its member routines, but that member has no local variables
   and can call no other routines; it may only modify the class variables
   created when the nano-task is allocated. Since, the storage for the
   nano-task object is allocated on another stack (or heap) and the nano-task
   does not have a stack itself, it is example of a thread without a stack.
   However, due to the significant restriction of this programming model, I
   rejected this case. But I'm willing to be talked back into it! It would
   require compiler support to statically guarantee the above restrictions.

2. In embedded systems, they do very bad things to make programs work with
   little memory and low power. The real-time scheduling often used in embedded
   systems defines independent periodic task execution. When tasks do not need
   to retain state between periodic cycles, it is possible for multiple tasks
   to use the same stack to save space. In this context, a thread *does*
   require a stack to execute, but it does not actually have its own stack.
   While this case is not actually an example of a thread without a stack, I
   thought the loose coupling was close enough to mention.

So the table is great, and treating the stack independently is still needed for
coroutines (which I know you are willing to reject).

   b) We made sure that synchronization was not too tightly coupled to a class.
   I still think it's essential to synchronize on a user-specified lock,
   e.g. to map a large number of class instances (or other data) down to a
   smaller number of locks.

I don't see how coupling mutual-exclusion and synchronization with a class
prevents you from mapping a large number of class instances down to a small
number of locks. I'm not suggesting all classes have implicit locking (like
Java's silly notion that all classes have a hidden condition variable.)  You
can compose classes with and without locking anyway the language allows.  Maybe
you can give me an example, and I can try to code it in uC++ to see how well it
does. You can then assess the solution. (This can be done off-line from this
newsgroup.)



More information about the cpp-threads mailing list