Hi Dirk and Gerrit!

I have some questions and a possible feature request regarding
osg::ChangeList.


        Disabled ChangList::applyTo(int aspect)

In the source code there are a disabled method "applyTo" that
takes an aspect as argument.  Using that, it is (or would be)
possible to make the synchronization in the thread that is most
convenient.  For instance: a thread that happens to know that the
other thread(s) is locked may apply its changelist to the other
threads.  With the present solution the threads would have to be
exclusively waken up and apply the changlist to its own aspect.

I tried to enable it (the applyTo method) myself, but did not get it to work good. Synchronization seemed to work but I got
strange errors with materials (everything except background
became white).

Why was the method disabled and is it possible to get it
working and reintroduced again?


       Bug in ChangeList?

A (possible) bug in current apply() method: The readOnly members
are set to false after the method is called.  The value is set to
false on both the ChangeList instance called and the ChangeList
instance of the current thread. I assume this is not on purpose?


       Something fishy with osg::Barrier

Attached to this mail is is a short program that stress-test
osg::Barrier. At least in Win32 it fails almost immediately. If you allow some slack by introducing some sleeps in the loop, it
seems to work a bit more often. (Not that that is a pretty solution
though :-)


Best regards,

  Johan Grafström
#include <windows.h>
#include <assert.h>

#include <OpenSG/OSGBaseFunctions.h>
#include <OpenSG/OSGBarrier.h>
#include <OpenSG/OSGThread.h>
#include <OpenSG/OSGThreadManager.h>

using namespace osg;


void testFunction1(void * /* arg */);
void testFunction2(void * /* arg */);
inline void enterBarrier();


Barrier *gBarrier = NULL;


int main(int argc, char *argv[])
{
  osgInit(argc, argv);
  
  osg::Thread * thread = NULL;

  gBarrier = Barrier::get("Nisse");

  thread = dynamic_cast<Thread *>
    (ThreadManager::the()->getThread("RenderThread"));
  thread->addRef();
 
  thread->runFunction(testFunction1,
                      0,   // aspect
                      0);  // argument
  testFunction2(0);
  
  Thread::join(thread);
  thread->subRef();

  return 0;
}

volatile int gA = 0, gB = 0, gC = 0, gD = 0;

inline void enterBarrier()
{
  // Adding a pause here or in the loops makes the error occur less often 
  // (probably very seldom unless the cpu(s) are loaded)
  // Sleep(100);
  gBarrier->enter(2);
}


void testFunction1(void * /* arg */) 
{
  for (int i = 0; i < 10000; i++) {
    enterBarrier();
        // b := b + 1
    gC = gB;
    gB = gC + 1;

    enterBarrier();
        // a := a - 1
    gD = gA;
    gA = gD - 1;

    enterBarrier();
    assert(gA == 0);
    assert(gB == 0);
    
  }
}


void testFunction2(void * /* arg */)
{
  for (int i = 0; i < 10000; i++) {
    enterBarrier();
        // a := a + 1
    gD = gA;
    gA = gD + 1;

    enterBarrier();
        // b := b - 1
    gC = gB;
    gB = gC - 1;

    enterBarrier();
    assert(gA == 0);
    assert(gB == 0);
    
  }
}

Reply via email to