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
84 changes: 84 additions & 0 deletions score/ts_client/docs/detailed_design/_assets/ipc_channel.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
' *******************************************************************************
' Copyright (c) 2026 Contributors to the Eclipse Foundation
'
' See the NOTICE file(s) distributed with this work for additional
' information regarding copyright ownership.
'
' This program and the accompanying materials are made available under the
' terms of the Apache License Version 2.0 which is available at
' https://www.apache.org/licenses/LICENSE-2.0
'
' SPDX-License-Identifier: Apache-2.0
' *******************************************************************************

@startuml ts_client_ipc_channel
!theme plain

title libTSClient Shared Memory IPC

legend top left
|= Color |= Description |
| <#LightPink> | IPC components |
| <#LightCyan> | Shared memory region |
| <#LightSalmon> | TimeDaemon adapter |
endlegend

package "TimeSlave Process" {
class GptpIpcPublisher #LightPink {
- region_ : GptpIpcRegion*
- shm_resource_ : shared_ptr<ISharedMemoryResource>
- ipc_name_ : string
+ Init(name) : bool
+ Publish(data : GptpIpcData) : void
+ Destroy() : void
}
}

package "Shared Memory" {
class GptpIpcRegion <<aligned(64)>> #LightCyan {
+ magic : atomic<uint32_t> = 0x47505450
+ seq : atomic<uint32_t>
+ data : GptpIpcData
+ seq_confirm : atomic<uint32_t>
--
64-byte aligned for\ncache line efficiency
}
}

package "TimeDaemon Process" {
class GptpIpcReceiver #LightPink {
- region_ : const GptpIpcRegion*
- shm_resource_ : shared_ptr<ISharedMemoryResource>
+ Init(name) : bool
+ Receive() : std::optional<GptpIpcData>
+ Close() : void
}

class ShmPTPEngine #LightSalmon {
- receiver_ : GptpIpcReceiver
- ipc_name_ : string
+ Initialize() : bool
+ Deinitialize() : bool
+ ReadPTPSnapshot(info : PtpTimeInfo&) : bool
}
}

GptpIpcPublisher --> GptpIpcRegion : "shm_open(O_CREAT)\nmmap(PROT_WRITE)"
GptpIpcReceiver --> GptpIpcRegion : "shm_open(O_RDONLY)\nmmap(PROT_READ)"
ShmPTPEngine *-- GptpIpcReceiver
ShmPTPEngine ..> "PtpTimeInfo" : converts to

note right of GptpIpcRegion
**Seqlock Protocol:**
Writer: seq++ (odd) → fence → memcpy → seq_confirm++, seq++ (even)
Reader: read seq1 (even) → memcpy → fence → read seq2, seq3
retry if seq1 != seq2 or seq1 != seq3
Retry up to 20 times on torn read
end note

note bottom of ShmPTPEngine
Maps GptpIpcData fields to PtpTimeInfo.
Instantiated as GPTPShmMachine via CreateGPTPShmMachine().
end note

@enduml
65 changes: 65 additions & 0 deletions score/ts_client/docs/detailed_design/_assets/ipc_sequence.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
' *******************************************************************************
' Copyright (c) 2026 Contributors to the Eclipse Foundation
'
' See the NOTICE file(s) distributed with this work for additional
' information regarding copyright ownership.
'
' This program and the accompanying materials are made available under the
' terms of the Apache License Version 2.0 which is available at
' https://www.apache.org/licenses/LICENSE-2.0
'
' SPDX-License-Identifier: Apache-2.0
' *******************************************************************************

@startuml ts_client_ipc_sequence
!theme plain

title libTSClient Seqlock IPC Protocol

participant "TimeSlave\n(GptpIpcPublisher)" as PUB #LightPink
participant "SharedMemory\n(GptpIpcRegion)" as SHM #LightCyan
participant "TimeDaemon\n(GptpIpcReceiver)" as RCV #LightPink

== Initialization ==

PUB -> SHM : shm_open("/gptp_ptp_info", O_CREAT | O_RDWR)
PUB -> SHM : ftruncate(sizeof(GptpIpcRegion))
PUB -> SHM : mmap(PROT_READ | PROT_WRITE)
PUB -> SHM : write magic = 0x47505450 ('GPTP')

...

RCV -> SHM : shm_open("/gptp_ptp_info", O_RDONLY)
RCV -> SHM : mmap(PROT_READ)
RCV -> SHM : verify magic == 0x47505450

== Publish (Writer Side) ==

PUB -> SHM : seq.fetch_add(1, relaxed) // seq becomes odd (write in progress)
PUB -> SHM : atomic_thread_fence(release)
PUB -> SHM : memcpy(&data, &src, sizeof(GptpIpcData))
PUB -> SHM : seq_confirm.store(seq+1, release) // seq_confirm becomes even
PUB -> SHM : seq.store(seq+1, release) // seq becomes even (write done)

== Receive (Reader Side) ==

loop up to 20 retries
RCV -> SHM : seq1 = seq.load(acquire)
alt seq1 is odd (write in progress)
RCV -> RCV : retry
else seq1 is even
RCV -> SHM : memcpy(&local, &data, sizeof(GptpIpcData))
RCV -> SHM : atomic_thread_fence(acq_rel)
RCV -> SHM : seq2 = seq_confirm.load(acquire)
RCV -> SHM : seq3 = seq.load(acquire)
alt seq1 == seq2 && seq1 == seq3
RCV --> RCV : return GptpIpcData (consistent)
else torn read (new write started)
RCV -> RCV : retry
end
end
end

RCV --> RCV : return std::nullopt (exhausted retries)

@enduml
96 changes: 0 additions & 96 deletions score/ts_client/docs/detailed_design/detailed_design.rst

This file was deleted.

Loading
Loading