FreeBSD Bugzilla – Attachment 233787 Details for
Bug 263825
umtx: Sporadic hang in glibc test case in Linuxulator's signal trampoline code on arm64 (passes on amd64)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
test
tst-cond25.c (text/plain), 5.73 KB, created by
Dmitry Chagin
on 2022-05-07 11:13:07 UTC
(
hide
)
Description:
test
Filename:
MIME Type:
Creator:
Dmitry Chagin
Created:
2022-05-07 11:13:07 UTC
Size:
5.73 KB
patch
obsolete
>/* glibc nptl tests */ >#include <pthread.h> >#include <stdio.h> >#include <stdlib.h> >#include <stdint.h> >#include <string.h> >#include <errno.h> >#include <sys/types.h> >#include <sys/syscall.h> >#include <unistd.h> >#include <sys/time.h> >#include <time.h> > >#define NUM 15 >#define ITERS 10000 >#define COUNT 10 > >typedef void *(*thr_func)(void *); > >pthread_mutex_t mutex; >pthread_cond_t cond; > >void >cleanup(void *u) >{ > int ret; > int seq = (uintptr_t) u; > > ret = pthread_mutex_trylock(&mutex); > > if (ret != EDEADLK && ret != EBUSY) { > printf("mutex not locked in cleanup %d\n", ret); > abort(); > } > if (pthread_mutex_unlock(&mutex)) { > printf("mutex not unlocked in cleanup %d\n", ret); > abort(); > } >} > >void * >signaller(void *u) >{ > int i, ret = 0; > void *tret = NULL; > int seq = (uintptr_t) u; > > for (i = 0; i < ITERS; i++) { > if ((ret = pthread_mutex_lock(&mutex)) != 0) { > tret = (void *)1; > printf("signaller:mutex_lock failed: %s\n", strerror(ret)); > goto out; > } > if ((ret = pthread_cond_signal(&cond)) != 0) { > tret = (void *)1; > printf("signaller:signal failed: %s\n", strerror(ret)); > goto unlock_out; > } > if ((ret = pthread_mutex_unlock(&mutex)) != 0) { > tret = (void *)1; > printf("signaller:mutex_unlock failed: %s\n", strerror(ret)); > goto out; > } > pthread_testcancel(); > } > >out: > return (tret); > >unlock_out: > if ((ret = pthread_mutex_unlock(&mutex)) != 0) > printf("signaller:mutex_unlock[2] failed: %s\n", strerror(ret)); > goto out; >} > >void * >waiter(void *u) >{ > int i = 0, ret = 0; > void *tret = NULL; > int seq = (uintptr_t) u; > pthread_t id = pthread_self(); > > for (i = 0; i < ITERS / NUM; i++) { > if ((ret = pthread_mutex_lock(&mutex)) != 0) { > tret = (void *) (uintptr_t) 1; > printf("waiter[%u]:mutex_lock failed: %s\n", seq, strerror(ret)); > goto out; > } > > pthread_cleanup_push(cleanup, (void *) (uintptr_t) seq); > > if ((ret = pthread_cond_wait(&cond, &mutex)) != 0) { > tret = (void *) (uintptr_t) 1; > printf("waiter[%u]:wait failed: %s\n", seq, strerror(ret)); > goto unlock_out; > } > if ((ret = pthread_mutex_unlock(&mutex)) != 0) { > tret = (void *) (uintptr_t) 1; > printf("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror(ret)); > goto out; > } > pthread_cleanup_pop(0); > } > >out: > printf("waiter[%u] cond_wait done\n", seq); > return (tret); > >unlock_out: > if ((ret = pthread_mutex_unlock(&mutex)) != 0) > printf("waiter:mutex_unlock[2] failed: %s\n", strerror(ret)); > goto out; >} > >void * >timed_waiter(void *u) >{ > int i = 0, ret; > void *tret = NULL; > int seq = (uintptr_t) u; > pthread_t id = pthread_self(); > > for (i = 0; i < ITERS / NUM; i++) { > struct timespec ts; > if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) != 0) { > tret = (void *) (uintptr_t) 1; > printf("%u:clock_gettime failed: %s\n", seq, strerror(errno)); > goto out; > } > ts.tv_sec += 20; > > if ((ret = pthread_mutex_lock(&mutex)) != 0) { > tret = (void *) (uintptr_t) 1; > printf("waiter[%u]:mutex_lock failed: %s\n", seq, strerror(ret)); > goto out; > } > > pthread_cleanup_push(cleanup, NULL); > > /* We should not time out either. */ > if ((ret = pthread_cond_timedwait(&cond, &mutex, &ts)) != 0) { > tret = (void *) (uintptr_t) 1; > printf("waiter[%u]:timedwait failed: %s\n", seq, strerror(ret)); > goto unlock_out; > } > if ((ret = pthread_mutex_unlock(&mutex)) != 0) { > tret = (void *) (uintptr_t) 1; > printf("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror(ret)); > goto out; > } > pthread_cleanup_pop(0); > } > >out: > printf("timed_waiter[%u] cond_wait done\n", seq); > return (tret); > >unlock_out: > if ((ret = pthread_mutex_unlock(&mutex)) != 0) > printf("waiter[%u]:mutex_unlock[2] failed: %s\n", seq, strerror(ret)); > goto out; >} > >int >do_test_wait(thr_func f) >{ > pthread_t w[NUM], s; > pthread_mutexattr_t attr; > int i, j, ret = 0; > void *thr_ret; > > for (i = 0; i < COUNT; i++) { > printf("do_test_wait: iter %d\n", i); > > if ((ret = pthread_mutexattr_init(&attr)) != 0) { > printf("mutexattr_init failed: %s\n", strerror(ret)); > goto out; > } > if ((ret = pthread_mutexattr_setprotocol(&attr, > PTHREAD_PRIO_INHERIT)) != 0) { > printf("mutexattr_setprotocol failed: %s\n", strerror(ret)); > goto out; > } > if ((ret = pthread_cond_init(&cond, NULL)) != 0) { > printf("cond_init failed: %s\n", strerror(ret)); > goto out; > } > if ((ret = pthread_mutex_init(&mutex, &attr)) != 0) { > printf("mutex_init failed: %s\n", strerror(ret)); > goto out; > } > for (j = 0; j < NUM; j++) { > if ((ret = pthread_create(&w[j], NULL, > f, (void *) (uintptr_t) j)) != 0) { > printf("waiter[%d]: create failed: %s\n", j, strerror(ret)); > goto out; > } > } > if ((ret = pthread_create(&s, NULL, signaller, (void *) (uintptr_t) i)) != 0) { > printf("signaller: create failed: %s\n", strerror(ret)); > goto out; > } > > for (j = 0; j < NUM; j++) { > pthread_cancel(w[j]); > if ((ret = pthread_join(w[j], &thr_ret)) != 0) { > printf("waiter[%d]: join failed: %s\n", j, strerror(ret)); > goto out; > } > if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED) { > printf("waiter[%d]: cancel failed: %s\n", j, strerror(ret)); > ret = 1; > goto out; > } > } > > /* The signalling thread could have ended before it was cancelled. */ > pthread_cancel(s); > > if ((ret = pthread_join(s, &thr_ret)) != 0) { > printf("signaller: join failed: %s\n", strerror(ret)); > goto out; > } > if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED) { > printf("signaller[%d]: cancel failed: %s\n", i, strerror(ret)); > ret = 1; > goto out; > } > if ((ret = pthread_cond_destroy(&cond)) != 0) { > printf("cond_destroy failed: %s\n", strerror(ret)); > goto out; > } > } > >out: > return (ret); >} > >int >main(int argc, char **argv) >{ > int ret; > > ret = do_test_wait(waiter); > printf("first ret: %d\n", ret); > if (ret) > return (ret); > > ret = do_test_wait(timed_waiter); > printf("second ret: %d\n", ret); > return (ret); >}
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 263825
: 233787