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:
#4 0xb7e2f691 in raise () from /lib/tls/i686/cmov/libc.so.6
#5 0xb7e30f5b in abort () from /lib/tls/i686/cmov/libc.so.6
#6 0xb7e28695 in __assert_fail () from /lib/tls/i686/cmov/libc.so.6
#7 0xb7f680c9 in pthread_mutex_lock () from /lib/tls/i686/cmov/libpthread.so.0
#8 0x08049a55 in _d_monitorenter (h=0xb7d05ff0) at internal/monitor.c:142
#9 0x08056da9 in std.thread.Thread.getThis() () at std/thread.d:604
#10 0x0804d730 in
mango.locks.LockImpl.AbstractLock.addWaiter(mango.locks.LockImpl.AbstractLock.Node)
()
#11 0x0804dabb in mango.locks.LockImpl.AbstractLock.doAcquireShared(int) ()
#12 0x0804ddf8 in mango.locks.LockImpl.AbstractLock.acquireShared(int) ()
#13 0x0804caf3 in mango.locks.Semaphore.Semaphore.acquire(int) ()
#14 0x0804c73d in mangolocks.TaskParent.switchToOther(mangolocks.TaskParent) ()
#15 0x0804c81d in mangolocks.Task.task() ()
#16 0x0804c7a7 in mangolocks.Task.threadMethod() ()
#17 0x08056c7b in std.thread.Thread.run() () at std/thread.d:515
#18 0x080570e8 in std.thread.Thread.threadstart() () at std/thread.d:749
#19 0xb7f66e70 in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#20 0xb7ed6c6e in clone () from /lib/tls/i686/cmov/libc.so.6


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




------- Comment #1 from benoit tionex.de  2006-03-09 19:56 -------

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