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 /**********************************************************//**
299 Returns the difference of two times in seconds.
300 @return time2 - time1 expressed in seconds */
301 UNIV_INTERN
302 double
303 ut_difftime(
304 /*========*/
305 ib_time_t time2, /*!< in: time */
306 ib_time_t time1); /*!< in: time */
307
308 #endif /* !UNIV_INNOCHECKSUM */
309
310 /**********************************************************//**
311 Prints a timestamp to a file. */
312 UNIV_INTERN
313 void
314 ut_print_timestamp(
315 /*===============*/
316 FILE* file) /*!< in: file where to print */
317 UNIV_COLD MY_ATTRIBUTE((nonnull));
318
319 #ifndef UNIV_INNOCHECKSUM
320
321 /**********************************************************//**
322 Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
323 UNIV_INTERN
324 void
325 ut_sprintf_timestamp(
326 /*=================*/
327 char* buf); /*!< in: buffer where to sprintf */
328 #ifdef UNIV_HOTBACKUP
329 /**********************************************************//**
330 Sprintfs a timestamp to a buffer with no spaces and with ':' characters
331 replaced by '_'. */
332 UNIV_INTERN
333 void
334 ut_sprintf_timestamp_without_extra_chars(
335 /*=====================================*/
336 char* buf); /*!< in: buffer where to sprintf */
337 /**********************************************************//**
338 Returns current year, month, day. */
339 UNIV_INTERN
340 void
341 ut_get_year_month_day(
342 /*==================*/
343 ulint* year, /*!< out: current year */
344 ulint* month, /*!< out: month */
345 ulint* day); /*!< out: day */
346 #else /* UNIV_HOTBACKUP */
347 /*************************************************************//**
348 Runs an idle loop on CPU. The argument gives the desired delay
349 in microseconds on 100 MHz Pentium + Visual C++.
350 @return dummy value */
351 UNIV_INTERN
352 ulint
353 ut_delay(
354 /*=====*/
355 ulint delay); /*!< in: delay in microseconds on 100 MHz Pentium */
356 #endif /* UNIV_HOTBACKUP */
357 /*************************************************************//**
358 Prints the contents of a memory buffer in hex and ascii. */
359 UNIV_INTERN
360 void
361 ut_print_buf(
362 /*=========*/
363 FILE* file, /*!< in: file where to print */
364 const void* buf, /*!< in: memory buffer */
365 ulint len); /*!< in: length of the buffer */
366
367 /**********************************************************************//**
368 Outputs a NUL-terminated file name, quoted with apostrophes. */
369 UNIV_INTERN
370 void
371 ut_print_filename(
372 /*==============*/
373 FILE* f, /*!< in: output stream */
374 const char* name); /*!< in: name to print */
375
376 #ifndef UNIV_HOTBACKUP
377 /* Forward declaration of transaction handle */
378 struct trx_t;
379
380 /**********************************************************************//**
381 Outputs a fixed-length string, quoted as an SQL identifier.
382 If the string contains a slash '/', the string will be
383 output as two identifiers separated by a period (.),
384 as in SQL database_name.identifier. */
385 UNIV_INTERN
386 void
387 ut_print_name(
388 /*==========*/
389 FILE* f, /*!< in: output stream */
390 const trx_t* trx, /*!< in: transaction */
391 ibool table_id,/*!< in: TRUE=print a table name,
392 FALSE=print other identifier */
393 const char* name); /*!< in: name to print */
394
395 /**********************************************************************//**
396 Outputs a fixed-length string, quoted as an SQL identifier.
397 If the string contains a slash '/', the string will be
398 output as two identifiers separated by a period (.),
399 as in SQL database_name.identifier. */
400 UNIV_INTERN
401 void
402 ut_print_namel(
403 /*===========*/
404 FILE* f, /*!< in: output stream */
405 const trx_t* trx, /*!< in: transaction (NULL=no quotes) */
406 ibool table_id,/*!< in: TRUE=print a table name,
407 FALSE=print other identifier */
408 const char* name, /*!< in: name to print */
409 ulint namelen);/*!< in: length of name */
410
411 /**********************************************************************//**
412 Formats a table or index name, quoted as an SQL identifier. If the name
413 contains a slash '/', the result will contain two identifiers separated by
414 a period (.), as in SQL database_name.identifier.
415 @return pointer to 'formatted' */
416 UNIV_INTERN
417 char*
418 ut_format_name(
419 /*===========*/
420 const char* name, /*!< in: table or index name, must be
421 '\0'-terminated */
422 ibool is_table, /*!< in: if TRUE then 'name' is a table
423 name */
424 char* formatted, /*!< out: formatted result, will be
425 '\0'-terminated */
426 ulint formatted_size);/*!< out: no more than this number of
427 bytes will be written to 'formatted' */
428
429 /**********************************************************************//**
430 Catenate files. */
431 UNIV_INTERN
432 void
433 ut_copy_file(
434 /*=========*/
435 FILE* dest, /*!< in: output file */
436 FILE* src); /*!< in: input file to be appended to output */
437 #endif /* !UNIV_HOTBACKUP */
438
439 #ifdef __WIN__
440 /**********************************************************************//**
441 A substitute for vsnprintf(3), formatted output conversion into
442 a limited buffer. Note: this function DOES NOT return the number of
443 characters that would have been printed if the buffer was unlimited because
444 VC's _vsnprintf() returns -1 in this case and we would need to call
445 _vscprintf() in addition to estimate that but we would need another copy
446 of "ap" for that and VC does not provide va_copy(). */
447 UNIV_INTERN
448 void
449 ut_vsnprintf(
450 /*=========*/
451 char* str, /*!< out: string */
452 size_t size, /*!< in: str size */
453 const char* fmt, /*!< in: format */
454 va_list ap); /*!< in: format values */
455
456 /**********************************************************************//**
457 A substitute for snprintf(3), formatted output conversion into
458 a limited buffer.
459 @return number of characters that would have been printed if the size
460 were unlimited, not including the terminating '\0'. */
461 UNIV_INTERN
462 int
463 ut_snprintf(
464 /*========*/
465 char* str, /*!< out: string */
466 size_t size, /*!< in: str size */
467 const char* fmt, /*!< in: format */
468 ...); /*!< in: format values */
469 #else
470 /**********************************************************************//**
471 A wrapper for vsnprintf(3), formatted output conversion into
472 a limited buffer. Note: this function DOES NOT return the number of
473 characters that would have been printed if the buffer was unlimited because
474 VC's _vsnprintf() returns -1 in this case and we would need to call
475 _vscprintf() in addition to estimate that but we would need another copy
476 of "ap" for that and VC does not provide va_copy(). */
477 # define ut_vsnprintf(buf, size, fmt, ap) \
478 ((void) vsnprintf(buf, size, fmt, ap))
479 /**********************************************************************//**
480 A wrapper for snprintf(3), formatted output conversion into
481 a limited buffer. */
482 # define ut_snprintf snprintf
483 #endif /* __WIN__ */
484
485 /*************************************************************//**
486 Convert an error number to a human readable text message. The
487 returned string is static and should not be freed or modified.
488 @return string, describing the error */
489 UNIV_INTERN
490 const char*
491 ut_strerr(
492 /*======*/
493 dberr_t num); /*!< in: error number */
494
495 /****************************************************************
496 Sort function for ulint arrays. */
497 UNIV_INTERN
498 void
499 ut_ulint_sort(
500 /*==========*/
501 ulint* arr, /*!< in/out: array to sort */
502 ulint* aux_arr, /*!< in/out: aux array to use in sort */
503 ulint low, /*!< in: lower bound */
504 ulint high) /*!< in: upper bound */
505 MY_ATTRIBUTE((nonnull));
506
507 #ifndef UNIV_NONINL
508 #include "ut0ut.ic"
509 #endif
510
511 #endif /* !UNIV_INNOCHECKSUM */
512
513 #endif
514
515