How to explain this glibc modification on libpthread? - pthreads

We found an issue while we upgrade Yocto from 1.7 to 2.2.
App below behaves differently on newer glibc, it always got stuck on pthread_cond_destroy on glibc2.25, while on glibc2.20 it ends well.
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *thread1(void *);
void *thread2(void *);
int main(void)
{
pthread_t t_a;
pthread_t t_b;
pthread_create(&t_a,NULL,thread1,(void *)NULL);
pthread_create(&t_b,NULL,thread2,(void *)NULL);
sleep(1);
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
exit(0);
}
void *thread1(void *args)
{
pthread_cond_wait(&cond,&mutex);
}
void *thread2(void *args)
{
}
After investigation I find a glibc commit here:
https://sourceware.org/git/?p=glibc.git;a=commit;f=sysdeps/arm/nptl/bits/pthreadtypes.h;h=ed19993b5b0d05d62cc883571519a67dae481a14, which seems to be the reason.
We noticed the comment of __pthread_cond_destroy, it mentioned:
A correct program must make sure that no waiters are blocked on the
condvar when it is destroyed.
It must also ensure that no signal or broadcast are still pending to
unblock waiters.
and destruction that is concurrent with still-active waiters is
probably neither common nor performance critical.
From my perspective it brings in a defect. But glibc team seems to have a good reason. Could anybody explain whether this modification is necessary?

From the standard:
Attempting to destroy a condition variable upon which other threads
are currently blocked results in undefined behavior.
From my perspective it brings in a defect.
Your program depended on undefined behavior. Now you pay the price of doing so.

Related

Queues in FreeRTOS

I'm using Freescale FRDM-KL25Z board with Codewarrior 10.6 software. My goal is to make small program in FreeRTOS, which reads voltage from thermistor by analog/digital converter (0-3,3v) and depends on this voltage I'd like turn on/off led diodes. It worked for me till the moment, when I added second task and queues. I'm thinking that problem might be in stack size, but I have no idea how to configure it.
Code is below:
xQueueHandle queue_led;
void TaskLed (void *p)
{
uint16_t temp_val;
xQueueReceive(queue_led, &temp_val, 1);
if (temp_val<60000)
{
LED_1_Neg();
}
}
void TaskTemp (void *p)
{
uint16_t temp_val;
(void)AD1_Measure(TRUE);
(void)AD1_GetValue16(&temp_val);
xQueueSendToBack(queue_led, &temp_val, 1000);
FRTOS1_vTaskDelay(1000);
}
Code in main():
xTaskCreate(TaskLed, (signed char *)"tl", 200, NULL, 1, NULL);
xTaskCreate(TaskTemp, (signed char *)"tt", 200, NULL, 1, NULL);
vTaskStartScheduler();
return(0);
A task is normally a continuous thread of execution - that is - it is implemented as an infinite loop that runs forever. It is very rare for a task to exit its loop - and in FreeRTOS you cannot run off the bottom of a function that implements a task without deleting the task (in more recent versions of FreeRTOS you will trigger an assert if you try). Therefore the functions that implement your tasks are not valid.
FreeRTOS has excellent documentation (and an excellent support forum, for that matter, which would be a more appropriate place to post this question). You can see how a task should be written here: http://www.freertos.org/implementing-a-FreeRTOS-task.html
In the code you post I can't see that you are creating the queue that you are trying to use. That is also documented on the FreeRTOS.org website, and the download has hundreds of examples of how to do it.
If it were a stack issue then Google would show you to go here:
http://www.freertos.org/Stacks-and-stack-overflow-checking.html
You should create the queue and then check that the returned value is not zero (the queue is successfully created)

iOS using pthread_mutexattr_t trouble

i am porting an existing c++ project to objective-c++ and came across this mutex stuff. I am not sure what is done here neither if it is correct. To initialize some kind of multithreading lock mechanism (called "CriticalSection") the following is done:
#include <pthread.h>
pthread_mutex_t cs;
pthread_mutexattr_t attr;
Later in code:
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&cs, &attr);
To enter the "lock" there is:
pthread_mutex_lock(&cs);
To leave the "lock":
pthread_mutex_unlock(&cs);
pthread_mutex_destroy(&cs);
My question (since I have no clue how this is done) is: Does this look like a correct implementation?
Because I encounter problems that look like the lock mechanism just does not work (bad memory access errors, corrupt pointers in situations where the "CriticalSection" was used).
It's correct except that you don't want to destroy the mutex when unlocking. Only destroy the mutex when you can guarantee that all threads have finished with the it.
for example:
class CriticalSection
{
public:
CriticalSection()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &attr);
}
~CriticalSection() { pthread_mutex_destroy(&mutex); }
void Enter() { pthread_mutex_lock(&mutex); }
void Leave() { pthread_mutex_unlock(&mutex); }
private:
pthread_mutex_t mutex;
};

Multithreading in Ubuntu 11.10 Vmware

I'm writing a multithread program in C++ using "pthread" libraries, but when I come to execute it on Ubuntu Virtual machine, my threads don't seem to run in parallel although I have a multicore processor (i7-2630QM)... the code is too long so I'm going to explain my problem with this simple code:
#include <iostream>
#include <pthread.h>
using namespace std;
void* myfunction(void* arg); //function that the thread will execute
int main()
{
pthread_t thread;
pthread_create(&thread, NULL, myfunction, NULL); //thread created
for (int i=0; i<10; i++) //show "1" 10 times
cout << "1";
pthread_join(thread, NULL); //wait for the thread to finish executing
return 0;
}
void* myfunction(void* arg)
{
for (int j=0; j<10; j++) //show "2" 10 times
cout << "2";
return NULL;
}
When I run this code on my host OS (Windows 7 with VC++2010) I get a result like 12212121211121212..., which is what a multithread app supposed to do, but when I run the same code on the guest OS (Ubuntu on Vmware with Code::Blocks) I always get 11111111112222222222 !!!
AFAIK the thread should run in parallel with the main() function, not sequentially. My VM's core number is set to 4, but it seems that the program use only one core, I don't know what is wrong? is it the code or ...? am I missing something here?
I appreciate any help, thanks in advance and please forgive my english :/
Use a semaphore (global or passed as a parameter to my function) to synchronise the threads properly. You're probably running into timing issues due to the different scheduling characteristics between the OSes (it's not really an issue per se). Have the first thread wait on the semaphore after the call to pthread_create, and have the new thread signal it as soon as myfunction is entered.
Also, your loops are quite short, make them take longer.
example here
Windows and Linux CRT/STDC++ libs have different synchronization behaviors. You can't learn much of anything about parallel execution with calls to cout. Write some actual parallel computation and measure elapsed time to tell what's going on.

Odd behavior when creating and cancelling a thread in close succession

I'm using g++ version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) and libpthread v. 2-11-1. The following code simply creates a thread running Foo(), and immediately cancels it:
void* Foo(void*){
printf("Foo\n");
/* wait 1 second, e.g. using nanosleep() */
return NULL;
}
int main(){
pthread_t thread;
int res_create, res_cancel;
printf("creating thread\n);
res_create = pthread_create(&thread, NULL, &Foo, NULL);
res_cancel = pthread_cancel(thread);
printf("cancelled thread\n);
printf("create: %d, cancel: %d\n", res_create, res_cancel);
return 0;
}
The output I get is:
creating thread
Foo
Foo
cancelled thread
create: 0, cancel: 0
Why the second Foo output? Am I abusing the pthread API by calling pthread_cancel right after pthread_create? If so, how can I know when it's safe to touch the thread? If I so much as stick a printf() between the two, I don't have this problem.
I cannot reproduce this on a slightly newer Ubuntu. Sometimes I get one Foo and sometimes none. I had to fix a few things to get your code to compile (missing headers, missing call to some sleep function implied by a comment and string literals not closed), which indicate you did not paste the actual code which reproduced the problem.
If the problem is indeed real, it might indicate some thread cancellation problem in glibc's IO library. It looks a lot like two threads doing a flush(stdout) on the same buffer contents. Now that should never happen normally because the IO library is thread safe. But what if there is some cancellation scenario like: the thread has the mutex on stdout, and has just done a flush, but has not updated the buffer yet to clear the output. Then it is canceled before it can do that, and the main thread flushes the same data again.

How does one precisely release a pthreads rwlock after a pthread_cancel?

Consider the following program flow:
pthread_rwlock_rdlock( &mylock);
... compute a lot, maybe be the target of a pthread_cancel() ...
pthread_rwlock_unlock( &mylock);
that is going to leave the lock in a rdlock state if thread is canceled.
It appears that the "right" thing to do is to use pthread_cleanup_push() and pthread_cleanup_pop() and do the unlock inside my cleanup function, but there doesn't seem to be a valid order for the function calls:
void my_cleanup(void *arg) { pthread_rwlock_unlock(&mylock); }
...
pthread_cleanup_push( my_cleanup, 0);
/* A */
pthread_rwlock_rdlock( &mylock);
... compute a lot, maybe be the target of a pthread_cancel() ...
pthread_cleanup_pop( 1);
... that appears nearly correct, except that if the pthread_cancel() hits at "A" then the cleanup will unlock a mylock which is not yet locked leading to undefined behavior.
The whole answer may be:
void my_cleanup(void *arg) { pthread_rwlock_unlock(&mylock); }
...
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate);
pthread_cleanup_push( my_cleanup, 0);
pthread_rwlock_rdlock( &mylock);
pthread_setcancelstate( oldstate, 0);
... compute a lot, maybe be the target of a pthread_cancel() ...
pthread_cleanup_pop( 1);
but at that point it seems like I'm wrapping some well defined primitives in bandages.
So is there a better idiom for this?
Unless you allow asynchronous cancel, the pending pthread_cancel() will be processed only at known points. Therefore it should be safe to push just after successfully locking, and the pop just before unlocking.
I took a look at the glibc/nptl source and I don't see a better way than what you suggested. There's not even enough state in a rwlock for you to "cheat" and trust that the unlock side will know if you got the lock or not. If you didn't acquire the lock but someone else did, a spurious unlock will corrupt the state (rather than returning error).
In fact, offhand I can't find a reason why a well-placed SIGCANCEL couldn't interrupt pthread_rwlock_rdlock itself and leave the lll_lock (glibc internal) lock held, causing all other access to the rwlock to hang. So your PTHREAD_CANCEL_DISABLE might be even more important. Add one around the cleanup as well if you really plan to create/cancel many of these threads. It would be worth writing a test program to stress-test it.

Resources