[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nptl] Re: NPTL Issue getrusage() / times
Hello,
> > accordingly to SUSv3, getrusage() and times() should return the timing
> > (user and system time) information for the *process*. That is the sum
> > over all thread's time.
> >
> > With NPTL, the timing is thread-wise only. That is, the timing is
> > given only for the thread that calls getrusage(), resp. times().
> > This deviates from SUSv3.
>
> According to this message:
> http://sources.redhat.com/ml/libc-alpha/2004-10/msg00013.html
> the glibc is claimed to return the usage for the process. So, if it
> appears that it is not the case, there surely is a bug!
Hmm... I must admit that I only tested with the default glibc provided in
FC2, which is not necessarily a *branding new* one...
> > I would definitively keep that neat feature of obtaining timing
> > thread-wise, but not with the standard getrusage(), resp. times().
>
> Yeah, the POSIX function have to conform to the POSIX spec; otherwise it
> makes no sense :)
>
> >
> > If you like, I can devise a test program proving my claim.
>
> It would be great. If you have no time for this, please let me know,
> I'll try to figure out a way to check this. Anyway, at the moment, I
> don't really can imagine how to prove this... Can you give me some more
> information on a design for such a test?
You _can't_ prove that the computation is done correctly. But you _can_
prove when it is obviously wrong. For instance, if the main thread spent 300
ticks before starting a thread, then calling /times()/ in that thread should
returns something greater or equal to 300 ticks...
In attachement, you'll find the corresponding test program.
Cheers,
Loic.
--
--
// Sender address goes to /dev/null (!!)
// Use my 32/64 bits, ANSI C89, compliant email-address instead:
unsigned y[]=
{0,34432,26811,16721,41866,63119,61007,48155,26147,10986};
void x(z){putchar(z);}; unsigned t;
main(i){if(i<10){t=(y[i]*47560)%65521;x(t>>8);x(t&255);main(++i);}}
+++ GMX DSL Premiumtarife 3 Monate gratis* + WLAN-Router 0,- EUR* +++
Clevere DSL-Nutzer wechseln jetzt zu GMX: http://www.gmx.net/de/go/dsl
/*
*----------------------------------------------------------------------------
* Copyright (c) 2004, Loic Domaigne. All rights reserved.
* Created by: Loic Domaigne.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.5 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
*---------------------------------------------------------------------------
*
* This program tests that virtual times returns by time() is process-wise
* (that is, the sum of of timings over all threads). If the test succeed
* it terminates returning 0, otherwise 1.
*
* #------------------------#
* # To compile #
* #------------------------#
* $ gcc -W -Wall -pthread test_times.c -o test_times
*
* #------------------------#
* # To call the program: #
* #------------------------#
* $ ./test_times
*
* #------------------------#
* # Program Tunings: #
* #------------------------#
* You might tune:
*
* o the number of ticks VTIME_THRESHOLD the process should spent in
* computation (in order to have a non-zero time).
*
* Example:
* $ gcc -W -Wall -pthread -DVTIME_THRESHOLD=50 test_times.c -o test_times
*/
#include <assert.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/times.h>
#ifndef _U_
#define _U_ __attribute__((unused))
#endif
#ifndef VTIME_THRESHOLD
#define VTIME_THRESHOLD 300
#endif
#define CHUNK_SIZE 1000000
#define BAD_CLOCK ( (clock_t) -1 )
double s=0.0;
unsigned long n=1;
unsigned long global_vt=0;
/*****************************************************************************
* do_computation- perform computation in order to spent some time.
*****************************************************************************
*
* This function computes the sum_{i=1}^n 1/(n^2) until at least VT_THRESHOLD
* time ticks has been elapsed.
*
*****************************************************************************/
void
do_computation(void)
{
struct tms now;
unsigned long count;
do {
for (count=0; count<CHUNK_SIZE; count++) {
s += 1.0/((double)n*n);
++n;
}
assert ( times (&now) != BAD_CLOCK );
global_vt = now.tms_utime + now.tms_stime;
}
while ( global_vt < VTIME_THRESHOLD);
}
/*****************************************************************************
* testThread- Check current virtual times.
*****************************************************************************
*
* This thread just call times() and check that the times elapsed
* (user + system) is greater or equal the times saved in global_vt.
*
*****************************************************************************/
void*
myThread(void* unused _U_)
{
struct tms now;
unsigned long my_vt;
int success;
assert ( times (&now) != BAD_CLOCK );
my_vt = now.tms_utime + now.tms_stime;
success = (my_vt >= global_vt);
return (void*) success;
}
/*###########################################################################*/
/*## MAIN PROCESS ENTRY POINT ##*/
/*###########################################################################*/
int
main()
{
int status;
int success;
void* retVal;
pthread_t thrId;
/*
* spent about VTIME_THRESHOLD ticks in computation.
*/
do_computation();
/*
* here, global_vt should have a value of about VTIME_THRESHOLD.
*
* Create a thread which checks that times() is process-wide.
* In other words, times of that thread should be >= global_vt.
*/
status = pthread_create (&thrId, NULL, myThread, NULL);
assert (status==0);
status = pthread_join(thrId, &retVal);
assert (status==0);
/*
* Test succeed or failed?
*/
success = (int) retVal;
printf ("Test: %s\n",
(success)? "PASS":"FAIL"
);
return (success==0)? 1:0;
}