27 #define __STDC_LIMIT_MACROS
38 #ifdef HAVE_SYS_TYPES_H
39 #include <sys/types.h>
42 #ifdef HAVE_SYS_PARAM_H
43 #include <sys/param.h>
46 #ifdef HAVE_SYS_MMAN_H
50 #ifdef HAVE_SYS_TIME_H
53 #ifdef HAVE_SYS_TIMEB_H
54 #include <sys/timeb.h>
57 #ifdef HAVE_SYS_RESOURCE_H
58 #include <sys/resource.h>
62 # define GRN_API __declspec(dllexport)
64 # define GRN_VAR __declspec(dllimport)
66 # define GRN_VAR __declspec(dllexport) extern
70 # define GRN_VAR extern
74 # define GRN_OPEN(pathname, ...) open(pathname, __VA_ARGS__)
76 # define GRN_OPEN(pathname, ...) _open(pathname, __VA_ARGS__)
80 # define GRN_CLOSE(fd) close(fd)
82 # define GRN_CLOSE(fd) _close(fd)
86 # define GRN_READ(fd, buf, count) read(fd, buf, count)
88 # define GRN_READ(fd, buf, count) _read(fd, buf, count)
92 # define GRN_WRITE(fd, buf, count) write(fd, buf, count)
94 # define GRN_WRITE(fd, buf, count) _write(fd, buf, count)
99 #if defined(__GNUC__) && !defined(WINVER)
101 # define WINVER WindowsXP
106 #include <winsock2.h>
107 #include <ws2tcpip.h>
113 #include <sys/types.h>
116 # define PATH_MAX (MAX_PATH - 1)
118 # define inline _inline
122 #define snprintf(str, size, ...) _snprintf(str, size, __VA_ARGS__)
124 # define vsnprintf(str, size, format, ap) _vsnprintf(str, size, format, ap)
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)
132 #if !defined(strcasecmp)
133 # define strcasecmp(s1, s2) stricmp(s1, s2)
139 #define uint8_t UINT8
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
154 #define MSG_WAITALL 0
155 #define SHUT_RDWR SD_BOTH
158 #define grn_sock_close(sock) closesocket(sock)
160 #define CALLBACK __stdcall
164 #include <sys/timeb.h>
177 # if defined(MAXPATHLEN)
178 # define PATH_MAX MAXPATHLEN
180 # define PATH_MAX 1024
183 # ifndef INT_LEAST8_MAX
186 # ifndef UINT_LEAST8_MAX
190 # define grn_sock_close(sock) close(sock)
196 #define INT8_MAX (127)
200 #define INT8_MIN (-128)
204 #define INT16_MAX (32767)
208 #define INT16_MIN (-32768)
212 #define INT32_MAX (2147483647)
216 #define INT32_MIN (-2147483648)
220 #define UINT32_MAX (4294967295)
224 #define INT64_MAX (9223372036854775807)
228 #define INT64_MIN (-9223372036854775808)
231 #ifdef HAVE_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)
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);\
250 # define MUTEX_INIT_SHARED MUTEX_INIT
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)
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);\
272 # define COND_INIT_SHARED COND_INIT
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)
282 extern int grn_uyield_count;
283 #define GRN_TEST_YIELD() do {\
284 if (((++grn_uyield_count) & (0x20 - 1)) == 0) {\
286 if(grn_uyield_count > 0x1000) {\
287 grn_uyield_count = (uint32_t)time(NULL) % 0x1000;\
293 #define assert(assert_expr) do {\
294 if (!(assert_expr)){\
295 fprintf(stderr, "assertion failed: %s\n", #assert_expr);\
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))
306 #if !defined(_POSIX_PRIORITY_SCHEDULING)
307 #define sched_yield() grn_nanosleep(1000000 * 20)
310 #define GRN_TEST_YIELD() do {} while (0)
317 #define THREAD_KEY_CREATE(key,destr)
318 #define THREAD_KEY_DELETE(key)
319 #define THREAD_SETSPECIFIC(key)
320 #define THREAD_GETSPECIFIC(key,value)
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))
342 HANDLE waiters_count_lock_;
344 HANDLE waiters_done_;
345 size_t was_broadcast_;
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); \
355 #define COND_SIGNAL(c) do { \
356 MUTEX_LOCK((c).waiters_count_lock_); \
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); \
366 #define COND_BROADCAST(c) do { \
367 MUTEX_LOCK((c).waiters_count_lock_); \
369 int have_waiters = (c).waiters_count_ > 0; \
370 if ((c).waiters_count_ > 0) { \
371 (c).was_broadcast_ = 1; \
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; \
381 MUTEX_UNLOCK((c).waiters_count_lock_); \
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_--; \
394 int last_waiter = (c).was_broadcast_ && (c).waiters_count_ == 0; \
395 MUTEX_UNLOCK((c).waiters_count_lock_); \
397 SignalObjectAndWait((c).waiters_done_, (m), INFINITE, FALSE); \
400 WaitForSingleObject((m), FALSE); \
408 #define COND_INIT(c) ((c) = 0)
409 #define COND_SIGNAL(c)
410 #define COND_WAIT(c,m) do { \
412 grn_nanosleep(1000000); \
419 #define MUTEX_INIT_SHARED MUTEX_INIT
420 #define COND_INIT_SHARED COND_INIT
422 #define GRN_TEST_YIELD() do {} while (0)
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"
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"
444 # define GRN_FMT_INT32D "d"
445 # define GRN_FMT_INT32U "u"
447 # define GRN_FMT_INT64D "ld"
448 # define GRN_FMT_INT64U "lu"
450 # define GRN_FMT_INT64D "lld"
451 # define GRN_FMT_INT64U "llu"
453 # define GRN_FMT_LLD "lld"
454 # define GRN_FMT_LLU "llu"
459 # if (defined(__i386__) || defined(__x86_64__))
463 # define GRN_ATOMIC_ADD_EX(p, i, r) \
464 __asm__ __volatile__ ("lock xaddl %0, %1" : "=r"(r), "+m"(*p) : "0"(i))
469 # define GRN_BIT_SCAN_REV(v, r) \
470 __asm__ __volatile__ ("bsrl %1, %%eax; movl %%eax, %0" : "=r"(r) : "r"(v) : "%eax")
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__))
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")
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))
485 # define GRN_ATOMIC_ADD_EX(p,i,r) \
486 (r = atomic_add_32_nv(p, i) - i)
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)
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)
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__)
500 # define GRN_SET_64BIT(p,v) \
502 # elif (defined(__sun) && defined(__SVR4))
504 # define GRN_SET_64BIT(p,v) \
505 (void)atomic_swap_64(p, v)
508 # ifdef HAVE_MKOSTEMP
509 # define GRN_MKOSTEMP(template,flags,mode) mkostemp(template,flags)
511 # define GRN_MKOSTEMP(template,flags,mode) \
512 (mktemp(template), GRN_OPEN((template),flags,mode))
515 #elif (defined(WIN32) || defined (_WIN64))
517 # define GRN_ATOMIC_ADD_EX(p,i,r) \
518 ((r) = (uint32_t)InterlockedExchangeAdd((int32_t *)(p), (int32_t)(i)))
520 # define GRN_SET_64BIT(p,v) \
523 # define GRN_SET_64BIT(p,v) do {\
526 v1 = *(((uint32_t *)&(v))+0);\
527 v2 = *(((uint32_t *)&(v))+1);\
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 \
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)
544 # define GRN_MKOSTEMP(template,flags,mode) \
545 (mktemp(template), GRN_OPEN((template),((flags)|O_BINARY),mode))
549 # if (defined(__sun) && defined(__SVR4))
550 # define __FUNCTION__ ""
552 # define GRN_ATOMIC_ADD_EX(p,i,r) \
553 (r = atomic_add_32_nv(p, i) - i)
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)
558 # define GRN_SET_64BIT(p,v) \
559 (void)atomic_swap_64(p, v)
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)
565 # define GRN_MKOSTEMP(template,flags,mode) \
566 (mktemp(template), GRN_OPEN((template),flags,mode))
572 #define GRN_ID_WIDTH 30
576 grn_str_greater(
const uint8_t *ap, uint32_t as,
const uint8_t *bp, uint32_t bs)
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; }
586 # define grn_str_greater(ap,as,bp,bs)\
587 (((as) > (bs)) ? (memcmp((ap), (bp), (bs)) >= 0) : (memcmp((ap), (bp), (as)) > 0))
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_++; }\
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_--; }\
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_); }\
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_); } \
619 #define grn_ntoh(buf,key,size) grn_hton(buf,key,size)
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))
626 # define __GNUC_PREREQ(maj, min) 0
631 # define grn_bswap_uint64(in, out) ((out) = _byteswap_uint64(in))
633 # if defined(__GNUC__) && __GNUC_PREREQ(4, 3)
634 # define grn_bswap_uint64(in, out) ((out) = __builtin_bswap64(in))
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) |\
650 #ifdef WORDS_BIGENDIAN
651 # define grn_hton_uint64(in, out) ((out) = (in))
653 # define grn_hton_uint64(in, out) grn_bswap_uint64(in, out)
655 #define grn_ntoh_uint64(in, out) grn_hton_uint64(in, out)
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;\
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_));\
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;\
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_;\
698 #ifndef HAVE_STRTOULL
699 # ifdef HAVE__STRTOUI64
700 # define strtoull(nptr,endptr,base) _strtoui64(nptr,endptr,base)
705 #include <linux/futex.h>
706 #include <sys/syscall.h>
708 #define GRN_FUTEX_WAIT(p) do {\
710 struct timespec timeout = {1, 0};\
712 if (!(err = syscall(SYS_futex, p, FUTEX_WAIT, *p, &timeout))) {\
715 if (err == ETIMEDOUT) {\
716 GRN_LOG(ctx, GRN_LOG_CRIT, "timeout in GRN_FUTEX_WAIT(%p)", p);\
718 } else if (err != EWOULDBLOCK) {\
719 GRN_LOG(ctx, GRN_LOG_CRIT, "error %d in GRN_FUTEX_WAIT(%p)", err);\
725 #define GRN_FUTEX_WAKE(p) syscall(SYS_futex, p, FUTEX_WAKE, 1)
727 #define GRN_FUTEX_WAIT(p) grn_nanosleep(1000000)
728 #define GRN_FUTEX_WAKE(p)
731 #ifndef HOST_NAME_MAX
732 #ifdef _POSIX_HOST_NAME_MAX
733 #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
735 #define HOST_NAME_MAX 128