www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Bug 12] New: Assertion in pthread

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/bugzilla/show_bug.cgi?id=12

           Summary: Assertion in pthread
           Product: D
           Version: 0.148
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: braddr puremagic.com
        ReportedBy: benoit tionex.de


Running the following code i get this assertion:

pthread_mutex_lock.c:108: __pthread_mutex_lock: Assertion
`mutex->__data.__owner == 0' failed.

GDB print this backtrace:







mango.locks.LockImpl.AbstractLock.addWaiter(mango.locks.LockImpl.AbstractLock.Node)
()












Here is the code:
----------------------------------------------------------------
module mangolocks;

import std.stdio;
import std.thread;

import mango.locks.Semaphore;

void main()
{
  auto t = new Task();
  auto taskParent = new TaskParent;
  t.configureLinks( taskParent );
  while( !t.finished )
  {
    taskParent.switchToOther( t );
  }
  t.prepareDeletion();
}

class TaskParent
{
  bit block;
  Semaphore lock;

  public this()
  {
    block = true;
    lock = new Semaphore( 0 );
  }

  public ~this()
  {
    block = false;
    delete lock;
  }

  public void unBlockAll()
  {
    block = false;
    lock.release();
  }

  public void switchToOther( TaskParent other )
  {
    if( other !is null )
    {
      other.lock.release();
    }
    if( block )
    {
      lock.acquire();
    }
  }
}

class Task : TaskParent
{
  private TaskParent mTaskParent;
  private bit finished;
  private long mNextPointInTime;
  private Thread mThread;

  public this()
  {
    super();
    mThread = new Thread( &(this.threadMethod) );
    mThread.start();
  }

  public int threadMethod()
  {
    try
    {
      // wait for parent
      switchToOther( null );
      task();
    }
    finally
    {
      finished = true;
      // unblock parent
      mTaskParent.unBlockAll();
    }
    return 0;
  }

  private void configureLinks( TaskParent aTaskParent )
  {
    mTaskParent = aTaskParent;
  }

  private void prepareDeletion()
  {
    mThread.wait();
    mTaskParent = null;
  }

  public void task()
  {
    //for( int i = 0; i < 100; ++i )
    for( int i = 0; i < 10000; ++i )
    {
      switchToOther( mTaskParent );
    }
  }
}
----------------------------------------------------------------


When i run the loop with 100 instead of 10000 this assertion error does not
occur.


-- 
Mar 05 2006
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/bugzilla/show_bug.cgi?id=12


benoit tionex.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID






I changed the program to use linux semaphores directly, then the error is gone.
Increasing the loop with factor 100 is OK as well. So I think the problem is
mango.locks related.

I forgot to post this here, sorry about that.

Here is the program that works without error:
Code:

module mangolocks;

import std.stdio;
import std.thread;

struct sem_t
{
    _pthread_fastlock __sem_lock;
    int __sem_value;
    void* __sem_waiting;
}

unittest
{
    assert(sem_t.sizeof == 16);
}

extern (C)
{
    int sem_wait(sem_t*);
    int sem_init(sem_t*, int, uint);
    int sem_post(sem_t*);
    int sem_destroy( sem_t* );
}

void main()
{
  auto t = new Task();
  auto taskParent = new TaskParent;
  t.configureLinks( taskParent );
  while( !t.finished )
  {
    taskParent.switchToOther( t );
    //writefln( "main" );
  }
  t.prepareDeletion();
}

class TaskParent
{
  bit block;
  sem_t sem;

  public this()
  {
    block = true;
    assert( sem_init( & sem, 0, 0 ) >= 0 );
  }

  public ~this()
  {
    block = false;
    sem_destroy( & sem );
  }

  public void unBlockAll()
  {
    block = false;
    sem_post( & sem );
  }

  public void switchToOther( TaskParent other )
  {
    if( other !is null )
    {
      sem_post( & other.sem );
    }
    if( block )
    {
      sem_wait( & sem );
    }
  }
}

class Task : TaskParent
{
  private TaskParent mTaskParent;
  private bit finished;
  private long mNextPointInTime;
  private Thread mThread;

  public this()
  {
    super();
    mThread = new Thread( &(this.threadMethod) );
    mThread.start();
  }

  public int threadMethod()
  {
    try
    {
      // wait for parent
      switchToOther( null );
      task();
    }
    finally
    {
      finished = true;
      // unblock parent
      mTaskParent.unBlockAll();
    }
    return 0;
  }

  private void configureLinks( TaskParent aTaskParent )
  {
    mTaskParent = aTaskParent;
  }

  private void prepareDeletion()
  {
    mThread.wait();
    mTaskParent = null;
  }

  public void task()
  {
    //for( int i = 0; i < 100; ++i )
    //for( int i = 0; i < 10000; ++i )
    for( int i = 0; i < 10000000; ++i )
    {
      switchToOther( mTaskParent );
      //writefln( "task" );
    }
  }
} 


-- 
Mar 09 2006