diff --git a/Makefile b/Makefile index f69d6aa..03a172f 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,10 @@ -TROOT=. -include Makefile.inc - - -# build binary in each test dir DIRS = $(sort $(wildcard src/*)) -local: - for i in $(DIRS); do make -C $$i; done -localrun: local - for i in $(DIRS); do $$i/t; done -localclean: - for i in $(DIRS); do make -C $$i clean; done -cleanall: clean localclean +all: + for i in $(DIRS); do echo $$i; make -s -C $$i; done +#t: all +# for i in $(DIRS); do echo $$i; $$i/t; done +b: all + for i in $(DIRS); do echo $$i; $$i/b; done +clean: + for i in $(DIRS); do make -s -C $$i clean; done diff --git a/Makefile.conf.def b/Makefile.conf.def deleted file mode 100644 index 619adf5..0000000 --- a/Makefile.conf.def +++ /dev/null @@ -1,5 +0,0 @@ -# copy to Makefile.conf and edit -usemusl=yes -prefix = /usr/local/musl -includedir = $(prefix)/include -libdir = $(prefix)/lib diff --git a/Makefile.inc b/Makefile.inc index 22f0282..4613e08 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -1,37 +1,22 @@ # gnu makefile -# when included in src/*/Makefile then it builds a binary locally -# when included in ./Makefile then all tests are linked into one binary +# when included in a Makefile it builds *.c unless SRCS are overridden +# default TROOT works from src/*/Makefile TROOT ?= ../.. -ifeq ($(TROOT), .) -SRCS ?= $(sort $(wildcard src/*/*.c)) -else SRCS ?= $(sort $(wildcard *.c)) -endif OBJS = $(SRCS:.c=.o) -usemusl = yes -prefix = /usr/local/musl -includedir = $(prefix)/include -libdir = $(prefix)/lib - AR=ar RANLIB=ranlib CFLAGS += -g -D_POSIX_C_SOURCE=200809L -std=c99 -pipe -Wall LDFLAGS += -g -lpthread -lrt -lm -INC += -I$(TROOT)/common --include $(TROOT)/Makefile.conf +-include $(TROOT)/config.mak + +CFLAGS += -I$(TROOT)/common -ifeq ($(usemusl), yes) -CC=gcc -LIBCC=$(shell gcc -print-file-name=libgcc.a |sed 's,/libgcc.a,,') -#LIBCC=$(shell pcc -v /dev/null 2>&1 |sed -n 's,/crtbegin.o.*,,;s,.* /,/,p') -CFLAGS += -nostdinc -ffreestanding -fno-stack-protector -LDFLAGS += -nostdlib -Wl,-e,_start,-Bstatic $(libdir)/crti.o $(libdir)/crt1.o $(libdir)/crtn.o -L $(libdir) -lc -L $(LIBCC) -l$(CC) -INC += -isystem $(includedir) -endif +all: test test: t b ./t @@ -40,9 +25,9 @@ clean: rm -f $(OBJS) t t_.o b b_.o tests.a tests.h .c.o: - $(CC) $(CFLAGS) $(INC) -c -o $@ $< + $(CC) $(CFLAGS) -c -o $@ $< -$(OBJS): $(TROOT)/common/test.h $(TROOT)/Makefile.conf +$(OBJS): $(TROOT)/common/test.h tests.h: $(OBJS) nm -f posix $+ |awk ' \ @@ -56,15 +41,15 @@ tests.a: $(OBJS) # TODO: /tmp/t.o ? t_.o: $(TROOT)/common/t.c $(TROOT)/common/test.h tests.h - $(CC) $(CFLAGS) $(INC) -I. -c -o $@ $< + $(CC) $(CFLAGS) -I. -c -o $@ $< t: t_.o tests.a $(CC) $+ $(LDFLAGS) -o $@ b_.o: $(TROOT)/common/b.c $(TROOT)/common/test.h tests.h - $(CC) $(CFLAGS) $(INC) -I. -c -o $@ $< + $(CC) $(CFLAGS) -I. -c -o $@ $< b: b_.o tests.a $(CC) $+ $(LDFLAGS) -lrt -o $@ -.PHONY: all clean +.PHONY: all clean test diff --git a/common/b.c b/common/b.c index ee0650d..6fa1963 100644 --- a/common/b.c +++ b/common/b.c @@ -88,7 +88,7 @@ void vmstats() { f = fopen("/proc/self/smaps", "rb"); if (f) while (fgets(buf, sizeof buf, f)) { - if (sscanf(buf, "%*lx-%*lx %*s %*lx %x:%x %*lu %*s", &maj, &min)==2) + if (sscanf(buf, "%*x-%*x %*s %*x %x:%x %*u %*s", &maj, &min)==2) in_heap = (!maj && !min && !strstr(buf, "---p") && (strstr(buf, "[heap]") || !strchr(buf, '['))); if (in_heap) { if (sscanf(buf, "Size: %lu", &l)==1) vm_size += l; diff --git a/common/t.c b/common/t.c index 083e308..ecaaf7f 100644 --- a/common/t.c +++ b/common/t.c @@ -72,7 +72,10 @@ static void run(const char *n, void (*f)()) { } static int summary() { - fprintf(stderr, "PASS:%d FAIL:%d\n", count-nfailed, nfailed); + if (nfailed) + fprintf(stderr, "FAIL:%d (all: %d)\n", nfailed, count); + else + fprintf(stderr, "PASS (all: %d)\n", count); return !!nfailed; } diff --git a/src/env/Makefile b/src/env/Makefile index ee4552b..278e884 100644 --- a/src/env/Makefile +++ b/src/env/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/foo/Makefile b/src/foo/Makefile index ee4552b..278e884 100644 --- a/src/foo/Makefile +++ b/src/foo/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/malloc/Makefile b/src/malloc/Makefile index ee4552b..278e884 100644 --- a/src/malloc/Makefile +++ b/src/malloc/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/misc/Makefile b/src/misc/Makefile index ee4552b..278e884 100644 --- a/src/misc/Makefile +++ b/src/misc/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/multibyte/Makefile b/src/multibyte/Makefile index ee4552b..278e884 100644 --- a/src/multibyte/Makefile +++ b/src/multibyte/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/process/Makefile b/src/process/Makefile index ee4552b..278e884 100644 --- a/src/process/Makefile +++ b/src/process/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/regex/Makefile b/src/regex/Makefile index ee4552b..278e884 100644 --- a/src/regex/Makefile +++ b/src/regex/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/stdio/Makefile b/src/stdio/Makefile index ee4552b..278e884 100644 --- a/src/stdio/Makefile +++ b/src/stdio/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/stdlib/Makefile b/src/stdlib/Makefile index ee4552b..278e884 100644 --- a/src/stdlib/Makefile +++ b/src/stdlib/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c index 872c8f8..6edbc17 100644 --- a/src/stdlib/qsort.c +++ b/src/stdlib/qsort.c @@ -67,7 +67,7 @@ void bench_qsort_small(int N) { void bench_qsort_large(int N) { int i,j; - int len = 100000; + int len = 10000; int *a = malloc(len * sizeof *a); for (i = 0; i < N; i++) { diff --git a/src/stdlib/strtol.c b/src/stdlib/strtol.c index 0656527..7d15542 100644 --- a/src/stdlib/strtol.c +++ b/src/stdlib/strtol.c @@ -39,21 +39,18 @@ void test_strtol(void) { TEST(ul, strtoul(s="4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); TEST2(i, c-s, 10, "wrong final position %d != %d"); TEST2(i, errno, ERANGE, "missing errno %d != %d"); - TEST(ul, strtoul(s="-1", &c, 0), (unsigned long)-1, "bad conversion result: %lu != %lu"); + TEST(ul, strtoul(s="-1", &c, 0), -1UL, "rejected negative %lu != %lu"); TEST2(i, c-s, 2, "wrong final position %d != %d"); - TEST2(i, errno, 0, "no overflow, but errno is %d != %d"); - TEST(ul, strtoul(s="-2", &c, 0), (unsigned long)-2, "bad conversion result: %lu != %lu"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2", &c, 0), -2UL, "rejected negative %lu != %lu"); TEST2(i, c-s, 2, "wrong final position %d != %d"); - TEST2(i, errno, 0, "no overflow, but errno is %d != %d"); - TEST(ul, strtoul(s="-2147483648", &c, 0), (unsigned long)-2147483648, "bad conversion result: %lu != %lu"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu"); TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, 0, "no overflow, but errno is %d != %d"); - TEST(ul, strtoul(s="-2147483649", &c, 0), (unsigned long)-2147483649, "bad conversion result: %lu != %lu"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu"); TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, 0, "no overflow, but errno is %d != %d"); - TEST(ul, strtoul(s="-4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); - TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); } else { TEST(i, 0, 1, "64bit tests not implemented"); } diff --git a/src/stdlib/wcstol.c b/src/stdlib/wcstol.c index c0d49d4..c92fa2d 100644 --- a/src/stdlib/wcstol.c +++ b/src/stdlib/wcstol.c @@ -33,21 +33,18 @@ void test_wcstol(void) { TEST(ul, wcstoul(s=L"4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); TEST2(i, c-s, 10, "wrong final position %d != %d"); TEST2(i, errno, ERANGE, "missing errno %d != %d"); - TEST(ul, wcstoul(s=L"-1", &c, 0), (unsigned long)-1, "bad conversion result: %lu != %lu"); + TEST(ul, wcstoul(s=L"-1", &c, 0), -1UL, "rejected negative %lu != %lu"); TEST2(i, c-s, 2, "wrong final position %d != %d"); - TEST2(i, errno, 0, "no overflow, but errno is %d != %d"); - TEST(ul, wcstoul(s=L"-2", &c, 0), (unsigned long)-2, "bad conversion result: %lu != %lu"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, wcstoul(s=L"-2", &c, 0), -2UL, "rejected negative %lu != %lu"); TEST2(i, c-s, 2, "wrong final position %d != %d"); - TEST2(i, errno, 0, "no overflow, but errno is %d != %d"); - TEST(ul, wcstoul(s=L"-2147483648", &c, 0), (unsigned long)-2147483648, "bad conversion result: %lu != %lu"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, wcstoul(s=L"-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu"); TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, 0, "no overflow, but errno is %d != %d"); - TEST(ul, wcstoul(s=L"-2147483649", &c, 0), (unsigned long)-2147483649, "bad conversion result: %lu != %lu"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, wcstoul(s=L"-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu"); TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, 0, "no overflow, but errno is %d != %d"); - TEST(ul, wcstoul(s=L"-4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); - TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); } else { TEST(i, 0, 1, "64bit tests not implemented"); } diff --git a/src/string/Makefile b/src/string/Makefile index ee4552b..278e884 100644 --- a/src/string/Makefile +++ b/src/string/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/thread/Makefile b/src/thread/Makefile index ee4552b..278e884 100644 --- a/src/thread/Makefile +++ b/src/thread/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc diff --git a/src/thread/pthread.c b/src/thread/pthread.c index ce39a0b..3cc6b84 100644 --- a/src/thread/pthread.c +++ b/src/thread/pthread.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -45,7 +46,7 @@ static void *start2(void *arg) static void *start3(void *arg) { pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); - pthread_barrier_wait(arg); + sem_post(arg); for (;;); return 0; } @@ -71,7 +72,6 @@ static void cleanup4a2(void *arg) static void cleanup4a3(void *arg) { *(int *)arg += 3; - pthread_exit(0); } static void cleanup4a4(void *arg) @@ -118,17 +118,32 @@ static void *start7(void *arg) return 0; } +static void *start8(void *arg) +{ + void **args = arg; + pthread_mutex_t *m = args[1]; + pthread_cond_t *c = args[0]; + int *x = args[2]; + + pthread_mutex_lock(m); + while (*x) pthread_cond_wait(c, m); + pthread_mutex_unlock(m); + + return 0; +} + void test_pthread(void) { - pthread_t td; + pthread_t td, td1, td2, td3; int r; void *res; int foo[4], bar[2]; pthread_barrier_t barrier2; -// pthread_mutexattr_t mtx_a; -// pthread_mutex_t *sh_mtx; -// int fd; + pthread_mutexattr_t mtx_a; + pthread_mutex_t *sh_mtx; + sem_t sem1; + int fd; pthread_mutex_t mtx; pthread_cond_t cond; @@ -136,6 +151,7 @@ void test_pthread(void) alarm(10); TEST(r, pthread_barrier_init(&barrier2, 0, 2), 0, "creating barrier"); + TEST(r, sem_init(&sem1, 0, 0), 0, "creating semaphore"); /* Test basic thread creation and joining */ TEST(r, pthread_create(&td, 0, start1, &res), 0, "failed to create thread"); @@ -162,8 +178,8 @@ void test_pthread(void) TEST(r, pthread_key_delete(k2), 0, "failed to destroy key"); /* Asynchronous cancellation */ - TEST(r, pthread_create(&td, 0, start3, &barrier2), 0, "failed to create thread"); - pthread_barrier_wait(&barrier2); + TEST(r, pthread_create(&td, 0, start3, &sem1), 0, "failed to create thread"); + while (sem_wait(&sem1)); TEST(r, pthread_cancel(td), 0, "canceling"); TEST(r, pthread_join(td, &res), 0, "joining canceled thread"); TEST(res, res, PTHREAD_CANCELED, "canceled thread exit status"); @@ -181,14 +197,13 @@ void test_pthread(void) TEST(r, pthread_create(&td, 0, start4a, foo), 0, "failed to create thread"); TEST(r, pthread_cancel(td), 0, "cancelling"); TEST(r, pthread_join(td, &res), 0, "joining canceled thread"); - TEST(res, res, 0, "canceled thread exit status"); + TEST(res, res, PTHREAD_CANCELED, "canceled thread exit status"); TEST(r, foo[0], 1, "cleanup handler failed to run"); TEST(r, foo[1], 2, "cleanup handler failed to run"); TEST(r, foo[2], 3, "cleanup handler failed to run"); TEST(r, foo[3], 4, "cleanup handler failed to run"); /* Robust mutexes */ -/* TEST(r, pthread_mutexattr_init(&mtx_a), 0, "initializing mutex attr"); TEST(r, pthread_mutexattr_setrobust(&mtx_a, PTHREAD_MUTEX_ROBUST), 0, "setting robust attribute"); TEST(r, pthread_mutex_init(&mtx, &mtx_a), 0, "initializing robust mutex"); @@ -218,7 +233,7 @@ void test_pthread(void) TEST(r, pthread_mutex_consistent(&mtx), 0, "%d != %d"); TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); -*/ + //TEST(r, (fd=open("/dev/zero", O_RDWR))>=0, 1, "opening zero page file"); //TEST(r, @@ -232,4 +247,50 @@ void test_pthread(void) TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); + + /* Condition variables with multiple waiters */ + TEST(r, pthread_mutex_init(&mtx, 0), 0, "%d != %d"); + TEST(r, pthread_cond_init(&cond, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + foo[0] = 1; + TEST(r, pthread_create(&td1, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_create(&td2, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_create(&td3, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + nanosleep(&(struct timespec){.tv_nsec=1000000}, 0); + foo[0] = 0; + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_join(td1, 0), 0, "%d != %d"); + TEST(r, pthread_join(td2, 0), 0, "%d != %d"); + TEST(r, pthread_join(td3, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); + + /* Condition variables with broadcast signals */ + TEST(r, pthread_mutex_init(&mtx, 0), 0, "%d != %d"); + TEST(r, pthread_cond_init(&cond, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + foo[0] = 1; + TEST(r, pthread_create(&td1, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_create(&td2, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_create(&td3, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + nanosleep(&(struct timespec){.tv_nsec=1000000}, 0); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + foo[0] = 0; + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_broadcast(&cond), 0, "%d != %d"); + TEST(r, pthread_join(td1, 0), 0, "%d != %d"); + TEST(r, pthread_join(td2, 0), 0, "%d != %d"); + TEST(r, pthread_join(td3, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); } diff --git a/src/time/Makefile b/src/time/Makefile index ee4552b..278e884 100644 --- a/src/time/Makefile +++ b/src/time/Makefile @@ -1 +1,2 @@ -include ../../Makefile.inc +TROOT=../.. +include $(TROOT)/Makefile.inc