-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathutils.c
98 lines (91 loc) · 2.6 KB
/
utils.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <sys/resource.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
// 1: error; 2: warning; 3: message; 4: progress; 5: debugging; >=10: pure debugging
int fm_verbose = 4;
void *xmalloc_core(size_t s, const char *func)
{
unsigned char *x;
x = (unsigned char*)malloc(s);
if (x == 0) {
fprintf(stderr, "[E::%s] Fail to allocate %ld bytes of memory.\n", func, s);
return 0;
}
return (void*)x;
}
void *xcalloc_core(size_t n, size_t s, const char *func)
{
unsigned char *x;
x = (unsigned char*)calloc(n, s);
if (x == 0) {
fprintf(stderr, "[E::%s] Fail to allocate %ld bytes of memory.\n", func, s * n);
return 0;
}
return (void*)x;
}
double cputime()
{
struct rusage r;
getrusage(RUSAGE_SELF, &r);
return r.ru_utime.tv_sec + r.ru_stime.tv_sec + 1e-6 * (r.ru_utime.tv_usec + r.ru_stime.tv_usec);
}
void liftrlimit()
{
#ifdef __linux__
struct rlimit r;
getrlimit(RLIMIT_AS, &r);
r.rlim_cur = r.rlim_max;
setrlimit(RLIMIT_AS, &r);
#endif
}
/* Comment on the memory usage. We may think getrusage() is the easiest way to
* get the memory usage of the current process. However, on Linux, ru_maxrss
* is not supported by the kernel. We can get the current usage from file
* "/proc/self/stat" if the "/proc" file system is built in the kernel, but
* this is a snapshot instead of the maximum memory usage. We have to monitor
* the "stat" file constantly to get the maximum resident memory (RSS). On
* Linux, perhaps the easiest way to get the maximum RSS is to use my "runit".
* Even "/usr/bin/time" may not always work on all versions/distributions.
*
* On Mac, getrusage() writes ru_maxrss, but it seems to me that this field
* tends to be much larger than my expectation. This may be caused by the
* memory manager (i.e. malloc) instead of the kernel. When I have time,
* perhaps it is worth investigating an alternative memory manager or
* controling the major memory allocation by myself, which though could make
* the code look nasty.
*/
#if defined(__linux__)
double rssmem()
{
FILE *fp;
int c, n_spc = 0;
long mem, page_size;
page_size = sysconf(_SC_PAGESIZE);
fp = fopen("/proc/self/stat", "r");
while ((c = fgetc(fp)) != EOF) {
if (c == ' ') ++n_spc;
if (n_spc == 23) break;
}
fscanf(fp, "%ld", &mem);
fclose(fp);
return mem * page_size / 1024.0 / 1024.0;
}
#elif defined(__APPLE__)
double rssmem()
{
struct rusage r;
getrusage(RUSAGE_SELF, &r);
return r.ru_maxrss / 1024.0 / 1024.0;
}
#else
double rssmem() { return 0.; }
#endif
double realtime()
{
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);
return tp.tv_sec + tp.tv_usec * 1e-6;
}