summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-01-30 12:12:17 -0800
committerKeith Packard <keithp@keithp.com>2014-01-30 12:12:17 -0800
commit899a945e31aa9cf2da031c1bdbba43df7b43149f (patch)
treeaa2c7d82f213fde50a8d2e079bf18c220813f982
parent8ec3e0a5b1cf9d94c5e1b3d66b979ef9e9019aa8 (diff)
Shared memory pthread sync primitive test
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--Makefile9
-rw-r--r--condtest.c101
2 files changed, 108 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index e77f938..bdfb0cb 100644
--- a/Makefile
+++ b/Makefile
@@ -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);
+}