1 /*-------------------------------------------------------------------------
2  *
3  * pg_rusage.c
4  *	  Resource usage measurement support routines.
5  *
6  *
7  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *	  src/backend/utils/misc/pg_rusage.c
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17 
18 #include <unistd.h>
19 
20 #include "utils/pg_rusage.h"
21 
22 
23 /*
24  * Initialize usage snapshot.
25  */
26 void
pg_rusage_init(PGRUsage * ru0)27 pg_rusage_init(PGRUsage *ru0)
28 {
29 	getrusage(RUSAGE_SELF, &ru0->ru);
30 	gettimeofday(&ru0->tv, NULL);
31 }
32 
33 /*
34  * Compute elapsed time since ru0 usage snapshot, and format into
35  * a displayable string.  Result is in a static string, which is
36  * tacky, but no one ever claimed that the Postgres backend is
37  * threadable...
38  */
39 const char *
pg_rusage_show(const PGRUsage * ru0)40 pg_rusage_show(const PGRUsage *ru0)
41 {
42 	static char result[100];
43 	PGRUsage	ru1;
44 
45 	pg_rusage_init(&ru1);
46 
47 	if (ru1.tv.tv_usec < ru0->tv.tv_usec)
48 	{
49 		ru1.tv.tv_sec--;
50 		ru1.tv.tv_usec += 1000000;
51 	}
52 	if (ru1.ru.ru_stime.tv_usec < ru0->ru.ru_stime.tv_usec)
53 	{
54 		ru1.ru.ru_stime.tv_sec--;
55 		ru1.ru.ru_stime.tv_usec += 1000000;
56 	}
57 	if (ru1.ru.ru_utime.tv_usec < ru0->ru.ru_utime.tv_usec)
58 	{
59 		ru1.ru.ru_utime.tv_sec--;
60 		ru1.ru.ru_utime.tv_usec += 1000000;
61 	}
62 
63 	snprintf(result, sizeof(result),
64 			 _("CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s"),
65 			 (int) (ru1.ru.ru_utime.tv_sec - ru0->ru.ru_utime.tv_sec),
66 			 (int) (ru1.ru.ru_utime.tv_usec - ru0->ru.ru_utime.tv_usec) / 10000,
67 			 (int) (ru1.ru.ru_stime.tv_sec - ru0->ru.ru_stime.tv_sec),
68 			 (int) (ru1.ru.ru_stime.tv_usec - ru0->ru.ru_stime.tv_usec) / 10000,
69 			 (int) (ru1.tv.tv_sec - ru0->tv.tv_sec),
70 			 (int) (ru1.tv.tv_usec - ru0->tv.tv_usec) / 10000);
71 
72 	return result;
73 }
74