void TaskSchedulerSys::run(size_t threadIndex, size_t threadCount)
  {
    while (true)
    {      
      /* wait for available task */
      mutex.lock();
      while ((end-begin) == 0 && !terminateThreads) {
        condition.wait(mutex); continue;
      }
      
      /* terminate this thread */
      if (terminateThreads) {
        mutex.unlock(); return;
      }

      /* take next task from stack */
      size_t i = (end-1)&(tasks.size()-1);
      Task* task = tasks[i]; 
      size_t elt = --task->started;
      if (elt == 0) end--;
      mutex.unlock();
      
      /* run the task */
      TaskScheduler::Event* event = task->event;
      thread2event[threadIndex] = event; 
      if (task->run) task->run(task->runData,threadIndex,threadCount,elt,task->elts,task->event);
      
      /* complete the task */
      if (--task->completed == 0) {
        if (task->complete) task->complete(task->completeData,threadIndex,threadCount,task->event);
        if (event) event->dec();
      } 
    }
  }
 void TaskSchedulerSys::work(size_t threadIndex, size_t threadCount, bool wait)
 {
   /* wait for available task */
   mutex.lock();
   while ((end-begin) == 0 && !terminateThreads) {
     if (wait) condition.wait(mutex);
     else { mutex.unlock(); return; }
   }
   
   /* terminate this thread */
   if (terminateThreads) {
     mutex.unlock();
     throw TaskScheduler::Terminate();
   }
   
   /* take next task from stack */
   size_t i = (end-1)&(tasks.size()-1);
   Task* task = tasks[i]; 
   size_t elt = --task->started;
   if (elt == 0) end--;
   mutex.unlock();
   
   /* run the task */
   TaskScheduler::Event* event = task->event;
   thread2event[threadIndex].event = event; 
   if (task->run) {
     size_t taskID = TaskLogger::beginTask(threadIndex,task->name,elt);
     task->run(task->runData,threadIndex,threadCount,elt,task->elts,task->event);
     TaskLogger::endTask(threadIndex,taskID);
   }
   
   /* complete the task */
   if (--task->completed == 0) {
     if (task->complete) {
       size_t taskID = TaskLogger::beginTask(threadIndex,task->name,0);
       task->complete(task->completeData,threadIndex,threadCount,task->event);
       TaskLogger::endTask(threadIndex,taskID);
     }
     if (event) event->dec();
   }
 }