Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions fbclock/fbclock.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ limitations under the License.
*/

#include "fbclock.h"
#include <assert.h> // for static_assert in C11
#include <fcntl.h> // For O_* constants
#include <linux/ptp_clock.h>
#include <stdint.h>
Expand All @@ -29,6 +30,20 @@ limitations under the License.
#include <arm_acle.h>
#endif

// This file implements the seqlock, so it must see the real atomics. Defining
// FBCLOCK_CGO here would also leave the assert below comparing a type with
// itself.
#ifdef FBCLOCK_CGO
#error "FBCLOCK_CGO is only for cgo's view of the header, never for fbclock.c"
#endif

// fbclock.h hands cgo a plain uint_fast64_t in place of atomic_uint64 so it can
// convert the shm structs. That is only sound while the two lay out the same.
static_assert(
sizeof(atomic_uint64) == sizeof(uint_fast64_t) &&
alignof(atomic_uint64) == alignof(uint_fast64_t),
"atomic_uint64 must match its base type's layout; see FBCLOCK_CGO in fbclock.h");

#if defined(__GNUC__) && !defined(__OPTIMIZE__)
#define fbclock_debug_print(fmt, ...) \
do { \
Expand Down
4 changes: 4 additions & 0 deletions fbclock/fbclock.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ package fbclock
#cgo LDFLAGS: -lrt
#cgo amd64 CFLAGS: -msse4.2

// Scoped to this preamble on purpose: a #cgo CFLAGS define would also reach
// fbclock.c, which needs the real atomics. See FBCLOCK_CGO in fbclock.h.
#define FBCLOCK_CGO 1

#include "fbclock.h" // @oss-only
// @fb-only: #include "time/fbclock/fbclock.h"

Expand Down
15 changes: 13 additions & 2 deletions fbclock/fbclock.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,26 @@ limitations under the License.

#pragma once

#if defined(__cplusplus) && !defined(__clang__)
#include <stdint.h> /* for proper fixed width types */

// Only the cgo preambles in fbclock.go and shmem.go define FBCLOCK_CGO. cgo
// builds its Go types from DWARF, and Go's debug/dwarf has no model for
// DW_TAG_atomic_type, which clang 21 emits where clang 19 folded the atomic
// into its base integer; every struct reachable from fbclock_lib then fails to
// convert. Go needs the size and field offsets of the shm structs; it must
// never touch seq or crc itself, so a plain base type serves it. fbclock.c
// static_asserts that the substitution is layout-identical. The Rust bindings
// solve the same problem with --opaque-type; see this directory's BUCK.
#if defined(FBCLOCK_CGO)
typedef uint_fast64_t atomic_uint64;
#elif defined(__cplusplus) && !defined(__clang__)
#include <atomic>
typedef std::atomic_uint_fast64_t atomic_uint64;
#else
#include <stdatomic.h>
typedef atomic_uint_fast64_t atomic_uint64;
#endif

#include <stdint.h> /* for proper fixed width types */
#ifndef __cplusplus
#include <stdalign.h> /* for alignas in C; alignas is a keyword in C++ */
#endif
Expand Down
4 changes: 4 additions & 0 deletions fbclock/shmem.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ package fbclock
/*
#cgo LDFLAGS: -lrt

// cgo compiles each preamble as its own translation unit, so every file that
// includes the header needs this, not just fbclock.go. See FBCLOCK_CGO there.
#define FBCLOCK_CGO 1

#include "fbclock.h" // @oss-only
// @fb-only: #include "time/fbclock/fbclock.h"

Expand Down
Loading