Page 1 of 1

[Solved] pthreads_cond_xxx and CreateThread

Posted: Fri Oct 30, 2015 6:23 pm
by NicTheQuick
Hi there,

anyone here who can explain to me why this code is not working as expected? Is it a bug or not?

Code: Select all

Structure pthread_cond_t
	l.l
EndStructure

Structure pthread_mutex_t
	l.l
EndStructure

ImportC ""
	pthread_cond_signal(*cond)
EndImport

Define cond.pthread_cond_t

; Create condition variable
pthread_cond_init_(@cond, 0)

; Create mutex (internally pthread_mutex_init())
Define *mutex.pthread_mutex_t = CreateMutex()
Debug "locked? " + *mutex\l

; Lock mutex because pthread_cond_wait() needs this.
LockMutex(*mutex)
Debug "locked? " + *mutex\l

Delay(100)

Procedure signal2(*cond.pthread_cond_t)
	Delay(1000)
	Debug *cond\l
	Protected l.l = pthread_cond_signal(*cond)
	Debug "signal " + l 
EndProcedure

; Create a thread which signals the following waiter.
CreateThread(@signal2(), @cond)

Delay(100)

; Wait until the threads sends a signal.
pthread_cond_wait_(@cond, *mutex)

Delay(2000)

pthread_cond_destroy_(@cond)

FreeMutex(*mutex)

Re: pthreads_cond_xxx and CreateThread

Posted: Fri Oct 30, 2015 8:27 pm
by freak
If you are not sure its a bug, then it does not belong into the bugs section: http://www.purebasic.fr/english/viewtop ... 23&t=28694

Its also helpful to describe how you expect the code to work if you ask why it does not work "as expected".

Re: pthreads_cond_xxx and CreateThread

Posted: Fri Oct 30, 2015 9:06 pm
by NicTheQuick
I assumed the PB-Teams knows what a condition variable is and what is does. I can not explain it completely. Please read wiki: Monitor (synchronization)

I had added some comments to the code which describe what the code should do. If I start the code I get an invalid memory acces in line 1. If I comment out "CreateThread(@signal2(), @cond)" in line 36 the code runs correctly until "pthread_cond_wait_(@cond, *mutex)" is executed and waits for a signal.

I am very sure this is a bug. Of course "Threading" is enabled in the compiler options.

Re: pthreads_cond_xxx and CreateThread

Posted: Fri Oct 30, 2015 10:21 pm
by bbanelli
Works fineTM@Ubuntu 14.04.3, gcc 4.8.4

Code: Select all

locked? 0
locked? 4294967297
4294967296
signal 0
No errors of whatsoever (but I've changed structures to integers instead of longs since I've used 64 bit Ubuntu for testing)

Re: pthreads_cond_xxx and CreateThread

Posted: Fri Oct 30, 2015 11:57 pm
by freak
I know condition variables, but from your code I'm not sure you do:
  • Your structures are completely wrong: According to bits/pthreadtypes.h, the pthread_cond_t should have a size of 48 bytes. Yours is only 4 byte large. In the same way, pthread_mutex_t must be 40 bytes (x64) or 32 bytes (x86).
  • I'm not sure what the *mutex\l and *cond\l debug output should mean since these are supposed to be opaque structures, so you cannot rely on anything inside of them.
The code is simply wrong. I don't see a bug.

Re: pthreads_cond_xxx and CreateThread

Posted: Sat Oct 31, 2015 12:11 pm
by NicTheQuick
You are absolutely right. Unfortunality I used the wrong header file. For some reason I used the definition in /usr/include/newlib/sys/types.h:

Code: Select all

typedef __uint32_t pthread_cond_t;       /* identify a condition variable */

typedef struct {
  int   is_initialized;
#if defined(_POSIX_THREAD_PROCESS_SHARED)
  int   process_shared;       /* allow this to be shared amongst processes */
#endif
} pthread_condattr_t;         /* a condition attribute object */
With the correct structures it works perfectly.

Code: Select all

#__SIZEOF_PTHREAD_COND_T = 48

Structure pthread_cond_t__data
	__lock.l
	__futex.l
	__total_seq.q
	__wakeup_seq.q
	__woken_seq.q
	*__mutex
	__nwaiters.l
	__broadcast_seq.l
EndStructure

Structure pthread_cond_t
	StructureUnion
		__data.pthread_cond_t__data
		__size.a[#__SIZEOF_PTHREAD_COND_T]
		__align.q
	EndStructureUnion
EndStructure

Structure pthread_mutex_t
	l.l
EndStructure

ImportC ""
	pthread_cond_signal(*cond)
EndImport

Define cond.pthread_cond_t

; Create condition variable
pthread_cond_init_(@cond, 0)

; Create mutex (internally pthread_mutex_init())
Define *mutex.pthread_mutex_t = CreateMutex()
Debug "locked? " + *mutex\l

; Lock mutex because pthread_cond_wait() needs this.
LockMutex(*mutex)
Debug "locked? " + *mutex\l

Delay(100)

Procedure signal2(*cond.pthread_cond_t)
	Delay(1000)
	Debug *cond\__data\__nwaiters
	Protected l.l = pthread_cond_signal(*cond)
	Debug "signal " + l
EndProcedure

; Create a thread which signals the following waiter.
CreateThread(@signal2(), @cond)

Delay(100)

; Wait until the threads sends a signal.
pthread_cond_wait_(@cond, *mutex)

Delay(2000)

pthread_cond_destroy_(@cond)

FreeMutex(*mutex) 
Thank you!