Coverage Report

Created: 2025-06-22 06:56

/src/lvm2/libdm/libdm-timestamp.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2006 Rackable Systems All rights reserved.
3
 * Copyright (C) 2015 Red Hat, Inc. All rights reserved.
4
 *
5
 * This file is part of the device-mapper userspace tools.
6
 *
7
 * This copyrighted material is made available to anyone wishing to use,
8
 * modify, copy, or redistribute it subject to the terms and conditions
9
 * of the GNU Lesser General Public License v.2.1.
10
 *
11
 * You should have received a copy of the GNU Lesser General Public License
12
 * along with this program; if not, write to the Free Software Foundation,
13
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
 */
15
16
/*
17
 * Abstract out the time methods used so they can be adjusted later -
18
 * the results of these routines should stay in-core.  
19
 */
20
21
#include "libdm/misc/dmlib.h"
22
23
#include <stdlib.h>
24
25
#define NSEC_PER_USEC UINT64_C(1000)
26
#define NSEC_PER_MSEC UINT64_C(1000000)
27
0
#define NSEC_PER_SEC  UINT64_C(1000000000)
28
29
/*
30
 * The realtime section uses clock_gettime with the CLOCK_MONOTONIC
31
 * parameter to prevent issues with time warps
32
 * This implementation requires librt.
33
 */
34
#ifdef HAVE_REALTIME
35
36
#include <time.h>
37
38
struct dm_timestamp {
39
  struct timespec t;
40
};
41
42
static uint64_t _timestamp_to_uint64(struct dm_timestamp *ts)
43
0
{
44
0
  uint64_t stamp = 0;
45
46
0
  stamp += (uint64_t) ts->t.tv_sec * NSEC_PER_SEC;
47
0
  stamp += (uint64_t) ts->t.tv_nsec;
48
49
0
  return stamp;
50
0
}
51
52
struct dm_timestamp *dm_timestamp_alloc(void)
53
0
{
54
0
  struct dm_timestamp *ts = NULL;
55
56
0
  if (!(ts = dm_zalloc(sizeof(*ts))))
57
0
    stack;
58
59
0
  return ts;
60
0
}
61
62
int dm_timestamp_get(struct dm_timestamp *ts)
63
0
{
64
0
  if (!ts)
65
0
    return 0;
66
67
0
  if (clock_gettime(CLOCK_MONOTONIC, &ts->t)) {
68
0
    log_sys_error("clock_gettime", "get_timestamp");
69
0
    ts->t.tv_sec = 0;
70
0
    ts->t.tv_nsec = 0;
71
0
    return 0;
72
0
  }
73
74
0
  return 1;
75
0
}
76
77
#else /* ! HAVE_REALTIME */
78
79
/*
80
 * The !realtime section just uses gettimeofday and is therefore subject
81
 * to ntp-type time warps - not sure if should allow that.
82
 */
83
84
#include <sys/time.h>
85
86
struct dm_timestamp {
87
  struct timeval t;
88
};
89
90
static uint64_t _timestamp_to_uint64(struct dm_timestamp *ts)
91
{
92
  uint64_t stamp = 0;
93
94
  stamp += ts->t.tv_sec * NSEC_PER_SEC;
95
  stamp += ts->t.tv_usec * NSEC_PER_USEC;
96
97
  return stamp;
98
}
99
100
struct dm_timestamp *dm_timestamp_alloc(void)
101
{
102
  struct dm_timestamp *ts;
103
104
  if (!(ts = dm_malloc(sizeof(*ts))))
105
    stack;
106
107
  return ts;
108
}
109
110
int dm_timestamp_get(struct dm_timestamp *ts)
111
{
112
  if (!ts)
113
    return 0;
114
115
  if (gettimeofday(&ts->t, NULL)) {
116
    log_sys_error("gettimeofday", "get_timestamp");
117
    ts->t.tv_sec = 0;
118
    ts->t.tv_usec = 0;
119
    return 0;
120
  }
121
122
  return 1;
123
}
124
125
#endif /* HAVE_REALTIME */
126
127
/*
128
 * Compare two timestamps.
129
 *
130
 * Return: -1 if ts1 is less than ts2
131
 *          0 if ts1 is equal to ts2
132
 *          1 if ts1 is greater than ts2
133
 */
134
int dm_timestamp_compare(struct dm_timestamp *ts1, struct dm_timestamp *ts2)
135
0
{
136
0
  uint64_t t1, t2;
137
138
0
  t1 = _timestamp_to_uint64(ts1);
139
0
  t2 = _timestamp_to_uint64(ts2);
140
141
0
  if (t2 < t1)
142
0
    return 1;
143
144
0
  if (t1 < t2)
145
0
    return -1;
146
147
0
  return 0;
148
0
}
149
150
/*
151
 * Return the absolute difference in nanoseconds between
152
 * the dm_timestamp objects ts1 and ts2.
153
 *
154
 * Callers that need to know whether ts1 is before, equal to, or after ts2
155
 * in addition to the magnitude should use dm_timestamp_compare.
156
 */
157
uint64_t dm_timestamp_delta(struct dm_timestamp *ts1, struct dm_timestamp *ts2)
158
0
{
159
0
  uint64_t t1, t2;
160
161
0
  t1 = _timestamp_to_uint64(ts1);
162
0
  t2 = _timestamp_to_uint64(ts2);
163
164
0
  if (t1 > t2)
165
0
    return t1 - t2;
166
167
0
  return t2 - t1;
168
0
}
169
170
void dm_timestamp_copy(struct dm_timestamp *ts_new, struct dm_timestamp *ts_old)
171
0
{
172
0
  *ts_new = *ts_old;
173
0
}
174
175
void dm_timestamp_destroy(struct dm_timestamp *ts)
176
10.9k
{
177
10.9k
  dm_free(ts);
178
10.9k
}