NetBSD Problem Report #47703
From www@NetBSD.org Thu Mar 28 16:12:00 2013
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
by www.NetBSD.org (Postfix) with ESMTP id 5750C63F26F
for <gnats-bugs@gnats.NetBSD.org>; Thu, 28 Mar 2013 16:12:00 +0000 (UTC)
Message-Id: <20130328161159.0B96263F26F@www.NetBSD.org>
Date: Thu, 28 Mar 2013 16:11:58 +0000 (UTC)
From: oshima-ya@yagoto-urayama.jp
Reply-To: oshima-ya@yagoto-urayama.jp
To: gnats-bugs@NetBSD.org
Subject: pthread_cond_timedwait() does not wait after call pthread_condattr_setclock(CLOCK_MONOTONIC)
X-Send-Pr-Version: www-1.0
>Number: 47703
>Category: lib
>Synopsis: pthread_cond_timedwait() does not wait after call pthread_condattr_setclock(CLOCK_MONOTONIC)
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: lib-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Mar 28 16:15:00 +0000 2013
>Closed-Date: Mon Oct 07 07:26:39 +0000 2013
>Last-Modified: Sun Dec 11 10:05:01 +0000 2022
>Originator: Yasushi Oshima
>Release: 6.1_RC2
>Organization:
>Environment:
NetBSD hassaku 6.1_RC2 NetBSD 6.1_RC2 (GENERIC) #1: Mon Mar 18 08:10:25 JST 2013 oshima@bergamot:/export/netbsd-6/obj/amd64/sys/arch/amd64/compile/GENERIC amd64
>Description:
pthread_cond_timedwait() does not wait after call pthread_condattr_setclock(CLOCK_MONOTONIC).
This is a result of a test code (see How To Repeat) which call pthread_cond_timedwait() set to 10sec:
**** REALTIME clock wait starting
STARTTIME: 1364483493.092059685 sec
TIMEDOUTED: 1364483503.112246279 sec
ELAPSED : 10.020186594 sec
**** REALTIME clock wait ended
**** MONOTONIC clock wait starting
STARTTIME: 508074.001066903 sec
TIMEDOUTED: 508074.001109810 sec
ELAPSED : 0.000042907 sec
**** MONOTONIC clock wait ended
in MONOTONIC, this returned with TIMEDOUTED after only 0.00004sec even setting as 10sec.
This occurs on both NetBSD 6.1_RC2 and NetBSD-current.
And,
pkgsrc/lang/ruby193-base uses MONOTONIC clock like this.
Some application program of ruby (for example, pkgsrc/net/mikutter) can't sleep, CPU load becomes 100%.
>How-To-Repeat:
Execute following test code:
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define WAITTIME 10 /* Timeout wait secound */
void *test_thread(void *param)
{
struct timespec ts, to, te;
clockid_t clck;
pthread_condattr_t attr;
pthread_cond_t cond;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int sec, nsec;
int ret=0;
clck= *(clockid_t *)param;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, clck); /* REALTIME or MONOTONIC */
pthread_cond_init(&cond, &attr);
if ((ret = pthread_mutex_lock(&m))) {
fprintf(stderr, "pthread_mutex_lock: %s\n",strerror(ret));
pthread_exit(&ret);
}
clock_gettime(clck, &ts); /* get now */
to = ts;
printf("STARTTIME: %ld.%09ld sec\n", to.tv_sec, to.tv_nsec);
ts.tv_sec += WAITTIME; /* Timeout wait */
if ((ret = pthread_cond_timedwait(&cond, &m, &ts))) {
if (ret == ETIMEDOUT) {
/* Timeout */
clock_gettime(clck, &te);
sec = te.tv_sec-to.tv_sec;
nsec = te.tv_nsec-to.tv_nsec;
if ( nsec < -1 ) {
nsec+=1000*1000*1000;
sec-=1;
}
fprintf(stderr,"TIMEDOUTED: %ld.%09ld sec\n", te.tv_sec, te.tv_nsec);
fprintf(stderr,"ELAPSED : %d.%09d sec\n", sec, nsec);
} else {
fprintf(stderr, "pthread_cond_timedout: %s\n",strerror(ret));
pthread_exit(&ret);
}
}
if ((ret = pthread_mutex_unlock(&m))) {
fprintf(stderr, "pthread_mutex_unlock: %s\n",strerror(ret));
pthread_exit(&ret);
}
pthread_exit(&ret);
}
int main(int argc, char* argv[]){
pthread_t child_thread;
clockid_t clck;
/*
* REALTIME clock thread wait
*/
clck = CLOCK_REALTIME;
printf( "**** REALTIME clock wait starting\n");
if (pthread_create(&child_thread, NULL, test_thread, &clck)!=0)
err(1,"pthread_create");
if( pthread_join(child_thread, NULL)!=0) /* wait for terminate */
err(1,"pthread_join");
printf( "**** REALTIME clock wait ended\n");
printf( "\n");
/*
* MONOTONIC clock thread wait
*/
clck = CLOCK_MONOTONIC;
printf( "**** MONOTONIC clock wait starting\n");
if (pthread_create(&child_thread, NULL, test_thread, &clck)!=0)
err(1,"pthread_create");
if( pthread_join(child_thread, NULL)!=0) /* wait for terminate */
err(1,"pthread_join");
printf( "**** MONOTONIC clock wait ended\n");
return 0;
}
>Fix:
I don't know
>Release-Note:
>Audit-Trail:
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/47703 CVS commit: src/lib/libpthread
Date: Thu, 28 Mar 2013 14:07:12 -0400
Module Name: src
Committed By: christos
Date: Thu Mar 28 18:07:12 UTC 2013
Modified Files:
src/lib/libpthread: pthread_cond.c
Log Message:
PR/47703: Yasushi Oshima: pthread_cond_timedwait() does not wait
after call pthread_condattr_setclock(CLOCK_MONOTONIC)
_lwp_park(2) expects a realtime clock, and it gets passed a monotonic
one. Since monotonic < real, it never sleeps. This patch adjusts
the monotonic clock to be a real one before it passes is to
_lwp_park(2). This is the minimal hacky fix and it will be fixed
properly in _lwp_park(2) in the future.
XXX: pullup to 6.
To generate a diff of this commit:
cvs rdiff -u -r1.59 -r1.60 src/lib/libpthread/pthread_cond.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/47703 CVS commit: src/tests/lib/libpthread
Date: Thu, 28 Mar 2013 14:50:02 -0400
Module Name: src
Committed By: christos
Date: Thu Mar 28 18:50:02 UTC 2013
Modified Files:
src/tests/lib/libpthread: Makefile
Added Files:
src/tests/lib/libpthread: t_condwait.c
Log Message:
Add pthread_cond_timedwait(3) test from PR/47703
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/tests/lib/libpthread/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/lib/libpthread/t_condwait.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Manuel Bouyer" <bouyer@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/47703 CVS commit: [netbsd-6] src/lib/libpthread
Date: Sat, 20 Apr 2013 15:14:08 +0000
Module Name: src
Committed By: bouyer
Date: Sat Apr 20 15:14:08 UTC 2013
Modified Files:
src/lib/libpthread [netbsd-6]: pthread_cond.c
Log Message:
Pull up following revision(s) (requested by christos in ticket #862):
lib/libpthread/pthread_cond.c: revision 1.60
lib/libpthread/pthread_cond.c: revision 1.61
PR/47703: Yasushi Oshima: pthread_cond_timedwait() does not wait
after call pthread_condattr_setclock(CLOCK_MONOTONIC)
_lwp_park(2) expects a realtime clock, and it gets passed a monotonic
one. Since monotonic < real, it never sleeps. This patch adjusts
the monotonic clock to be a real one before it passes is to
_lwp_park(2). This is the minimal hacky fix and it will be fixed
properly in _lwp_park(2) in the future.
XXX: pullup to 6.
for safety, declare mono on the outermost block it is used.
To generate a diff of this commit:
cvs rdiff -u -r1.56.8.1 -r1.56.8.2 src/lib/libpthread/pthread_cond.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Mon, 07 Oct 2013 07:26:39 +0000
State-Changed-Why:
Committed and pulled up to netbsd-6.
From: "Robert Elz" <kre@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/47703 CVS commit: src/tests/lib/libpthread
Date: Sun, 11 Dec 2022 10:02:54 +0000
Module Name: src
Committed By: kre
Date: Sun Dec 11 10:02:53 UTC 2022
Modified Files:
src/tests/lib/libpthread: t_condwait.c
Log Message:
This test makes (made) a false assumption about the way that
process scheduling works. That a process (or in this case,
a thread) is no longer blocked at time T does not mean that it
will resume execution at time T. The OS is free to devote
resources to other processes/threads instead - all we should
normally be able to expect is that if it is not unblocked before
time T, that it will not start running before then.
In general though, the pthread_cond_*wait() functions don't guarantee
even that - but for this test, the possibility of something else
randomly signalling the condvar isn't believable, so don't worry about
that possibility (but do fail without calling strerror(0) on the off
chance it does happen).
Once we cease testing that the process resumed running before some
particular time, we can stop dealing with qemu timekeeping issues,
it might (seem to) take qemu twice as long as was requested before
the thread resumes, but that's OK - the same thing could happen on
a loaded system for other reasons.
Beyond that, the test also has (had) a race condition. When using
CLOCK_REALTIME though that clock needed to have advanced to T before
the ETIMEDOUT should happen, there is no guarantee that it will stay >T
(CLOCK_REALTIME is allowed to be reset backwards). So, only test
that the current time (after ETIMEDOUT) >= T when we're using
CLOCK_MONOTONIC - for CLOCK_REALTIME the time might have stepped
back between when the ETIMEDOUT happened and when the thread
obtains the current clock reading. For that case, all we can test
is that the ETIMEDOUT actually happens.
With much of what was there now gone, the code can be simplified,
we no longer need to do timespec arithmetic, just one comparison
(simpler to test that Tend >= Tstart+period than Tend-Tstart > period
as we need Tstart+period for the abstime value for the timeout anyway).
Note that this still tests for the issue reported in PR lib/47703
which is where the test came from in the first place.
ps: we seem to be missing pthread_cond_clockwait() which is the same
as pthread_cond_timedwait() except that the clock to use is passed
as a parameter, rather than as an attribute of the condition variable.
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/tests/lib/libpthread/t_condwait.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
>Unformatted:
(Contact us)
$NetBSD: gnats-precook-prs,v 1.4 2018/12/21 14:20:20 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.