(linenum→info "unix/slp.c:2238")

glibc/2.7/nptl/pthread_clock_gettime.c

    1: /* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3: 
    4:    The GNU C Library is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU Lesser General Public License as
    6:    published by the Free Software Foundation; either version 2.1 of the
    7:    License, or (at your option) any later version.
    8: 
    9:    The GNU C Library is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:    Lesser General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU Lesser General Public
   15:    License along with the GNU C Library; see the file COPYING.LIB.  If not,
   16:    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   17:    Boston, MA 02111-1307, USA.  */
   18: 
   19: #include <errno.h>
   20: #include <stdlib.h>
   21: #include <time.h>
   22: #include <libc-internal.h>
   23: #include "pthreadP.h"
   24: 
   25: 
   26: #if HP_TIMING_AVAIL
   27: int
   28: __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
   29:                          struct timespec *tp)
   30: {
   31:   hp_timing_t tsc;
   32: 
   33:   /* Get the current counter.  */
   34:   HP_TIMING_NOW (tsc);
   35: 
   36:   /* This is the ID of the thread we are looking for.  */
   37:   pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE;
   38: 
   39:   /* Compute the offset since the start time of the process.  */
   40:   if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid))
   41:     /* Our own clock.  */
   42:     tsc -= THREAD_GETMEM (THREAD_SELF, cpuclock_offset);
   43:   else
   44:     {
   45:       /* This is more complicated.  We have to locate the thread based
   46:          on the ID.  This means walking the list of existing
   47:          threads.  */
   48:       struct pthread *thread = __find_thread_by_id (tid);
   49:       if (thread == NULL)
   50:         {
   51:           __set_errno (EINVAL);
   52:           return -1;
   53:         }
   54: 
   55:       /* There is a race here.  The thread might terminate and the stack
   56:          become unusable.  But this is the user's problem.  */
   57:       tsc -= thread->cpuclock_offset;
   58:     }
   59: 
   60:   /* Compute the seconds.  */
   61:   tp->tv_sec = tsc / freq;
   62: 
   63:   /* And the nanoseconds.  This computation should be stable until
   64:      we get machines with about 16GHz frequency.  */
   65:   tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq;
   66: 
   67:   return 0;
   68: }
   69: #endif
Syntax (Markdown)