summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Antipov <dmitry.antipov@linaro.org>2013-01-31 15:05:18 +0400
committerDmitry Antipov <dmitry.antipov@linaro.org>2013-01-31 15:05:18 +0400
commitd75c0fbc152135bfbee969bbbdf5fe83e8bf134c (patch)
tree8142f17c15a175f57bf581fe8a6973e410056c67
parente83f776840320022f38405ad8acc90110221d731 (diff)
downloadlinaro-android-kernel-test-d75c0fbc152135bfbee969bbbdf5fe83e8bf134c.tar.gz
Initial commit of the sync framework test.
-rw-r--r--product.mk3
-rw-r--r--sync-basic/Android.mk8
-rw-r--r--sync-basic/Makefile10
-rw-r--r--sync-basic/sync-basic.c329
4 files changed, 349 insertions, 1 deletions
diff --git a/product.mk b/product.mk
index 2f1f104..5d216cd 100644
--- a/product.mk
+++ b/product.mk
@@ -1,5 +1,6 @@
PRODUCT_PACKAGES += ashmemtest \
- ashmemtest-expanded
+ ashmemtest-expanded \
+ sync-basic
PRODUCT_COPY_FILES += \
external/linaro-android-kernel-test/ashmemtest-expanded/test0.txt:data/linaro-android-kernel-test/ashmemtest-expanded/test0.txt \
diff --git a/sync-basic/Android.mk b/sync-basic/Android.mk
new file mode 100644
index 0000000..5a436b6
--- /dev/null
+++ b/sync-basic/Android.mk
@@ -0,0 +1,8 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := sync-basic.c
+LOCAL_MODULE := sync-basic
+LOCAL_MODULE_TAGS := optional tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/sync-basic/Makefile b/sync-basic/Makefile
new file mode 100644
index 0000000..b51d5d0
--- /dev/null
+++ b/sync-basic/Makefile
@@ -0,0 +1,10 @@
+CROSS_COMPILE =
+KDIR = /home/dima/work/linaro/linux.git
+CC = $(CROSS_COMPILE)gcc
+CFLAGS = -O2 -g
+
+sync-basic: sync-basic.c
+ $(CC) $(CFLAGS) -I$(KDIR)/drivers/staging/android -o $@ $<
+
+clean:
+ $(RM) sync-basic
diff --git a/sync-basic/sync-basic.c b/sync-basic/sync-basic.c
new file mode 100644
index 0000000..47b0960
--- /dev/null
+++ b/sync-basic/sync-basic.c
@@ -0,0 +1,329 @@
+/* sync framework test */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef ANDROID
+/* kernel headers on android */
+#include <linux/sync.h>
+#include <linux/sw_sync.h>
+#else
+/* set KDIR in Makefile to point to these headers */
+#include "sync.h"
+#include "sw_sync.h"
+#endif /* ANDROID */
+
+#define SW_SYNC_DEV "/dev/sw_sync"
+
+/* current test run */
+int testno = -1;
+char testname[32];
+
+/* fd of SW_SYNC_DEV */
+int sw_fd;
+
+void fatal (int error, const char *fmt, ...)
+{
+ va_list ap;
+
+ fprintf (stderr, "Test %d: ", testno);
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ if (error)
+ fprintf (stderr, " (error %d [%s])", error, strerror (error));
+ va_end (ap);
+ fprintf (stderr, "\n");
+ printf ("%d [%s]: test failed\n", testno, testname);
+ exit (1);
+}
+
+void create_and_delete_fence (void)
+{
+ struct sw_sync_create_fence_data f;
+ int ret;
+
+ testno++;
+ strcpy (testname, __func__);
+
+ strncpy (f.name, "test fence 0", sizeof (f.name));
+ f.value = 0;
+
+ ret = ioctl (sw_fd, SW_SYNC_IOC_CREATE_FENCE, &f);
+ if (ret < 0)
+ fatal (errno, "can't create fence");
+ ret = close (f.fence);
+ if (ret < 0)
+ fatal (errno, "can't delete fence");
+
+ printf ("%d [%s]: test passed\n", testno, __func__);
+}
+
+void create_fence_invalid (void)
+{
+ struct sw_sync_create_fence_data *f = (void *)0xdeaddead;
+ int ret;
+
+ testno++;
+ strcpy (testname, __func__);
+
+ ret = ioctl (sw_fd, SW_SYNC_IOC_CREATE_FENCE, f);
+ if (ret >= 0 || errno != EFAULT)
+ fatal (0, "expect -1 and EFAULT, but got %d and %d", ret, errno);
+
+ printf ("%d [%s]: test passed\n", testno, __func__);
+}
+
+#define TOOMANY 100000 /* should be larger than max fds per process */
+
+void create_many_fences (void)
+{
+ struct sw_sync_create_fence_data f;
+ static int fencefds[TOOMANY];
+ int ret, nr, i;
+
+ testno++;
+ strcpy (testname, __func__);
+
+ for (nr = 0; nr < TOOMANY; nr++) {
+ sprintf (f.name, "fence %d", nr);
+ f.value = nr;
+ ret = ioctl (sw_fd, SW_SYNC_IOC_CREATE_FENCE, &f);
+ if (ret < 0)
+ break;
+ else
+ fencefds[nr] = f.fence;
+ }
+
+ if (errno != EMFILE)
+ fatal (0, "expect EMFILE but got %d", errno);
+
+ for (i = 0; i < nr; i++) {
+ ret = close (fencefds[i]);
+ if (ret < 0)
+ fatal (errno, "error closing fence %d of %d", i, nr);
+ }
+
+ printf ("%d [%s]: test passed (%d fences was used)\n", testno, __func__, nr);
+}
+
+void fence_info (void)
+{
+ struct sw_sync_create_fence_data f;
+ struct sync_fence_info_data *d;
+ int ret;
+
+ testno++;
+ strcpy (testname, __func__);
+
+ strncpy (f.name, "test fence 1", sizeof (f.name));
+ f.value = 0;
+
+ ret = ioctl (sw_fd, SW_SYNC_IOC_CREATE_FENCE, &f);
+ if (ret < 0)
+ fatal (errno, "can't create fence");
+
+ d = malloc (128);
+ if (!d)
+ abort ();
+ d->len = 128;
+ ret = ioctl (f.fence, SYNC_IOC_FENCE_INFO, d);
+ if (ret < 0)
+ fatal (errno, "can't get fence %d info", f.fence);
+
+ if (strcmp (d->name, "test fence 1"))
+ fatal (0, "invalid fence name");
+ if (d->status != 1)
+ fatal (0, "invalid fence status");
+
+ free (d);
+ ret = close (f.fence);
+ if (ret < 0)
+ fatal (errno, "can't delete fence");
+
+ printf ("%d [%s]: test passed\n", testno, __func__);
+}
+
+void fence_info_invalid (void)
+{
+ struct sync_fence_info_data *d;
+ int ret;
+
+ testno++;
+ strcpy (testname, __func__);
+
+ d = malloc (128);
+ if (!d)
+ abort ();
+ d->len = 128;
+
+ ret = ioctl (fileno (stdout), SYNC_IOC_FENCE_INFO, d);
+ if (ret >= 0 || errno != ENOTTY)
+ fatal (0, "expect -1 and ENOTTY, but got %d and %d", ret, errno);
+
+ free (d);
+
+ printf ("%d [%s]: test passed\n", testno, __func__);
+}
+
+void fence_merge (void)
+{
+ struct sw_sync_create_fence_data f1, f2;
+ struct sync_merge_data f3;
+ struct sync_fence_info_data *d;
+ int ret;
+
+ testno++;
+ strcpy (testname, __func__);
+
+ strncpy (f1.name, "test fence 1", sizeof (f1.name));
+ f1.value = 1;
+ ret = ioctl (sw_fd, SW_SYNC_IOC_CREATE_FENCE, &f1);
+ if (ret < 0)
+ fatal (errno, "can't create fence 1");
+
+ strncpy (f2.name, "test fence 2", sizeof (f2.name));
+ f2.value = 2;
+ ret = ioctl (sw_fd, SW_SYNC_IOC_CREATE_FENCE, &f2);
+ if (ret < 0)
+ fatal (errno, "can't create fence 2");
+
+ f3.fd2 = f2.fence;
+ strncpy (f3.name, "merged fence 1 + 2", sizeof (f3.name));
+ ret = ioctl (f1.fence, SYNC_IOC_MERGE, &f3);
+ if (ret < 0)
+ fatal (errno, "can't merge fences");
+
+ d = malloc (128);
+ if (!d)
+ abort ();
+ d->len = 128;
+ ret = ioctl (f3.fence, SYNC_IOC_FENCE_INFO, d);
+ if (ret < 0)
+ fatal (errno, "can't get information about merged fence");
+ if (strcmp (d->name, "merged fence 1 + 2"))
+ fatal (0, "invalid merged fence name");
+ free (d);
+
+ if (f1.fence == f2.fence ||
+ f2.fence == f3.fence ||
+ f3.fence == f1.fence)
+ fatal (0, "impossible fence fds: %d %d %d", f1.fence, f2.fence, f3.fence);
+
+ ret = close (f3.fence);
+ if (ret < 0)
+ fatal (errno, "can't close merged fence");
+ ret = close (f2.fence);
+ if (ret < 0)
+ fatal (errno, "can't close fence 2");
+ ret = close (f1.fence);
+ if (ret < 0)
+ fatal (errno, "can't close fence 1");
+
+ printf ("%d [%s]: test passed\n", testno, __func__);
+}
+
+void fence_merge_itself (void)
+{
+ struct sw_sync_create_fence_data f1;
+ struct sync_merge_data f2;
+ int ret;
+
+ testno++;
+ strcpy (testname, __func__);
+
+ strncpy (f1.name, "test fence 1", sizeof (f1.name));
+ f1.value = 1;
+ ret = ioctl (sw_fd, SW_SYNC_IOC_CREATE_FENCE, &f1);
+ if (ret < 0)
+ fatal (errno, "can't create fence 1");
+
+ f2.fd2 = f1.fence;
+ strncpy (f2.name, "copy of fence 1", sizeof (f2.name));
+ ret = ioctl (f1.fence, SYNC_IOC_MERGE, &f2);
+ if (ret < 0)
+ fatal (errno, "can't merge fence with itself");
+
+ ret = close (f2.fence);
+ if (ret < 0)
+ fatal (errno, "can't close copy fence");
+ ret = close (f1.fence);
+ if (ret < 0)
+ fatal (errno, "can't close fence 1");
+
+ printf ("%d [%s]: test passed\n", testno, __func__);
+}
+
+void fence_merge_invalid (void)
+{
+ struct sw_sync_create_fence_data f1;
+ struct sync_merge_data f2;
+ int ret;
+
+ testno++;
+ strcpy (testname, __func__);
+
+ strncpy (f1.name, "test fence 1", sizeof (f1.name));
+ f1.value = 1;
+ ret = ioctl (sw_fd, SW_SYNC_IOC_CREATE_FENCE, &f1);
+ if (ret < 0)
+ fatal (errno, "can't create fence 1");
+
+ f2.fd2 = fileno (stdout);
+ strncpy (f2.name, "impossible fence 2", sizeof (f2.name));
+ ret = ioctl (f1.fence, SYNC_IOC_MERGE, &f2);
+
+ if (ret >= 0 || errno != ENOENT)
+ fatal (0, "expect -1 and ENOENT, but got %d and %d", ret, errno);
+
+ ret = close (f1.fence);
+ if (ret < 0)
+ fatal (errno, "can't close fence 1");
+
+ printf ("%d [%s]: test passed\n", testno, __func__);
+}
+
+int main (int argc, char *argv[])
+{
+ /* 0 - just try to open */
+ testno++;
+ strcpy (testname, __func__);
+
+ sw_fd = open (SW_SYNC_DEV, O_RDWR);
+ if (sw_fd < 0)
+ fatal (errno, "can't open '%s'", SW_SYNC_DEV);
+ printf ("%d [%s]: test passed\n", testno, __func__);
+
+ /* 1 - create and delete just one fence */
+ create_and_delete_fence ();
+
+ /* 2 - try to create fence fron invalid data */
+ create_fence_invalid ();
+
+ /* 3 - try to create as much as possible */
+ create_many_fences ();
+
+ /* 4 - basic fence info */
+ fence_info ();
+
+ /* 5 - invalid fence info */
+ fence_info_invalid ();
+
+ /* 6 - basic merge */
+ fence_merge ();
+
+ /* 7 - merge with itself (e.g. copy) */
+ fence_merge_itself ();
+
+ /* 8 - merge with invalid fence */
+ fence_merge_invalid ();
+
+ close (sw_fd);
+ return 0;
+}