]> granicus.if.org Git - postgresql/blob - src/port/getrusage.c
Fix the fastpath rule for jsonb_concat with an empty operand.
[postgresql] / src / port / getrusage.c
1 /*-------------------------------------------------------------------------
2  *
3  * getrusage.c
4  *        get information about resource utilisation
5  *
6  * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        src/port/getrusage.c
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 #include "c.h"
17
18 #include "rusagestub.h"
19
20 /* This code works on:
21  *              sco
22  *              solaris_i386
23  *              solaris_sparc
24  *              hpux 9.*
25  *              win32
26  * which currently is all the supported platforms that don't have a
27  * native version of getrusage().  So, if configure decides to compile
28  * this file at all, we just use this version unconditionally.
29  */
30
31 int
32 getrusage(int who, struct rusage * rusage)
33 {
34 #ifdef WIN32
35         FILETIME        starttime;
36         FILETIME        exittime;
37         FILETIME        kerneltime;
38         FILETIME        usertime;
39         ULARGE_INTEGER li;
40
41         if (who != RUSAGE_SELF)
42         {
43                 /* Only RUSAGE_SELF is supported in this implementation for now */
44                 errno = EINVAL;
45                 return -1;
46         }
47
48         if (rusage == (struct rusage *) NULL)
49         {
50                 errno = EFAULT;
51                 return -1;
52         }
53         memset(rusage, 0, sizeof(struct rusage));
54         if (GetProcessTimes(GetCurrentProcess(),
55                                                 &starttime, &exittime, &kerneltime, &usertime) == 0)
56         {
57                 _dosmaperr(GetLastError());
58                 return -1;
59         }
60
61         /* Convert FILETIMEs (0.1 us) to struct timeval */
62         memcpy(&li, &kerneltime, sizeof(FILETIME));
63         li.QuadPart /= 10L;                     /* Convert to microseconds */
64         rusage->ru_stime.tv_sec = li.QuadPart / 1000000L;
65         rusage->ru_stime.tv_usec = li.QuadPart % 1000000L;
66
67         memcpy(&li, &usertime, sizeof(FILETIME));
68         li.QuadPart /= 10L;                     /* Convert to microseconds */
69         rusage->ru_utime.tv_sec = li.QuadPart / 1000000L;
70         rusage->ru_utime.tv_usec = li.QuadPart % 1000000L;
71 #else                                                   /* all but WIN32 */
72
73         struct tms      tms;
74         int                     tick_rate = CLK_TCK;    /* ticks per second */
75         clock_t         u,
76                                 s;
77
78         if (rusage == (struct rusage *) NULL)
79         {
80                 errno = EFAULT;
81                 return -1;
82         }
83         if (times(&tms) < 0)
84         {
85                 /* errno set by times */
86                 return -1;
87         }
88         switch (who)
89         {
90                 case RUSAGE_SELF:
91                         u = tms.tms_utime;
92                         s = tms.tms_stime;
93                         break;
94                 case RUSAGE_CHILDREN:
95                         u = tms.tms_cutime;
96                         s = tms.tms_cstime;
97                         break;
98                 default:
99                         errno = EINVAL;
100                         return -1;
101         }
102 #define TICK_TO_SEC(T, RATE)    ((T)/(RATE))
103 #define TICK_TO_USEC(T,RATE)    (((T)%(RATE)*1000000)/RATE)
104         rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
105         rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
106         rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
107         rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
108 #endif   /* WIN32 */
109
110         return 0;
111 }