CUBRID Engine  latest
porting.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * porting.h - Functions supporting platform porting
22  */
23 
24 #ifndef _PORTING_H_
25 #define _PORTING_H_
26 
27 #ident "$Id$"
28 
29 #include "config.h"
30 
31 #if defined (AIX)
32 #include <sys/socket.h>
33 #endif
34 
35 #if !defined (__GNUC__)
36 #define __attribute__(X)
37 #endif
38 
39 #if defined (__GNUC__) && defined (__GNUC_MINOR__) && defined (__GNUC_PATCHLEVEL__)
40 #define CUB_GCC_VERSION (__GNUC__ * 10000 \
41  + __GNUC_MINOR__ * 100 \
42  + __GNUC_PATCHLEVEL__)
43 #endif
44 
45 #if defined (WINDOWS)
46 #define IMPORT_VAR __declspec(dllimport)
47 #define EXPORT_VAR __declspec(dllexport)
48 #include <WinBase.h>
49 #else
50 #define IMPORT_VAR extern
51 #define EXPORT_VAR
52 #endif
53 
54 #if defined (WINDOWS)
55 #define L_cuserid 9
56 #else /* WINDOWS */
57 #ifndef L_cuserid
58 #define L_cuserid 9
59 #endif /* !L_cuserid */
60 #endif /* WINDOWS */
61 
62 #define ONE_K 1024
63 #define ONE_M 1048576
64 #define ONE_G 1073741824
65 #define ONE_T 1099511627776LL
66 #define ONE_P 1125899906842624LL
67 
68 #define ONE_SEC 1000
69 #define ONE_MIN 60000
70 #define ONE_HOUR 3600000
71 
72 #define CTIME_MAX 64
73 
74 #ifndef LLONG_MAX
75 #define LLONG_MAX 9223372036854775807LL
76 #endif
77 #ifndef LLONG_MIN
78 #define LLONG_MIN (-LLONG_MAX - 1LL)
79 #endif
80 #ifndef ULLONG_MAX
81 #define ULLONG_MAX 18446744073709551615ULL
82 #endif
83 
84 
85 #define MEM_SIZE_IS_VALID(size) \
86  (((long long unsigned) (size) <= ULONG_MAX) \
87  || (sizeof (long long unsigned) <= sizeof (size_t)))
88 
89 #if defined (__cplusplus)
90 #include <type_traits>
91 #include <utility>
92 #endif // C++
93 
94 #if defined (WINDOWS)
95 #include <fcntl.h>
96 #include <direct.h>
97 #include <process.h>
98 #include <sys/timeb.h>
99 #include <time.h>
100 #include <sys/locking.h>
101 #include <windows.h>
102 #include <winbase.h>
103 #include <sys/types.h>
104 #include <sys/stat.h>
105 #include <errno.h>
106 #include <assert.h>
107 
108 #if !defined (ENOMSG)
109 /* not defined errno on Windows */
110 #define ENOMSG 100
111 #endif
112 
113 #if !defined PATH_MAX
114 #define PATH_MAX 256
115 #endif
116 #if !defined NAME_MAX
117 #define NAME_MAX 256
118 #endif
119 
120 #if !defined (_MSC_VER) || _MSC_VER < 1700 || (defined __cplusplus && _MSC_VER == 1700)
121 #define log2(x) (log ((double) x) / log ((double) 2))
122 #endif /* !_MSC_VER or c before _MSC_VER 1700 or c++ at 1700 */
123 extern char *realpath (const char *path, char *resolved_path);
124 #define sleep(sec) Sleep(1000*(sec))
125 #define usleep(usec) Sleep((usec)/1000)
126 
127 #define mkdir(dir, mode) _mkdir(dir)
128 #define getpid() _getpid()
129 #define snprintf _sprintf_p
130 #define strcasecmp(str1, str2) _stricmp(str1, str2)
131 #define strncasecmp(str1, str2, size) _strnicmp(str1, str2, size)
132 #define lseek(fd, offset, origin) _lseeki64(fd, offset, origin)
133 #define fseek(fd, offset, origin) _fseeki64(fd, offset, origin)
134 #define ftruncate(fd, size) _chsize_s(fd, size)
135 #define strdup(src) _strdup(src)
136 #define getcwd(buffer, length) _getcwd(buffer, length)
137 #define popen _popen
138 #define pclose _pclose
139 #define strtok_r strtok_s
140 #define strtoll _strtoi64
141 #define strtoull _strtoui64
142 // todo - remove define stat; name is too common
143 #define stat _stati64
144 #define fstat _fstati64
145 #define ftell _ftelli64
146 #define ftime _ftime_s
147 #define timeb _timeb
148 #define fileno _fileno
149 #define vsnprintf cub_vsnprintf
150 #define tempnam _tempnam
151 #define printf _printf_p
152 #define fprintf _fprintf_p
153 #define vfprintf _vfprintf_p
154 #define vprintf _vprintf_p
155 #define strtof strtof_win
156 #if defined (_WIN32)
157 #define mktime mktime_for_win32
158 #endif
159 #if (_WIN32_WINNT < 0x0600)
160 #define POLLRDNORM 0x0100
161 #define POLLRDBAND 0x0200
162 #define POLLIN (POLLRDNORM | POLLRDBAND)
163 #define POLLPRI 0x0400
164 
165 #define POLLWRNORM 0x0010
166 #define POLLOUT (POLLWRNORM)
167 #define POLLWRBAND 0x0020
168 
169 #define POLLERR 0x0001
170 #define POLLHUP 0x0002
171 #define POLLNVAL 0x0004
172 
173 struct pollfd
174 {
175  SOCKET fd;
176  SHORT events;
177  SHORT revents;
178 };
179 #endif /* (_WIN32_WINNT < 0x0600) */
180 
181 typedef unsigned long int nfds_t;
182 extern int poll (struct pollfd *fds, nfds_t nfds, int timeout);
183 
184 #if 0
185 #define O_RDONLY _O_RDONLY
186 #endif
187 #define O_SYNC 0
188 
189 
190 
191 #undef O_CREAT
192 #undef O_RDWR
193 #undef O_RDONLY
194 #undef O_TRUNC
195 #undef O_EXCL
196 
197 #define O_CREAT _O_CREAT|_O_BINARY
198 #define O_RDWR _O_RDWR|_O_BINARY
199 #define O_RDONLY _O_RDONLY|_O_BINARY
200 #define O_TRUNC _O_TRUNC|_O_BINARY
201 #define O_EXCL _O_EXCL|_O_BINARY
202 
203 /* Fake up approxomate DOS definitions see sys/stat.h */
204 /* for umask() stub */
205 #define S_IRGRP 0
206 #define S_IWGRP 0
207 #define S_IROTH 0
208 #define S_IWOTH 0
209 
210 /* read, write, execute for owner */
211 #define S_IRWXU _S_IREAD | _S_IWRITE | _S_IEXEC
212 /* rwx for group, same as owner since there are no groups in DOS */
213 #define S_IRWXG S_IRWXU
214 /* rwx for other, same as owner since there are no groups in DOS */
215 #define S_IRWXO S_IRWXU
216 
217 /* access() mode flags */
218 #define F_OK 0 /* Test for existence. */
219 #define W_OK 2 /* Test for write permission. */
220 #define R_OK 4 /* Test for read permission. */
221 
222 /* definitions for the WINDOWS implementation of lockf() */
223 #define F_ULOCK _LK_UNLCK
224 #define F_LOCK _LK_LOCK
225 #define F_TLOCK _LK_NBLCK
226 #define F_TEST -1
227 
228 /* definitions for the WINDOWS implmentation of pathconf() */
229 #define _PC_NAME_MAX 4
230 #define _PC_PATH_MAX 5
231 #define _PC_NO_TRUNC 8
232 
233 typedef char *caddr_t;
234 
235 typedef SSIZE_T ssize_t;
236 
237 #if 0
238 struct stat
239 {
240  _dev_t st_dev;
241  _ino_t st_ino;
242  unsigned short st_mode;
243  short st_nlink;
244  short st_uid;
245  short st_gid;
246  _dev_t st_rdev;
247  _off_t st_size;
248  time_t st_atime;
249  time_t st_mtime;
250  time_t st_ctime;
251 };
252 extern int stat (const char *path, struct stat *buf);
253 #endif
254 
255 extern int gettimeofday (struct timeval *tp, void *tzp);
256 
257 extern int lockf (int fd, int cmd, long size);
258 
259 extern char *cuserid (char *string);
260 
261 extern int getlogin_r (char *buf, size_t bufsize);
262 
263 extern struct tm *localtime_r (const time_t * time, struct tm *tm_val);
264 
265 extern char *ctime_r (const time_t * time, char *time_buf);
266 
267 #if 0
268 extern int umask (int mask);
269 #endif
270 int fsync (int filedes);
271 
272 long pathconf (char *path, int name);
273 
274 /*
275  * Used by the sigfillset() etc. function in pcio.c
276  */
277 typedef struct sigsettype
278 {
279  unsigned int mask;
280  void (*abrt_state) (int);
281  void (*fpe_state) (int);
282  void (*ill_state) (int);
283  void (*int_state) (int);
284  void (*term_state) (int);
285  void (*sev_state) (int);
286 } sigset_t;
287 
288 int sigfillset (sigset_t * set);
289 
290 int sigprocmask (int how, sigset_t * set, sigset_t * oldset);
291 
292 /*
293  * MS Windows specific operations
294  */
295 extern void pc_init (void);
296 extern void pc_final (void);
297 #if defined (ENABLE_UNUSED_FUNCTION)
298 extern int lock_region (int fd, int cmd, long offset, long size);
299 #endif
300 extern int free_space (const char *, int);
301 
302 #define _longjmp longjmp
303 /*
304 #define _setjmp setjmp
305 */
306 #else /* WINDOWS */
307 
308 #if !defined (HAVE_CTIME_R)
309 #error "HAVE_CTIME_R"
310 #endif
311 
312 #if !defined (HAVE_LOCALTIME_R)
313 #error "HAVE_LOCALTIME_R"
314 #endif
315 
316 #if !defined (HAVE_DRAND48_R)
317 #error "HAVE_DRAND48_R"
318 #endif
319 
320 
321 #endif /* WINDOWS */
322 
323 #define snprintf_dots_truncate(dest, max_len, ...) \
324  if (snprintf (dest, max_len, __VA_ARGS__) < 0) \
325  snprintf (dest + max_len - 4, 4, "...")
326 #define strncpy_size(buf, str, size) \
327  strncpy (buf, str, size); buf[(size) - 1] = '\0'
328 #if defined (__cplusplus)
329 // *INDENT-OFF*
330 template<typename T>
331 inline void
332 check_is_array (const T & a)
333 {
334  static_assert (std::is_array<T>::value == 1, "expected array");
335 }
336 #define strncpy_bufsize(buf, str) \
337  strncpy_size (buf, str, sizeof (buf)); check_is_array (buf)
338 // *INDENT-ON*
339 #else // not C++
340 #define strncpy_bufsize(buf, str) \
341  strncpy_size (buf, str, sizeof (buf))
342 #endif // not C++
343 
344 #if defined (WINDOWS)
345 #define PATH_SEPARATOR '\\'
346 #else /* WINDOWS */
347 #define PATH_SEPARATOR '/'
348 #endif /* WINDOWS */
349 #define PATH_CURRENT '.'
350 
351 #define IS_PATH_SEPARATOR(c) ((c) == PATH_SEPARATOR)
352 
353 #if defined (WINDOWS)
354 #define IS_ABS_PATH(p) IS_PATH_SEPARATOR((p)[0]) \
355  || (isalpha((p)[0]) && (p)[1] == ':' && IS_PATH_SEPARATOR((p)[2]))
356 #else /* WINDOWS */
357 #define IS_ABS_PATH(p) IS_PATH_SEPARATOR((p)[0])
358 #endif /* WINDOWS */
359 
360 /*
361  * Some platforms (e.g., Solaris) evidently don't define _longjmp. If
362  * it's not available, just use regular old longjmp.
363  */
364 #if defined (SOLARIS) || defined (WINDOWS)
365 #define LONGJMP longjmp
366 #define SETJMP setjmp
367 #else
368 #define LONGJMP _longjmp
369 #define SETJMP _setjmp
370 #endif
371 
379 #define CUB_MAXHOSTNAMELEN 256 /* 255 + 1(for NULL terminator) */
380 
381 #define GETHOSTNAME(p, l) css_gethostname(p, l)
382 
383 #if defined (WINDOWS)
384 #define FINITE(x) _finite(x)
385 #elif defined (HPUX)
386 #define FINITE(x) isfinite(x)
387 #else /* ! WINDOWS && ! HPUX */
388 #define FINITE(x) finite(x)
389 #endif
390 
391 #if defined (WINDOWS)
392 #define difftime64(time1, time2) _difftime64(time1, time2)
393 #else /* !WINDOWS */
394 #define difftime64(time1, time2) difftime(time1, time2)
395 #endif /* !WINDOWS */
396 
397 #if defined (WINDOWS)
398 #ifndef wcswcs
399 #define wcswcs(ws1, ws2) wcsstr((ws1), (ws2))
400 #endif
401 #define wcsspn(ws1, ws2) ((int) wcsspn((ws1), (ws2)))
402 #endif /* WINDOWS */
403 
404 #if defined (SOLARIS)
405 #define wcslen(ws) wslen((ws))
406 #define wcschr(ws, wc) wschr((ws), (wc))
407 #define wcsrchr(ws, wc) wsrchr((ws), (wc))
408 #define wcstok(ws1, ws2) wstok((ws1), (ws2))
409 #define wcscoll(ws1, ws2) wscoll((ws1), (ws2))
410 #define wcsspn(ws1, ws2) wsspn((ws1), (ws2))
411 #define wcscspn(ws1, ws2) wscspn((ws1), (ws2))
412 #define wcscmp(ws1, ws2) wscmp((ws1), (ws2))
413 #define wcsncmp(ws1, ws2, n) wsncmp((ws1), (ws2), (n))
414 #define wcscpy(ws1, ws2) wscpy((ws1), (ws2))
415 #define wcsncpy(ws1, ws2, n) wsncpy((ws1), (ws2), (n))
416 #endif /* SOLARIS */
417 
418 #if !defined (HAVE_STRDUP)
419 extern char *strdup (const char *str);
420 #endif /* HAVE_STRDUP */
421 
422 #if !defined (HAVE_VASPRINTF)
423 extern int vasprintf (char **ptr, const char *format, va_list ap);
424 #endif /* HAVE_VASPRINTF */
425 #if !defined (HAVE_ASPRINTF)
426 extern int asprintf (char **ptr, const char *format, ...);
427 #endif /* HAVE_ASPRINTF */
428 #if defined (HAVE_ERR_H)
429 #include <err.h>
430 #else
431 #define err(fd, ...) do { fprintf(stderr, __VA_ARGS__); exit(1); } while (0)
432 #define errx(fd, ...) do { fprintf(stderr, __VA_ARGS__); exit(1); } while (0)
433 #endif
434 extern int cub_dirname_r (const char *path, char *pathbuf, size_t buflen);
435 #if defined (AIX)
436 double aix_ceil (double x);
437 #define ceil(x) aix_ceil(x)
438 #endif
439 
440 #if !defined (HAVE_DIRNAME)
441 char *dirname (const char *path);
442 #endif /* HAVE_DIRNAME */
443 extern int basename_r (const char *path, char *pathbuf, size_t buflen);
444 #if !defined (HAVE_BASENAME)
445 extern char *basename (const char *path);
446 #endif /* HAVE_BASENAME */
447 #if defined (WINDOWS)
448 #if !defined (HAVE_STRSEP)
449 extern char *strsep (char **stringp, const char *delim);
450 #endif
451 extern char *getpass (const char *prompt);
452 #endif
453 
454 #if defined (ENABLE_UNUSED_FUNCTION)
455 extern int utona (unsigned int u, char *s, size_t n);
456 extern int itona (int i, char *s, size_t n);
457 #endif
458 
459 extern char *stristr (const char *s, const char *find);
460 
461 #if 1
462 #define SUPPRESS_STRLEN_WARNING
463 #else /* !1 */
464 /* TODO: this causes a compile error on windows, since it uses in its headers std::strlen. anyway, this is an ugly hack
465  * too.
466  * now, we have hundreds of annoying warnings of casts from size_t to int. so either rename this define and all
467  * its usages, or replaces all occurrences of strlen with (int) strlen. either way, all project is changed. */
468 #define strlen(s1) ((int) strlen(s1))
469 #endif /* !1 */
470 #define CAST_STRLEN (int)
471 #define CAST_BUFLEN (int)
472 #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 32
473 #define OFF_T_MAX INT_MAX
474 #else
475 #define OFF_T_MAX LLONG_MAX
476 #endif
477 
478 #if defined (WINDOWS)
479 #define IS_INVALID_SOCKET(socket) ((socket) == INVALID_SOCKET)
480 typedef int socklen_t;
481 #else
482 typedef int SOCKET;
483 #define INVALID_SOCKET (-1)
484 #define IS_INVALID_SOCKET(socket) ((socket) < 0)
485 #endif
486 
487 /*
488  * wrapper for cuserid()
489  */
490 extern char *getuserid (char *string, int size);
491 /*
492  * wrapper for OS dependent operations
493  */
494 extern int os_rename_file (const char *src_path, const char *dest_path);
495 
496 /* os_send_kill() - send the KILL signal to ourselves */
497 #if defined (WINDOWS)
498 #define os_send_kill() os_send_signal(SIGABRT)
499 #else
500 #define os_send_kill() os_send_signal(SIGKILL)
501 #endif
502 typedef void (*SIGNAL_HANDLER_FUNCTION) (int sig_no);
503 extern SIGNAL_HANDLER_FUNCTION os_set_signal_handler (const int sig_no, SIGNAL_HANDLER_FUNCTION sig_handler);
504 extern void os_send_signal (const int sig_no);
505 
506 #if defined (WINDOWS)
507 #define atoll(a) _atoi64((a))
508 #if !defined(_MSC_VER) || _MSC_VER < 1800
509 /* ref: https://msdn.microsoft.com/en-us/library/a206stx2.aspx */
510 #define llabs(a) _abs64((a))
511 #endif /* _MSC_VER && _MSC_VER < 1800 */
512 #endif
513 
514 #if defined (AIX) && !defined (NAME_MAX)
515 #define NAME_MAX pathconf("/",_PC_NAME_MAX)
516 #endif
517 
518 #if defined (AIX) && !defined (DONT_HOOK_MALLOC)
519 void *aix_malloc (size_t size);
520 #define malloc(a) aix_malloc(a)
521 #endif
522 
523 #if defined (AIX) && !defined (SOL_TCP)
524 #define SOL_TCP IPPROTO_TCP
525 #endif
526 
527 #if defined (WINDOWS)
528 int setenv (const char *name, const char *value, int overwrite);
529 int cub_vsnprintf (char *buffer, size_t count, const char *format, va_list argptr);
530 #endif
531 
532 #if defined (WINDOWS)
533 /* The following structure is used to generate uniformly distributed
534  * pseudo-random numbers reentrantly.
535  */
536 struct drand48_data
537 {
538  unsigned short _rand48_seed[3];
539 };
540 
541 /* These functions are implemented in rand.c. And rand.c will be included
542  * on Windows build.
543  */
544 extern long lrand48 (void);
545 extern void srand48 (long seed);
546 extern double drand48 (void);
547 extern int srand48_r (long int seedval, struct drand48_data *buffer);
548 extern int lrand48_r (struct drand48_data *buffer, long int *result);
549 extern int drand48_r (struct drand48_data *buffer, double *result);
550 extern int rand_r (unsigned int *seedp);
551 
552 #if !defined(_MSC_VER) || _MSC_VER < 1800
553  /* Ref: https://msdn.microsoft.com/en-us/library/dn353646(v=vs.140).aspx */
554 extern double round (double d);
555 #endif /* !_MSC_VER || _MSC_VER < 1800 */
556 
557 /* Maybe replace this with std::mutex */
558 typedef struct
559 {
560  CRITICAL_SECTION cs;
561  CRITICAL_SECTION *csp;
562  UINT32 watermark;
563 } pthread_mutex_t;
564 
565 typedef HANDLE pthread_mutexattr_t;
566 
567 /* Use a large prime as watermark */
568 #define WATERMARK_MUTEX_INITIALIZED 0x96438AF7
569 
570 #define PTHREAD_MUTEX_INITIALIZER {{ NULL, 0, 0, NULL, NULL, 0 }, NULL, 0}
571 
572 typedef enum
573 {
574  COND_SIGNAL = 0,
575  COND_BROADCAST = 1,
576  MAX_EVENTS = 2
577 } EVENTS;
578 
579 typedef union
580 {
581  CONDITION_VARIABLE native_cond;
582 
583  struct
584  {
585  bool initialized;
586  unsigned int waiting;
587  CRITICAL_SECTION lock_waiting;
588  HANDLE events[MAX_EVENTS];
589  HANDLE broadcast_block_event;
590  };
591 } pthread_cond_t;
592 
593 
594 typedef HANDLE pthread_condattr_t;
595 
596 #if !defined (ETIMEDOUT)
597 #define ETIMEDOUT WAIT_TIMEOUT
598 #endif
599 #define PTHREAD_COND_INITIALIZER { NULL }
600 
601 #if defined(_MSC_VER) && _MSC_VER >= 1900 && !defined(_CRT_NO_TIME_T)
602 #define _TIMESPEC_DEFINED
603 #endif /* _MSC_VER && _MSC_VER >= 1900 && !_CRT_NO_TIME_T */
604 #if !defined(_TIMESPEC_DEFINED)
605 #define _TIMESPEC_DEFINED
606 struct timespec
607 {
608  int tv_sec;
609  int tv_nsec;
610 };
611 #endif /* !_TIMESPEC_DEFINED */
612 
613 extern pthread_mutex_t css_Internal_mutex_for_mutex_initialize;
614 
615 int pthread_mutex_init (pthread_mutex_t * mutex, pthread_mutexattr_t * attr);
616 int pthread_mutex_destroy (pthread_mutex_t * mutex);
617 
618 void port_win_mutex_init_and_lock (pthread_mutex_t * mutex);
619 int port_win_mutex_init_and_trylock (pthread_mutex_t * mutex);
620 
621 __inline int
622 pthread_mutex_lock (pthread_mutex_t * mutex)
623 {
624  if (mutex->csp == &mutex->cs && mutex->watermark == WATERMARK_MUTEX_INITIALIZED)
625  {
626  EnterCriticalSection (mutex->csp);
627  }
628  else
629  {
630  port_win_mutex_init_and_lock (mutex);
631  }
632 
633  return 0;
634 }
635 
636 __inline int
637 pthread_mutex_unlock (pthread_mutex_t * mutex)
638 {
639  if (mutex->csp->LockCount == -1)
640  {
641  /* this means unlock mutex which isn't locked */
642  assert (0);
643  return 0;
644  }
645 
646  LeaveCriticalSection (mutex->csp);
647  return 0;
648 }
649 
650 __inline int
651 pthread_mutex_trylock (pthread_mutex_t * mutex)
652 {
653  if (mutex->csp == &mutex->cs && mutex->watermark == WATERMARK_MUTEX_INITIALIZED)
654  {
655  if (TryEnterCriticalSection (mutex->csp))
656  {
657  if (mutex->csp->RecursionCount > 1)
658  {
659  LeaveCriticalSection (mutex->csp);
660  return EBUSY;
661  }
662 
663  return 0;
664  }
665 
666  return EBUSY;
667  }
668  else
669  {
670  return port_win_mutex_init_and_trylock (mutex);
671  }
672 
673  return 0;
674 }
675 
676 int pthread_mutexattr_init (pthread_mutexattr_t * attr);
677 int pthread_mutexattr_settype (pthread_mutexattr_t * attr, int type);
678 int pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
679 
680 int pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr);
681 int pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex);
682 int pthread_cond_timedwait (pthread_cond_t * cond, pthread_mutex_t * mutex, struct timespec *ts);
683 int pthread_cond_destroy (pthread_cond_t * cond);
684 int pthread_cond_signal (pthread_cond_t * cond);
685 int pthread_cond_broadcast (pthread_cond_t * cond);
686 
687 
688 
689 /* Data Types */
690 typedef HANDLE pthread_t;
691 typedef int pthread_attr_t;
692 typedef int pthread_key_t;
693 
694 #define THREAD_RET_T unsigned int
695 #define THREAD_CALLING_CONVENTION __stdcall
696 
697 int pthread_create (pthread_t * thread, const pthread_attr_t * attr,
698  THREAD_RET_T (THREAD_CALLING_CONVENTION * start_routine) (void *), void *arg);
699 void pthread_exit (THREAD_RET_T ptr);
700 pthread_t pthread_self (void);
701 int pthread_join (pthread_t thread, void **value_ptr);
702 
703 #define pthread_attr_init(dummy1) 0
704 #define pthread_attr_destroy(dummy1) 0
705 
706 int pthread_key_create (pthread_key_t * key, void (*destructor) (void *));
707 int pthread_key_delete (pthread_key_t key);
708 int pthread_setspecific (pthread_key_t key, const void *value);
709 void *pthread_getspecific (pthread_key_t key);
710 
711 #else /* WINDOWS */
712 
713 #define THREAD_RET_T void*
714 #define THREAD_CALLING_CONVENTION
715 
716 #endif /* WINDOWS */
717 
718 #if (defined (WINDOWS) || defined (X86))
719 #define COPYMEM(type,dst,src) do { \
720  *((type *) (dst)) = *((type *) (src)); \
721 }while(0)
722 #else /* WINDOWS || X86 */
723 #define COPYMEM(type,dst,src) do { \
724  memcpy((dst), (src), sizeof(type)); \
725 }while(0)
726 #endif /* WINDOWS || X86 */
727 
728 /*
729  * Interfaces for atomic operations
730  *
731  * Developers should check HAVE_ATOMIC_BUILTINS before using atomic builtins
732  * as follows.
733  * #if defined (HAVE_ATOMIC_BUILTINS)
734  * ... write codes with atomic builtins ...
735  * #else
736  * ... leave legacy codes or write codes without atomic builtins ...
737  * #endif
738  *
739  * ATOMIC_TAS_xx (atomic test-and-set) writes new_val into *ptr, and returns
740  * the previous contents of *ptr. ATOMIC_CAS_xx (atomic compare-and-swap) returns
741  * true if the swap is done. It is only done if *ptr equals to cmp_val.
742  * ATOMIC_INC_xx (atomic increment) returns the result of *ptr + amount.
743  *
744  * Regarding Windows, there are two types of APIs to provide atomic operations.
745  * While InterlockedXXX functions handles 32bit values, InterlockedXXX64 handles
746  * 64bit values. That is why we define two types of macros.
747  */
748 #ifdef __cplusplus
749 
750 #if defined (WINDOWS)
751 #define MEMORY_BARRIER() \
752  MemoryBarrier()
753 #define HAVE_ATOMIC_BUILTINS
754 #else
755 #if defined (HAVE_GCC_ATOMIC_BUILTINS)
756 #define HAVE_ATOMIC_BUILTINS
757 #if defined (X86) && defined (CUB_GCC_VERSION) && (CUB_GCC_VERSION < 40400)
758 #define MEMORY_BARRIER() \
759  do { \
760  asm volatile("mfence" ::: "memory"); \
761  __sync_synchronize(); \
762  } while (0)
763 #else
764 #define MEMORY_BARRIER() \
765  __sync_synchronize()
766 #endif
767 #endif
768 #endif /* defined (WINDOWS) */
769 
770 #endif /* __cplusplus */
771 
772 #if defined(HAVE_ATOMIC_BUILTINS)
773 
774 #if defined (WINDOWS)
775 
776 #ifndef _WIN64
777 /*
778  * These functions are used on Windows 32bit OS.
779  * InterlockedXXX64 functions are provided by Windows Vista (client)/Windows
780  * 2003 (server) or later versions. So, Windows XP 32bit does not have them.
781  * We provide the following functions to support atomic operations on all
782  * Windows versions.
783  */
784 extern UINT64 win32_compare_exchange64 (UINT64 volatile *val_ptr, UINT64 swap_val, UINT64 cmp_val);
785 extern UINT64 win32_exchange_add64 (UINT64 volatile *ptr, UINT64 amount);
786 extern UINT64 win32_exchange64 (UINT64 volatile *ptr, UINT64 new_val);
787 
788 #endif /* !_WIN64 */
789 #endif /* defined (WINDOWS) */
790 
791 #ifndef __cplusplus
792 #define static_assert(a, b)
793 #endif /* not __cplusplus */
794 
795 /* *INDENT-OFF* */
796 template <typename T, typename V> inline T ATOMIC_INC_32 (volatile T *ptr, V amount)
797 {
798  static_assert (sizeof (T) == sizeof (UINT32), "Not 32bit");
799  static_assert (sizeof (V) == sizeof (UINT32), "Not 32bit");
800 #if defined (WINDOWS)
801 #if _MSC_VER <= 1500
802  return InterlockedExchangeAdd (reinterpret_cast <volatile LONG *>(ptr), amount) + amount;
803 #else
804  return InterlockedExchangeAdd (reinterpret_cast <volatile UINT32 *>(ptr), amount) + amount;
805 #endif
806 #else
807  return __sync_add_and_fetch (ptr, amount);
808 #endif
809 }
810 
811 template <typename T, typename V1, typename V2> inline bool ATOMIC_CAS_32 (volatile T *ptr, V1 cmp_val, V2 swap_val)
812 {
813  static_assert (sizeof (T) == sizeof (UINT32), "Not 32bit");
814  static_assert (sizeof (V1) == sizeof (UINT32), "Not 32bit");
815  static_assert (sizeof (V2) == sizeof (UINT32), "Not 32bit");
816 #if defined (WINDOWS)
817 #if _MSC_VER <= 1500
818  return InterlockedCompareExchange (reinterpret_cast <volatile LONG *>(ptr), swap_val, cmp_val) == cmp_val;
819 #else
820  return InterlockedCompareExchange (reinterpret_cast <volatile UINT32 *>(ptr), swap_val, cmp_val) == cmp_val;
821 #endif
822 #else
823  return __sync_bool_compare_and_swap (ptr, cmp_val, swap_val);
824 #endif
825 }
826 
827 template <typename T, typename V> inline T ATOMIC_TAS_32 (volatile T *ptr, V amount)
828 {
829  static_assert (sizeof (T) == sizeof (UINT32), "Not 32bit");
830  static_assert (sizeof (V) <= sizeof (UINT32), "Not 32bit");
831 #if defined (WINDOWS)
832 #if _MSC_VER <= 1500
833  return InterlockedExchange (reinterpret_cast <volatile LONG *>(ptr), amount);
834 #else
835  return InterlockedExchange (reinterpret_cast <volatile UINT32 *>(ptr), amount);
836 #endif
837 #else
838  return __sync_lock_test_and_set (ptr, amount);
839 #endif
840 }
841 
842 template <typename T, typename V> inline T ATOMIC_INC_64 (volatile T *ptr, V amount)
843 {
844  static_assert (sizeof (T) == sizeof (UINT64), "Not 64bit");
845 #if defined (_WIN64)
846  return (T) InterlockedExchangeAdd64 (reinterpret_cast <volatile INT64 *>(ptr), amount) + amount;
847 #elif defined(WINDOWS)
848  return win32_exchange_add64 (reinterpret_cast <volatile UINT64 *>(ptr), amount) + amount;
849 #else
850  return __sync_add_and_fetch (ptr, amount);
851 #endif
852 }
853 
854 template <typename T, typename V1, typename V2> inline bool ATOMIC_CAS_64 (volatile T *ptr, V1 cmp_val, V2 swap_val)
855 {
856  static_assert (sizeof (T) == sizeof (UINT64), "Not 64bit");
857 #if defined (_WIN64)
858  return InterlockedCompareExchange64 (reinterpret_cast <volatile INT64 *>(ptr), swap_val, cmp_val) == cmp_val;
859 #elif defined(WINDOWS)
860  return win32_compare_exchange64 (reinterpret_cast <volatile UINT64 *>(ptr), swap_val, cmp_val) == cmp_val;
861 #else
862  return __sync_bool_compare_and_swap (ptr, cmp_val, swap_val);
863 #endif
864 }
865 
866 template <typename T, typename V> inline T ATOMIC_TAS_64 (volatile T *ptr, V amount)
867 {
868  static_assert (sizeof (T) == sizeof (UINT64), "Not 64bit");
869 #if defined (_WIN64)
870  return (T) InterlockedExchange64 (reinterpret_cast <volatile INT64 *>(ptr), (__int64) amount);
871 #elif defined(WINDOWS)
872  return win32_exchange64 (reinterpret_cast <volatile UINT64 *>(ptr), amount);
873 #else
874  return __sync_lock_test_and_set (ptr, amount);
875 #endif
876 }
877 
878 namespace dispatch
879 {
880  template <bool B> struct Bool2Type
881  {
882  enum { value = B };
883  };
884 
885  template <typename T, typename V1, typename V2> inline bool atomic_cas (volatile T *ptr, V1 cmp_val, V2 swap_val,
886  Bool2Type <true> /*_is_64_bit*/ )
887  {
888  return ATOMIC_CAS_64 (ptr, cmp_val, swap_val);
889  }
890 
891  template <typename T, typename V1, typename V2> inline bool atomic_cas (volatile T *ptr, V1 cmp_val, V2 swap_val,
892  Bool2Type <false> /*_is_64_bit*/ )
893  {
894  return ATOMIC_CAS_32 (ptr, cmp_val, swap_val);
895  }
896 
897  template <typename T, typename V> inline T atomic_tas (volatile T *ptr, V amount, Bool2Type <true> /*_is_64_bit*/ )
898  {
899  return ATOMIC_TAS_64 (ptr, amount);
900  }
901 
902  template <typename T, typename V> inline T atomic_tas (volatile T * ptr, V amount, Bool2Type <false> /*_is_64_bit*/ )
903  {
904  return ATOMIC_TAS_32 (ptr, amount);
905  }
906 
907  template <typename T, typename V> inline T atomic_inc (volatile T *ptr, V amount, Bool2Type <true> /*_is_64_bit*/ )
908  {
909  return ATOMIC_INC_64 (ptr, amount);
910  }
911 
912  template <typename T, typename V> inline T atomic_inc (volatile T * ptr, V amount, Bool2Type <false> /*_is_64_bit*/ )
913  {
914  return ATOMIC_INC_32 (ptr, amount);
915  }
916 } /* namespace dispatch */
917 
918 template <typename T, typename V> inline T ATOMIC_TAS (volatile T *ptr, V amount)
919 {
920  return dispatch::atomic_tas (ptr, amount, dispatch::Bool2Type <sizeof (T) == sizeof (UINT64)> ());
921 }
922 
923 template <typename T, typename V1, typename V2> inline bool ATOMIC_CAS (volatile T *ptr, V1 cmp_val, V2 swap_val)
924 {
925  return dispatch::atomic_cas (ptr, cmp_val, swap_val, dispatch::Bool2Type <sizeof (T) == sizeof (UINT64)> ());
926 }
927 
928 template <typename T> inline T *ATOMIC_TAS_ADDR (T * volatile *ptr, T *new_val)
929 {
930 #if defined (WINDOWS)
931  return static_cast <T *>(InterlockedExchangePointer (reinterpret_cast <volatile PVOID *>(ptr), new_val));
932 #else
933  return __sync_lock_test_and_set (ptr, new_val);
934 #endif
935 }
936 
937 template <typename T> inline bool ATOMIC_CAS_ADDR (T * volatile *ptr, T *cmp_val, T *swap_val)
938 {
939 #if defined (WINDOWS)
940  return InterlockedCompareExchangePointer (reinterpret_cast <volatile PVOID *>(ptr), swap_val, cmp_val) == cmp_val;
941 #else
942  return __sync_bool_compare_and_swap (ptr, cmp_val, swap_val);
943 #endif
944 }
945 
946 template <typename T, typename V> inline T ATOMIC_INC (volatile T *ptr, V amount)
947 {
948  return dispatch::atomic_inc (ptr, amount, dispatch::Bool2Type <sizeof (T) == sizeof (UINT64)> ());
949 }
950 
951 template <typename T> inline T ATOMIC_LOAD (volatile T *ptr)
952 {
953  return ATOMIC_INC (ptr, 0);
954 }
955 
956 template <typename T, typename V> inline void ATOMIC_STORE (volatile T *ptr, V amount)
957 {
958  (void) ATOMIC_TAS (ptr, amount);
959 }
960 
961 /* *INDENT-ON* */
962 
963 #define ATOMIC_LOAD_64(ptr) ATOMIC_INC_64(ptr, 0)
964 #define ATOMIC_STORE_64(ptr, val) ATOMIC_TAS(ptr, val)
965 
966 #endif /* defined(HAVE_ATOMIC_BUILTINS) */
967 
968 #if defined (WINDOWS)
969 extern double strtod_win (const char *str, char **end_ptr);
970 #define string_to_double(str, end_ptr) strtod_win((str), (end_ptr));
971 #else
972 #define string_to_double(str, end_ptr) strtod((str), (end_ptr))
973 #endif
974 
975 extern INT64 timeval_diff_in_msec (const struct timeval *end_time, const struct timeval *start_time);
976 extern int timeval_add_msec (struct timeval *added_time, const struct timeval *start_time, int msec);
977 extern int timeval_to_timespec (struct timespec *to, const struct timeval *from);
978 
979 extern FILE *port_open_memstream (char **ptr, size_t * sizeloc);
980 
981 extern void port_close_memstream (FILE * fp, char **ptr, size_t * sizeloc);
982 
983 extern char *trim (char *str);
984 
985 extern int parse_bigint (INT64 * ret_p, const char *str_p, int base);
986 
987 extern int str_to_int32 (int *ret_p, char **end_p, const char *str_p, int base);
988 extern int str_to_uint32 (unsigned int *ret_p, char **end_p, const char *str_p, int base);
989 extern int str_to_int64 (INT64 * ret_p, char **end_p, const char *str_p, int base);
990 extern int str_to_uint64 (UINT64 * ret_p, char **end_p, const char *str_p, int base);
991 extern int str_to_double (double *ret_p, char **end_p, const char *str_p);
992 extern int str_to_float (float *ret_p, char **end_p, const char *str_p);
993 
994 #if defined (WINDOWS)
995 extern float strtof_win (const char *nptr, char **endptr);
996 #endif
997 
998 #ifndef HAVE_STRLCPY
999 extern size_t strlcpy (char *, const char *, size_t);
1000 #endif
1001 
1002 #if (defined (WINDOWS) && defined (_WIN32))
1003 extern time_t mktime_for_win32 (struct tm *tm);
1004 #endif
1005 
1006 #if (defined (WINDOWS) && !defined (PRId64))
1007 #define PRId64 "lld"
1008 #define PRIx64 "llx"
1009 #endif
1010 
1011 extern int msleep (const long msec);
1012 
1013 #ifdef __cplusplus
1014 extern "C"
1015 {
1016 #endif
1017  extern int parse_int (int *ret_p, const char *str_p, int base);
1018 #ifdef __cplusplus
1019 }
1020 #endif
1021 
1022 #if defined (_MSC_VER) || defined (__GNUC__)
1023 #define PORTABLE_FUNC_NAME __func__
1024 #else
1025 #define PORTABLE_FUNC_NAME "(unknown)"
1026 #endif
1027 
1028 #ifdef __GNUC__
1029 #define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
1030 #else
1031 #define UNUSED(x) x
1032 #endif
1033 
1034 #ifdef __GNUC__
1035 #define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
1036 #else
1037 #define UNUSED_FUNCTION(x) x
1038 #endif
1039 
1040 /* casts for C++ and C to be used in *.c files; cpp files should use C++ specific syntax. */
1041 /* todo: we should split porting.h into several files to avoid recompiling whole project every time we change
1042  * something. when we do that, we can avoid including dangerous macro's like these in header files.
1043  * so, try not to include this in header files. */
1044 #ifdef STATIC_CAST
1045 #error "STATIC_CAST definition conflict"
1046 #else /* !STATIC_CAST */
1047 #ifdef __cplusplus
1048 #define STATIC_CAST(dest_type, expr) static_cast<dest_type>(expr)
1049 #else /* !__cplusplus */
1050 #define STATIC_CAST(dest_type, expr) ((dest_type) (expr))
1051 #endif /* !__cplusplus */
1052 #endif /* !STATIC_CAST */
1053 
1054 #ifdef CONST_CAST
1055 #error "CONST_CAST definition conflict"
1056 #else /* !CONST_CAST */
1057 #ifdef __cplusplus
1058 #define CONST_CAST(dest_type, expr) const_cast<dest_type>(expr)
1059 #else /* !__cplusplus */
1060 #define CONST_CAST(dest_type, expr) ((dest_type) (expr))
1061 #endif /* !__cplusplus */
1062 #endif /* !CONST_CAST */
1063 
1064 #ifdef DYNAMIC_CAST
1065 #error "DYNAMIC_CAST definition conflict"
1066 #else /* !DYNAMIC_CAST */
1067 #ifdef __cplusplus
1068 #define DYNAMIC_CAST(dest_type, expr) dynamic_cast<dest_type>(expr)
1069 #else /* !__cplusplus */
1070 #define DYNAMIC_CAST(dest_type, expr) ((dest_type) (expr))
1071 #endif /* !__cplusplus */
1072 #endif /* !DYNAMIC_CAST */
1073 
1074 #ifdef REINTERPRET_CAST
1075 #error "REINTERPRET_CAST definition conflict"
1076 #else /* !REINTERPRET_CAST */
1077 #ifdef __cplusplus
1078 #define REINTERPRET_CAST(dest_type, expr) reinterpret_cast<dest_type>(expr)
1079 #else /* !__cplusplus */
1080 #define REINTERPRET_CAST(dest_type, expr) ((dest_type) (expr))
1081 #endif /* !__cplusplus */
1082 #endif /* !REINTERPRET_CAST */
1083 
1084 
1085 /* Use REFP to declare a reference to pointer in *.c files without indent complaining. Do not use it in .cpp files. */
1086 #ifdef REFPTR
1087 #error "REFP definition conflict"
1088 #else /* !REFPTR */
1089 #define REFPTR(T, name) T *& name
1090 #endif /* !REFPTR */
1091 
1092 #endif /* _PORTING_H_ */
int str_to_int64(INT64 *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2419
#define COND_BROADCAST(a)
void os_send_signal(const int sig_no)
Definition: porting.c:1378
int SOCKET
Definition: porting.h:482
#define pthread_mutex_init(a, b)
Definition: area_alloc.c:48
static API_MUTEX mutex
Definition: api_util.c:72
#define pthread_mutex_unlock(a)
Definition: area_alloc.c:51
char * basename(const char *path)
Definition: porting.c:1132
FILE * port_open_memstream(char **ptr, size_t *sizeloc)
Definition: porting.c:2198
char * strdup(const char *str)
Definition: porting.c:901
int str_to_uint64(UINT64 *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2449
int cub_dirname_r(const char *path, char *pathbuf, size_t buflen)
Definition: porting.c:989
int vasprintf(char **ptr, const char *format, va_list ap)
Definition: porting.c:936
int basename_r(const char *path, char *pathbuf, size_t buflen)
Definition: porting.c:1082
#define THREAD_RET_T
Definition: porting.h:713
#define assert(x)
int os_rename_file(const char *src_path, const char *dest_path)
Definition: porting.c:1294
#define pthread_mutex_trylock(a)
Definition: lock_free.c:38
int timeval_add_msec(struct timeval *added_time, const struct timeval *start_time, int msec)
Definition: porting.c:2152
char * getuserid(char *string, int size)
Definition: porting.c:1271
INT64 timeval_diff_in_msec(const struct timeval *end_time, const struct timeval *start_time)
Definition: porting.c:2133
char * stristr(const char *s, const char *find)
Definition: porting.c:1242
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
SIGNAL_HANDLER_FUNCTION os_set_signal_handler(const int sig_no, SIGNAL_HANDLER_FUNCTION sig_handler)
Definition: porting.c:1333
void port_close_memstream(FILE *fp, char **ptr, size_t *sizeloc)
Definition: porting.c:2220
static struct timeval start_time
int parse_bigint(INT64 *ret_p, const char *str_p, int base)
Definition: porting.c:2318
char * trim(char *str)
Definition: porting.c:2260
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
int msleep(const long msec)
Definition: porting.c:2657
int str_to_float(float *ret_p, char **end_p, const char *str_p)
Definition: porting.c:2509
char * dirname(const char *path)
Definition: porting.c:1066
int i
Definition: dynamic_load.c:954
int str_to_double(double *ret_p, char **end_p, const char *str_p)
Definition: porting.c:2479
#define pthread_mutex_lock(a)
Definition: area_alloc.c:50
int timeval_to_timespec(struct timespec *to, const struct timeval *from)
Definition: porting.c:2173
size_t strlcpy(char *, const char *, size_t)
Definition: porting.c:2584
void(* SIGNAL_HANDLER_FUNCTION)(int sig_no)
Definition: porting.h:502
int asprintf(char **ptr, const char *format,...)
Definition: porting.c:973
int str_to_int32(int *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2346
#define THREAD_CALLING_CONVENTION
Definition: porting.h:714
int str_to_uint32(unsigned int *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2382
#define pthread_mutex_destroy(a)
Definition: area_alloc.c:49