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