View previous topic :: View next topic |
Author |
Message |
keinfarbton
Joined: 03 Dec 2005 Posts: 224 Location: Stuttgart - Germany
|
Posted: Sat Mar 04, 2006 12:11 pm Post subject: Problem with locks on Linux |
|
|
I am running Linux debian unstable, GCC 4.0.2, dmd 0.148, phobos
I used mango from svn.
Running the following code i get this assertion:
Quote: | pthread_mutex_lock.c:108: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed. |
GDB print this backtrace:
Quote: | #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.
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 accur. |
|
Back to top |
|
|
keinfarbton
Joined: 03 Dec 2005 Posts: 224 Location: Stuttgart - Germany
|
Posted: Mon Mar 06, 2006 12:44 pm Post subject: Seem to be a mango.locks Problem |
|
|
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.
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" );
}
}
}
|
|
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Mon Mar 06, 2006 7:00 pm Post subject: |
|
|
Thanks ~ I'll look into it |
|
Back to top |
|
|
|