Motr  M0
clk_src.h
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2021 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #pragma once
24 #ifndef __MOTR_DTM0_CLK_SRC_H__
25 #define __MOTR_DTM0_CLK_SRC_H__
26 
27 #include "xcode/xcode.h" /* xcode attrs */
28 #include "lib/time.h" /* m0_time_t */
29 #include "lib/mutex.h" /* m0_mutex */
30 
31 /*
32  * DTM clock source overview
33  * -------------------------
34  *
35  * Clock source module is designed to be used by DTM0. At this point,
36  * only one type of clock is supported -- physical clock. Such a clock
37  * provides a way to enforce total ordering in a system with synchronised
38  * clocks.
39  * XXX: At this point the clock source module is a thin wrapper around
40  * ::m0_time_now (which is enough to satisfy the requirements from [1]),
41  * however later on it might be extended to support logical clocks [2].
42  *
43  * @see [1] "A.clock.sync" in the DTM0 HLD.
44  * @see [2] https://github.com/Seagate/cortx-motr/blob/clock/mw/clock.h
45  *
46  * Interface
47  * ---------
48  *
49  * CS.TS -- A data type that represents a point in time (timestamp).
50  * CS.TS.CMP(L,R) -- a 3-way comparison for timestamps; it returns
51  * -1 when "left" happened before "right", +1 when
52  * "left" happened after "right", and 0 otherwise.
53  * CS.INIT -- initialise a clock source of the given type.
54  * CS.FINI -- finalise a clock source.
55  * CS.NOW -- get the current value of a clock source.
56  *
57  * Concurrency
58  * -----------
59  *
60  * It is safe to call CS.NOW from any context as long as the caller owns the
61  * corresponding source clock.
62  * The user must ensure to use only one type of clock source in the system.
63  * The module provides no protection against such cases.
64  */
65 
66 
75  /*
76  * Physical clock.
77  * Physical clock supports total ordering and requires
78  * no synchronisation (from DTM0 perspective). But it has
79  * one drawback: two dependent events could have the same
80  * timestamp (it might be resolved with help of unique comparable
81  * clock ids).
82  * It is assumed that the clock drift between nodes does not exceed
83  * some "reasonable" values (for example, the upper bound for the
84  * duration of a transient failure). If such assumption is not enforced
85  * then user should always check the clock drift value.
86  */
88 };
89 
91 struct m0_dtm0_ts {
92  /* TODO: Think about adding enum cs_types here */
94 } M0_XCA_RECORD M0_XCA_DOMAIN(rpc);
95 
97 #define M0_DTM0_TS_MIN (struct m0_dtm0_ts) { .dts_phys = 1 }
98 
99 #define M0_DTM0_TS_MAX (struct m0_dtm0_ts) { .dts_phys = (UINT64_MAX - 1) }
100 
101 #define M0_DTM0_TS_INIT (struct m0_dtm0_ts) { .dts_phys = UINT64_MAX }
102 
103 #define M0_DTM0_TS_NONE (struct m0_dtm0_ts) { .dts_phys = 0 }
104 
105 #define DTS0_P(_ts) ((_ts)->dts_phys)
106 #define DTS0_F "@%" PRIu64
107 
113  /* Left happened before Right */
114  M0_DTS_LT = -1,
115  /* Left and Right happened at the same time */
117  /* Left happened after Right */
119 };
120 
121 struct m0_dtm_clk_src_ops;
122 
128 };
129 
131 M0_INTERNAL enum m0_dtm0_ts_ord m0_dtm0_ts_cmp(const struct m0_dtm0_clk_src *cs,
132  const struct m0_dtm0_ts *left,
133  const struct m0_dtm0_ts *right);
134 
136 M0_INTERNAL void m0_dtm0_clk_src_init(struct m0_dtm0_clk_src *cs,
137  enum m0_dtm0_cs_types type);
138 
140 M0_INTERNAL void m0_dtm0_clk_src_fini(struct m0_dtm0_clk_src *cs);
141 
143 M0_INTERNAL void m0_dtm0_clk_src_now(struct m0_dtm0_clk_src *cs,
144  struct m0_dtm0_ts *now);
145 
146 M0_INTERNAL bool m0_dtm0_ts__invariant(const struct m0_dtm0_ts *ts);
147 
148 M0_INTERNAL bool m0_dtm0_ts_is_none(const struct m0_dtm0_ts *ts);
149 
151 #endif /* __MOTR_DTM0_CLK_SRC_H__ */
152 
153 /*
154  * Local variables:
155  * c-indentation-style: "K&R"
156  * c-basic-offset: 8
157  * tab-width: 8
158  * fill-column: 80
159  * scroll-step: 1
160  * End:
161  */
162 /*
163  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
164  */
M0_INTERNAL enum m0_dtm0_ts_ord m0_dtm0_ts_cmp(const struct m0_dtm0_clk_src *cs, const struct m0_dtm0_ts *left, const struct m0_dtm0_ts *right)
Definition: clk_src.c:61
struct m0_dtm0_ts cs_last
Definition: clk_src.h:126
uint64_t m0_time_t
Definition: time.h:37
static int left
Definition: locality.c:280
m0_time_t dts_phys
Definition: clk_src.h:93
M0_INTERNAL bool m0_dtm0_ts_is_none(const struct m0_dtm0_ts *ts)
Definition: clk_src.c:118
M0_INTERNAL void m0_dtm0_clk_src_now(struct m0_dtm0_clk_src *cs, struct m0_dtm0_ts *now)
Definition: clk_src.c:71
m0_dtm0_cs_types
Definition: clk_src.h:74
const struct m0_dtm0_clk_src_ops * cs_ops
Definition: clk_src.h:125
struct m0_mutex cs_phys_lock
Definition: clk_src.h:127
M0_INTERNAL void m0_dtm0_clk_src_fini(struct m0_dtm0_clk_src *cs)
Definition: clk_src.c:49
enum m0_dtm0_ts_ord M0_XCA_DOMAIN
M0_INTERNAL bool m0_dtm0_ts__invariant(const struct m0_dtm0_ts *ts)
Definition: clk_src.c:79
m0_dtm0_ts_ord
Definition: clk_src.h:112
int type
Definition: dir.c:1031
Definition: mutex.h:47
M0_INTERNAL void m0_dtm0_clk_src_init(struct m0_dtm0_clk_src *cs, enum m0_dtm0_cs_types type)
Definition: clk_src.c:38