Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
groonga_in.h
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2 -*- */
2 /* Copyright(C) 2009-2012 Brazil
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #ifndef GROONGA_IN_H
20 #define GROONGA_IN_H
21 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif /* HAVE_CONFIG_H */
25 
26 #ifdef __cplusplus
27 #define __STDC_LIMIT_MACROS
28 #endif
29 
30 #ifdef HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif /* HAVE_STDLIB_H */
33 
34 #ifdef HAVE_STDINT_H
35 #include <stdint.h>
36 #endif /* HAVE_STDINT_H */
37 
38 #ifdef HAVE_SYS_TYPES_H
39 #include <sys/types.h>
40 #endif /* HAVE_SYS_TYPES_H */
41 
42 #ifdef HAVE_SYS_PARAM_H
43 #include <sys/param.h>
44 #endif /* HAVE_SYS_PARAM_H */
45 
46 #ifdef HAVE_SYS_MMAN_H
47 #include <sys/mman.h>
48 #endif /* HAVE_SYS_MMAN_H */
49 
50 #ifdef HAVE_SYS_TIME_H
51 #include <sys/time.h>
52 #endif /* HAVE_SYS_TIME_H */
53 #ifdef HAVE_SYS_TIMEB_H
54 #include <sys/timeb.h>
55 #endif /* HAVE_SYS_TIMEB_H */
56 
57 #ifdef HAVE_SYS_RESOURCE_H
58 #include <sys/resource.h>
59 #endif /* HAVE_SYS_RESOURCE_H */
60 
61 #ifdef WIN32
62 # define GRN_API __declspec(dllexport)
63 #ifdef GROONGA_MAIN
64 # define GRN_VAR __declspec(dllimport)
65 #else
66 # define GRN_VAR __declspec(dllexport) extern
67 #endif /* GROONGA_MAIN */
68 #else
69 # define GRN_API
70 # define GRN_VAR extern
71 #endif
72 
73 #ifdef HAVE_OPEN
74 # define GRN_OPEN(pathname, ...) open(pathname, __VA_ARGS__)
75 #else
76 # define GRN_OPEN(pathname, ...) _open(pathname, __VA_ARGS__)
77 #endif /* HAVE_OPEN */
78 
79 #ifdef HAVE_CLOSE
80 # define GRN_CLOSE(fd) close(fd)
81 #else
82 # define GRN_CLOSE(fd) _close(fd)
83 #endif /* HAVE_CLOSE */
84 
85 #ifdef HAVE_READ
86 # define GRN_READ(fd, buf, count) read(fd, buf, count)
87 #else
88 # define GRN_READ(fd, buf, count) _read(fd, buf, count)
89 #endif /* HAVE_READ */
90 
91 #ifdef HAVE_WRITE
92 # define GRN_WRITE(fd, buf, count) write(fd, buf, count)
93 #else
94 # define GRN_WRITE(fd, buf, count) _write(fd, buf, count)
95 #endif /* HAVE_WRITE */
96 
97 #ifdef WIN32
98 
99 #if defined(__GNUC__) && !defined(WINVER)
100 # include <w32api.h>
101 # define WINVER WindowsXP
102 #endif /* defined(__GNUC__) && !defined(WINVER) */
103 
104 #include <basetsd.h>
105 #include <process.h>
106 #include <winsock2.h>
107 #include <ws2tcpip.h>
108 #include <windows.h>
109 #include <stddef.h>
110 #include <windef.h>
111 #include <float.h>
112 #include <time.h>
113 #include <sys/types.h>
114 
115 #ifndef __GNUC__
116 # define PATH_MAX (MAX_PATH - 1)
117 # ifndef __cplusplus
118 # define inline _inline
119 # endif
120 #endif
121 
122 #define snprintf(str, size, ...) _snprintf(str, size, __VA_ARGS__)
123 #if _MSC_VER < 1500
124 # define vsnprintf(str, size, format, ap) _vsnprintf(str, size, format, ap)
125 #endif /* _MSC_VER < 1500 */
126 #define unlink(pathname) _unlink(pathname)
127 #define lseek(fd, offset, whence) _lseek(fd, offset, whence)
128 #define getpid() _getpid()
129 #if !defined(__GNUC__) && _MSC_VER < 1400
130 # define fstat(fd, buf) _fstat(fd, buf)
131 #endif /* !defined(__GNUC__) && _MSC_VER < 1400 */
132 #if !defined(strcasecmp)
133 # define strcasecmp(s1, s2) stricmp(s1, s2)
134 #endif /* !defined(strcasecmp) */
135 
136 #ifdef __GNUC__
137 #include <stdint.h>
138 #else
139 #define uint8_t UINT8
140 #define int8_t INT8
141 #define int_least8_t INT8
142 #define uint_least8_t UINT8
143 #define int16_t INT16
144 #define uint16_t UINT16
145 #define int32_t INT32
146 #define uint32_t UINT32
147 #define int64_t INT64
148 #define uint64_t UINT64
149 #define ssize_t SSIZE_T
150 #define pid_t int
151 #endif
152 
153 #undef MSG_WAITALL
154 #define MSG_WAITALL 0 /* before Vista, not supported... */
155 #define SHUT_RDWR SD_BOTH
156 
157 typedef SOCKET grn_sock;
158 #define grn_sock_close(sock) closesocket(sock)
159 
160 #define CALLBACK __stdcall
161 
162 #ifndef __GNUC__
163 #include <intrin.h>
164 #include <sys/timeb.h>
165 #include <errno.h>
166 #endif
167 
168 #else /* WIN32 */
169 
170 #define GROONGA_API
171 
172 #ifdef HAVE_UNISTD_H
173 #include <unistd.h>
174 #endif /* HAVE_UNISTD_H */
175 
176 # ifndef PATH_MAX
177 # if defined(MAXPATHLEN)
178 # define PATH_MAX MAXPATHLEN
179 # else /* MAXPATHLEN */
180 # define PATH_MAX 1024
181 # endif /* MAXPATHLEN */
182 # endif /* PATH_MAX */
183 # ifndef INT_LEAST8_MAX
184 typedef char int_least8_t;
185 # endif /* INT_LEAST8_MAX */
186 # ifndef UINT_LEAST8_MAX
187 typedef unsigned char uint_least8_t;
188 # endif /* UINT_LEAST8_MAX */
189 typedef int grn_sock;
190 # define grn_sock_close(sock) close(sock)
191 # define CALLBACK
192 
193 #endif /* WIN32 */
194 
195 #ifndef INT8_MAX
196 #define INT8_MAX (127)
197 #endif /* INT8_MAX */
198 
199 #ifndef INT8_MIN
200 #define INT8_MIN (-128)
201 #endif /* INT8_MIN */
202 
203 #ifndef INT16_MAX
204 #define INT16_MAX (32767)
205 #endif /* INT16_MAX */
206 
207 #ifndef INT16_MIN
208 #define INT16_MIN (-32768)
209 #endif /* INT16_MIN */
210 
211 #ifndef INT32_MAX
212 #define INT32_MAX (2147483647)
213 #endif /* INT32_MAX */
214 
215 #ifndef INT32_MIN
216 #define INT32_MIN (-2147483648)
217 #endif /* INT32_MIN */
218 
219 #ifndef UINT32_MAX
220 #define UINT32_MAX (4294967295)
221 #endif /* UINT32_MAX */
222 
223 #ifndef INT64_MAX
224 #define INT64_MAX (9223372036854775807)
225 #endif /* INT64_MAX */
226 
227 #ifndef INT64_MIN
228 #define INT64_MIN (-9223372036854775808)
229 #endif /* INT64_MIN */
230 
231 #ifdef HAVE_PTHREAD_H
232 #include <pthread.h>
233 typedef pthread_t grn_thread;
234 #define THREAD_CREATE(thread,func,arg) \
235  (pthread_create(&(thread), NULL, (func), (arg)))
236 #define THREAD_JOIN(thread) (pthread_join(thread, NULL))
237 typedef pthread_mutex_t grn_mutex;
238 #define MUTEX_INIT(m) pthread_mutex_init(&m, NULL)
239 #define MUTEX_LOCK(m) pthread_mutex_lock(&m)
240 #define MUTEX_UNLOCK(m) pthread_mutex_unlock(&m)
241 #define MUTEX_FIN(m)
242 #ifdef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
243 # define MUTEX_INIT_SHARED(m) do {\
244  pthread_mutexattr_t mutexattr;\
245  pthread_mutexattr_init(&mutexattr);\
246  pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);\
247  pthread_mutex_init(&m, &mutexattr);\
248 } while (0)
249 #else
250 # define MUTEX_INIT_SHARED MUTEX_INIT
251 #endif /* HAVE_PTHREAD_MUTEXATTR_SETPSHARED */
252 
253 typedef pthread_mutex_t grn_critical_section;
254 #define CRITICAL_SECTION_INIT(cs) pthread_mutex_init(&(cs), NULL)
255 #define CRITICAL_SECTION_ENTER(cs) pthread_mutex_lock(&(cs))
256 #define CRITICAL_SECTION_LEAVE(cs) pthread_mutex_unlock(&(cs))
257 #define CRITICAL_SECTION_FIN(cs)
258 
259 typedef pthread_cond_t grn_cond;
260 #define COND_INIT(c) pthread_cond_init(&c, NULL)
261 #define COND_SIGNAL(c) pthread_cond_signal(&c)
262 #define COND_WAIT(c,m) pthread_cond_wait(&c, &m)
263 #define COND_BROADCAST(c) pthread_cond_broadcast(&c)
264 #ifdef HAVE_PTHREAD_CONDATTR_SETPSHARED
265 # define COND_INIT_SHARED(c) do {\
266  pthread_condattr_t condattr;\
267  pthread_condattr_init(&condattr);\
268  pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED);\
269  pthread_cond_init(&c, &condattr);\
270 } while (0)
271 #else
272 # define COND_INIT_SHARED COND_INIT
273 #endif /* HAVE_PTHREAD_CONDATTR_SETPSHARE */
274 
275 typedef pthread_key_t grn_thread_key;
276 #define THREAD_KEY_CREATE(key, destr) pthread_key_create(key, destr)
277 #define THREAD_KEY_DELETE(key) pthread_key_delete(key)
278 #define THREAD_SETSPECIFIC(key, value) pthread_setspecific(key, value)
279 #define THREAD_GETSPECIFIC(key) pthread_getspecific(key)
280 
281 #if USE_UYIELD
282  extern int grn_uyield_count;
283  #define GRN_TEST_YIELD() do {\
284  if (((++grn_uyield_count) & (0x20 - 1)) == 0) {\
285  sched_yield();\
286  if(grn_uyield_count > 0x1000) {\
287  grn_uyield_count = (uint32_t)time(NULL) % 0x1000;\
288  }\
289  }\
290  } while (0)
291 
292  #undef assert
293  #define assert(assert_expr) do {\
294  if (!(assert_expr)){\
295  fprintf(stderr, "assertion failed: %s\n", #assert_expr);\
296  abort();\
297  }\
298  GRN_TEST_YIELD();\
299  } while (0)
300 
301  #define if(if_cond) \
302  if ((((++grn_uyield_count) & (0x100 - 1)) != 0 || (sched_yield() * 0) == 0) && (if_cond))
303  #define while(while_cond) \
304  while ((((++grn_uyield_count) & (0x100 - 1)) != 0 || (sched_yield() * 0) == 0) && (while_cond))
305 
306  #if !defined(_POSIX_PRIORITY_SCHEDULING)
307  #define sched_yield() grn_nanosleep(1000000 * 20)
308  #endif
309 #else /* USE_UYIELD */
310  #define GRN_TEST_YIELD() do {} while (0)
311 #endif /* USE_UYIELD */
312 
313 #else /* HAVE_PTHREAD_H */
314 
315 /* todo */
316 typedef int grn_thread_key;
317 #define THREAD_KEY_CREATE(key,destr)
318 #define THREAD_KEY_DELETE(key)
319 #define THREAD_SETSPECIFIC(key)
320 #define THREAD_GETSPECIFIC(key,value)
321 
322 #ifdef WIN32
323 typedef uintptr_t grn_thread;
324 #define THREAD_CREATE(thread,func,arg) \
325  (((thread)=_beginthreadex(NULL, 0, (func), (arg), 0, NULL)) == NULL)
326 #define THREAD_JOIN(thread) \
327  (WaitForSingleObject((thread), INFINITE) == WAIT_FAILED)
328 typedef HANDLE grn_mutex;
329 #define MUTEX_INIT(m) ((m) = CreateMutex(0, FALSE, NULL))
330 #define MUTEX_LOCK(m) WaitForSingleObject((m), INFINITE)
331 #define MUTEX_UNLOCK(m) ReleaseMutex(m)
332 #define MUTEX_FIN(m) CloseHandle(m)
333 typedef CRITICAL_SECTION grn_critical_section;
334 #define CRITICAL_SECTION_INIT(cs) InitializeCriticalSection(&(cs))
335 #define CRITICAL_SECTION_ENTER(cs) EnterCriticalSection(&(cs))
336 #define CRITICAL_SECTION_LEAVE(cs) LeaveCriticalSection(&(cs))
337 #define CRITICAL_SECTION_FIN(cs) DeleteCriticalSection(&(cs))
338 
339 typedef struct
340 {
341  int waiters_count_;
342  HANDLE waiters_count_lock_;
343  HANDLE sema_;
344  HANDLE waiters_done_;
345  size_t was_broadcast_;
346 } grn_cond;
347 
348 #define COND_INIT(c) do { \
349  (c).waiters_count_ = 0; \
350  (c).sema_ = CreateSemaphore(NULL, 0, 0x7fffffff, NULL); \
351  MUTEX_INIT((c).waiters_count_lock_); \
352  (c).waiters_done_ = CreateEvent(NULL, FALSE, FALSE, NULL); \
353 } while (0)
354 
355 #define COND_SIGNAL(c) do { \
356  MUTEX_LOCK((c).waiters_count_lock_); \
357  { \
358  int have_waiters = (c).waiters_count_ > 0; \
359  MUTEX_UNLOCK((c).waiters_count_lock_); \
360  if (have_waiters) { \
361  ReleaseSemaphore((c).sema_, 1, 0); \
362  } \
363  } \
364 } while (0)
365 
366 #define COND_BROADCAST(c) do { \
367  MUTEX_LOCK((c).waiters_count_lock_); \
368  { \
369  int have_waiters = (c).waiters_count_ > 0; \
370  if ((c).waiters_count_ > 0) { \
371  (c).was_broadcast_ = 1; \
372  have_waiters = 1; \
373  } \
374  if (have_waiters) { \
375  ReleaseSemaphore((c).sema_, (c).waiters_count_, 0); \
376  MUTEX_UNLOCK((c).waiters_count_lock_); \
377  WaitForSingleObject((c).waiters_done_, INFINITE); \
378  (c).was_broadcast_ = 0; \
379  } \
380  else { \
381  MUTEX_UNLOCK((c).waiters_count_lock_); \
382  } \
383  } \
384 } while (0)
385 
386 #define COND_WAIT(c,m) do { \
387  MUTEX_LOCK((c).waiters_count_lock_); \
388  (c).waiters_count_++; \
389  MUTEX_UNLOCK((c).waiters_count_lock_); \
390  SignalObjectAndWait((m), (c).sema_, INFINITE, FALSE); \
391  MUTEX_LOCK((c).waiters_count_lock_); \
392  (c).waiters_count_--; \
393  { \
394  int last_waiter = (c).was_broadcast_ && (c).waiters_count_ == 0; \
395  MUTEX_UNLOCK((c).waiters_count_lock_); \
396  if (last_waiter) { \
397  SignalObjectAndWait((c).waiters_done_, (m), INFINITE, FALSE); \
398  } \
399  else { \
400  WaitForSingleObject((m), FALSE); \
401  } \
402  } \
403 } while (0)
404 
405 #else /* WIN32 */
406 /* todo */
407 typedef int grn_cond;
408 #define COND_INIT(c) ((c) = 0)
409 #define COND_SIGNAL(c)
410 #define COND_WAIT(c,m) do { \
411  MUTEX_UNLOCK(m); \
412  grn_nanosleep(1000000); \
413  MUTEX_LOCK(m); \
414 } while (0)
415 /* todo : must be enhanced! */
416 
417 #endif /* WIN32 */
418 
419 #define MUTEX_INIT_SHARED MUTEX_INIT
420 #define COND_INIT_SHARED COND_INIT
421 
422 #define GRN_TEST_YIELD() do {} while (0)
423 
424 #endif /* HAVE_PTHREAD_H */
425 
426 /* format string for printf */
427 #ifdef HAVE_INTTYPES_H
428 # include <inttypes.h>
429 # define GRN_FMT_INT32D PRId32
430 # define GRN_FMT_INT32U PRIu32
431 # define GRN_FMT_INT64D PRId64
432 # define GRN_FMT_INT64U PRIu64
433 # define GRN_FMT_LLD "lld"
434 # define GRN_FMT_LLU "llu"
435 #else /* HAVE_INTTYPES_H */
436 # ifdef WIN32
437 # define GRN_FMT_INT32D "I32d"
438 # define GRN_FMT_INT32U "I32u"
439 # define GRN_FMT_INT64D "I64d"
440 # define GRN_FMT_INT64U "I64u"
441 # define GRN_FMT_LLD "I64d"
442 # define GRN_FMT_LLU "I64u"
443 # else /* WIN32 */
444 # define GRN_FMT_INT32D "d"
445 # define GRN_FMT_INT32U "u"
446 # ifdef __x86_64__
447 # define GRN_FMT_INT64D "ld"
448 # define GRN_FMT_INT64U "lu"
449 # else /* __x86_64__ */
450 # define GRN_FMT_INT64D "lld"
451 # define GRN_FMT_INT64U "llu"
452 # endif /* __x86_64__ */
453 # define GRN_FMT_LLD "lld"
454 # define GRN_FMT_LLU "llu"
455 # endif /* WIN32 */
456 #endif /* HAVE_INTTYPES_H */
457 
458 #ifdef __GNUC__
459 # if (defined(__i386__) || defined(__x86_64__)) /* ATOMIC ADD */
460 /*
461  * GRN_ATOMIC_ADD_EX() performs { r = *p; *p += i; } atomically.
462  */
463 # define GRN_ATOMIC_ADD_EX(p, i, r) \
464  __asm__ __volatile__ ("lock xaddl %0, %1" : "=r"(r), "+m"(*p) : "0"(i))
465 /*
466  * GRN_BIT_SCAN_REV() finds the most significant 1 bit of `v'. Then, `r' is set
467  * to the index of the found bit. Note that `v' must not be 0.
468  */
469 # define GRN_BIT_SCAN_REV(v, r) \
470  __asm__ __volatile__ ("bsrl %1, %%eax; movl %%eax, %0" : "=r"(r) : "r"(v) : "%eax")
471 /*
472  * GRN_BIT_SCAN_REV0() is similar to GRN_BIT_SCAN_REV() but if `v' is 0, `r' is
473  * set to 0.
474  */
475 #define GRN_BIT_SCAN_REV0(v, r) \
476  __asm__ __volatile__ ("bsrl %1, %%eax; cmovzl %1, %%eax; movl %%eax, %0" : "=r"(r) : "r"(v) : "%eax", "cc")
477 # elif (defined(__PPC__) || defined(__ppc__)) /* ATOMIC ADD */
478 # define GRN_ATOMIC_ADD_EX(p,i,r) \
479  __asm__ __volatile__ ("\n1:\n\tlwarx %0, 0, %1\n\tadd %0, %0, %2\n\tstwcx. %0, 0, %1\n\tbne- 1b\n\tsub %0, %0, %2" : "=&r" (r) : "r" (p), "r" (i) : "cc", "memory")
480 /* todo */
481 # define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
482 # define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
483 # elif (defined(__sun) && defined(__SVR4)) /* ATOMIC ADD */
484 # include <atomic.h>
485 # define GRN_ATOMIC_ADD_EX(p,i,r) \
486  (r = atomic_add_32_nv(p, i) - i)
487 /* todo */
488 # define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
489 # define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
490 # else /* ATOMIC ADD */
491 /* todo */
492 # define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
493 # define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
494 # endif /* ATOMIC ADD */
495 
496 # ifdef __i386__ /* ATOMIC 64BIT SET */
497 # define GRN_SET_64BIT(p,v) \
498  __asm__ __volatile__ ("\txchgl %%esi, %%ebx\n1:\n\tmovl (%0), %%eax\n\tmovl 4(%0), %%edx\n\tlock; cmpxchg8b (%0)\n\tjnz 1b\n\txchgl %%ebx, %%esi" : : "D"(p), "S"(*(((uint32_t *)&(v))+0)), "c"(*(((uint32_t *)&(v))+1)) : "ax", "dx", "memory")
499 # elif defined(__x86_64__) /* ATOMIC 64BIT SET */
500 # define GRN_SET_64BIT(p,v) \
501  (*(p) = (v))
502 # elif (defined(__sun) && defined(__SVR4)) /* ATOMIC 64BIT SET */
503 /* todo */
504 # define GRN_SET_64BIT(p,v) \
505  (void)atomic_swap_64(p, v)
506 # endif /* ATOMIC 64BIT SET */
507 
508 # ifdef HAVE_MKOSTEMP
509 # define GRN_MKOSTEMP(template,flags,mode) mkostemp(template,flags)
510 # else /* HAVE_MKOSTEMP */
511 # define GRN_MKOSTEMP(template,flags,mode) \
512  (mktemp(template), GRN_OPEN((template),flags,mode))
513 # endif /* HAVE_MKOSTEMP */
514 
515 #elif (defined(WIN32) || defined (_WIN64)) /* __GNUC__ */
516 
517 # define GRN_ATOMIC_ADD_EX(p,i,r) \
518  ((r) = (uint32_t)InterlockedExchangeAdd((int32_t *)(p), (int32_t)(i)))
519 # if defined(_WIN64) /* ATOMIC 64BIT SET */
520 # define GRN_SET_64BIT(p,v) \
521  (*(p) = (v))
522 # else /* ATOMIC 64BIT SET */
523 # define GRN_SET_64BIT(p,v) do {\
524  uint32_t v1, v2; \
525  uint64_t *p2= (p); \
526  v1 = *(((uint32_t *)&(v))+0);\
527  v2 = *(((uint32_t *)&(v))+1);\
528  __asm _set_loop: \
529  __asm mov esi, p2 \
530  __asm mov ebx, v1 \
531  __asm mov ecx, v2 \
532  __asm mov eax, dword ptr [esi] \
533  __asm mov edx, dword ptr [esi + 4] \
534  __asm lock cmpxchg8b qword ptr [esi] \
535  __asm jnz _set_loop \
536 } while (0)
537 /* TODO: use _InterlockedCompareExchange64 or inline asm */
538 # endif /* ATOMIC 64BIT SET */
539 
540 /* todo */
541 # define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
542 # define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
543 
544 # define GRN_MKOSTEMP(template,flags,mode) \
545  (mktemp(template), GRN_OPEN((template),((flags)|O_BINARY),mode))
546 
547 #else /* __GNUC__ */
548 
549 # if (defined(__sun) && defined(__SVR4)) /* ATOMIC ADD */
550 # define __FUNCTION__ ""
551 # include <atomic.h>
552 # define GRN_ATOMIC_ADD_EX(p,i,r) \
553  (r = atomic_add_32_nv(p, i) - i)
554 /* todo */
555 # define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
556 # define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
557 /* todo */
558 # define GRN_SET_64BIT(p,v) \
559  (void)atomic_swap_64(p, v)
560 # endif /* ATOMIC ADD */
561 /* todo */
562 # define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
563 # define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
564 
565 # define GRN_MKOSTEMP(template,flags,mode) \
566  (mktemp(template), GRN_OPEN((template),flags,mode))
567 
568 #endif /* __GNUC__ */
569 
570 typedef uint8_t byte;
571 
572 #define GRN_ID_WIDTH 30
573 
574 #ifdef __GNUC__
575 inline static int
576 grn_str_greater(const uint8_t *ap, uint32_t as, const uint8_t *bp, uint32_t bs)
577 {
578  for (;; ap++, bp++, as--, bs--) {
579  if (!as) { return 0; }
580  if (!bs) { return 1; }
581  if (*ap < *bp) { return 0; }
582  if (*ap > *bp) { return 1; }
583  }
584 }
585 #else /* __GNUC__ */
586 # define grn_str_greater(ap,as,bp,bs)\
587  (((as) > (bs)) ? (memcmp((ap), (bp), (bs)) >= 0) : (memcmp((ap), (bp), (as)) > 0))
588 #endif /* __GNUC__ */
589 
590 #ifdef WORDS_BIGENDIAN
591 #define grn_hton(buf,key,size) do {\
592  uint32_t size_ = (uint32_t)size;\
593  uint8_t *buf_ = (uint8_t *)buf;\
594  uint8_t *key_ = (uint8_t *)key;\
595  while (size_--) { *buf_++ = *key_++; }\
596 } while (0)
597 #define grn_ntohi(buf,key,size) do {\
598  uint32_t size_ = (uint32_t)size;\
599  uint8_t *buf_ = (uint8_t *)buf;\
600  uint8_t *key_ = (uint8_t *)key;\
601  if (size_) { *buf_++ = 0x80 ^ *key_++; size_--; }\
602  while (size_) { *buf_++ = *key_++; size_--; }\
603 } while (0)
604 #else /* WORDS_BIGENDIAN */
605 #define grn_hton(buf,key,size) do {\
606  uint32_t size_ = (uint32_t)size;\
607  uint8_t *buf_ = (uint8_t *)buf;\
608  uint8_t *key_ = (uint8_t *)key + size;\
609  while (size_--) { *buf_++ = *(--key_); }\
610 } while (0)
611 #define grn_ntohi(buf,key,size) do {\
612  uint32_t size_ = (uint32_t)size;\
613  uint8_t *buf_ = (uint8_t *)buf;\
614  uint8_t *key_ = (uint8_t *)key + size;\
615  while (size_ > 1) { *buf_++ = *(--key_); size_--; }\
616  if (size_) { *buf_ = 0x80 ^ *(--key_); } \
617 } while (0)
618 #endif /* WORDS_BIGENDIAN */
619 #define grn_ntoh(buf,key,size) grn_hton(buf,key,size)
620 
621 #ifndef __GNUC_PREREQ
622 # if defined(__GNUC__) && defined(__GNUC_MINOR__)
623 # define __GNUC_PREREQ(maj, min) \
624  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
625 # else
626 # define __GNUC_PREREQ(maj, min) 0
627 # endif /* defined(__GNUC__) && defined(__GNUC_MINOR__) */
628 #endif /* __GNUC_PREREQ */
629 
630 #ifdef _MSC_VER
631 # define grn_bswap_uint64(in, out) ((out) = _byteswap_uint64(in))
632 #else /* _MSC_VER */
633 # if defined(__GNUC__) && __GNUC_PREREQ(4, 3)
634 # define grn_bswap_uint64(in, out) ((out) = __builtin_bswap64(in))
635 # else /* defined(__GNUC__) && __GNUC_PREREQ(4, 3) */
636 # define grn_bswap_uint64(in, out) do {\
637  uint64_t temp_ = (in);\
638  (out) = (temp_ << 56) |\
639  ((temp_ & (0xFFULL << 8)) << 40) |\
640  ((temp_ & (0xFFULL << 16)) << 24) |\
641  ((temp_ & (0xFFULL << 24)) << 8) |\
642  ((temp_ & (0xFFULL << 32)) >> 8) |\
643  ((temp_ & (0xFFULL << 40)) >> 24) |\
644  ((temp_ & (0xFFULL << 48)) >> 40) |\
645  (temp_ >> 56);\
646 } while (0)
647 # endif /* __GNUC__ */
648 #endif /* _MSC_VER */
649 
650 #ifdef WORDS_BIGENDIAN
651 # define grn_hton_uint64(in, out) ((out) = (in))
652 #else /* WORDS_BIGENDIAN */
653 # define grn_hton_uint64(in, out) grn_bswap_uint64(in, out)
654 #endif /* WORDS_BIGENDIAN */
655 #define grn_ntoh_uint64(in, out) grn_hton_uint64(in, out)
656 
657 #define grn_gton(keybuf,key,size) do {\
658  const grn_geo_point *point_ = (const grn_geo_point *)key;\
659  uint64_t la_ = (uint32_t)point_->latitude;\
660  uint64_t lo_ = (uint32_t)point_->longitude;\
661  uint64_t result_;\
662  la_ = (la_ | (la_ << 16)) & 0x0000FFFF0000FFFFULL;\
663  la_ = (la_ | (la_ << 8)) & 0x00FF00FF00FF00FFULL;\
664  la_ = (la_ | (la_ << 4)) & 0x0F0F0F0F0F0F0F0FULL;\
665  la_ = (la_ | (la_ << 2)) & 0x3333333333333333ULL;\
666  la_ = (la_ | (la_ << 1)) & 0x5555555555555555ULL;\
667  lo_ = (lo_ | (lo_ << 16)) & 0x0000FFFF0000FFFFULL;\
668  lo_ = (lo_ | (lo_ << 8)) & 0x00FF00FF00FF00FFULL;\
669  lo_ = (lo_ | (lo_ << 4)) & 0x0F0F0F0F0F0F0F0FULL;\
670  lo_ = (lo_ | (lo_ << 2)) & 0x3333333333333333ULL;\
671  lo_ = (lo_ | (lo_ << 1)) & 0x5555555555555555ULL;\
672  result_ = (la_ << 1) | lo_;\
673  grn_hton_uint64(result_, result_);\
674  memcpy(keybuf, &result_, sizeof(result_));\
675 } while (0)
676 
677 #define grn_ntog(keybuf,key,size) do {\
678  grn_geo_point *point_ = (grn_geo_point *)keybuf;\
679  uint64_t key_ = *(const uint64_t *)key;\
680  uint64_t la_, lo_;\
681  grn_ntoh_uint64(key_, key_);\
682  la_ = (key_ >> 1) & 0x5555555555555555ULL;\
683  lo_ = key_ & 0x5555555555555555ULL;\
684  la_ = (la_ | (la_ >> 1)) & 0x3333333333333333ULL;\
685  la_ = (la_ | (la_ >> 2)) & 0x0F0F0F0F0F0F0F0FULL;\
686  la_ = (la_ | (la_ >> 4)) & 0x00FF00FF00FF00FFULL;\
687  la_ = (la_ | (la_ >> 8)) & 0x0000FFFF0000FFFFULL;\
688  la_ = (la_ | (la_ >> 16)) & 0x00000000FFFFFFFFULL;\
689  lo_ = (lo_ | (lo_ >> 1)) & 0x3333333333333333ULL;\
690  lo_ = (lo_ | (lo_ >> 2)) & 0x0F0F0F0F0F0F0F0FULL;\
691  lo_ = (lo_ | (lo_ >> 4)) & 0x00FF00FF00FF00FFULL;\
692  lo_ = (lo_ | (lo_ >> 8)) & 0x0000FFFF0000FFFFULL;\
693  lo_ = (lo_ | (lo_ >> 16)) & 0x00000000FFFFFFFFULL;\
694  point_->latitude = la_;\
695  point_->longitude = lo_;\
696 } while (0)
697 
698 #ifndef HAVE_STRTOULL
699 # ifdef HAVE__STRTOUI64
700 # define strtoull(nptr,endptr,base) _strtoui64(nptr,endptr,base)
701 # endif /* HAVE__STRTOUI64 */
702 #endif /* HAVE_STRTOULL */
703 
704 #ifdef USE_FUTEX
705 #include <linux/futex.h>
706 #include <sys/syscall.h>
707 
708 #define GRN_FUTEX_WAIT(p) do {\
709  int err;\
710  struct timespec timeout = {1, 0};\
711  while (1) {\
712  if (!(err = syscall(SYS_futex, p, FUTEX_WAIT, *p, &timeout))) {\
713  break;\
714  }\
715  if (err == ETIMEDOUT) {\
716  GRN_LOG(ctx, GRN_LOG_CRIT, "timeout in GRN_FUTEX_WAIT(%p)", p);\
717  break;\
718  } else if (err != EWOULDBLOCK) {\
719  GRN_LOG(ctx, GRN_LOG_CRIT, "error %d in GRN_FUTEX_WAIT(%p)", err);\
720  break;\
721  }\
722  }\
723 } while(0)
724 
725 #define GRN_FUTEX_WAKE(p) syscall(SYS_futex, p, FUTEX_WAKE, 1)
726 #else /* USE_FUTEX */
727 #define GRN_FUTEX_WAIT(p) grn_nanosleep(1000000)
728 #define GRN_FUTEX_WAKE(p)
729 #endif /* USE_FUTEX */
730 
731 #ifndef HOST_NAME_MAX
732 #ifdef _POSIX_HOST_NAME_MAX
733 #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
734 #else /* POSIX_HOST_NAME_MAX */
735 #define HOST_NAME_MAX 128
736 #endif /* POSIX_HOST_NAME_MAX */
737 #endif /* HOST_NAME_MAX */
738 
739 GRN_API void grn_sleep(uint32_t seconds);
740 GRN_API void grn_nanosleep(uint64_t nanoseconds);
741 
742 #ifndef GROONGA_H
743 #include "groonga.h"
744 #endif /* GROONGA_H */
745 
746 #endif /* GROONGA_IN_H */