diff options
author | Keith Packard <keithp@keithp.com> | 2014-01-30 12:12:17 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2014-01-30 12:12:17 -0800 |
commit | 899a945e31aa9cf2da031c1bdbba43df7b43149f (patch) | |
tree | aa2c7d82f213fde50a8d2e079bf18c220813f982 | |
parent | 8ec3e0a5b1cf9d94c5e1b3d66b979ef9e9019aa8 (diff) |
Shared memory pthread sync primitive test
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | condtest.c | 101 |
2 files changed, 108 insertions, 2 deletions
@@ -1,7 +1,7 @@ CFLAGS=-Wall -O0 -g $(shell pkg-config --cflags xcb-shm xcb-aux xcb-dri3 xcb-present xshmfence) -LIBS=$(shell pkg-config --libs xcb-shm xcb-aux xcb-dri3 xcb-present xshmfence) +LIBS=$(shell pkg-config --libs xcb-shm xcb-aux xcb-dri3 xcb-present xshmfence xcb-sync xcb-xfixes) -all: shmfd dri3 futex xfence present pipefence shmtest +all: shmfd dri3 futex xfence present pipefence shmtest condtest SHMFD_OBJS=shmfd.o @@ -38,6 +38,11 @@ SHMTEST_OBJS=shmtest.o shmtest: $(SHMTEST_OBJS) $(CC) $(CFLAGS) -o $@ $(SHMTEST_OBJS) +CONDTEST_OBJS=condtest.o + +condtest: $(CONDTEST_OBJS) + $(CC) $(CFLAGS) -o $@ $(CONDTEST_OBJS) -lpthread + clean: rm -f shmfd $(SHMFD_OBJS) rm -f dri3 $(DRI3_OBJS) diff --git a/condtest.c b/condtest.c new file mode 100644 index 0000000..4b8b868 --- /dev/null +++ b/condtest.c @@ -0,0 +1,101 @@ +#include <stdint.h> +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <sys/time.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <values.h> +#include <pthread.h> + +struct xshmfence { + pthread_mutex_t lock; + pthread_cond_t cond; + int value; +}; + +struct xshmfence * +map_shm(int fd) +{ + struct xshmfence *addr; + addr = mmap (NULL, sizeof (struct xshmfence) , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + close (fd); + return 0; + } + return addr; +} + +void +unmap_shm(struct xshmfence *f) +{ + munmap(f, sizeof (struct xshmfence)); +} + +int +alloc_shm(void) +{ + char template[] = "/run/shm/shmfd-XXXXXX"; + int fd; + struct xshmfence *f; + pthread_condattr_t attr; + +#ifdef O_TMPFILE + fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666); + if (fd < 0) +#endif + { + fd = mkstemp(template); + if (fd < 0) + return fd; + unlink(template); + } + ftruncate(fd, sizeof (struct xshmfence)); + f = map_shm(fd); + pthread_condattr_init(&attr); + pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_cond_init(&f->cond, &attr); + return fd; +} + +void * +thread(void *arg) +{ + int *fdp = arg; + int fd = *fdp; + struct xshmfence *f = map_shm(fd); + + printf ("thread starting\n"); + pthread_mutex_lock(&f->lock); + pthread_cond_wait(&f->cond, &f->lock); + pthread_mutex_unlock(&f->lock); + printf ("thread done\n"); + pthread_exit(0); +} + +int +main(int argc, char **argv) +{ + pthread_t child; + void *ret; + int fd; + struct xshmfence *f; + + fd = alloc_shm(); + pthread_create (&child, NULL, thread, &fd); + + f = map_shm(fd); + sleep(1); + printf ("parent starting\n"); + pthread_mutex_lock(&f->lock); + pthread_cond_broadcast(&f->cond); + printf ("parent done\n"); + pthread_mutex_unlock(&f->lock); + pthread_join(child, &ret); + printf ("finished\n"); + exit(0); +} |