[PATCH grout] replace clock_t with Grout specific high-res clock
Morten Brørup
mb at smartsharesystems.com
Sun May 24 20:39:34 CEST 2026
> From: Robin Jarry [mailto:rjarry at redhat.com]
> Sent: Sunday, 24 May 2026 16.36
>
> Hi Morten,
>
> Morten Brørup, May 24, 2026 at 12:50:
> > The clock_t type is implementation specific.
> > E.g. on Linux, it is microseconds, and on Windows it is milliseconds.
> >
> > Replace all uses of clock_t and its accompanying function,
> gr_clock_us(),
> > with a new nanosecond resolution clock type, gr_clock_ns_t, and its
> > accompanying function, gr_grout_ns().
> >
> > Note about signedness:
> > I condidered making the gr_clock_ns_t unsigned, but that would
> require
> > additional considerations in code where it is used, e.g. for
> calculating
> > age, to prevent wraparound in race conditions. E.g.:
> > age = (gr_clock_ns() - fdb->last_seen) / NS_PER_S;
> > If the current thread reads the clock using gr_clock_ns(), and
> another
> > thread races to set fdb->last_seen afterwards, the result of the
> > subtraction is negative. The division by NS_PER_S makes the age zero.
> > If gr_clock_ns_t was unsigned, the negative result of the subtraction
> > would be a very large unsigned number. Dividing this very large
> number
> > by NS_PER_S would be a large unsigned number, not zero.
> > Obviously, this could be fixed by type casting gr_clock_ns_t values
> to
> > signed int64_t everywhere they are used with subtraction. But such a
> > requirement increases the risk of bugs.
> > So I decided to make it signed, like type_t.
> >
> > Signed-off-by: Morten Brørup <mb at smartsharesystems.com>
>
> I have a few remarks:
>
> 1) Do we really need nanosecond precision? I am not worried about the
> date limit as 63 bits (signed 64bit integer) allow holding up to 292
> years. But this seems excessive for a simple timestamp.
>
> Or maybe you are planning on adding other less precise types?
Nanosecond resolution opens possibilities, which are not available with microsecond resolution, e.g. shaping and pacing (which I understand is WIP); and the type it replaces also uses 64 bit, so the resolution improvement does not have a memory cost.
Yes, in the long term, I plan to add less precise types.
>
> 2) Make sure to satisfy `make lint`:
>
> $ make lint
> [clang-format]
> Clang-formatting 273 files
> modules/infra/control/lacp.c:178:26: error: code should be clang-
> formatted [-Wclang-format-violations]
> member->next_tx = now +
> LACP_SHORT_TIMEOUT * (gr_clock_ns_t)NS_PER_S;
> ^
> modules/ip/control/icmp.c:49:25: error: code should be clang-formatted
> [-Wclang-format-violations]
> static struct rte_mbuf *get_icmp_response(uint16_t ident, uint16_t
> seq_num, gr_clock_ns_t *timestamp) {
> ^
> modules/l2/cli/fdb.c:141:17: error: code should be clang-formatted [-
> Wclang-format-violations]
> gr_table_cell(table, 6, "%ld", (gr_clock_ns() - fdb-
> >last_seen) / INT64_C(1000000000));
> ^
> modules/l2/cli/fdb.c:141:88: error: code should be clang-formatted [-
> Wclang-format-violations]
> gr_table_cell(table, 6, "%ld", (gr_clock_ns() - fdb-
> >last_seen) / INT64_C(1000000000));
>
> ^
> [license-check]
> [white-space]
> [comments]
> api/gr_clock.h:13:// Note: Using signed, to avoid need for casting to
> signed in calculations where race conditions may cause negative
> differences.<-- comment too long
> api/gr_clock.h:16:// Get powered-on (non-suspended, non-hibernated)
> time since last boot (using a common clock across all processes).<--
> comment too long
> make: *** [GNUmakefile:181: lint] Error 123
I can fix long lines.
What's the max number of characters per line?
How to continue a long line on the next line in Grout?
In DPDK we use double-indentation. E.g.:
int verylongfunction(int a,
int b);
if (some + very +
large + sum + continues +
with + even + more) {
some_function(some, sum);
other_function(very, more);
}
Alternatively, we continue at the function brace, using spaces for the continuation indentation, e.g.:
int verylongfunction(int a,
int b);
Both types of indentation are readable, regardless if the editor is set up to render TAB as 4 or 8 spaces.
"make lint" spews out warnings about things I didn't touch.
Do I need to set up some configuration file or pass special parameters for this to work?
My build server is running: Ubuntu 24.04.<redacted> LTS
$ clang-format --version
Ubuntu clang-format version 18.1.3 (1ubuntu1)
$ make lint
[clang-format]
Clang-formating 273 files
frr/rt_grout.c:529:12: error: code should be clang-formatted [-Wclang-format-violations]
if (new && nh_id == 0) {
^
frr/rt_grout.c:547:45: error: code should be clang-formatted [-Wclang-format-violations]
req.r4_add = (struct gr_ip4_route_add_req) {
^
frr/rt_grout.c:547:48: error: code should be clang-formatted [-Wclang-format-violations]
req.r4_add = (struct gr_ip4_route_add_req) {
^
frr/rt_grout.c:548:39: error: code should be clang-formatted [-Wclang-format-violations]
.exist_ok = true, .vrf_id = vrf_id
^
frr/rt_grout.c:559:45: error: code should be clang-formatted [-Wclang-format-violations]
req.r4_del = (struct gr_ip4_route_del_req) {
^
frr/rt_grout.c:559:48: error: code should be clang-formatted [-Wclang-format-violations]
req.r4_del = (struct gr_ip4_route_del_req) {
^
frr/rt_grout.c:560:41: error: code should be clang-formatted [-Wclang-format-violations]
.missing_ok = true, .vrf_id = vrf_id
^
frr/rt_grout.c:575:45: error: code should be clang-formatted [-Wclang-format-violations]
req.r6_add = (struct gr_ip6_route_add_req) {
^
frr/rt_grout.c:575:48: error: code should be clang-formatted [-Wclang-format-violations]
req.r6_add = (struct gr_ip6_route_add_req) {
^
frr/rt_grout.c:576:39: error: code should be clang-formatted [-Wclang-format-violations]
.exist_ok = true, .vrf_id = vrf_id
^
frr/rt_grout.c:586:45: error: code should be clang-formatted [-Wclang-format-violations]
req.r6_del = (struct gr_ip6_route_del_req) {
^
frr/rt_grout.c:586:48: error: code should be clang-formatted [-Wclang-format-violations]
req.r6_del = (struct gr_ip6_route_del_req) {
^
frr/rt_grout.c:587:41: error: code should be clang-formatted [-Wclang-format-violations]
.missing_ok = true, .vrf_id = vrf_id
^
frr/rt_grout.c:676:22: error: code should be clang-formatted [-Wclang-format-violations]
len += sizeof(*sr6)
^
frr/rt_grout.c:676:23: error: code should be clang-formatted [-Wclang-format-violations]
len += sizeof(*sr6)
^
modules/dhcp/control/client.c:83:17: error: code should be clang-formatted [-Wclang-format-violations]
LOG(WARNING,
^
modules/dhcp/control/client.c:84:48: error: code should be clang-formatted [-Wclang-format-violations]
"failed to create gateway nexthop: %s",
^
modules/dhcp/control/client.c:85:24: error: code should be clang-formatted [-Wclang-format-violations]
strerror(errno));
^
modules/dhcp/control/dhcp.h:122:24: error: code should be clang-formatted [-Wclang-format-violations]
int dhcp_parse_options(
^
modules/dhcp/control/dhcp.h:123:25: error: code should be clang-formatted [-Wclang-format-violations]
const uint8_t *options,
^
modules/dhcp/control/dhcp.h:124:23: error: code should be clang-formatted [-Wclang-format-violations]
uint16_t options_len,
^
modules/dhcp/control/dhcp.h:125:23: error: code should be clang-formatted [-Wclang-format-violations]
struct dhcp_client *,
^
modules/dhcp/control/dhcp.h:126:23: error: code should be clang-formatted [-Wclang-format-violations]
dhcp_message_type_t *
^
modules/infra/control/ctlplane.c:407:11: error: code should be clang-formatted [-Wclang-format-violations]
LOG(ERR,
^
modules/infra/control/ctlplane.c:408:45: error: code should be clang-formatted [-Wclang-format-violations]
"netlink_link_set_master(%s, %u): %s",
^
modules/infra/control/ctlplane.c:409:19: error: code should be clang-formatted [-Wclang-format-violations]
iface->name,
^
modules/infra/control/ctlplane.c:410:14: error: code should be clang-formatted [-Wclang-format-violations]
master,
^
modules/infra/control/ctlplane.c:411:22: error: code should be clang-formatted [-Wclang-format-violations]
strerror(errno));
^
modules/infra/control/graph.c:636:13: error: code should be clang-formatted [-Wclang-format-violations]
LOG(NOTICE,
^
modules/infra/control/graph.c:637:38: error: code should be clang-formatted [-Wclang-format-violations]
"vector_max=%u rx_burst_max=%u",
^
modules/infra/control/graph.c:638:28: error: code should be clang-formatted [-Wclang-format-violations]
graph_conf.vector_max,
^
modules/infra/control/graph.c:639:29: error: code should be clang-formatted [-Wclang-format-violations]
graph_conf.rx_burst_max);
^
modules/infra/control/lacp.c:178:26: error: code should be clang-formatted [-Wclang-format-violations]
member->next_tx = now + LACP_SHORT_TIMEOUT * (gr_clock_ns_t)NS_PER_S;
^
modules/infra/control/port.c:451:16: error: code should be clang-formatted [-Wclang-format-violations]
LOG(WARNING,
^
modules/infra/control/port.c:452:30: error: code should be clang-formatted [-Wclang-format-violations]
"rename %s -> %s: %s",
^
modules/infra/control/port.c:453:22: error: code should be clang-formatted [-Wclang-format-violations]
entry->d_name,
^
modules/infra/control/port.c:454:17: error: code should be clang-formatted [-Wclang-format-violations]
new_name,
^
modules/infra/control/port.c:455:23: error: code should be clang-formatted [-Wclang-format-violations]
strerror(errno));
^
modules/ip/control/icmp.c:49:25: error: code should be clang-formatted [-Wclang-format-violations]
static struct rte_mbuf *get_icmp_response(uint16_t ident, uint16_t seq_num, gr_clock_ns_t *timestamp) {
^
modules/ip/datapath/ip_input.c:253:20: error: code should be clang-formatted [-Wclang-format-violations]
gr_conn_parse_key(
^
modules/ip/datapath/ip_input.c:254:24: error: code should be clang-formatted [-Wclang-format-violations]
const struct iface *,
^
modules/ip/datapath/ip_input.c:255:23: error: code should be clang-formatted [-Wclang-format-violations]
const addr_family_t,
^
modules/ip/datapath/ip_input.c:256:27: error: code should be clang-formatted [-Wclang-format-violations]
const struct rte_mbuf *,
^
modules/ip/datapath/ip_input.c:257:20: error: code should be clang-formatted [-Wclang-format-violations]
struct conn_key *
^
modules/ip6/datapath/ip6_input.c:257:53: error: code should be clang-formatted [-Wclang-format-violations]
fake_mbuf.ipv6_hdr.src_addr = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ip6_input.c:257:63: error: code should be clang-formatted [-Wclang-format-violations]
fake_mbuf.ipv6_hdr.src_addr = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ip6_input.c:258:65: error: code should be clang-formatted [-Wclang-format-violations]
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
^
modules/ip6/datapath/ip6_input.c:270:53: error: code should be clang-formatted [-Wclang-format-violations]
fake_mbuf.ipv6_hdr.dst_addr = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ip6_input.c:270:63: error: code should be clang-formatted [-Wclang-format-violations]
fake_mbuf.ipv6_hdr.dst_addr = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ip6_input.c:271:41: error: code should be clang-formatted [-Wclang-format-violations]
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
^
modules/ip6/datapath/ip6_input.c:284:53: error: code should be clang-formatted [-Wclang-format-violations]
fake_mbuf.ipv6_hdr.dst_addr = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ip6_input.c:284:63: error: code should be clang-formatted [-Wclang-format-violations]
fake_mbuf.ipv6_hdr.dst_addr = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ip6_input.c:285:45: error: code should be clang-formatted [-Wclang-format-violations]
0xff00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
^
modules/ip6/datapath/ip6_input.c:291:53: error: code should be clang-formatted [-Wclang-format-violations]
fake_mbuf.ipv6_hdr.dst_addr = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ip6_input.c:291:63: error: code should be clang-formatted [-Wclang-format-violations]
fake_mbuf.ipv6_hdr.dst_addr = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ip6_input.c:292:45: error: code should be clang-formatted [-Wclang-format-violations]
0xff00, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
^
modules/ip6/datapath/ip6_output.c:106:32: error: code should be clang-formatted [-Wclang-format-violations]
|| (l3->flags & GR_NH_F_LINK
^
modules/ip6/datapath/ip6_output.c:107:55: error: code should be clang-formatted [-Wclang-format-violations]
&& !rte_ipv6_addr_eq(&ip->dst_addr, &l3->ipv6)))) {
^
modules/ip6/datapath/ndp_na_input.c:163:49: error: code should be clang-formatted [-Wclang-format-violations]
ndp_mbuf->na_hdr.target = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ndp_na_input.c:163:59: error: code should be clang-formatted [-Wclang-format-violations]
ndp_mbuf->na_hdr.target = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ndp_na_input.c:164:65: error: code should be clang-formatted [-Wclang-format-violations]
0xfe80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00aa
^
modules/ip6/datapath/ndp_na_input.c:183:67: error: code should be clang-formatted [-Wclang-format-violations]
ip6_local_mbuf_data(&ndp_mbuf->mbuf)->dst = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ndp_na_input.c:183:77: error: code should be clang-formatted [-Wclang-format-violations]
ip6_local_mbuf_data(&ndp_mbuf->mbuf)->dst = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ndp_na_input.c:184:35: error: code should be clang-formatted [-Wclang-format-violations]
0xfe80, 0, 0, 0, 0, 0, 0, 0x00bb
^
modules/ip6/datapath/ndp_na_input.c:239:48: error: code should be clang-formatted [-Wclang-format-violations]
ndp_mbuf.na_hdr.target = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ndp_na_input.c:239:58: error: code should be clang-formatted [-Wclang-format-violations]
ndp_mbuf.na_hdr.target = (struct rte_ipv6_addr)RTE_IPV6(
^
modules/ip6/datapath/ndp_na_input.c:240:45: error: code should be clang-formatted [-Wclang-format-violations]
0xff02, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
^
modules/l2/cli/fdb.c:141:17: error: code should be clang-formatted [-Wclang-format-violations]
gr_table_cell(table, 6, "%ld", (gr_clock_ns() - fdb->last_seen) / INT64_C(1000000000));
^
modules/l2/cli/fdb.c:141:88: error: code should be clang-formatted [-Wclang-format-violations]
gr_table_cell(table, 6, "%ld", (gr_clock_ns() - fdb->last_seen) / INT64_C(1000000000));
^
modules/policy/control/conntrack.h:50:24: error: code should be clang-formatted [-Wclang-format-violations]
bool gr_conn_parse_key(
^
modules/policy/control/conntrack.h:51:23: error: code should be clang-formatted [-Wclang-format-violations]
const struct iface *,
^
modules/policy/control/conntrack.h:52:22: error: code should be clang-formatted [-Wclang-format-violations]
const addr_family_t,
^
modules/policy/control/conntrack.h:53:26: error: code should be clang-formatted [-Wclang-format-violations]
const struct rte_mbuf *,
^
modules/policy/control/conntrack.h:54:19: error: code should be clang-formatted [-Wclang-format-violations]
struct conn_key *
^
modules/srv6/control/route.c:67:26: error: code should be clang-formatted [-Wclang-format-violations]
memcpy(sr6_pub->seglist,
^
modules/srv6/control/route.c:68:27: error: code should be clang-formatted [-Wclang-format-violations]
sr6_priv->seglist,
^
modules/srv6/control/route.c:69:57: error: code should be clang-formatted [-Wclang-format-violations]
sizeof(sr6_pub->seglist[0]) * sr6_pub->n_seglist);
^
make: *** [GNUmakefile:175: lint] Error 1
More information about the grout
mailing list