FreeBSD Bugzilla – Attachment 155764 Details for
Bug 199557
Hang on sysconf(_SC_OPEN_MAX)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
The test source.
test.c (text/plain), 7.59 KB, created by
Ivan Kosarev
on 2015-04-20 10:55:16 UTC
(
hide
)
Description:
The test source.
Filename:
MIME Type:
Creator:
Ivan Kosarev
Created:
2015-04-20 10:55:16 UTC
Size:
7.59 KB
patch
obsolete
> >#include <assert.h> >#include <string.h> >#include <stdarg.h> >#include <errno.h> >#include <stdint.h> > >#include <pthread.h> >#include <unistd.h> >#include <fcntl.h> >#include <sys/syscall.h> >#include <sys/types.h> >#include <sys/mman.h> > >extern "C" { >#include <sys/umtx.h> >} > > >#define INLINE inline >#define UNLIKELY(x) __builtin_expect(!!(x), 0) >#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) >typedef int fd_t; >typedef uint64_t uptr; >typedef int64_t sptr; >typedef uint64_t u64; >typedef int64_t s64; >typedef uint32_t u32; >typedef uint8_t u8; > >#define CHECK_IMPL(c1, op, c2) \ > do { \ > u64 v1 = (u64)(c1); \ > u64 v2 = (u64)(c2); \ > if (UNLIKELY(!(v1 op v2))) \ > assert(0); \ > } while (false) \ >/**/ > >#define CHECK(a) CHECK_IMPL((a), !=, 0) >#define CHECK_EQ(a, b) CHECK_IMPL((a), ==, (b)) >#define CHECK_NE(a, b) CHECK_IMPL((a), !=, (b)) >#define CHECK_LT(a, b) CHECK_IMPL((a), <, (b)) >#define CHECK_LE(a, b) CHECK_IMPL((a), <=, (b)) >#define CHECK_GT(a, b) CHECK_IMPL((a), >, (b)) >#define CHECK_GE(a, b) CHECK_IMPL((a), >=, (b)) > >#define DCHECK(a) >#define DCHECK_EQ(a, b) >#define DCHECK_NE(a, b) >#define DCHECK_LT(a, b) >#define DCHECK_LE(a, b) >#define DCHECK_GT(a, b) >#define DCHECK_GE(a, b) > >enum memory_order { > memory_order_relaxed = 1 << 0, > memory_order_consume = 1 << 1, > memory_order_acquire = 1 << 2, > memory_order_release = 1 << 3, > memory_order_acq_rel = 1 << 4, > memory_order_seq_cst = 1 << 5 >}; > >struct atomic_uint8_t { > typedef u8 Type; > volatile Type val_dont_use; >}; > >struct atomic_uintptr_t { > typedef uptr Type; > volatile Type val_dont_use; >}; > >template<typename T> >INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) { > DCHECK(mo & (memory_order_relaxed | memory_order_release > | memory_order_seq_cst)); > DCHECK(!((uptr)a % sizeof(*a))); > > if (sizeof(*a) < 8 || sizeof(void*) == 8) { > // Assume that aligned loads are atomic. > if (mo == memory_order_relaxed) { > a->val_dont_use = v; > } else if (mo == memory_order_release) { > // On x86 stores are implicitly release. > __asm__ __volatile__("" ::: "memory"); > a->val_dont_use = v; > __asm__ __volatile__("" ::: "memory"); > } else { // seq_cst > // On x86 stores are implicitly release. > __asm__ __volatile__("" ::: "memory"); > a->val_dont_use = v; > __sync_synchronize(); > } > } else { > // 64-bit store on 32-bit platform. > __asm__ __volatile__( > "movq %1, %%mm0;" // Use mmx reg for 64-bit atomic moves > "movq %%mm0, %0;" > "emms;" // Empty mmx state/Reset FP regs > : "=m" (a->val_dont_use) > : "m" (v) > : // mark the FP stack and mmx registers as clobbered > "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", >#ifdef __MMX__ > "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", >#endif // #ifdef __MMX__ > "memory"); > if (mo == memory_order_seq_cst) > __sync_synchronize(); > } >} > >template<typename T> >INLINE typename T::Type atomic_load( > const volatile T *a, memory_order mo) { > DCHECK(mo & (memory_order_relaxed | memory_order_consume > | memory_order_acquire | memory_order_seq_cst)); > DCHECK(!((uptr)a % sizeof(*a))); > typename T::Type v; > > if (sizeof(*a) < 8 || sizeof(void*) == 8) { > // Assume that aligned loads are atomic. > if (mo == memory_order_relaxed) { > v = a->val_dont_use; > } else if (mo == memory_order_consume) { > // Assume that processor respects data dependencies > // (and that compiler won't break them). > __asm__ __volatile__("" ::: "memory"); > v = a->val_dont_use; > __asm__ __volatile__("" ::: "memory"); > } else if (mo == memory_order_acquire) { > __asm__ __volatile__("" ::: "memory"); > v = a->val_dont_use; > // On x86 loads are implicitly acquire. > __asm__ __volatile__("" ::: "memory"); > } else { // seq_cst > // On x86 plain MOV is enough for seq_cst store. > __asm__ __volatile__("" ::: "memory"); > v = a->val_dont_use; > __asm__ __volatile__("" ::: "memory"); > } > } else { > // 64-bit load on 32-bit platform. > __asm__ __volatile__( > "movq %1, %%mm0;" // Use mmx reg for 64-bit atomic moves > "movq %%mm0, %0;" // (ptr could be read-only) > "emms;" // Empty mmx state/Reset FP regs > : "=m" (v) > : "m" (a->val_dont_use) > : // mark the FP stack and mmx registers as clobbered > "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", >#ifdef __MMX__ > "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", >#endif // #ifdef __MMX__ > "memory"); > } > return v; >} > >///////////////////////////////////////////////////////////////////////// > >#define ZZ_SYSCALL(name) SYS_ ## name >#define internal_syscall __syscall > >#define ZZ_HANDLE_EINTR(res, f) \ > ((res) = (f)) > >uptr zz_internal_write(fd_t fd, const void *buf, uptr count) { > sptr res; > ZZ_HANDLE_EINTR(res, (sptr)internal_syscall(ZZ_SYSCALL(write), fd, (uptr)buf, > count)); > return res; >} > >uptr zz_internal_strlen(const char *s) { > uptr i = 0; > while (s[i]) i++; > return i; >} > >void zz_RawWrite(const char *buffer) { > uptr length = zz_internal_strlen(buffer); > if (length != zz_internal_write(2, buffer, length)) { > assert(0); > } >} > >static void zz_AppendChar(char **buff, const char *buff_end, char c) { > if (*buff < buff_end) { > **buff = c; > (*buff)++; > } >} > >void zz_VSNPrintf(char *buff, int buff_length, > const char *format, va_list args) { > assert(format); > assert(buff_length > 0); > const char *buff_end = &buff[buff_length - 1]; > const char *cur = format; > for (; *cur; cur++) { > zz_AppendChar(&buff, buff_end, *cur); > } > assert(buff <= buff_end); > zz_AppendChar(&buff, buff_end + 1, '\0'); >} > >void zz_Printf(const char *format, ...) { > va_list args; > va_start(args, format); > > char local_buffer[400]; > int buffer_size = ARRAY_SIZE(local_buffer); > zz_VSNPrintf(local_buffer, sizeof(local_buffer), format, args); > zz_RawWrite(local_buffer); > > va_end(args); >} > >void zz_sysconf(const char *file, int line) >{ > zz_Printf("before sysconf()\n"); > sysconf(_SC_OPEN_MAX); > zz_Printf("after sysconf()\n\n"); >} > >extern "C" __pid_t __sys_fork(void); > >void zz_fork(const char *file, int line) >{ > int pid = __syscall(SYS_fork); > // int pid = __sys_fork(); // doesn't work either > // int pid = fork(); // does work > > if(pid == 0) { > zz_sysconf(file, line); > _exit(1); > } > int pid_status; > __syscall(SYS_wait4, pid, &pid_status, 0, (struct rusage*)0); >} > >struct ThreadParam { > atomic_uintptr_t tid; >}; > >extern "C" void *__tsan_thread_start_func(void *arg) { > ThreadParam *p = (ThreadParam*)arg; > int tid; > while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0) > pthread_yield(); > > return 0; >} > >extern "C" int zz_pthread_create(void *th, void *attr, > void *(*callback)(void*), void * param) { > ThreadParam p; > atomic_store(&p.tid, 0, memory_order_relaxed); > int res = pthread_create((pthread_t*)th, 0, __tsan_thread_start_func, (void*)&p); > CHECK_EQ(res, 0); > > atomic_store(&p.tid, 1, memory_order_release); > > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > zz_fork(__FILE__, __LINE__); > > return 0; >} > >void *Thread(void *x) { > return NULL; >} > >int main() { > pthread_t t; > zz_pthread_create(&t, NULL, Thread, NULL); >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 199557
: 155764