public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-02  8:43 pthread_mutex_timedlock() vs. clock_settime() Sebastian Huber
@ 2022-08-01  7:10 ` Joël Krähemann
  2022-08-01  7:41   ` Joël Krähemann
  2022-08-03 23:44   ` Sebastian Huber
  0 siblings, 2 replies; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01  7:10 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi Sebastian,

You have a dead-lock, probably. I just looked at your code. You are
using non-recursive mutices and I think this mutex was locked twice by
the very same thread.

 Your code is buggy.

regards,
Joël

On Mon, Aug 1, 2022 at 8:47 AM Sebastian Huber
<sebastian.huber@embedded-brains.de> wrote:
>
> Hello,
>
> I use the attached test program to check several POSIX functions which
> use an absolute CLOCK_REALTIME timeout. I noticed that the
> pthread_mutex_timedlock() with clock_settime() test cases doesn't work
> (it doesn't time out when the CLOCK_REALTIME is set past the time out
> time point). The test case works for the other synchronization objects,
> for example semaphores (sem_timedwait()) or condition variables
> (pthread_cond_timedwait()). I am not sure if this is a problem with my
> understanding of the POSIX standard, my test case implementation, or the
> glibc/Linux version. I use Linux 5.3.18.
>
> --
> embedded brains GmbH
> Herr Sebastian HUBER
> Dornierstr. 4
> 82178 Puchheim
> Germany
> email: sebastian.huber@embedded-brains.de
> phone: +49-89-18 94 741 - 16
> fax:   +49-89-18 94 741 - 08
>
> Registergericht: Amtsgericht München
> Registernummer: HRB 157899
> Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> Unsere Datenschutzerklärung finden Sie hier:
> https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01  7:10 ` Joël Krähemann
@ 2022-08-01  7:41   ` Joël Krähemann
  2022-08-03 23:44   ` Sebastian Huber
  1 sibling, 0 replies; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01  7:41 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi,

At my opinion, if you do really parallelism you should make use of
something like this:

https://www.nongnu.org/gsequencer/api/4.2.0/libags/thread.html

The AgsThread::run() function is what you usually override to run your
parallel code.

AgsConcurrencyProvider::get_task_launcher() can be used to run in
conflict free context, without any parallelism.
Your AgsTask implementation is launched while the tree is fully synchronized ...

What I want to say is, parallelism is a complex topic and libags.so
would provide abstraction to it.

regards,
Joël

On Mon, Aug 1, 2022 at 9:10 AM Joël Krähemann <jkraehemann@gmail.com> wrote:
>
> Hi Sebastian,
>
> You have a dead-lock, probably. I just looked at your code. You are
> using non-recursive mutices and I think this mutex was locked twice by
> the very same thread.
>
>  Your code is buggy.
>
> regards,
> Joël
>
> On Mon, Aug 1, 2022 at 8:47 AM Sebastian Huber
> <sebastian.huber@embedded-brains.de> wrote:
> >
> > Hello,
> >
> > I use the attached test program to check several POSIX functions which
> > use an absolute CLOCK_REALTIME timeout. I noticed that the
> > pthread_mutex_timedlock() with clock_settime() test cases doesn't work
> > (it doesn't time out when the CLOCK_REALTIME is set past the time out
> > time point). The test case works for the other synchronization objects,
> > for example semaphores (sem_timedwait()) or condition variables
> > (pthread_cond_timedwait()). I am not sure if this is a problem with my
> > understanding of the POSIX standard, my test case implementation, or the
> > glibc/Linux version. I use Linux 5.3.18.
> >
> > --
> > embedded brains GmbH
> > Herr Sebastian HUBER
> > Dornierstr. 4
> > 82178 Puchheim
> > Germany
> > email: sebastian.huber@embedded-brains.de
> > phone: +49-89-18 94 741 - 16
> > fax:   +49-89-18 94 741 - 08
> >
> > Registergericht: Amtsgericht München
> > Registernummer: HRB 157899
> > Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> > Unsere Datenschutzerklärung finden Sie hier:
> > https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-03 23:44   ` Sebastian Huber
@ 2022-08-01  8:28     ` Joël Krähemann
  2022-08-01  8:36       ` Sebastian Huber
  0 siblings, 1 reply; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01  8:28 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi,

pthread_mutex_t mtx of struct test_context.

You lock it in line 503 first, then you call test_timeout_finite(),
which calls event_post() in run() second lock.

cheers,
Joël

On Mon, Aug 1, 2022 at 9:52 AM Sebastian Huber
<sebastian.huber@embedded-brains.de> wrote:
>
> Hello Joël,
>
> On 01/08/2022 09:10, Joël Krähemann wrote:
> > Hi Sebastian,
> >
> > You have a dead-lock, probably. I just looked at your code. You are
> > using non-recursive mutices and I think this mutex was locked twice by
> > the very same thread.
>
> thanks for having a look at the test case. Sorry for being so blind, but
> which mutex is where in the code locked twice by the same thread?
>
> If I omit the mutex test case by starting with ACTION_CND_WAIT:
>
>    for (action = ACTION_CND_WAIT; action < ACTION_TERMINATE; ++action) {
>      event_post(&ctx->action, action);
>
> Then the test runs fine:
>
> *** timeout finite ***
> pthread_cond_timedwait
> wake up
> pthread_cond_timedwait: actual 'Connection timed out', expected
> 'Connection timed out'
> pthread_rwlock_timedrdlock
> wake up
> pthread_rwlock_timedrdlock: actual 'Connection timed out', expected
> 'Connection timed out'
> pthread_rwlock_timedwrlock
> wake up
> pthread_rwlock_timedwrlock: actual 'Connection timed out', expected
> 'Connection timed out'
> sem_timedwait
> wake up
> sem_timedwait: actual 'Connection timed out', expected 'Connection timed
> out'
> mq_send
> mq_timedsend
> wake up
> mq_timedsend: actual 'Connection timed out', expected 'Connection timed out'
> mq_receive
> mq_timedreceive
> wake up
> mq_timedreceive: actual 'Connection timed out', expected 'Connection
> timed out'
> clock_nanosleep
> wake up
> clock_nanosleep: actual 'Success', expected 'Success'
>
> --
> embedded brains GmbH
> Herr Sebastian HUBER
> Dornierstr. 4
> 82178 Puchheim
> Germany
> email: sebastian.huber@embedded-brains.de
> phone: +49-89-18 94 741 - 16
> fax:   +49-89-18 94 741 - 08
>
> Registergericht: Amtsgericht München
> Registernummer: HRB 157899
> Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> Unsere Datenschutzerklärung finden Sie hier:
> https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01  8:28     ` Joël Krähemann
@ 2022-08-01  8:36       ` Sebastian Huber
  2022-08-01  9:51         ` Joël Krähemann
  0 siblings, 1 reply; 13+ messages in thread
From: Sebastian Huber @ 2022-08-01  8:36 UTC (permalink / raw)
  To: Joël Krähemann; +Cc: libc-help

On 01/08/2022 10:28, Joël Krähemann wrote:
> pthread_mutex_t mtx of struct test_context.
> 
> You lock it in line 503 first, then you call test_timeout_finite(),
> which calls event_post() in run() second lock.

the event_post() and event_get() use their own data structures with 
dedicated mutexes and condition variables:

typedef struct {
   int value;
   pthread_mutex_t mtx;
   pthread_cond_t cnd;
} event;

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01  8:36       ` Sebastian Huber
@ 2022-08-01  9:51         ` Joël Krähemann
  2022-08-01 11:51           ` Joël Krähemann
  0 siblings, 1 reply; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01  9:51 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi,

Sorry, you are right. Might be your conditional lock is buggy. I think
of a race-condition ending in a dead-lock, because you don't do any
initial sync.

^^ this is really probable, but let me check later.

regards,
Joël


On Mon, Aug 1, 2022 at 10:36 AM Sebastian Huber
<sebastian.huber@embedded-brains.de> wrote:
>
> On 01/08/2022 10:28, Joël Krähemann wrote:
> > pthread_mutex_t mtx of struct test_context.
> >
> > You lock it in line 503 first, then you call test_timeout_finite(),
> > which calls event_post() in run() second lock.
>
> the event_post() and event_get() use their own data structures with
> dedicated mutexes and condition variables:
>
> typedef struct {
>    int value;
>    pthread_mutex_t mtx;
>    pthread_cond_t cnd;
> } event;
>
> --
> embedded brains GmbH
> Herr Sebastian HUBER
> Dornierstr. 4
> 82178 Puchheim
> Germany
> email: sebastian.huber@embedded-brains.de
> phone: +49-89-18 94 741 - 16
> fax:   +49-89-18 94 741 - 08
>
> Registergericht: Amtsgericht München
> Registernummer: HRB 157899
> Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> Unsere Datenschutzerklärung finden Sie hier:
> https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01  9:51         ` Joël Krähemann
@ 2022-08-01 11:51           ` Joël Krähemann
  2022-08-01 11:59             ` Joël Krähemann
  2022-08-01 16:31             ` Sebastian Huber
  0 siblings, 2 replies; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01 11:51 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi Sebastian,

You should inform yourself better about the topic. Maybe read a manual
about conditional locks. Since you are doing it wrong.

All conditional locks take 2 condition variables, in order to prevent
race-condition.

See for example here:

https://git.savannah.nongnu.org/cgit/gsequencer.git/tree/ags/thread/ags_thread.c?id=393da4d9fdc6c50ef3ab8eab27b562c85bd57664#n2002

Or check this for condition:

~~~~

volatile int is_wait;
volatile int is_done;

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER:
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

pthread_mutex_lock(&mutex);

if(g_atomic_int_get(&is_wait) &&
  !g_atomic_int_get(&is_done)){
  g_atomic_int_set(&is_wait, TRUE);

  while(g_atomic_int_get(&is_wait) &&
    !g_atomic_int_get(&is_done)){
    pthread_cond_wait(&cond);
  }
}

pthread_mutex_lock(&mutex);


~~~~

Then later signal:

~~~~

g_mutex_lock(&mutex);

g_atomic_int_set(&is_done, TRUE);

if(g_atomic_int_get(&is_wait)){
    pthread_cond_signal(&cond);
}

g_mutex_unlock(&mutex);

~~~~

regards,
Joël

On Mon, Aug 1, 2022 at 11:51 AM Joël Krähemann <jkraehemann@gmail.com> wrote:
>
> Hi,
>
> Sorry, you are right. Might be your conditional lock is buggy. I think
> of a race-condition ending in a dead-lock, because you don't do any
> initial sync.
>
> ^^ this is really probable, but let me check later.
>
> regards,
> Joël
>
>
> On Mon, Aug 1, 2022 at 10:36 AM Sebastian Huber
> <sebastian.huber@embedded-brains.de> wrote:
> >
> > On 01/08/2022 10:28, Joël Krähemann wrote:
> > > pthread_mutex_t mtx of struct test_context.
> > >
> > > You lock it in line 503 first, then you call test_timeout_finite(),
> > > which calls event_post() in run() second lock.
> >
> > the event_post() and event_get() use their own data structures with
> > dedicated mutexes and condition variables:
> >
> > typedef struct {
> >    int value;
> >    pthread_mutex_t mtx;
> >    pthread_cond_t cnd;
> > } event;
> >
> > --
> > embedded brains GmbH
> > Herr Sebastian HUBER
> > Dornierstr. 4
> > 82178 Puchheim
> > Germany
> > email: sebastian.huber@embedded-brains.de
> > phone: +49-89-18 94 741 - 16
> > fax:   +49-89-18 94 741 - 08
> >
> > Registergericht: Amtsgericht München
> > Registernummer: HRB 157899
> > Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> > Unsere Datenschutzerklärung finden Sie hier:
> > https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01 11:51           ` Joël Krähemann
@ 2022-08-01 11:59             ` Joël Krähemann
  2022-08-01 14:44               ` Joël Krähemann
  2022-08-01 16:31             ` Sebastian Huber
  1 sibling, 1 reply; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01 11:59 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi,

I co authored an article, check the section about working with parallelism:

https://opensource.com/article/21/11/community-code-stories

regards,
Joël

On Mon, Aug 1, 2022 at 1:51 PM Joël Krähemann <jkraehemann@gmail.com> wrote:
>
> Hi Sebastian,
>
> You should inform yourself better about the topic. Maybe read a manual
> about conditional locks. Since you are doing it wrong.
>
> All conditional locks take 2 condition variables, in order to prevent
> race-condition.
>
> See for example here:
>
> https://git.savannah.nongnu.org/cgit/gsequencer.git/tree/ags/thread/ags_thread.c?id=393da4d9fdc6c50ef3ab8eab27b562c85bd57664#n2002
>
> Or check this for condition:
>
> ~~~~
>
> volatile int is_wait;
> volatile int is_done;
>
> static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER:
> static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
>
> pthread_mutex_lock(&mutex);
>
> if(g_atomic_int_get(&is_wait) &&
>   !g_atomic_int_get(&is_done)){
>   g_atomic_int_set(&is_wait, TRUE);
>
>   while(g_atomic_int_get(&is_wait) &&
>     !g_atomic_int_get(&is_done)){
>     pthread_cond_wait(&cond);
>   }
> }
>
> pthread_mutex_lock(&mutex);
>
>
> ~~~~
>
> Then later signal:
>
> ~~~~
>
> g_mutex_lock(&mutex);
>
> g_atomic_int_set(&is_done, TRUE);
>
> if(g_atomic_int_get(&is_wait)){
>     pthread_cond_signal(&cond);
> }
>
> g_mutex_unlock(&mutex);
>
> ~~~~
>
> regards,
> Joël
>
> On Mon, Aug 1, 2022 at 11:51 AM Joël Krähemann <jkraehemann@gmail.com> wrote:
> >
> > Hi,
> >
> > Sorry, you are right. Might be your conditional lock is buggy. I think
> > of a race-condition ending in a dead-lock, because you don't do any
> > initial sync.
> >
> > ^^ this is really probable, but let me check later.
> >
> > regards,
> > Joël
> >
> >
> > On Mon, Aug 1, 2022 at 10:36 AM Sebastian Huber
> > <sebastian.huber@embedded-brains.de> wrote:
> > >
> > > On 01/08/2022 10:28, Joël Krähemann wrote:
> > > > pthread_mutex_t mtx of struct test_context.
> > > >
> > > > You lock it in line 503 first, then you call test_timeout_finite(),
> > > > which calls event_post() in run() second lock.
> > >
> > > the event_post() and event_get() use their own data structures with
> > > dedicated mutexes and condition variables:
> > >
> > > typedef struct {
> > >    int value;
> > >    pthread_mutex_t mtx;
> > >    pthread_cond_t cnd;
> > > } event;
> > >
> > > --
> > > embedded brains GmbH
> > > Herr Sebastian HUBER
> > > Dornierstr. 4
> > > 82178 Puchheim
> > > Germany
> > > email: sebastian.huber@embedded-brains.de
> > > phone: +49-89-18 94 741 - 16
> > > fax:   +49-89-18 94 741 - 08
> > >
> > > Registergericht: Amtsgericht München
> > > Registernummer: HRB 157899
> > > Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> > > Unsere Datenschutzerklärung finden Sie hier:
> > > https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01 11:59             ` Joël Krähemann
@ 2022-08-01 14:44               ` Joël Krähemann
  0 siblings, 0 replies; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01 14:44 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi Sebastian,

Since you are new to parallelism, make sure you know about cache
coherency and its implications.

https://www.intel.com/content/dam/support/us/en/documents/processors/pentium4/sb/25366821.pdf

There are different synchronization scenarios.

1. hit and run, you can use ordinary boolean variables in your conditional lock
2. continuously synchronization within a loop, use atomic boolean
variables in your conditional lock

The second case is different. You probably want to take advantage of
atomic operations memory barrier behaviour.

regards,
Joël

On Mon, Aug 1, 2022 at 1:59 PM Joël Krähemann <jkraehemann@gmail.com> wrote:
>
> Hi,
>
> I co authored an article, check the section about working with parallelism:
>
> https://opensource.com/article/21/11/community-code-stories
>
> regards,
> Joël
>
> On Mon, Aug 1, 2022 at 1:51 PM Joël Krähemann <jkraehemann@gmail.com> wrote:
> >
> > Hi Sebastian,
> >
> > You should inform yourself better about the topic. Maybe read a manual
> > about conditional locks. Since you are doing it wrong.
> >
> > All conditional locks take 2 condition variables, in order to prevent
> > race-condition.
> >
> > See for example here:
> >
> > https://git.savannah.nongnu.org/cgit/gsequencer.git/tree/ags/thread/ags_thread.c?id=393da4d9fdc6c50ef3ab8eab27b562c85bd57664#n2002
> >
> > Or check this for condition:
> >
> > ~~~~
> >
> > volatile int is_wait;
> > volatile int is_done;
> >
> > static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER:
> > static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
> >
> > pthread_mutex_lock(&mutex);
> >
> > if(g_atomic_int_get(&is_wait) &&
> >   !g_atomic_int_get(&is_done)){
> >   g_atomic_int_set(&is_wait, TRUE);
> >
> >   while(g_atomic_int_get(&is_wait) &&
> >     !g_atomic_int_get(&is_done)){
> >     pthread_cond_wait(&cond);
> >   }
> > }
> >
> > pthread_mutex_lock(&mutex);
> >
> >
> > ~~~~
> >
> > Then later signal:
> >
> > ~~~~
> >
> > g_mutex_lock(&mutex);
> >
> > g_atomic_int_set(&is_done, TRUE);
> >
> > if(g_atomic_int_get(&is_wait)){
> >     pthread_cond_signal(&cond);
> > }
> >
> > g_mutex_unlock(&mutex);
> >
> > ~~~~
> >
> > regards,
> > Joël
> >
> > On Mon, Aug 1, 2022 at 11:51 AM Joël Krähemann <jkraehemann@gmail.com> wrote:
> > >
> > > Hi,
> > >
> > > Sorry, you are right. Might be your conditional lock is buggy. I think
> > > of a race-condition ending in a dead-lock, because you don't do any
> > > initial sync.
> > >
> > > ^^ this is really probable, but let me check later.
> > >
> > > regards,
> > > Joël
> > >
> > >
> > > On Mon, Aug 1, 2022 at 10:36 AM Sebastian Huber
> > > <sebastian.huber@embedded-brains.de> wrote:
> > > >
> > > > On 01/08/2022 10:28, Joël Krähemann wrote:
> > > > > pthread_mutex_t mtx of struct test_context.
> > > > >
> > > > > You lock it in line 503 first, then you call test_timeout_finite(),
> > > > > which calls event_post() in run() second lock.
> > > >
> > > > the event_post() and event_get() use their own data structures with
> > > > dedicated mutexes and condition variables:
> > > >
> > > > typedef struct {
> > > >    int value;
> > > >    pthread_mutex_t mtx;
> > > >    pthread_cond_t cnd;
> > > > } event;
> > > >
> > > > --
> > > > embedded brains GmbH
> > > > Herr Sebastian HUBER
> > > > Dornierstr. 4
> > > > 82178 Puchheim
> > > > Germany
> > > > email: sebastian.huber@embedded-brains.de
> > > > phone: +49-89-18 94 741 - 16
> > > > fax:   +49-89-18 94 741 - 08
> > > >
> > > > Registergericht: Amtsgericht München
> > > > Registernummer: HRB 157899
> > > > Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> > > > Unsere Datenschutzerklärung finden Sie hier:
> > > > https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01 11:51           ` Joël Krähemann
  2022-08-01 11:59             ` Joël Krähemann
@ 2022-08-01 16:31             ` Sebastian Huber
  2022-08-01 20:11               ` Joël Krähemann
  1 sibling, 1 reply; 13+ messages in thread
From: Sebastian Huber @ 2022-08-01 16:31 UTC (permalink / raw)
  To: Joël Krähemann; +Cc: libc-help

Hello Joël,

this is just a test case and not a real application. There is only a 
main thread and a worker thread.  The worker thread should just block on 
an synchronization object and then wait for a time out (or it is 
cancelled). The main thread uses a simple sleep(1) to hopefully ensure 
that the worker task had enough time to block on the synchronization 
object under test. There are different action and done events. Since a 
mutex is used, there is no need for atomic objects.

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01 16:31             ` Sebastian Huber
@ 2022-08-01 20:11               ` Joël Krähemann
  2022-08-01 22:05                 ` Joël Krähemann
  0 siblings, 1 reply; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01 20:11 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi Sebastian,

I am unsure where are your doubts in what I told you:

#1 conditional locks always use 2 condition variables with logical and
#2 signal only waiting conditions

The points above apply to any conditional lock. Thought, there is an
exception for synchronized threads. But your threads aren't
synchronized.

If your conditional lock is invoked more than once:

#3 do initial sync
#4 provide additional variables to avoid override by previous run.
Yes, we need some tuples. If you use three you can even detect
dead-locks.
#5 your threads may run on a different CPU even physically. You need
atomic operations.

I am willing to do further explanation, but what I am telling you is
based on experience with AgsThread::clock()

https://git.savannah.nongnu.org/cgit/gsequencer.git/tree/ags/thread/ags_thread.c?h=4.3.x#n2302

This code was reworked by me different times to fine tune it. First I
was using the POSIX API and migrated later to GLib.

regards,
Joël

On Mon, Aug 1, 2022 at 6:31 PM Sebastian Huber
<sebastian.huber@embedded-brains.de> wrote:
>
> Hello Joël,
>
> this is just a test case and not a real application. There is only a
> main thread and a worker thread.  The worker thread should just block on
> an synchronization object and then wait for a time out (or it is
> cancelled). The main thread uses a simple sleep(1) to hopefully ensure
> that the worker task had enough time to block on the synchronization
> object under test. There are different action and done events. Since a
> mutex is used, there is no need for atomic objects.
>
> --
> embedded brains GmbH
> Herr Sebastian HUBER
> Dornierstr. 4
> 82178 Puchheim
> Germany
> email: sebastian.huber@embedded-brains.de
> phone: +49-89-18 94 741 - 16
> fax:   +49-89-18 94 741 - 08
>
> Registergericht: Amtsgericht München
> Registernummer: HRB 157899
> Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> Unsere Datenschutzerklärung finden Sie hier:
> https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01 20:11               ` Joël Krähemann
@ 2022-08-01 22:05                 ` Joël Krähemann
  0 siblings, 0 replies; 13+ messages in thread
From: Joël Krähemann @ 2022-08-01 22:05 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: libc-help

Hi Sebastian,

About atomic operations and its memory barriers. It gives you
additional synchronization to target 1 problem.

You don't have any promise on what time or order your code is executed
on assembly level and on the stack.

GCC can change program flow.

regards,
Joël

On Mon, Aug 1, 2022 at 10:11 PM Joël Krähemann <jkraehemann@gmail.com> wrote:
>
> Hi Sebastian,
>
> I am unsure where are your doubts in what I told you:
>
> #1 conditional locks always use 2 condition variables with logical and
> #2 signal only waiting conditions
>
> The points above apply to any conditional lock. Thought, there is an
> exception for synchronized threads. But your threads aren't
> synchronized.
>
> If your conditional lock is invoked more than once:
>
> #3 do initial sync
> #4 provide additional variables to avoid override by previous run.
> Yes, we need some tuples. If you use three you can even detect
> dead-locks.
> #5 your threads may run on a different CPU even physically. You need
> atomic operations.
>
> I am willing to do further explanation, but what I am telling you is
> based on experience with AgsThread::clock()
>
> https://git.savannah.nongnu.org/cgit/gsequencer.git/tree/ags/thread/ags_thread.c?h=4.3.x#n2302
>
> This code was reworked by me different times to fine tune it. First I
> was using the POSIX API and migrated later to GLib.
>
> regards,
> Joël
>
> On Mon, Aug 1, 2022 at 6:31 PM Sebastian Huber
> <sebastian.huber@embedded-brains.de> wrote:
> >
> > Hello Joël,
> >
> > this is just a test case and not a real application. There is only a
> > main thread and a worker thread.  The worker thread should just block on
> > an synchronization object and then wait for a time out (or it is
> > cancelled). The main thread uses a simple sleep(1) to hopefully ensure
> > that the worker task had enough time to block on the synchronization
> > object under test. There are different action and done events. Since a
> > mutex is used, there is no need for atomic objects.
> >
> > --
> > embedded brains GmbH
> > Herr Sebastian HUBER
> > Dornierstr. 4
> > 82178 Puchheim
> > Germany
> > email: sebastian.huber@embedded-brains.de
> > phone: +49-89-18 94 741 - 16
> > fax:   +49-89-18 94 741 - 08
> >
> > Registergericht: Amtsgericht München
> > Registernummer: HRB 157899
> > Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> > Unsere Datenschutzerklärung finden Sie hier:
> > https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* pthread_mutex_timedlock() vs. clock_settime()
@ 2022-08-02  8:43 Sebastian Huber
  2022-08-01  7:10 ` Joël Krähemann
  0 siblings, 1 reply; 13+ messages in thread
From: Sebastian Huber @ 2022-08-02  8:43 UTC (permalink / raw)
  To: libc-help

[-- Attachment #1: Type: text/plain, Size: 1054 bytes --]

Hello,

I use the attached test program to check several POSIX functions which 
use an absolute CLOCK_REALTIME timeout. I noticed that the 
pthread_mutex_timedlock() with clock_settime() test cases doesn't work 
(it doesn't time out when the CLOCK_REALTIME is set past the time out 
time point). The test case works for the other synchronization objects, 
for example semaphores (sem_timedwait()) or condition variables 
(pthread_cond_timedwait()). I am not sure if this is a problem with my 
understanding of the POSIX standard, my test case implementation, or the 
glibc/Linux version. I use Linux 5.3.18.

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/

[-- Attachment #2: init.c --]
[-- Type: text/x-csrc, Size: 13421 bytes --]

/*
 * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rtems.com/license/LICENSE.
 */

/*
 * This test program runs also on GNU/Linux.  Use
 *
 * cc init.c -pthread -Wall -Wextra -lrt && sudo ./a.out
 *
 * to run it.  It must run probably as root for the clock_settime().
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <mqueue.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#ifdef __rtems__

#include "tmacros.h"

#else /* __rtems__ */

#include <assert.h>

#define rtems_test_assert(x) assert(x)

#endif /* __rtems__ */

static void assert_eno(const char *hint, int eno, int expected_eno)
{
  const char *warn;

  if (eno != expected_eno) {
    warn = "WARNING: ";
  } else {
    warn = "";
  }

  printf(
    "%s%s: actual '%s', expected '%s'\n",
    warn,
    hint,
    strerror(eno),
    strerror(expected_eno)
  );
#ifdef __rtems__
  rtems_test_assert(eno == expected_eno);
#endif /* __rtems__ */
}

static void assert_rv(const char *hint, int rv, int expected_eno)
{
  int eno;

  if (rv != 0) {
    eno = errno;
  } else {
    eno = 0;
  }

  assert_eno(hint, eno, expected_eno);
}

typedef struct {
  char data;
} test_msg;

#define MSG_COUNT 1

#define MSG_SIZE sizeof(test_msg)

typedef struct {
  int value;
  pthread_mutex_t mtx;
  pthread_cond_t cnd;
} event;

typedef enum {
  ACTION_NONE,
  ACTION_MTX_LOCK,
  ACTION_CND_WAIT,
  ACTION_RW_RDLOCK,
  ACTION_RW_WRLOCK,
  ACTION_SEM_WAIT,
  ACTION_MQ_SEND,
  ACTION_MQ_RECV,
  ACTION_CLOCK_NANOSLEEP,
  ACTION_TERMINATE
} test_action;

typedef enum {
  MODE_TIMEOUT_FINITE,
  MODE_TIMEOUT_NEGATIVE_SEC,
  MODE_TIMEOUT_NEGATIVE_NSEC,
  MODE_TIMEOUT_NEGATIVE_SEC_NSEC,
  MODE_TIMEOUT_HUGE_NSEC,
#ifdef __rtems__
  MODE_TIMEOUT_NULL,
#endif /* __rtems__ */
  MODE_TIMEOUT_PRACTICALLY_INFINITE,
  MODE_COUNT
} test_mode;

typedef struct {
  test_mode mode;
  pthread_t worker;
  event action;
  event done;
  pthread_mutex_t mtx;
  pthread_mutex_t mtx2;
  pthread_cond_t cnd;
  pthread_rwlock_t rw;
  sem_t sem;
  mqd_t mq;
  int counter[ACTION_TERMINATE + 1];
} test_context;

static test_context test_instance;

static void event_init(event *e)
{
  int eno;

  eno = pthread_mutex_init(&e->mtx, NULL);
  rtems_test_assert(eno == 0);

  eno = pthread_cond_init(&e->cnd, NULL);
  rtems_test_assert(eno == 0);
}

static void event_destroy(event *e)
{
  int eno;

  eno = pthread_mutex_destroy(&e->mtx);
  rtems_test_assert(eno == 0);

  eno = pthread_cond_destroy(&e->cnd);
  rtems_test_assert(eno == 0);
}

static void event_post(event *e, int value)
{
  int eno;

  eno = pthread_mutex_lock(&e->mtx);
  rtems_test_assert(eno == 0);

  e->value = value;

  eno = pthread_cond_signal(&e->cnd);
  rtems_test_assert(eno == 0);

  eno = pthread_mutex_unlock(&e->mtx);
  rtems_test_assert(eno == 0);
}

static int event_get(event *e)
{
  int eno;
  int value;

  eno = pthread_mutex_lock(&e->mtx);
  rtems_test_assert(eno == 0);

  while (true) {
    value = e->value;

    if (value != 0) {
      e->value = 0;
      break;
    }

    eno = pthread_cond_wait(&e->cnd, &e->mtx);
    rtems_test_assert(eno == 0);
  }

  eno = pthread_mutex_unlock(&e->mtx);
  rtems_test_assert(eno == 0);

  return value;
}

static void *worker(void *arg)
{
  test_context *ctx;
  test_action action;
  test_mode mode;
  int eno;
  int unused;

  ctx = arg;
  mode = ctx->mode;

  eno = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &unused);
  rtems_test_assert(eno == 0);

  eno = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &unused);
  rtems_test_assert(eno == 0);

  while ((action = event_get(&ctx->action)) != ACTION_TERMINATE) {
    int rv;
    struct timespec to_storage;
    const struct timespec *to;
    int expected_eno;
    test_msg msg;
    unsigned prio;

    switch (mode) {
      case MODE_TIMEOUT_FINITE:
        rv = clock_gettime(CLOCK_REALTIME, &to_storage);
        rtems_test_assert(rv == 0);

        to_storage.tv_sec += 3600;
        to = &to_storage;
        expected_eno = ETIMEDOUT;
        break;
      case MODE_TIMEOUT_NEGATIVE_SEC:
        to_storage.tv_sec = -1;
        to_storage.tv_nsec = 1;
        to = &to_storage;
        expected_eno = ETIMEDOUT;
        break;
      case MODE_TIMEOUT_NEGATIVE_NSEC:
        to_storage.tv_sec = 1;
        to_storage.tv_nsec = -1;
        to = &to_storage;
        expected_eno = EINVAL;
        break;
      case MODE_TIMEOUT_NEGATIVE_SEC_NSEC:
        to_storage.tv_sec = -1;
        to_storage.tv_nsec = -1;
        to = &to_storage;
        expected_eno = EINVAL;
        break;
      case MODE_TIMEOUT_HUGE_NSEC:
        to_storage.tv_sec = 1;
        to_storage.tv_nsec = LONG_MAX;
        to = &to_storage;
        expected_eno = EINVAL;
        break;
#ifdef __rtems__
      case MODE_TIMEOUT_NULL:
        to = NULL;
        expected_eno = EINVAL;
        break;
#endif /* __rtems__ */
      case MODE_TIMEOUT_PRACTICALLY_INFINITE:
        to_storage.tv_sec = INT64_MAX;
        to_storage.tv_nsec = 999999999;
        to = &to_storage;
        expected_eno = -1;
        break;
      default:
        to = NULL;
        expected_eno = -1;
        rtems_test_assert(0);
        break;
    }

    switch (action) {
      case ACTION_MTX_LOCK:
        puts("pthread_mutex_timedlock");
        eno = pthread_mutex_timedlock(&ctx->mtx, to);
        assert_eno("pthread_mutex_timedlock", eno, expected_eno);
        break;
      case ACTION_CND_WAIT:
        eno = pthread_mutex_lock(&ctx->mtx2);
        rtems_test_assert(eno == 0);

        puts("pthread_cond_timedwait");
        eno = pthread_cond_timedwait(&ctx->cnd, &ctx->mtx2, to);
        assert_eno("pthread_cond_timedwait", eno, expected_eno);

        eno = pthread_mutex_unlock(&ctx->mtx2);
        rtems_test_assert(eno == 0);
        break;
      case ACTION_RW_RDLOCK:
        puts("pthread_rwlock_timedrdlock");
        eno = pthread_rwlock_timedrdlock(&ctx->rw, to);
        assert_eno("pthread_rwlock_timedrdlock", eno, expected_eno);
        break;
      case ACTION_RW_WRLOCK:
        puts("pthread_rwlock_timedwrlock");
        eno = pthread_rwlock_timedwrlock(&ctx->rw, to);
        assert_eno("pthread_rwlock_timedwrlock", eno, expected_eno);
        break;
      case ACTION_SEM_WAIT:
        puts("sem_timedwait");
        errno = 0;
        rv = sem_timedwait(&ctx->sem, to);
        assert_rv("sem_timedwait", rv, expected_eno);
        break;
      case ACTION_MQ_SEND:
        puts("mq_send");
        msg.data = 13;
        rv = mq_send(ctx->mq, &msg.data, sizeof(msg), 7);
        rtems_test_assert(rv == 0);
        puts("mq_timedsend");
        msg.data = 31;
        errno = 0;
        rv = mq_timedsend(ctx->mq, &msg.data, sizeof(msg), 5, to);
        assert_rv("mq_timedsend", rv, expected_eno);
        break;
      case ACTION_MQ_RECV:
        puts("mq_receive");
        msg.data = 0;
        prio = 0;
        rv = mq_receive(ctx->mq, &msg.data, sizeof(msg), &prio);
        rtems_test_assert(rv == 1);
        rtems_test_assert(msg.data == 13);
        rtems_test_assert(prio == 7);
        puts("mq_timedreceive");
        msg.data = 0;
        prio = 0;
        errno = 0;
        rv = mq_timedreceive(ctx->mq, &msg.data, sizeof(msg), &prio, to);
        assert_rv("mq_timedreceive", rv, expected_eno);
        rtems_test_assert(msg.data == 0);
        rtems_test_assert(prio == 0);
        break;
      case ACTION_CLOCK_NANOSLEEP:
        puts("clock_nanosleep");
        rv = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, to, NULL);

        if (expected_eno == ETIMEDOUT) {
          assert_rv("clock_nanosleep", rv, 0);
        } else {
          assert_rv("clock_nanosleep", rv, expected_eno);
        }
        break;
      default:
        rtems_test_assert(0);
        break;
    }

    ++ctx->counter[action];

    event_post(&ctx->done, 1);
  }

  return ctx;
}

static void delay(void)
{
  int rv;

  rv = sleep(1);
  rtems_test_assert(rv == 0);
}

static void run(
  test_context *ctx,
  const char *test,
  test_mode mode,
  void (*f)(void)
)
{
  test_action action;
  int eno;
  void *status;

  printf("*** %s ***\n", test);
  ctx->mode = mode;

  eno = pthread_create(&ctx->worker, NULL, worker, ctx);
  rtems_test_assert(eno == 0);

  for (action = ACTION_MTX_LOCK; action < ACTION_TERMINATE; ++action) {
    event_post(&ctx->action, action);
    delay();

    puts("wake up");
    (*f)();

    event_get(&ctx->done);
  }

  event_post(&ctx->action, ACTION_TERMINATE);

  status = NULL;
  eno = pthread_join(ctx->worker, &status);
  rtems_test_assert(eno == 0);
  rtems_test_assert(status == ctx);
}

static void timeout_finite(void)
{
  struct timespec now;
  int rv;

  rv = clock_gettime(CLOCK_REALTIME, &now);
  rtems_test_assert(rv == 0);

  now.tv_sec += 7200;

  rv = clock_settime(CLOCK_REALTIME, &now);
  rtems_test_assert(rv == 0);
}

static void test_timeout_finite(test_context *ctx)
{
  run(ctx, "timeout finite", MODE_TIMEOUT_FINITE, timeout_finite);
}

static void do_nothing(void)
{
  /* Do nothing */
}

static void test_timeout_negative_sec(test_context *ctx)
{
  run(ctx, "timeout negative sec", MODE_TIMEOUT_NEGATIVE_SEC, do_nothing);
}

static void test_timeout_negative_nsec(test_context *ctx)
{
  run(ctx, "timout negative nsec", MODE_TIMEOUT_NEGATIVE_NSEC, do_nothing);
}

static void test_timeout_negative_sec_nsec(test_context *ctx)
{
  run(
    ctx,
    "timout negative sec and nsec",
    MODE_TIMEOUT_NEGATIVE_SEC_NSEC,
    do_nothing
  );
}

static void test_timeout_huge_nsec(test_context *ctx)
{
  run(ctx, "timout huge nsec", MODE_TIMEOUT_HUGE_NSEC, do_nothing);
}

#ifdef __rtems__
static void test_timeout_null(test_context *ctx)
{
  run(ctx, "timeout NULL", MODE_TIMEOUT_NULL, do_nothing);
}
#endif /* __rtems__ */

static void test_timeout_practically_infinite(test_context *ctx)
{
  test_action action;
  int eno;

  puts("*** timeout practically infinite ***");
  ctx->mode = MODE_TIMEOUT_PRACTICALLY_INFINITE;

  for (action = ACTION_MTX_LOCK; action < ACTION_TERMINATE; ++action) {
    void *status;

    eno = pthread_create(&ctx->worker, NULL, worker, ctx);
    rtems_test_assert(eno == 0);

    event_post(&ctx->action, action);
    delay();

    eno = pthread_cancel(ctx->worker);
    rtems_test_assert(eno == 0);

    status = NULL;
    eno = pthread_join(ctx->worker, &status);
    rtems_test_assert(eno == 0);
    rtems_test_assert(status == PTHREAD_CANCELED);
  }
}

static void test(test_context *ctx)
{
  test_action action;
  int eno;
  int rv;
  mode_t mode;
  struct mq_attr ma;

  event_init(&ctx->action);
  event_init(&ctx->done);

  eno = pthread_mutex_init(&ctx->mtx, NULL);
  rtems_test_assert(eno == 0);

  eno = pthread_mutex_lock(&ctx->mtx);
  rtems_test_assert(eno == 0);

  eno = pthread_mutex_init(&ctx->mtx2, NULL);
  rtems_test_assert(eno == 0);

  eno = pthread_cond_init(&ctx->cnd, NULL);
  rtems_test_assert(eno == 0);

  eno = pthread_rwlock_init(&ctx->rw, NULL);
  rtems_test_assert(eno == 0);

  eno = pthread_rwlock_wrlock(&ctx->rw);
  rtems_test_assert(eno == 0);

  rv = sem_init(&ctx->sem, 0, 0);
  rtems_test_assert(rv == 0);

  mode = S_IRWXU | S_IRWXG | S_IRWXO;
  memset(&ma, 0, sizeof(ma));
  ma.mq_maxmsg = MSG_COUNT;
  ma.mq_msgsize = MSG_SIZE;
  ctx->mq = mq_open("/mq", O_CREAT | O_RDWR, mode, &ma);
  rtems_test_assert(ctx->mq != (mqd_t) -1);

  test_timeout_finite(ctx);
  test_timeout_negative_sec(ctx);
  test_timeout_negative_nsec(ctx);
  test_timeout_negative_sec_nsec(ctx);
  test_timeout_huge_nsec(ctx);
#ifdef __rtems__
  test_timeout_null(ctx);
#endif /* __rtems__ */
  test_timeout_practically_infinite(ctx);

  event_destroy(&ctx->action);
  event_destroy(&ctx->done);

  eno = pthread_mutex_unlock(&ctx->mtx);
  rtems_test_assert(eno == 0);

  eno = pthread_mutex_destroy(&ctx->mtx);
  rtems_test_assert(eno == 0);

  eno = pthread_mutex_destroy(&ctx->mtx2);
#ifdef __rtems__
  rtems_test_assert(eno == 0);
#else /* __rtems__ */
  rtems_test_assert(eno == 0 || eno == EBUSY);
#endif /* __rtems__ */

  eno = pthread_cond_destroy(&ctx->cnd);
  rtems_test_assert(eno == 0);

  eno = pthread_rwlock_unlock(&ctx->rw);
  rtems_test_assert(eno == 0);

  eno = pthread_rwlock_destroy(&ctx->rw);
  rtems_test_assert(eno == 0);

  rv = sem_destroy(&ctx->sem);
  rtems_test_assert(rv == 0);

  rv = mq_close(ctx->mq);
  rtems_test_assert(rv == 0);

  rv = mq_unlink("/mq");
  rtems_test_assert(rv == 0);

  for (action = ACTION_MTX_LOCK; action < ACTION_TERMINATE; ++action) {
    rtems_test_assert(ctx->counter[action] == MODE_COUNT - 1);
  }
}

#ifdef __rtems__

const char rtems_test_name[] = "PSXCLOCKREALTIME 1";

static void *POSIX_Init(void *arg)
{
  TEST_BEGIN();
  test(&test_instance);
  TEST_END();
  rtems_test_exit(0);
}

#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER

#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
#define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 1

#define CONFIGURE_POSIX_INIT_THREAD_TABLE

#define CONFIGURE_INIT

#include <rtems/confdefs.h>

#else /* __rtems__ */

int main(void)
{
  test(&test_instance);
  return 0;
}

#endif /* __rtems__ */

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: pthread_mutex_timedlock() vs. clock_settime()
  2022-08-01  7:10 ` Joël Krähemann
  2022-08-01  7:41   ` Joël Krähemann
@ 2022-08-03 23:44   ` Sebastian Huber
  2022-08-01  8:28     ` Joël Krähemann
  1 sibling, 1 reply; 13+ messages in thread
From: Sebastian Huber @ 2022-08-03 23:44 UTC (permalink / raw)
  To: Joël Krähemann; +Cc: libc-help

Hello Joël,

On 01/08/2022 09:10, Joël Krähemann wrote:
> Hi Sebastian,
> 
> You have a dead-lock, probably. I just looked at your code. You are
> using non-recursive mutices and I think this mutex was locked twice by
> the very same thread.

thanks for having a look at the test case. Sorry for being so blind, but 
which mutex is where in the code locked twice by the same thread?

If I omit the mutex test case by starting with ACTION_CND_WAIT:

   for (action = ACTION_CND_WAIT; action < ACTION_TERMINATE; ++action) {
     event_post(&ctx->action, action);

Then the test runs fine:

*** timeout finite ***
pthread_cond_timedwait
wake up
pthread_cond_timedwait: actual 'Connection timed out', expected 
'Connection timed out'
pthread_rwlock_timedrdlock
wake up
pthread_rwlock_timedrdlock: actual 'Connection timed out', expected 
'Connection timed out'
pthread_rwlock_timedwrlock
wake up
pthread_rwlock_timedwrlock: actual 'Connection timed out', expected 
'Connection timed out'
sem_timedwait
wake up
sem_timedwait: actual 'Connection timed out', expected 'Connection timed 
out'
mq_send
mq_timedsend
wake up
mq_timedsend: actual 'Connection timed out', expected 'Connection timed out'
mq_receive
mq_timedreceive
wake up
mq_timedreceive: actual 'Connection timed out', expected 'Connection 
timed out'
clock_nanosleep
wake up
clock_nanosleep: actual 'Success', expected 'Success'

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-08-01 22:07 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-02  8:43 pthread_mutex_timedlock() vs. clock_settime() Sebastian Huber
2022-08-01  7:10 ` Joël Krähemann
2022-08-01  7:41   ` Joël Krähemann
2022-08-03 23:44   ` Sebastian Huber
2022-08-01  8:28     ` Joël Krähemann
2022-08-01  8:36       ` Sebastian Huber
2022-08-01  9:51         ` Joël Krähemann
2022-08-01 11:51           ` Joël Krähemann
2022-08-01 11:59             ` Joël Krähemann
2022-08-01 14:44               ` Joël Krähemann
2022-08-01 16:31             ` Sebastian Huber
2022-08-01 20:11               ` Joël Krähemann
2022-08-01 22:05                 ` Joël Krähemann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).