Skip to content

Commit

Permalink
reduce heap allocations #12
Browse files Browse the repository at this point in the history
Summary:
* Make `corrToDuration` as a method of `Correction`
* Migrate usages
* Implement tests

This should help to avoid allocations in logging, but definitely improve code readability

Reviewed By: deathowl

Differential Revision: D58468150

fbshipit-source-id: 76d91cbc317435729595a81e2ee0dd2193e4fb54
  • Loading branch information
leoleovich authored and facebook-github-bot committed Jun 12, 2024
1 parent c967447 commit 3b1737f
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 29 deletions.
9 changes: 9 additions & 0 deletions ptp/protocol/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@ func (t Correction) Nanoseconds() float64 {
return IntFloat(t).Value()
}

// Duration converts PTP CorrectionField to time.Duration, ignoring
// case where correction is too big, and dropping fractions of nanoseconds
func (t Correction) Duration() time.Duration {
if !t.TooBig() {
return time.Duration(t.Nanoseconds())
}
return 0
}

func (t Correction) String() string {
if t.TooBig() {
return "Correction(Too big)"
Expand Down
24 changes: 23 additions & 1 deletion ptp/protocol/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ func TestTimestamp(t *testing.T) {
}
}

func TestCorrection(t *testing.T) {
func TestCorrectionFromDuration(t *testing.T) {
tests := []struct {
in time.Duration
want Correction
Expand Down Expand Up @@ -285,6 +285,28 @@ func TestCorrection(t *testing.T) {
}
}

func TestDurationFromCorrection(t *testing.T) {
tests := []struct {
in Correction
want time.Duration
}{
{
in: Correction(65536000000),
want: time.Millisecond,
},
{
in: Correction(0x7fffffffffffffff),
want: 0,
},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("Duration of %v", tt.in), func(t *testing.T) {
got := tt.in.Duration()
require.Equal(t, tt.want, got)
})
}
}

func TestLogInterval(t *testing.T) {
tests := []struct {
in LogInterval
Expand Down
21 changes: 6 additions & 15 deletions ptp/simpleclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,6 @@ func (c *udpConnTS) WriteToWithTS(b []byte, addr net.Addr) (int, time.Time, erro
return n, hwts, nil
}

// corrToDuration converts PTP CorrectionField to time.Duration, ignoring
// case where correction is too big, and dropping fractions of nanoseconds
func corrToDuration(correction ptp.Correction) (corr time.Duration) {
if !correction.TooBig() {
corr = time.Duration(correction.Nanoseconds())
}
return
}

// Config specifies Client run options
type Config struct {
// address of a server to talk to
Expand Down Expand Up @@ -361,16 +352,16 @@ func (c *Client) handleAnnounce(b *ptp.Announce) error {

// handleSync handles SYNC packet and adds send timestamp to measurements
func (c *Client) handleSync(b *ptp.SyncDelayReq, ts time.Time) error {
c.logReceive(ptp.MessageSync, "seq=%d, our ReceiveTimestamp(T2)=%v, correctionField(C1)=%v", b.SequenceID, ts, corrToDuration(b.CorrectionField))
c.m.addSync(b.SequenceID, ts, corrToDuration(b.CorrectionField))
c.logReceive(ptp.MessageSync, "seq=%d, our ReceiveTimestamp(T2)=%v, correctionField(C1)=%v", b.SequenceID, ts, b.CorrectionField.Duration())
c.m.addSync(b.SequenceID, ts, b.CorrectionField.Duration())
return nil
}

// handleDelay handles DELAY packet and adds ReceiveTimestamp to measurements
func (c *Client) handleDelay(b *ptp.DelayResp) error {
c.logReceive(ptp.MessageDelayResp, "seq=%d, server ReceiveTimestamp(T4)=%v, correctionField(C3)=%v", b.SequenceID, b.ReceiveTimestamp.Time(), corrToDuration(b.CorrectionField))
c.logReceive(ptp.MessageDelayResp, "seq=%d, server ReceiveTimestamp(T4)=%v, correctionField(C3)=%v", b.SequenceID, b.ReceiveTimestamp.Time(), b.CorrectionField.Duration())
// store data in measurements
c.m.addDelayResp(b.SequenceID, b.ReceiveTimestamp.Time(), corrToDuration(b.CorrectionField))
c.m.addDelayResp(b.SequenceID, b.ReceiveTimestamp.Time(), b.CorrectionField.Duration())

// do whatever needs to be done with current measurements
res, err := c.m.latest()
Expand All @@ -384,8 +375,8 @@ func (c *Client) handleDelay(b *ptp.DelayResp) error {

// handleFollowUp handles FOLLOW_UP packet and sends DELAY_REQ packet
func (c *Client) handleFollowUp(b *ptp.FollowUp) error {
c.logReceive(ptp.MessageFollowUp, "seq=%d, server PreciseOriginTimestamp(T1)=%v, correctionField(C2)=%v", b.SequenceID, b.PreciseOriginTimestamp.Time(), corrToDuration(b.CorrectionField))
c.m.addFollowUp(b.SequenceID, b.PreciseOriginTimestamp.Time(), corrToDuration(b.CorrectionField))
c.logReceive(ptp.MessageFollowUp, "seq=%d, server PreciseOriginTimestamp(T1)=%v, correctionField(C2)=%v", b.SequenceID, b.PreciseOriginTimestamp.Time(), b.CorrectionField.Duration())
c.m.addFollowUp(b.SequenceID, b.PreciseOriginTimestamp.Time(), b.CorrectionField.Duration())
// ask for delay
seq, hwts, err := c.sendEventMsg(reqDelay(c.clockID))
if err != nil {
Expand Down
17 changes: 4 additions & 13 deletions ptp/sptp/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@ import (
ptp "github.com/facebook/time/ptp/protocol"
)

// corrToDuration converts PTP CorrectionField to time.Duration, ignoring
// case where correction is too big, and dropping fractions of nanoseconds
func corrToDuration(correction ptp.Correction) (corr time.Duration) {
if !correction.TooBig() {
corr = time.Duration(correction.Nanoseconds())
}
return
}

// ReqDelay is a helper to build ptp.SyncDelayReq
func ReqDelay(clockID ptp.ClockIdentity, portID uint16) *ptp.SyncDelayReq {
return &ptp.SyncDelayReq{
Expand Down Expand Up @@ -194,14 +185,14 @@ func (c *Client) handleAnnounce(b *ptp.Announce) {
ptp.MessageAnnounce,
b.SequenceID,
b.OriginTimestamp.Time(),
corrToDuration(b.CorrectionField),
b.CorrectionField.Duration(),
b.GrandmasterIdentity,
b.TimeSource,
b.StepsRemoved)
c.m.currentUTCoffset = time.Duration(b.CurrentUTCOffset) * time.Second
// announce carries T1 and CF2
c.m.addT1(b.SequenceID, b.OriginTimestamp.Time())
c.m.addCF2(b.SequenceID, corrToDuration(b.CorrectionField))
c.m.addCF2(b.SequenceID, b.CorrectionField.Duration())
c.m.addAnnounce(*b)
}

Expand All @@ -213,9 +204,9 @@ func (c *Client) handleSync(b *ptp.SyncDelayReq, ts time.Time) {
b.SequenceID,
ts,
b.OriginTimestamp.Time(),
corrToDuration(b.CorrectionField))
b.CorrectionField.Duration())
// T2 and CF1
c.m.addT2andCF1(b.SequenceID, ts, corrToDuration(b.CorrectionField))
c.m.addT2andCF1(b.SequenceID, ts, b.CorrectionField.Duration())
// sync carries T4 as well
c.m.addT4(b.SequenceID, b.OriginTimestamp.Time())
}
Expand Down

0 comments on commit 3b1737f

Please sign in to comment.