Skip to content

Commit 361e4a1

Browse files
Let's take out the compiler's dependent things
Taking one step towards cross-platform
1 parent 69cddd6 commit 361e4a1

9 files changed

Lines changed: 125 additions & 44 deletions

File tree

runtime/Cycles.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <stdint.h>
2020

21+
#include "Portability.h"
2122

2223
namespace PerfUtils {
2324

@@ -34,7 +35,7 @@ class Cycles {
3435
* Return the current value of the fine-grain CPU cycle counter
3536
* (accessed via the RDTSC instruction).
3637
*/
37-
static __inline __attribute__((always_inline))
38+
static NANOLOG_ALWAYS_INLINE
3839
uint64_t
3940
rdtsc()
4041
{
@@ -48,7 +49,7 @@ class Cycles {
4849
return (((uint64_t)hi << 32) | lo);
4950
}
5051

51-
static __inline __attribute__((always_inline))
52+
static NANOLOG_ALWAYS_INLINE
5253
double
5354
perSecond(){
5455
return getCyclesPerSec();
@@ -80,7 +81,7 @@ class Cycles {
8081
* Returns the conversion factor between cycles in seconds, using
8182
* a mock value for testing when appropriate.
8283
*/
83-
static __inline __attribute__((always_inline))
84+
static NANOLOG_ALWAYS_INLINE
8485
double
8586
getCyclesPerSec()
8687
{

runtime/Log.h

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "Common.h"
2424
#include "Cycles.h"
2525
#include "Packer.h"
26+
#include "Portability.h"
2627
#include "TestUtil.h"
2728
#include "Util.h"
2829

@@ -221,10 +222,12 @@ namespace Log {
221222
* in the first two bits and this structure is used to extract those bits
222223
* when the type/identify is unknown.
223224
*/
225+
NANOLOG_PACK_PUSH
224226
struct UnknownHeader {
225227
uint8_t entryType:2;
226228
uint8_t other:6;
227-
} __attribute((packed));
229+
} NANOLOG_PACK_ATTR;
230+
NANOLOG_PACK_POP
228231

229232
static_assert(sizeof(UnknownHeader) == 1, "Unknown Header should have a"
230233
" byte size of 1 to ensure that we can always determine the entry"
@@ -239,6 +242,7 @@ namespace Log {
239242
* (1-8 bytes) pack()-ed rdtsc() timestamp
240243
* (0-n bytes) arguments (determined by preprocessor)
241244
*/
245+
NANOLOG_PACK_PUSH
242246
struct CompressedEntry {
243247
// Byte representation of an EntryType::LOG_MSGS_OR_DIC to identify this
244248
// as a CompressedRecordEntry.
@@ -252,7 +256,8 @@ namespace Log {
252256

253257
// Value returned by pack(timestamp)
254258
uint8_t additionalTimestampBytes:4;
255-
} __attribute__((packed));
259+
} NANOLOG_PACK_ATTR;
260+
NANOLOG_PACK_POP
256261

257262
/**
258263
* Marker in the compressed log that indicates to which StagingBuffer/thread
@@ -261,6 +266,7 @@ namespace Log {
261266
* thread finishes processing a peek() and moves on to outputting the next
262267
* StagingBuffer.
263268
*/
269+
NANOLOG_PACK_PUSH
264270
struct BufferExtent {
265271
// Byte representation of EntryType::BUFFER_EXTENT
266272
uint8_t entryType:2;
@@ -289,7 +295,8 @@ namespace Log {
289295
static constexpr uint32_t maxSizeOfHeader() {
290296
return sizeof(BufferExtent) + sizeof(uint32_t);
291297
}
292-
} __attribute__((packed));
298+
} NANOLOG_PACK_ATTR;
299+
NANOLOG_PACK_POP
293300

294301
/**
295302
* Synchronization data structure in the compressed log that correlates the
@@ -298,6 +305,7 @@ namespace Log {
298305
* once at the beginning of a new log. If multiple exist in the log file,
299306
* that means the file has been appended to.
300307
*/
308+
NANOLOG_PACK_PUSH
301309
struct Checkpoint {
302310
// Byte representation of an EntryType::CHECKPOINT
303311
uint64_t entryType:2;
@@ -322,14 +330,16 @@ namespace Log {
322330
// in the log file.
323331
uint32_t totalMetadataEntries;
324332

325-
} __attribute__((packed));
333+
} NANOLOG_PACK_ATTR;
334+
NANOLOG_PACK_POP
326335

327336
/**
328337
* A DictionaryFragment contains a partial mapping of unique identifiers to
329338
* static log information on disk. Following this structure is one or more
330339
* CompressedLogInfo. The order in which these log infos appear determine
331340
* its unique identifier (i.e. by order of appearance starting at 0).
332341
*/
342+
NANOLOG_PACK_PUSH
333343
struct DictionaryFragment {
334344
// Byte representation of an EntryType::LOG_MSG_OR_DIC to indicate
335345
// the start of a dictionary fragment.
@@ -341,12 +351,14 @@ namespace Log {
341351
// Total number of FormatMetadata encountered so far in the log
342352
// including this fragment (used as a sanity check only).
343353
uint32_t totalMetadataEntries;
344-
} __attribute__((packed));
354+
} NANOLOG_PACK_ATTR;
355+
NANOLOG_PACK_POP
345356

346357
/**
347358
* Stores the static log information associated with a log message on disk.
348359
* Following this structure are the filename and format string.
349360
*/
361+
NANOLOG_PACK_PUSH
350362
struct CompressedLogInfo {
351363
// LogLevel severity of the original log invocation
352364
uint8_t severity;
@@ -361,14 +373,16 @@ namespace Log {
361373
// Length of the format string that is associated with this log
362374
// invocation and comes after filename.
363375
uint16_t formatStringLength;
364-
} __attribute((packed));
376+
} NANOLOG_PACK_ATTR;
377+
NANOLOG_PACK_POP
365378

366379
/**
367380
* Describes a unique log message within the user sources. The order in
368381
* which this structure appears in the log file determines the associated
369382
* logId. Following this structure are the source filename and
370383
* PrintFragments required for this message.
371384
*/
385+
NANOLOG_PACK_PUSH
372386
struct FormatMetadata {
373387
// Number of nibbles in the dynamic data stream used to pack() arguments
374388
uint8_t numNibbles;
@@ -387,12 +401,14 @@ namespace Log {
387401

388402
// Filename for the original source file containing the LOG statement
389403
char filename[];
390-
} __attribute__((packed));
404+
} NANOLOG_PACK_ATTR;
405+
NANOLOG_PACK_POP
391406

392407
/**
393408
* Describes how to interpret the dynamic log stream and partially
394409
* reconstruct the original log message.
395410
*/
411+
NANOLOG_PACK_PUSH
396412
struct PrintFragment {
397413
// The type of the argument to pull from the dynamic buffer to the
398414
// partial format string (formatFragment)
@@ -410,7 +426,8 @@ namespace Log {
410426
// A fragment of the original LOG statement that contains at most
411427
// one format specifier.
412428
char formatFragment[];
413-
} __attribute__((packed));
429+
} NANOLOG_PACK_ATTR;
430+
NANOLOG_PACK_POP
414431

415432

416433
/**

runtime/NanoLogCpp17.h

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "Common.h"
2626
#include "Cycles.h"
2727
#include "Packer.h"
28+
#include "Portability.h"
2829
#include "NanoLog.h"
2930

3031
/***
@@ -825,9 +826,9 @@ compressSingle(BufferUtils::TwoNibbles* nibbles,
825826
* https://stackoverflow.com/questions/23443511/how-to-match-empty-arguments-pack-in-variadic-template
826827
*/
827828
template<typename... Ts>
828-
__attribute__((always_inline))
829-
inline void compress_internal(BufferUtils::TwoNibbles*, int,
830-
const bool*, bool, int, char **, char **);
829+
NANOLOG_ALWAYS_INLINE
830+
void compress_internal(BufferUtils::TwoNibbles*, int,
831+
const bool*, bool, int, char **, char **);
831832

832833
/**
833834
* Recursively peels off an argument from an argument pack and compresses
@@ -855,15 +856,14 @@ inline void compress_internal(BufferUtils::TwoNibbles*, int,
855856
* Output buffer to write the compressed results to
856857
*/
857858
template<typename T1, typename... Ts>
858-
inline void
859-
__attribute__((always_inline))
860-
compressHelper(BufferUtils::TwoNibbles *nibbles,
861-
int nibbleCnt,
862-
const ParamType *paramTypes,
863-
bool stringsOnly,
864-
int argNum,
865-
char **in,
866-
char **out)
859+
NANOLOG_ALWAYS_INLINE
860+
void compressHelper(BufferUtils::TwoNibbles *nibbles,
861+
int nibbleCnt,
862+
const ParamType *paramTypes,
863+
bool stringsOnly,
864+
int argNum,
865+
char **in,
866+
char **out)
867867
{
868868
// Peel off the first argument, and recursively process the rest
869869
compressSingle<T1>(nibbles, &nibbleCnt, paramTypes[argNum], stringsOnly,
@@ -874,22 +874,20 @@ compressHelper(BufferUtils::TwoNibbles *nibbles,
874874

875875

876876
template<typename... Ts>
877-
inline void
878-
__attribute__((always_inline))
879-
compress_internal(BufferUtils::TwoNibbles *nibbles, int nibbleCnt,
880-
const ParamType *isArgString, bool stringsOnly, int argNum,
881-
char **in, char **out)
877+
NANOLOG_ALWAYS_INLINE
878+
void compress_internal(BufferUtils::TwoNibbles *nibbles, int nibbleCnt,
879+
const ParamType *isArgString, bool stringsOnly, int argNum,
880+
char **in, char **out)
882881
{
883882
compressHelper<Ts...>(nibbles, nibbleCnt, isArgString, stringsOnly,
884883
argNum, in, out);
885884
}
886885

887886
template<>
888-
inline void
889-
__attribute__((always_inline))
890-
compress_internal(BufferUtils::TwoNibbles *nibbles, int nibbleCnt,
891-
const ParamType *isArgString, bool stringsOnly, int argNum,
892-
char **in, char **out)
887+
NANOLOG_ALWAYS_INLINE
888+
void compress_internal(BufferUtils::TwoNibbles *nibbles, int nibbleCnt,
889+
const ParamType *isArgString, bool stringsOnly, int argNum,
890+
char **in, char **out)
893891
{
894892
// This is a catch for compress when the template arguments are empty,
895893
// in which case we do nothing. This is needed since the head/tail pack
@@ -1058,8 +1056,8 @@ log(int &logId,
10581056
* format parameters
10591057
*/
10601058
static void
1061-
__attribute__ ((format (printf, 1, 2)))
1062-
checkFormat(const char *, ...) {}
1059+
NANOLOG_PRINTF_FORMAT_ATTR(1, 2)
1060+
checkFormat(NANOLOG_PRINTF_FORMAT const char *, ...) {}
10631061

10641062

10651063
/**

runtime/Packer.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <cstdint>
2121

2222
#include "Common.h"
23+
#include "Portability.h"
2324

2425
#ifndef PACKER_H
2526
#define PACKER_H
@@ -71,10 +72,12 @@ namespace BufferUtils {
7172
* Packs two 4-bit nibbles into one byte. This is used to pack the special
7273
* codes returned by pack() in the compressed log.
7374
*/
75+
NANOLOG_PACK_PUSH
7476
struct TwoNibbles {
7577
uint8_t first:4;
7678
uint8_t second:4;
77-
} __attribute__((packed));
79+
} NANOLOG_PACK_ATTR;
80+
NANOLOG_PACK_POP
7881

7982
/**
8083
* Given an unsigned integer and a char array, find the fewest number of

runtime/Perf.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "Cycles.h"
4949
#include "Log.h"
5050
#include "PerfHelper.h"
51+
#include "Portability.h"
5152
#include "Util.h"
5253
#include "Fence.h"
5354

@@ -93,7 +94,7 @@ void function(uint64_t cycles) {
9394
* Return the current value of the fine-grain CPU cycle counter
9495
* (accessed via the RDTSC instruction).
9596
*/
96-
static __inline __attribute__((always_inline))
97+
static NANOLOG_ALWAYS_INLINE
9798
uint64_t
9899
rdtsc()
99100
{
@@ -106,7 +107,7 @@ rdtsc()
106107
* Return the current value of the fine-grain CPU cycle counter
107108
* (accessed via the RDTSCP instruction).
108109
*/
109-
static __inline __attribute__((always_inline))
110+
static NANOLOG_ALWAYS_INLINE
110111
uint64_t
111112
rdtscp()
112113
{

runtime/PerfHelper.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
#include <stdint.h>
2727
#include <stdio.h>
2828

29+
#include "Portability.h"
30+
2931
namespace PerfHelper {
3032

3133
void flushCache();
32-
uint64_t plusOne(uint64_t x) __attribute__ ((noinline));
34+
uint64_t plusOne(uint64_t x) NANOLOG_NOINLINE;
3335

3436
// Simple function that performs no computation
3537
template<int addTo>

runtime/Portability.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#ifndef NANOLOG_PORTABILITY_H
2+
#define NANOLOG_PORTABILITY_H
3+
4+
#ifdef _MSC_VER
5+
#define NANOLOG_ALWAYS_INLINE __forceinline
6+
#elif defined(__GNUC__)
7+
#define NANOLOG_ALWAYS_INLINE inline __attribute__((__always_inline__))
8+
#else
9+
#define NANOLOG_ALWAYS_INLINE inline
10+
#endif
11+
12+
#ifdef _MSC_VER
13+
#define NANOLOG_NOINLINE __declspec(noinline)
14+
#elif defined(__GNUC__)
15+
#define NANOLOG_NOINLINE __attribute__((__noinline__))
16+
#else
17+
#define NANOLOG_NOINLINE
18+
#endif
19+
20+
#ifdef _MSC_VER
21+
#define NANOLOG_PACK_ATTR
22+
#define NANOLOG_PACK_PUSH __pragma(pack(push, 1))
23+
#define NANOLOG_PACK_POP __pragma(pack(pop))
24+
#elif defined(__GNUC__)
25+
#define NANOLOG_PACK_ATTR __attribute__((__packed__))
26+
#define NANOLOG_PACK_PUSH
27+
#define NANOLOG_PACK_POP
28+
#else
29+
#define NANOLOG_PACK_ATTR
30+
#define NANOLOG_PACK_PUSH
31+
#define NANOLOG_PACK_POP
32+
#endif
33+
34+
#if _MSC_VER
35+
36+
#ifdef _USE_ATTRIBUTES_FOR_SAL
37+
#undef _USE_ATTRIBUTES_FOR_SAL
38+
#endif
39+
40+
#define _USE_ATTRIBUTES_FOR_SAL 1
41+
#include <sal.h>
42+
43+
#define NANOLOG_PRINTF_FORMAT _Printf_format_string_
44+
#define NANOLOG_PRINTF_FORMAT_ATTR(string_index, first_to_check)
45+
46+
#elif defined(__GNUC__)
47+
#define NANOLOG_PRINTF_FORMAT
48+
#define NANOLOG_PRINTF_FORMAT_ATTR(string_index, first_to_check) \
49+
__attribute__((__format__(__printf__, string_index, first_to_check)))
50+
#else
51+
#define NANOLOG_PRINTF_FORMAT
52+
#define NANOLOG_PRINTF_FORMAT_ATTR(string_index, first_to_check)
53+
#endif
54+
55+
#endif /* NANOLOG_PORTABILITY_H */

0 commit comments

Comments
 (0)