Header And Logo

PostgreSQL
| The world's most advanced open source database.

getrusage.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * getrusage.c
00004  *    get information about resource utilisation
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/port/getrusage.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 
00016 #include "c.h"
00017 
00018 #include "rusagestub.h"
00019 
00020 /* This code works on:
00021  *      sco
00022  *      solaris_i386
00023  *      solaris_sparc
00024  *      hpux 9.*
00025  *      win32
00026  * which currently is all the supported platforms that don't have a
00027  * native version of getrusage().  So, if configure decides to compile
00028  * this file at all, we just use this version unconditionally.
00029  */
00030 
00031 int
00032 getrusage(int who, struct rusage * rusage)
00033 {
00034 #ifdef WIN32
00035 
00036     FILETIME    starttime;
00037     FILETIME    exittime;
00038     FILETIME    kerneltime;
00039     FILETIME    usertime;
00040     ULARGE_INTEGER li;
00041 
00042     if (who != RUSAGE_SELF)
00043     {
00044         /* Only RUSAGE_SELF is supported in this implementation for now */
00045         errno = EINVAL;
00046         return -1;
00047     }
00048 
00049     if (rusage == (struct rusage *) NULL)
00050     {
00051         errno = EFAULT;
00052         return -1;
00053     }
00054     memset(rusage, 0, sizeof(struct rusage));
00055     if (GetProcessTimes(GetCurrentProcess(),
00056                         &starttime, &exittime, &kerneltime, &usertime) == 0)
00057     {
00058         _dosmaperr(GetLastError());
00059         return -1;
00060     }
00061 
00062     /* Convert FILETIMEs (0.1 us) to struct timeval */
00063     memcpy(&li, &kerneltime, sizeof(FILETIME));
00064     li.QuadPart /= 10L;         /* Convert to microseconds */
00065     rusage->ru_stime.tv_sec = li.QuadPart / 1000000L;
00066     rusage->ru_stime.tv_usec = li.QuadPart % 1000000L;
00067 
00068     memcpy(&li, &usertime, sizeof(FILETIME));
00069     li.QuadPart /= 10L;         /* Convert to microseconds */
00070     rusage->ru_utime.tv_sec = li.QuadPart / 1000000L;
00071     rusage->ru_utime.tv_usec = li.QuadPart % 1000000L;
00072 #else                           /* all but WIN32 */
00073 
00074     struct tms  tms;
00075     int         tick_rate = CLK_TCK;    /* ticks per second */
00076     clock_t     u,
00077                 s;
00078 
00079     if (rusage == (struct rusage *) NULL)
00080     {
00081         errno = EFAULT;
00082         return -1;
00083     }
00084     if (times(&tms) < 0)
00085     {
00086         /* errno set by times */
00087         return -1;
00088     }
00089     switch (who)
00090     {
00091         case RUSAGE_SELF:
00092             u = tms.tms_utime;
00093             s = tms.tms_stime;
00094             break;
00095         case RUSAGE_CHILDREN:
00096             u = tms.tms_cutime;
00097             s = tms.tms_cstime;
00098             break;
00099         default:
00100             errno = EINVAL;
00101             return -1;
00102     }
00103 #define TICK_TO_SEC(T, RATE)    ((T)/(RATE))
00104 #define TICK_TO_USEC(T,RATE)    (((T)%(RATE)*1000000)/RATE)
00105     rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
00106     rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
00107     rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
00108     rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
00109 #endif   /* WIN32 */
00110 
00111     return 0;
00112 }