From d75c0fbc152135bfbee969bbbdf5fe83e8bf134c Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 31 Jan 2013 15:05:18 +0400 Subject: Initial commit of the sync framework test. --- product.mk | 3 +- sync-basic/Android.mk | 8 ++ sync-basic/Makefile | 10 ++ sync-basic/sync-basic.c | 329 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 sync-basic/Android.mk create mode 100644 sync-basic/Makefile create mode 100644 sync-basic/sync-basic.c 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ANDROID +/* kernel headers on android */ +#include +#include +#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; +} -- cgit v1.2.3