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