diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/include/optrack.h')
-rw-r--r-- | src/third_party/wiredtiger/src/include/optrack.h | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/src/include/optrack.h b/src/third_party/wiredtiger/src/include/optrack.h new file mode 100644 index 00000000000..6c3d57deea6 --- /dev/null +++ b/src/third_party/wiredtiger/src/include/optrack.h @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2014-2017 MongoDB, Inc. + * Copyright (c) 2008-2014 WiredTiger, Inc. + * All rights reserved. + * + * See the file LICENSE for redistribution information. + */ + +#define WT_OPTRACK_MAXRECS 16384 +#define WT_OPTRACK_BUFSIZE WT_OPTRACK_MAXRECS * sizeof(WT_OPTRACK_RECORD) +#define WT_OPTRACK_VERSION 1 + +/* + * WT_OPTRACK_HEADER -- + * A header in the operation tracking log file. The internal session + * identifier is a boolean: 1 if the session is internal, 0 otherwise. + */ +struct __wt_optrack_header { + uint32_t optrack_version; + uint32_t optrack_session_internal; +}; + +/* + * WT_OPTRACK_RECORD -- + * A structure for logging function entry and exit events. + * + * We pad the record so that the size of the entire record is 16 bytes. If we + * don't do this, the compiler will pad it for us, because we keep records in + * the record buffer array and each new record must be aligned on the 8-byte + * boundary, since its first element is an 8-byte timestamp. Instead of letting + * the compiler insert the padding silently, we pad explicitly, so that whoever + * writes the binary decoder can refer to this struct to find out the record + * size. + * + * The operation id included in this structure is a unique address of a function + * in the binary. As we log operations, we keep track of the correspondence + * between function addresses and their names. When the log file is decoded, + * operations identifiers are replaced with function names. Therefore, the + * present design assumes that the user will be inserting the tracking macros + * on function boundaries: when we enter into the function and when we exit + * from it. + */ +struct __wt_optrack_record { + uint64_t op_timestamp; /* timestamp */ + uint16_t op_id; /* function ID */ + uint16_t op_type; /* start/stop */ + uint8_t padding[4]; +}; + +#define WT_TRACK_OP(s, optype) do { \ + WT_OPTRACK_RECORD *__tr; \ + __tr = &((s)->optrack_buf[ \ + (s)->optrackbuf_ptr % WT_OPTRACK_MAXRECS]); \ + __tr->op_timestamp = __wt_rdtsc(s); \ + __tr->op_id = __func_id; \ + __tr->op_type = optype; \ + \ + if (++(s)->optrackbuf_ptr == WT_OPTRACK_MAXRECS) { \ + (s)->optrack_offset += __wt_optrack_flush_buffer(s); \ + (s)->optrackbuf_ptr = 0; \ + } \ +} while (0) + +/* + * We do not synchronize access to optrack buffer pointer under the assumption + * that there is no more than one thread using a given session. This assumption + * does not always hold. When it does not, we might have a race. In this case, + * we may lose a few log records. We prefer to risk losing a few log records + * occasionally in order not to synchronize this code, which is intended to be + * very lightweight. + * Exclude the default session (ID 0) because it can be used by multiple + * threads and it is also used in error paths during failed open calls. + */ +#define WT_TRACK_OP_DECL \ + static uint16_t __func_id = 0 +#define WT_TRACK_OP_INIT(s) \ + if (F_ISSET(S2C(s), WT_CONN_OPTRACK) && (s)->id != 0) { \ + if (__func_id == 0) \ + __wt_optrack_record_funcid( \ + s, __func__, &__func_id); \ + WT_TRACK_OP(s, 0); \ + } + +#define WT_TRACK_OP_END(s) \ + if (F_ISSET(S2C(s), WT_CONN_OPTRACK) && (s)->id != 0) \ + WT_TRACK_OP(s, 1); |