1 /*****************************************************************************
2
3 Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation. The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License, version 2.0, for more details.
20
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24
25 *****************************************************************************/
26
27 /******************************************************************//**
28 @file include/ut0ut.h
29 Various utilities
30
31 Created 1/20/1994 Heikki Tuuri
32 ***********************************************************************/
33
34 #ifndef ut0ut_h
35 #define ut0ut_h
36
37 #include "univ.i"
38
39 #ifndef UNIV_INNOCHECKSUM
40
41 #include "db0err.h"
42
43 #ifndef UNIV_HOTBACKUP
44 # include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
45 #endif /* UNIV_HOTBACKUP */
46
47 #include <time.h>
48 #ifndef MYSQL_SERVER
49 #include <ctype.h>
50 #endif
51
52 #include <stdarg.h> /* for va_list */
53
54 /** Index name prefix in fast index creation */
55 #define TEMP_INDEX_PREFIX '\377'
56 /** Index name prefix in fast index creation, as a string constant */
57 #define TEMP_INDEX_PREFIX_STR "\377"
58
59 /** Time stamp */
60 typedef time_t ib_time_t;
61
62 /* In order to call a piece of code, when a function returns or when the
63 scope ends, use this utility class. It will invoke the given function
64 object in its destructor. */
65 template<typename F>
66 struct ut_when_dtor {
ut_when_dtorut_when_dtor67 ut_when_dtor(F& p) : f(p) {}
~ut_when_dtorut_when_dtor68 ~ut_when_dtor() {
69 f();
70 }
71 private:
72 F& f;
73 };
74
75 #ifndef UNIV_HOTBACKUP
76 # if defined(HAVE_PAUSE_INSTRUCTION)
77 /* According to the gcc info page, asm volatile means that the
78 instruction has important side-effects and must not be removed.
79 Also asm volatile may trigger a memory barrier (spilling all registers
80 to memory). */
81 # ifdef __SUNPRO_CC
82 # define UT_RELAX_CPU() asm ("pause" )
83 # else
84 # define UT_RELAX_CPU() __asm__ __volatile__ ("pause")
85 # endif /* __SUNPRO_CC */
86
87 # elif defined(HAVE_FAKE_PAUSE_INSTRUCTION)
88 # define UT_RELAX_CPU() __asm__ __volatile__ ("rep; nop")
89 # elif defined(HAVE_ATOMIC_BUILTINS)
90 # define UT_RELAX_CPU() do { \
91 volatile lint volatile_var; \
92 os_compare_and_swap_lint(&volatile_var, 0, 1); \
93 } while (0)
94 # elif defined(HAVE_WINDOWS_ATOMICS)
95 /* In the Win32 API, the x86 PAUSE instruction is executed by calling
96 the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
97 independent way by using YieldProcessor. */
98 # define UT_RELAX_CPU() YieldProcessor()
99 # else
100 # define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */
101 # endif
102
103 /*********************************************************************//**
104 Delays execution for at most max_wait_us microseconds or returns earlier
105 if cond becomes true.
106 @param cond in: condition to wait for; evaluated every 2 ms
107 @param max_wait_us in: maximum delay to wait, in microseconds */
108 #define UT_WAIT_FOR(cond, max_wait_us) \
109 do { \
110 ullint start_us; \
111 start_us = ut_time_us(NULL); \
112 while (!(cond) \
113 && ut_time_us(NULL) - start_us < (max_wait_us)) {\
114 \
115 os_thread_sleep(2000 /* 2 ms */); \
116 } \
117 } while (0)
118 #endif /* !UNIV_HOTBACKUP */
119
ut_min(T a,T b)120 template <class T> T ut_min(T a, T b) { return(a < b ? a : b); }
ut_max(T a,T b)121 template <class T> T ut_max(T a, T b) { return(a > b ? a : b); }
122
123 /******************************************************//**
124 Calculates the minimum of two ulints.
125 @return minimum */
126 UNIV_INLINE
127 ulint
128 ut_min(
129 /*===*/
130 ulint n1, /*!< in: first number */
131 ulint n2); /*!< in: second number */
132 /******************************************************//**
133 Calculates the maximum of two ulints.
134 @return maximum */
135 UNIV_INLINE
136 ulint
137 ut_max(
138 /*===*/
139 ulint n1, /*!< in: first number */
140 ulint n2); /*!< in: second number */
141 /****************************************************************//**
142 Calculates minimum of two ulint-pairs. */
143 UNIV_INLINE
144 void
145 ut_pair_min(
146 /*========*/
147 ulint* a, /*!< out: more significant part of minimum */
148 ulint* b, /*!< out: less significant part of minimum */
149 ulint a1, /*!< in: more significant part of first pair */
150 ulint b1, /*!< in: less significant part of first pair */
151 ulint a2, /*!< in: more significant part of second pair */
152 ulint b2); /*!< in: less significant part of second pair */
153 /******************************************************//**
154 Compares two ulints.
155 @return 1 if a > b, 0 if a == b, -1 if a < b */
156 UNIV_INLINE
157 int
158 ut_ulint_cmp(
159 /*=========*/
160 ulint a, /*!< in: ulint */
161 ulint b); /*!< in: ulint */
162 /*******************************************************//**
163 Compares two pairs of ulints.
164 @return -1 if a < b, 0 if a == b, 1 if a > b */
165 UNIV_INLINE
166 int
167 ut_pair_cmp(
168 /*========*/
169 ulint a1, /*!< in: more significant part of first pair */
170 ulint a2, /*!< in: less significant part of first pair */
171 ulint b1, /*!< in: more significant part of second pair */
172 ulint b2); /*!< in: less significant part of second pair */
173 /*************************************************************//**
174 Determines if a number is zero or a power of two.
175 @param n in: number
176 @return nonzero if n is zero or a power of two; zero otherwise */
177 #define ut_is_2pow(n) UNIV_LIKELY(!((n) & ((n) - 1)))
178 /*************************************************************//**
179 Calculates fast the remainder of n/m when m is a power of two.
180 @param n in: numerator
181 @param m in: denominator, must be a power of two
182 @return the remainder of n/m */
183 #define ut_2pow_remainder(n, m) ((n) & ((m) - 1))
184 /*************************************************************//**
185 Calculates the biggest multiple of m that is not bigger than n
186 when m is a power of two. In other words, rounds n down to m * k.
187 @param n in: number to round down
188 @param m in: alignment, must be a power of two
189 @return n rounded down to the biggest possible integer multiple of m */
190 #define ut_2pow_round(n, m) ((n) & ~((m) - 1))
191 /** Align a number down to a multiple of a power of two.
192 @param n in: number to round down
193 @param m in: alignment, must be a power of two
194 @return n rounded down to the biggest possible integer multiple of m */
195 #define ut_calc_align_down(n, m) ut_2pow_round(n, m)
196 /********************************************************//**
197 Calculates the smallest multiple of m that is not smaller than n
198 when m is a power of two. In other words, rounds n up to m * k.
199 @param n in: number to round up
200 @param m in: alignment, must be a power of two
201 @return n rounded up to the smallest possible integer multiple of m */
202 #define ut_calc_align(n, m) (((n) + ((m) - 1)) & ~((m) - 1))
203 /*************************************************************//**
204 Calculates fast the 2-logarithm of a number, rounded upward to an
205 integer.
206 @return logarithm in the base 2, rounded upward */
207 UNIV_INLINE
208 ulint
209 ut_2_log(
210 /*=====*/
211 ulint n); /*!< in: number */
212 /*************************************************************//**
213 Calculates 2 to power n.
214 @return 2 to power n */
215 UNIV_INLINE
216 ulint
217 ut_2_exp(
218 /*=====*/
219 ulint n); /*!< in: number */
220 /*************************************************************//**
221 Calculates fast the number rounded up to the nearest power of 2.
222 @return first power of 2 which is >= n */
223 UNIV_INTERN
224 ulint
225 ut_2_power_up(
226 /*==========*/
227 ulint n) /*!< in: number != 0 */
228 MY_ATTRIBUTE((const));
229
230 /** Determine how many bytes (groups of 8 bits) are needed to
231 store the given number of bits.
232 @param b in: bits
233 @return number of bytes (octets) needed to represent b */
234 #define UT_BITS_IN_BYTES(b) (((b) + 7) / 8)
235
236 /**********************************************************//**
237 Returns system time. We do not specify the format of the time returned:
238 the only way to manipulate it is to use the function ut_difftime.
239 @return system time */
240 UNIV_INTERN
241 ib_time_t
242 ut_time(void);
243 /*=========*/
244 #ifndef UNIV_HOTBACKUP
245 /**********************************************************//**
246 Returns system time.
247 Upon successful completion, the value 0 is returned; otherwise the
248 value -1 is returned and the global variable errno is set to indicate the
249 error.
250 @return 0 on success, -1 otherwise */
251 UNIV_INTERN
252 int
253 ut_usectime(
254 /*========*/
255 ulint* sec, /*!< out: seconds since the Epoch */
256 ulint* ms); /*!< out: microseconds since the Epoch+*sec */
257
258 /**********************************************************//**
259 Returns the number of microseconds since epoch. Similar to
260 time(3), the return value is also stored in *tloc, provided
261 that tloc is non-NULL.
262 @return us since epoch */
263 UNIV_INTERN
264 ullint
265 ut_time_us(
266 /*=======*/
267 ullint* tloc); /*!< out: us since epoch, if non-NULL */
268 /**********************************************************//**
269 Returns the number of milliseconds since some epoch. The
270 value may wrap around. It should only be used for heuristic
271 purposes.
272 @return ms since epoch */
273 UNIV_INTERN
274 ulint
275 ut_time_ms(void);
276 /*============*/
277 #ifdef _WIN32
278 /**********************************************************//**
279 Initialise highest available time resolution API on Windows
280 @return 0 if all OK else -1 */
281 int
282 ut_win_init_time();
283
284 #endif /* _WIN32 */
285
286 #endif /* !UNIV_HOTBACKUP */
287
288 /**********************************************************//**
289 Returns the number of milliseconds since some epoch. The
290 value may wrap around. It should only be used for heuristic
291 purposes.
292 @return ms since epoch */
293 UNIV_INTERN
294 ulint
295 ut_time_ms(void);
296 /*============*/
297
298 /** Returns the number of milliseconds since some epoch using monotonic clock.
299 The value may wrap around. This should not be used as an accurate Time Of Day.
300 It is only intended to be used as a means of calculating transient elapsed or
301 projected time that will not be influenced by changes to the systems real time
302 clock. Returns a small structure that contains the result so as to poison the
303 code and reveal any changes that might later be introduced by upstream.
304 */
305 struct ut_monotonic_time {
306 ulint ms;
307 };
308
309 ut_monotonic_time
310 ut_monotonic_time_ms(void);
311
312 /**********************************************************//**
313 Returns the difference of two times in seconds.
314 @return time2 - time1 expressed in seconds */
315 UNIV_INTERN
316 double
317 ut_difftime(
318 /*========*/
319 ib_time_t time2, /*!< in: time */
320 ib_time_t time1); /*!< in: time */
321
322 #endif /* !UNIV_INNOCHECKSUM */
323
324 /**********************************************************//**
325 Prints a timestamp to a file. */
326 UNIV_INTERN
327 void
328 ut_print_timestamp(
329 /*===============*/
330 FILE* file) /*!< in: file where to print */
331 UNIV_COLD MY_ATTRIBUTE((nonnull));
332
333 #ifndef UNIV_INNOCHECKSUM
334
335 /**********************************************************//**
336 Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
337 UNIV_INTERN
338 void
339 ut_sprintf_timestamp(
340 /*=================*/
341 char* buf); /*!< in: buffer where to sprintf */
342 #ifdef UNIV_HOTBACKUP
343 /**********************************************************//**
344 Sprintfs a timestamp to a buffer with no spaces and with ':' characters
345 replaced by '_'. */
346 UNIV_INTERN
347 void
348 ut_sprintf_timestamp_without_extra_chars(
349 /*=====================================*/
350 char* buf); /*!< in: buffer where to sprintf */
351 /**********************************************************//**
352 Returns current year, month, day. */
353 UNIV_INTERN
354 void
355 ut_get_year_month_day(
356 /*==================*/
357 ulint* year, /*!< out: current year */
358 ulint* month, /*!< out: month */
359 ulint* day); /*!< out: day */
360 #else /* UNIV_HOTBACKUP */
361 /*************************************************************//**
362 Runs an idle loop on CPU. The argument gives the desired delay
363 in microseconds on 100 MHz Pentium + Visual C++.
364 @return dummy value */
365 UNIV_INTERN
366 ulint
367 ut_delay(
368 /*=====*/
369 ulint delay); /*!< in: delay in microseconds on 100 MHz Pentium */
370 #endif /* UNIV_HOTBACKUP */
371 /*************************************************************//**
372 Prints the contents of a memory buffer in hex and ascii. */
373 UNIV_INTERN
374 void
375 ut_print_buf(
376 /*=========*/
377 FILE* file, /*!< in: file where to print */
378 const void* buf, /*!< in: memory buffer */
379 ulint len); /*!< in: length of the buffer */
380
381 /**********************************************************************//**
382 Outputs a NUL-terminated file name, quoted with apostrophes. */
383 UNIV_INTERN
384 void
385 ut_print_filename(
386 /*==============*/
387 FILE* f, /*!< in: output stream */
388 const char* name); /*!< in: name to print */
389
390 #ifndef UNIV_HOTBACKUP
391 /* Forward declaration of transaction handle */
392 struct trx_t;
393
394 /**********************************************************************//**
395 Outputs a fixed-length string, quoted as an SQL identifier.
396 If the string contains a slash '/', the string will be
397 output as two identifiers separated by a period (.),
398 as in SQL database_name.identifier. */
399 UNIV_INTERN
400 void
401 ut_print_name(
402 /*==========*/
403 FILE* f, /*!< in: output stream */
404 const trx_t* trx, /*!< in: transaction */
405 ibool table_id,/*!< in: TRUE=print a table name,
406 FALSE=print other identifier */
407 const char* name); /*!< in: name to print */
408
409 /**********************************************************************//**
410 Outputs a fixed-length string, quoted as an SQL identifier.
411 If the string contains a slash '/', the string will be
412 output as two identifiers separated by a period (.),
413 as in SQL database_name.identifier. */
414 UNIV_INTERN
415 void
416 ut_print_namel(
417 /*===========*/
418 FILE* f, /*!< in: output stream */
419 const trx_t* trx, /*!< in: transaction (NULL=no quotes) */
420 ibool table_id,/*!< in: TRUE=print a table name,
421 FALSE=print other identifier */
422 const char* name, /*!< in: name to print */
423 ulint namelen);/*!< in: length of name */
424
425 /**********************************************************************//**
426 Formats a table or index name, quoted as an SQL identifier. If the name
427 contains a slash '/', the result will contain two identifiers separated by
428 a period (.), as in SQL database_name.identifier.
429 @return pointer to 'formatted' */
430 UNIV_INTERN
431 char*
432 ut_format_name(
433 /*===========*/
434 const char* name, /*!< in: table or index name, must be
435 '\0'-terminated */
436 ibool is_table, /*!< in: if TRUE then 'name' is a table
437 name */
438 char* formatted, /*!< out: formatted result, will be
439 '\0'-terminated */
440 ulint formatted_size);/*!< out: no more than this number of
441 bytes will be written to 'formatted' */
442
443 /**********************************************************************//**
444 Catenate files. */
445 UNIV_INTERN
446 void
447 ut_copy_file(
448 /*=========*/
449 FILE* dest, /*!< in: output file */
450 FILE* src); /*!< in: input file to be appended to output */
451 #endif /* !UNIV_HOTBACKUP */
452
453 #ifdef __WIN__
454 /**********************************************************************//**
455 A substitute for vsnprintf(3), formatted output conversion into
456 a limited buffer. Note: this function DOES NOT return the number of
457 characters that would have been printed if the buffer was unlimited because
458 VC's _vsnprintf() returns -1 in this case and we would need to call
459 _vscprintf() in addition to estimate that but we would need another copy
460 of "ap" for that and VC does not provide va_copy(). */
461 UNIV_INTERN
462 void
463 ut_vsnprintf(
464 /*=========*/
465 char* str, /*!< out: string */
466 size_t size, /*!< in: str size */
467 const char* fmt, /*!< in: format */
468 va_list ap); /*!< in: format values */
469
470 /**********************************************************************//**
471 A substitute for snprintf(3), formatted output conversion into
472 a limited buffer.
473 @return number of characters that would have been printed if the size
474 were unlimited, not including the terminating '\0'. */
475 UNIV_INTERN
476 int
477 ut_snprintf(
478 /*========*/
479 char* str, /*!< out: string */
480 size_t size, /*!< in: str size */
481 const char* fmt, /*!< in: format */
482 ...); /*!< in: format values */
483 #else
484 /**********************************************************************//**
485 A wrapper for vsnprintf(3), formatted output conversion into
486 a limited buffer. Note: this function DOES NOT return the number of
487 characters that would have been printed if the buffer was unlimited because
488 VC's _vsnprintf() returns -1 in this case and we would need to call
489 _vscprintf() in addition to estimate that but we would need another copy
490 of "ap" for that and VC does not provide va_copy(). */
491 # define ut_vsnprintf(buf, size, fmt, ap) \
492 ((void) vsnprintf(buf, size, fmt, ap))
493 /**********************************************************************//**
494 A wrapper for snprintf(3), formatted output conversion into
495 a limited buffer. */
496 # define ut_snprintf snprintf
497 #endif /* __WIN__ */
498
499 /*************************************************************//**
500 Convert an error number to a human readable text message. The
501 returned string is static and should not be freed or modified.
502 @return string, describing the error */
503 UNIV_INTERN
504 const char*
505 ut_strerr(
506 /*======*/
507 dberr_t num); /*!< in: error number */
508
509 /****************************************************************
510 Sort function for ulint arrays. */
511 UNIV_INTERN
512 void
513 ut_ulint_sort(
514 /*==========*/
515 ulint* arr, /*!< in/out: array to sort */
516 ulint* aux_arr, /*!< in/out: aux array to use in sort */
517 ulint low, /*!< in: lower bound */
518 ulint high) /*!< in: upper bound */
519 MY_ATTRIBUTE((nonnull));
520
521 #ifndef UNIV_NONINL
522 #include "ut0ut.ic"
523 #endif
524
525 #endif /* !UNIV_INNOCHECKSUM */
526
527 #endif
528
529