digitalmars.D.bugs - [Bug 12] New: Assertion in pthread
- d-bugmail puremagic.com (133/133) Mar 05 2006 http://d.puremagic.com/bugzilla/show_bug.cgi?id=12
- d-bugmail puremagic.com (125/125) Mar 09 2006 http://d.puremagic.com/bugzilla/show_bug.cgi?id=12
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
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








d-bugmail puremagic.com