From f35975ea21d4018ea5dccfdce3c420de5b5f5140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 17 May 2019 01:45:05 +0300 Subject: [PATCH] core/rawdb, eth/downloader: align 64bit atomic fields --- core/rawdb/freezer.go | 6 +++++- core/rawdb/freezer_table.go | 6 +++++- eth/downloader/downloader.go | 10 +++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index 67ed87d66..33da53787 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -66,8 +66,12 @@ const ( // reserving it for go-ethereum. This would also reduce the memory requirements // of Geth, and thus also GC overhead. type freezer struct { + // WARNING: The `frozen` field is accessed atomically. On 32 bit platforms, only + // 64-bit aligned fields can be atomic. The struct is guaranteed to be so aligned, + // so take advantage of that (https://golang.org/pkg/sync/atomic/#pkg-note-BUG). + frozen uint64 // Number of blocks already frozen + tables map[string]*freezerTable // Data tables for storing everything - frozen uint64 // Number of blocks already frozen instanceLock fileutil.Releaser // File-system lock to prevent double opens } diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go index 673a181e4..d1ece414b 100644 --- a/core/rawdb/freezer_table.go +++ b/core/rawdb/freezer_table.go @@ -73,6 +73,11 @@ func (i *indexEntry) marshallBinary() []byte { // It consists of a data file (snappy encoded arbitrary data blobs) and an indexEntry // file (uncompressed 64 bit indices into the data file). type freezerTable struct { + // WARNING: The `items` field is accessed atomically. On 32 bit platforms, only + // 64-bit aligned fields can be atomic. The struct is guaranteed to be so aligned, + // so take advantage of that (https://golang.org/pkg/sync/atomic/#pkg-note-BUG). + items uint64 // Number of items stored in the table (including items removed from tail) + noCompression bool // if true, disables snappy compression. Note: does not work retroactively maxFileSize uint32 // Max file size for data-files name string @@ -86,7 +91,6 @@ type freezerTable struct { // In the case that old items are deleted (from the tail), we use itemOffset // to count how many historic items have gone missing. - items uint64 // Number of items stored in the table (including items removed from tail) itemOffset uint32 // Offset (number of discarded items) headBytes uint32 // Number of bytes written to the head file diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 495fa0e74..321c4473b 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -98,6 +98,13 @@ var ( ) type Downloader struct { + // WARNING: The `rttEstimate` and `rttConfidence` fields are accessed atomically. + // On 32 bit platforms, only 64-bit aligned fields can be atomic. The struct is + // guaranteed to be so aligned, so take advantage of that. For more information, + // see https://golang.org/pkg/sync/atomic/#pkg-note-BUG. + rttEstimate uint64 // Round trip time to target for download requests + rttConfidence uint64 // Confidence in the estimated RTT (unit: millionths to allow atomic ops) + mode SyncMode // Synchronisation mode defining the strategy used (per sync cycle) mux *event.TypeMux // Event multiplexer to announce sync operation events @@ -109,9 +116,6 @@ type Downloader struct { stateDB ethdb.Database // Database to state sync into (and deduplicate via) stateBloom *trie.SyncBloom // Bloom filter for fast trie node existence checks - rttEstimate uint64 // Round trip time to target for download requests - rttConfidence uint64 // Confidence in the estimated RTT (unit: millionths to allow atomic ops) - // Statistics syncStatsChainOrigin uint64 // Origin block number where syncing started at syncStatsChainHeight uint64 // Highest block number known when syncing started