1 /*****************************************************************************
2 
3 Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2008, Google Inc.
5 
6 Portions of this file contain modifications contributed and copyrighted by
7 Google, Inc. Those modifications are gratefully acknowledged and are described
8 briefly in the InnoDB documentation. The contributions by Google are
9 incorporated with their permission, and subject to the conditions contained in
10 the file COPYING.Google.
11 
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License, version 2.0, as published by the
14 Free Software Foundation.
15 
16 This program is also distributed with certain software (including but not
17 limited to OpenSSL) that is licensed under separate terms, as designated in a
18 particular file or component or in included license documentation. The authors
19 of MySQL hereby grant you an additional permission to link the program and
20 your derivative works with the separately licensed software that they have
21 included with MySQL.
22 
23 This program is distributed in the hope that it will be useful, but WITHOUT
24 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
26 for more details.
27 
28 You should have received a copy of the GNU General Public License along with
29 this program; if not, write to the Free Software Foundation, Inc.,
30 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
31 
32 *****************************************************************************/
33 
34 /***********************************************************************/ /**
35  @file include/univ.i
36  Version control for database, common definitions, and include files
37 
38  Created 1/20/1994 Heikki Tuuri
39  ****************************************************************************/
40 
41 #ifndef univ_i
42 #define univ_i
43 
44 #ifdef UNIV_HOTBACKUP
45 #include "hb_univ.i"
46 #endif /* UNIV_HOTBACKUP */
47 
48 /* aux macros to convert M into "123" (string) if M is defined like
49 #define M 123 */
50 #define _IB_TO_STR(s) #s
51 #define IB_TO_STR(s) _IB_TO_STR(s)
52 
53 #define INNODB_VERSION_MAJOR MYSQL_VERSION_MAJOR
54 #define INNODB_VERSION_MINOR MYSQL_VERSION_MINOR
55 #define INNODB_VERSION_BUGFIX MYSQL_VERSION_PATCH
56 
57 /* The following is the InnoDB version as shown in
58 SELECT plugin_version FROM information_schema.plugins;
59 calculated in make_version_string() in sql/sql_show.cc like this:
60 "version >> 8" . "version & 0xff"
61 because the version is shown with only one dot, we skip the last
62 component, i.e. we show M.N.P as M.N */
63 #define INNODB_VERSION_SHORT (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
64 
65 #define INNODB_VERSION_STR        \
66   IB_TO_STR(INNODB_VERSION_MAJOR) \
67   "." IB_TO_STR(INNODB_VERSION_MINOR) "." IB_TO_STR(INNODB_VERSION_BUGFIX)
68 
69 #define REFMAN                                  \
70   "http://dev.mysql.com/doc/refman/" IB_TO_STR( \
71       MYSQL_VERSION_MAJOR) "." IB_TO_STR(MYSQL_VERSION_MINOR) "/en/"
72 
73 #ifdef MYSQL_DYNAMIC_PLUGIN
74 /* In the dynamic plugin, redefine some externally visible symbols
75 in order not to conflict with the symbols of a builtin InnoDB. */
76 
77 /* Rename all C++ classes that contain virtual functions, because we
78 have not figured out how to apply the visibility=hidden attribute to
79 the virtual method table (vtable) in GCC 3. */
80 #define ha_innobase ha_innodb
81 #endif /* MYSQL_DYNAMIC_PLUGIN */
82 
83 #if defined(_WIN32)
84 #include <windows.h>
85 #endif /* _WIN32 */
86 
87 /* The defines used with MySQL */
88 
89 /* Include a minimum number of SQL header files so that few changes
90 made in SQL code cause a complete InnoDB rebuild.  These headers are
91 used throughout InnoDB but do not include too much themselves.  They
92 support cross-platform development and expose comonly used SQL names. */
93 
94 #include "m_string.h"
95 #ifndef UNIV_HOTBACKUP
96 #include "my_thread.h"
97 #endif /* !UNIV_HOTBACKUP  */
98 
99 /* Include <sys/stat.h> to get S_I... macros defined for os0file.cc */
100 #include <sys/stat.h>
101 
102 #include "my_psi_config.h"
103 
104 #ifndef _WIN32
105 #include <sched.h>
106 #include <sys/mman.h> /* mmap() for os0proc.cc */
107 #endif                /* !_WIN32 */
108 
109 /* Include the header file generated by CMake */
110 #ifndef _WIN32
111 #ifndef UNIV_HOTBACKUP
112 #include "my_config.h"
113 #endif /* !UNIV_HOTBACKUP */
114 #endif
115 
116 #ifndef UNIV_HOTBACKUP
117 #include <inttypes.h>
118 #include <stdint.h>
119 #ifdef HAVE_UNISTD_H
120 #include <unistd.h>
121 #endif
122 #endif /* !UNIV_HOTBACKUP */
123 
124 /* Following defines are to enable performance schema
125 instrumentation in each of five InnoDB modules if
126 HAVE_PSI_INTERFACE is defined. */
127 #if defined(HAVE_PSI_INTERFACE) && !defined(UNIV_LIBRARY)
128 #ifdef HAVE_PSI_MUTEX_INTERFACE
129 #define UNIV_PFS_MUTEX
130 #endif /* HAVE_PSI_MUTEX_INTERFACE */
131 
132 #if defined HAVE_PSI_RWLOCK_INTERFACE && defined UNIV_PFS_MUTEX
133 /* For the rwlocks to be tracked UNIV_PFS_MUTEX has to be defined. If not
134 defined, the rwlocks are simply not tracked. */
135 #define UNIV_PFS_RWLOCK
136 #endif /* HAVE_PSI_RWLOCK_INTERFACE */
137 
138 #ifdef HAVE_PSI_FILE_INTERFACE
139 #define UNIV_PFS_IO
140 #endif /* HAVE_PSI_FILE_INTERFACE */
141 
142 #ifdef HAVE_PSI_THREAD_INTERFACE
143 #define UNIV_PFS_THREAD
144 #endif /* HAVE_PSI_THREAD_INTERFACE */
145 
146 #ifdef HAVE_PSI_MEMORY_INTERFACE
147 #define UNIV_PFS_MEMORY
148 #endif /* HAVE_PSI_MEMORY_INTERFACE */
149 
150 #include "mysql/psi/mysql_file.h"
151 #include "mysql/psi/mysql_mutex.h"
152 #include "mysql/psi/mysql_rwlock.h"
153 #include "mysql/psi/mysql_thread.h"
154 /* For PSI_FILE_CALL(). */
155 #include "pfs_file_provider.h"
156 #include "pfs_mutex_provider.h"
157 #include "pfs_rwlock_provider.h"
158 /* For PSI_MUTEX_CALL() and similar. */
159 #include "pfs_thread_provider.h"
160 
161 #endif /* HAVE_PSI_INTERFACE && !UNIV_LIBRARY */
162 
163 #ifdef _WIN32
164 #define YY_NO_UNISTD_H 1
165 /* VC++ tries to optimise for size by default, from V8+. The size of
166 the pointer to member depends on whether the type is defined before the
167 compiler sees the type in the translation unit. This default behaviour
168 can cause the pointer to be a different size in different translation
169 units, depending on the above rule. We force optimise for size behaviour
170 for all cases. This is used by ut0lst.h related code. */
171 #pragma pointers_to_members(full_generality, single_inheritance)
172 #endif /* _WIN32 */
173 
174 /*			DEBUG VERSION CONTROL
175                         ===================== */
176 
177 /* When this macro is defined then additional test functions will be
178 compiled. These functions live at the end of each relevant source file
179 and have "test_" prefix. These functions can be called from the end of
180 innobase_init() or they can be called from gdb after
181 innobase_start_or_create_for_mysql() has executed using the call
182 command. */
183 /*
184 #define UNIV_COMPILE_TEST_FUNCS
185 #define UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR
186 #define UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH
187 #define UNIV_ENABLE_UNIT_TEST_DICT_STATS
188 #define UNIV_ENABLE_UNIT_TEST_ROW_RAW_FORMAT_INT
189 */
190 
191 #if defined HAVE_VALGRIND
192 #define UNIV_DEBUG_VALGRIND
193 #endif /* HAVE_VALGRIND */
194 
195 #ifdef DBUG_OFF
196 #undef UNIV_DEBUG
197 #elif !defined UNIV_DEBUG
198 #define UNIV_DEBUG
199 #endif
200 
201 #if 0
202 #define UNIV_DEBUG_VALGRIND        /* Enable extra \
203                                    Valgrind instrumentation */
204 #define UNIV_DEBUG_PRINT           /* Enable the compilation of \
205                                    some debug print functions */
206 #define UNIV_AHI_DEBUG             /* Enable adaptive hash index \
207                                    debugging without UNIV_DEBUG */
208 #define UNIV_BUF_DEBUG             /* Enable buffer pool \
209                                    debugging without UNIV_DEBUG */
210 #define UNIV_BLOB_LIGHT_DEBUG      /* Enable off-page column \
211                                    debugging without UNIV_DEBUG */
212 #define UNIV_DEBUG_LOCK_VALIDATE   /* Enable                       \
213                                    ut_ad(lock_rec_validate_page()) \
214                                    assertions. */
215 #define UNIV_LRU_DEBUG             /* debug the buffer pool LRU */
216 #define UNIV_HASH_DEBUG            /* debug HASH_ macros */
217 #define UNIV_LOG_LSN_DEBUG         /* write LSN to the redo log;               \
218 this will break redo log file compatibility, but it may be useful when \
219 debugging redo log application problems. */
220 #define UNIV_IBUF_DEBUG            /* debug the insert buffer */
221 #define UNIV_IBUF_COUNT_DEBUG      /* debug the insert buffer;               \
222 this limits the database to IBUF_COUNT_N_SPACES and IBUF_COUNT_N_PAGES, \
223 and the insert buffer must be empty when the database is started */
224 #define UNIV_PERF_DEBUG            /* debug flag that enables \
225                                    light weight performance   \
226                                    related stuff. */
227 #define UNIV_SEARCH_PERF_STAT      /* statistics for the \
228                                    adaptive hash index */
229 #define UNIV_SRV_PRINT_LATCH_WAITS /* enable diagnostic output \
230                                    in sync0sync.cc */
231 #define UNIV_BTR_PRINT             /* enable functions for \
232                                    printing B-trees */
233 #define UNIV_ZIP_DEBUG             /* extensive consistency checks \
234                                    for compressed pages */
235 #define UNIV_ZIP_COPY              /* call page_zip_copy_recs() \
236                                    more often */
237 #define UNIV_AIO_DEBUG             /* prints info about     \
238                                    submitted and reaped AIO \
239                                    requests to the log. */
240 #define UNIV_STATS_DEBUG           /* prints various stats \
241                                    related debug info from \
242                                    dict0stats.c */
243 #define FTS_INTERNAL_DIAG_PRINT    /* FTS internal debugging \
244                                    info output */
245 #define UNIV_DEBUG_DEDICATED       /* dedicated server debugging \
246                                    info output and code coverage */
247 #endif
248 
249 #define UNIV_BTR_DEBUG       /* check B-tree links */
250 #define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */
251 
252 // #define UNIV_SQL_DEBUG
253 
254 #if defined(COMPILER_HINTS) && defined __GNUC__ && \
255     (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3)
256 
257 /** Starting with GCC 4.3, the "cold" attribute is used to inform the
258 compiler that a function is unlikely executed.  The function is
259 optimized for size rather than speed and on many targets it is placed
260 into special subsection of the text section so all cold functions
261 appears close together improving code locality of non-cold parts of
262 program.  The paths leading to call of cold functions within code are
263 marked as unlikely by the branch prediction mechanism.  optimize a
264 rarely invoked function for size instead for speed. */
265 #define UNIV_COLD MY_ATTRIBUTE((cold))
266 #else
267 #define UNIV_COLD /* empty */
268 #endif
269 
270 #ifdef UNIV_HOTBACKUP
271 #define UNIV_INLINE inline
272 #else /* UNIV_HOTBACKUP */
273 #define UNIV_INLINE static inline
274 #endif /* UNIV_HOTBACKUP */
275 
276 #ifdef _WIN32
277 #ifdef _WIN64
278 constexpr size_t UNIV_WORD_SIZE = 8;
279 #else
280 constexpr size_t UNIV_WORD_SIZE = 4;
281 #endif
282 #else  /* !_WIN32 */
283 /** MySQL config.h generated by CMake will define SIZEOF_LONG in Posix */
284 constexpr size_t UNIV_WORD_SIZE = SIZEOF_LONG;
285 #endif /* _WIN32 */
286 
287 /** The following alignment is used in memory allocations in memory heap
288 management to ensure correct alignment for doubles etc. */
289 #define UNIV_MEM_ALIGNMENT 8
290 
291 /*
292                         DATABASE VERSION CONTROL
293                         ========================
294 */
295 
296 /** The 2-logarithm of UNIV_PAGE_SIZE: */
297 #define UNIV_PAGE_SIZE_SHIFT srv_page_size_shift
298 
299 /** The universal page size of the database */
300 #define UNIV_PAGE_SIZE ((ulint)srv_page_size)
301 
302 /** log2 of smallest compressed page size (1<<10 == 1024 bytes)
303 Note: This must never change! */
304 #define UNIV_ZIP_SIZE_SHIFT_MIN 10
305 
306 /** log2 of largest compressed page size (1<<14 == 16384 bytes).
307 A compressed page directory entry reserves 14 bits for the start offset
308 and 2 bits for flags. This limits the uncompressed page size to 16k.
309 Even though a 16k uncompressed page can theoretically be compressed
310 into a larger compressed page, it is not a useful feature so we will
311 limit both with this same constant. */
312 #define UNIV_ZIP_SIZE_SHIFT_MAX 14
313 
314 /* Define the Min, Max, Default page sizes. */
315 /** Minimum Page Size Shift (power of 2) */
316 #define UNIV_PAGE_SIZE_SHIFT_MIN 12
317 /** Maximum Page Size Shift (power of 2) */
318 #define UNIV_PAGE_SIZE_SHIFT_MAX 16
319 /** Default Page Size Shift (power of 2) */
320 #define UNIV_PAGE_SIZE_SHIFT_DEF 14
321 /** Original 16k InnoDB Page Size Shift, in case the default changes */
322 #define UNIV_PAGE_SIZE_SHIFT_ORIG 14
323 /** Original 16k InnoDB Page Size as an ssize (log2 - 9) */
324 #define UNIV_PAGE_SSIZE_ORIG (UNIV_PAGE_SIZE_SHIFT_ORIG - 9)
325 
326 /** Minimum page size InnoDB currently supports. */
327 #define UNIV_PAGE_SIZE_MIN (1 << UNIV_PAGE_SIZE_SHIFT_MIN)
328 /** Maximum page size InnoDB currently supports. */
329 constexpr size_t UNIV_PAGE_SIZE_MAX = (1 << UNIV_PAGE_SIZE_SHIFT_MAX);
330 /** Default page size for InnoDB tablespaces. */
331 #define UNIV_PAGE_SIZE_DEF (1 << UNIV_PAGE_SIZE_SHIFT_DEF)
332 /** Original 16k page size for InnoDB tablespaces. */
333 #define UNIV_PAGE_SIZE_ORIG (1 << UNIV_PAGE_SIZE_SHIFT_ORIG)
334 
335 /** Smallest compressed page size */
336 #define UNIV_ZIP_SIZE_MIN (1 << UNIV_ZIP_SIZE_SHIFT_MIN)
337 
338 /** Largest compressed page size */
339 #define UNIV_ZIP_SIZE_MAX (1 << UNIV_ZIP_SIZE_SHIFT_MAX)
340 
341 /** Largest possible ssize for an uncompressed page.
342 (The convention 'ssize' is used for 'log2 minus 9' or the number of
343 shifts starting with 512.)
344 This max number varies depending on UNIV_PAGE_SIZE. */
345 #define UNIV_PAGE_SSIZE_MAX \
346   static_cast<ulint>(UNIV_PAGE_SIZE_SHIFT - UNIV_ZIP_SIZE_SHIFT_MIN + 1)
347 
348 /** Smallest possible ssize for an uncompressed page. */
349 #define UNIV_PAGE_SSIZE_MIN \
350   static_cast<ulint>(UNIV_PAGE_SIZE_SHIFT_MIN - UNIV_ZIP_SIZE_SHIFT_MIN + 1)
351 
352 /** Maximum number of parallel threads in a parallelized operation */
353 #define UNIV_MAX_PARALLELISM 32
354 
355 /** This is the "mbmaxlen" for my_charset_filename (defined in
356 strings/ctype-utf8.c), which is used to encode File and Database names. */
357 #define FILENAME_CHARSET_MAXNAMLEN 5
358 
359 /** The maximum length of an encode table name in bytes.  The max
360 table and database names are NAME_CHAR_LEN (64) characters. After the
361 encoding, the max length would be NAME_CHAR_LEN (64) *
362 FILENAME_CHARSET_MAXNAMLEN (5) = 320 bytes. The number does not include a
363 terminating '\0'. InnoDB can handle longer names internally */
364 #define MAX_TABLE_NAME_LEN 320
365 
366 /** The maximum length of a database name. Like MAX_TABLE_NAME_LEN this is
367 the MySQL's NAME_LEN, see check_and_convert_db_name(). */
368 #define MAX_DATABASE_NAME_LEN MAX_TABLE_NAME_LEN
369 
370 /** MAX_FULL_NAME_LEN defines the full name path including the
371 database name and table name. In addition, 14 bytes is added for:
372         2 for surrounding quotes around table name
373         1 for the separating dot (.)
374         9 for the #mysql50# prefix */
375 #define MAX_FULL_NAME_LEN (MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN + 14)
376 
377 /** Maximum length of the compression alogrithm string. Currently we support
378 only (NONE | ZLIB | LZ4). */
379 #define MAX_COMPRESSION_LEN 4
380 
381 /*
382                         UNIVERSAL TYPE DEFINITIONS
383                         ==========================
384 */
385 
386 /* Note that inside MySQL 'byte' is defined as char on Linux! */
387 #define byte unsigned char
388 
389 /* Another basic type we use is unsigned long integer which should be equal to
390 the word size of the machine, that is on a 32-bit platform 32 bits, and on a
391 64-bit platform 64 bits. We also give the printf format for the type as a
392 macro ULINTPF. We also give the printf format suffix (without '%') macro
393 ULINTPFS, this one can be useful if we want to put something between % and
394 lu/llu, like in %03lu. */
395 
396 #ifdef _WIN32
397 /* Use the integer types and formatting strings defined in Visual Studio. */
398 #define UINT32PF "%lu"
399 #define UINT32PFS "lu"
400 #define UINT64PF "%llu"
401 #define UINT64PFx "%016llx"
402 typedef unsigned __int64 ib_uint64_t;
403 typedef unsigned __int32 ib_uint32_t;
404 #else
405 /* Use the integer types and formatting strings defined in the C99 standard. */
406 #define UINT32PF "%" PRIu32
407 #define UINT32PFS PRIu32
408 #define UINT64PF "%" PRIu64
409 #define UINT64PFx "%016" PRIx64
410 typedef uint64_t ib_uint64_t;
411 typedef uint32_t ib_uint32_t;
412 #endif /* _WIN32 */
413 
414 #define IB_ID_FMT UINT64PF
415 
416 #ifdef _WIN64
417 typedef unsigned __int64 ulint;
418 typedef __int64 lint;
419 #define ULINTPFS "llu"
420 #else
421 typedef unsigned long int ulint;
422 typedef long int lint;
423 #define ULINTPFS "lu"
424 #endif /* _WIN64 */
425 
426 #define ULINTPF "%" ULINTPFS
427 
428 #ifndef _WIN32
429 #if SIZEOF_LONG != SIZEOF_VOIDP
430 #error "Error: InnoDB's ulint must be of the same size as void*"
431 #endif
432 #endif
433 
434 /** The 'undefined' value for a ulint */
435 constexpr ulint ULINT_UNDEFINED = -1;
436 
437 constexpr ulong ULONG_UNDEFINED = -1;
438 
439 /** The 'undefined' value for a  64-bit unsigned integer */
440 constexpr uint64_t UINT64_UNDEFINED = -1;
441 
442 /** The 'undefined' value for a  32-bit unsigned integer */
443 constexpr uint32_t UINT32_UNDEFINED = -1;
444 
445 /** The bitmask of 32-bit unsigned integer */
446 #define ULINT32_MASK 0xFFFFFFFF
447 
448 /** Maximum value for a ulint */
449 #define ULINT_MAX ((ulint)(-2))
450 
451 /** Maximum value for ib_uint64_t */
452 #define IB_UINT64_MAX ((ib_uint64_t)(~0ULL))
453 
454 /** The generic InnoDB system object identifier data type */
455 typedef ib_uint64_t ib_id_t;
456 #define IB_ID_MAX IB_UINT64_MAX
457 
458 /** Page number */
459 typedef uint32_t page_no_t;
460 /** Tablespace identifier */
461 typedef uint32_t space_id_t;
462 
463 #define SPACE_ID_PF UINT32PF
464 #define SPACE_ID_PFS UINT32PFS
465 #define PAGE_NO_PF UINT32PF
466 #define PAGE_ID_PF "page " SPACE_ID_PF ":" PAGE_NO_PF
467 
468 /** This 'ibool' type is used within Innobase. Remember that different included
469 headers may define 'bool' differently. Do not assume that 'bool' is a ulint! */
470 #define ibool ulint
471 
472 #ifndef TRUE
473 
474 #define TRUE 1
475 #define FALSE 0
476 
477 #endif
478 
479 #define UNIV_NOTHROW
480 
481 /** The following number as the length of a logical field means that the field
482 has the SQL NULL as its value. NOTE that because we assume that the length
483 of a field is a 32-bit integer when we store it, for example, to an undo log
484 on disk, we must have also this number fit in 32 bits, also in 64-bit
485 computers! */
486 #define UNIV_SQL_NULL UINT32_UNDEFINED
487 
488 /** Flag to indicate a field which was added instantly */
489 #define UNIV_SQL_ADD_COL_DEFAULT (UINT32_UNDEFINED - 1)
490 
491 /** The following number as the length of a logical field means that no
492 attribute value for the multi-value index exists in the JSON doc */
493 #define UNIV_NO_INDEX_VALUE (UINT32_UNDEFINED - 2)
494 
495 /** The follwoing number as the length marker of a logical field, which
496 is only used for multi-value field data, means the data itself of the
497 field is actually an array. Define it as 0 to prevent any conflict with
498 normal data length */
499 #define UNIV_MULTI_VALUE_ARRAY_MARKER 0
500 
501 /** Lengths which are not UNIV_SQL_NULL, but bigger than the following
502 number indicate that a field contains a reference to an externally
503 stored part of the field in the tablespace. The length field then
504 contains the sum of the following flag and the locally stored len. */
505 
506 #define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE_DEF)
507 
508 #if defined(__GNUC__)
509 /* Tell the compiler that variable/function is unused. */
510 #define UNIV_UNUSED MY_ATTRIBUTE((unused))
511 #else
512 #define UNIV_UNUSED
513 #endif /* CHECK FOR GCC VER_GT_2 */
514 
515 /* Some macros to improve branch prediction and reduce cache misses */
516 #if defined(COMPILER_HINTS) && defined(__GNUC__)
517 /* Tell the compiler that 'expr' probably evaluates to 'constant'. */
518 #define UNIV_EXPECT(expr, constant) __builtin_expect(expr, constant)
519 /* Tell the compiler that a pointer is likely to be NULL */
520 #define UNIV_LIKELY_NULL(ptr) __builtin_expect((ulint)ptr, 0)
521 /* Minimize cache-miss latency by moving data at addr into a cache before
522 it is read. */
523 #define UNIV_PREFETCH_R(addr) __builtin_prefetch(addr, 0, 3)
524 /* Minimize cache-miss latency by moving data at addr into a cache before
525 it is read or written. */
526 #define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
527 
528 /* Sun Studio includes sun_prefetch.h as of version 5.9 */
529 #elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC))
530 
531 #include <sun_prefetch.h>
532 
533 #define UNIV_EXPECT(expr, value) (expr)
534 #define UNIV_LIKELY_NULL(expr) (expr)
535 
536 #if defined(COMPILER_HINTS)
537 //# define UNIV_PREFETCH_R(addr) sun_prefetch_read_many((void*) addr)
538 #define UNIV_PREFETCH_R(addr) ((void)0)
539 #define UNIV_PREFETCH_RW(addr) sun_prefetch_write_many(addr)
540 #else
541 #define UNIV_PREFETCH_R(addr) ((void)0)
542 #define UNIV_PREFETCH_RW(addr) ((void)0)
543 #endif /* COMPILER_HINTS */
544 
545 #elif defined __WIN__ && defined COMPILER_HINTS
546 #include <xmmintrin.h>
547 
548 #define UNIV_EXPECT(expr, value) (expr)
549 #define UNIV_LIKELY_NULL(expr) (expr)
550 // __MM_HINT_T0 - (temporal data)
551 // prefetch data into all levels of the cache hierarchy.
552 #define UNIV_PREFETCH_R(addr) _mm_prefetch((char *)addr, _MM_HINT_T0)
553 #define UNIV_PREFETCH_RW(addr) _mm_prefetch((char *)addr, _MM_HINT_T0)
554 #else
555 /* Dummy versions of the macros */
556 #define UNIV_EXPECT(expr, value) (expr)
557 #define UNIV_LIKELY_NULL(expr) (expr)
558 #define UNIV_PREFETCH_R(addr) ((void)0)
559 #define UNIV_PREFETCH_RW(addr) ((void)0)
560 #endif
561 
562 /* Tell the compiler that cond is likely to hold */
563 #define UNIV_LIKELY(cond) UNIV_EXPECT(cond, TRUE)
564 /* Tell the compiler that cond is unlikely to hold */
565 #define UNIV_UNLIKELY(cond) UNIV_EXPECT(cond, FALSE)
566 
567 /* Compile-time constant of the given array's size. */
568 #define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0]))
569 
570 /* The return type from a thread's start function differs between Unix and
571 Windows, so define a typedef for it and a macro to use at the end of such
572 functions. */
573 
574 #ifdef _WIN32
575 typedef ulint os_thread_ret_t;
576 #define OS_PATH_SEPARATOR_STR "\\"
577 #define OS_PATH_SEPARATOR '\\'
578 #define OS_PATH_SEPARATOR_ALT '/'
579 #else
580 typedef void *os_thread_ret_t;
581 #define OS_PATH_SEPARATOR_STR "/"
582 #define OS_PATH_SEPARATOR '/'
583 #define OS_PATH_SEPARATOR_ALT '\\'
584 #endif /* _WIN32 */
585 
586 #include <stdio.h>
587 
588 #include "db0err.h"
589 #include "sync0types.h"
590 #include "ut0dbg.h"
591 #include "ut0lst.h"
592 #include "ut0ut.h"
593 
594 #ifdef UNIV_DEBUG_VALGRIND
595 #include <valgrind/memcheck.h>
596 
597 #define UNIV_MEM_VALID(addr, size) VALGRIND_MAKE_MEM_DEFINED(addr, size)
598 #define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
599 #define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size)
600 #define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
601 #define UNIV_MEM_DESC(addr, size) VALGRIND_CREATE_BLOCK(addr, size, #addr)
602 #define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b)
603 #define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort)                      \
604   do {                                                                        \
605     const void *_p =                                                          \
606         (const void *)(ulint)VALGRIND_CHECK_MEM_IS_DEFINED(addr, size);       \
607     if (UNIV_LIKELY_NULL(_p)) {                                               \
608       fprintf(stderr, "%s:%d: %p[%u] undefined at %ld\n", __FILE__, __LINE__, \
609               (const void *)(addr), (unsigned)(size),                         \
610               (long)(((const char *)_p) - ((const char *)(addr))));           \
611       if (should_abort) {                                                     \
612         ut_error;                                                             \
613       }                                                                       \
614     }                                                                         \
615   } while (0)
616 #define UNIV_MEM_ASSERT_RW(addr, size) UNIV_MEM_ASSERT_RW_LOW(addr, size, false)
617 #define UNIV_MEM_ASSERT_RW_ABORT(addr, size) \
618   UNIV_MEM_ASSERT_RW_LOW(addr, size, true)
619 #define UNIV_MEM_ASSERT_W(addr, size)                                          \
620   do {                                                                         \
621     const void *_p =                                                           \
622         (const void *)(ulint)VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size);    \
623     if (UNIV_LIKELY_NULL(_p))                                                  \
624       fprintf(stderr, "%s:%d: %p[%u] unwritable at %ld\n", __FILE__, __LINE__, \
625               (const void *)(addr), (unsigned)(size),                          \
626               (long)(((const char *)_p) - ((const char *)(addr))));            \
627   } while (0)
628 #define UNIV_MEM_TRASH(addr, c, size) \
629   do {                                \
630     void *p = (addr);                 \
631     ut_d(memset(p, c, size));         \
632     UNIV_MEM_INVALID(addr, size);     \
633   } while (0)
634 #else
635 #define UNIV_MEM_VALID(addr, size) \
636   do {                             \
637   } while (0)
638 #define UNIV_MEM_INVALID(addr, size) \
639   do {                               \
640   } while (0)
641 #define UNIV_MEM_FREE(addr, size) \
642   do {                            \
643   } while (0)
644 #define UNIV_MEM_ALLOC(addr, size) \
645   do {                             \
646   } while (0)
647 #define UNIV_MEM_DESC(addr, size) \
648   do {                            \
649   } while (0)
650 #define UNIV_MEM_UNDESC(b) \
651   do {                     \
652   } while (0)
653 #define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) \
654   do {                                                   \
655   } while (0)
656 #define UNIV_MEM_ASSERT_RW(addr, size) \
657   do {                                 \
658   } while (0)
659 #define UNIV_MEM_ASSERT_RW_ABORT(addr, size) \
660   do {                                       \
661   } while (0)
662 #define UNIV_MEM_ASSERT_W(addr, size) \
663   do {                                \
664   } while (0)
665 #define UNIV_MEM_TRASH(addr, c, size) \
666   do {                                \
667   } while (0)
668 #endif
669 #define UNIV_MEM_ASSERT_AND_FREE(addr, size) \
670   do {                                       \
671     UNIV_MEM_ASSERT_W(addr, size);           \
672     UNIV_MEM_FREE(addr, size);               \
673   } while (0)
674 #define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) \
675   do {                                        \
676     UNIV_MEM_ASSERT_W(addr, size);            \
677     UNIV_MEM_ALLOC(addr, size);               \
678   } while (0)
679 
680 extern ulong srv_page_size_shift;
681 extern ulong srv_page_size;
682 
683 static const size_t UNIV_SECTOR_SIZE = 512;
684 
685 /* Dimension of spatial object we support so far. It has its root in
686 myisam/sp_defs.h. We only support 2 dimension data */
687 #define SPDIMS 2
688 
689 /** Hard-coded data dictionary entry */
690 #define INNODB_DD_TABLE(name, n_indexes) \
691   { name, n_indexes }
692 
693 /** Explicitly call the destructor, this is to get around Clang bug#12350.
694 @param[in,out]	p		Instance on which to call the destructor */
695 template <typename T>
call_destructor(T * p)696 void call_destructor(T *p) {
697   p->~T();
698 }
699 
700 template <typename T>
701 constexpr auto to_int(T v) -> typename std::underlying_type<T>::type {
702   return (static_cast<typename std::underlying_type<T>::type>(v));
703 }
704 
705 /** If we are doing something that takes longer than this many seconds then
706 print an informative message. Type should be return type of ut_time_monotonic().
707 */
708 static constexpr ib_time_monotonic_t PRINT_INTERVAL_SECS = 10;
709 
710 #if defined(UNIV_LIBRARY) && !defined(UNIV_NO_ERR_MSGS)
711 
712 /** Don't use the server logging infrastructure if building
713 as a standalone library. */
714 #define UNIV_NO_ERR_MSGS
715 
716 #endif /* UNIV_LIBRARY && !UNIV_NO_ERR_MSGS */
717 
718 #endif
719