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