From: Pierre Habouzit Date: Sun, 15 Jan 2012 19:06:25 +0000 (+0100) Subject: Add stupid tests. X-Git-Url: http://git.madism.org/?p=~madcoder%2Fpwqr.git;a=commitdiff_plain;h=98c615b91f0da85c9bd00bbff7a8fd1258400ab9 Add stupid tests. Signed-off-by: Pierre Habouzit --- diff --git a/.gitignore b/.gitignore index 4afe4d5..bc8b55e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ Module.symvers modules.order /Documentation/pwqr.html +/test/test diff --git a/Makefile b/Makefile index 7558a97..e03609c 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ all clean: $(MAKE) -C kernel $@ $(MAKE) -C lib $@ + $(MAKE) -C test $@ .PHONY: all clean diff --git a/kernel/pwqr.c b/kernel/pwqr.c index e5a232e..8248482 100644 --- a/kernel/pwqr.c +++ b/kernel/pwqr.c @@ -192,6 +192,7 @@ static void pwqr_sb_timer_cb(unsigned long arg) wake_up_locked(&sb->wqh); } if (sb->running > sb->concurrency) { + printk(KERN_DEBUG "wake up poll"); wake_up_poll(&sb->wqh_poll, POLLIN); } pwqr_sb_unlock_irqrestore(sb, flags); diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..b008934 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,9 @@ +all: test + +test: test.c + $(CC) -Wall -Werror -Wextra -Wno-unused-parameter -std=gnu99 $(CFLAGS) -O2 -g -lpthread -o $@ $< + +clean: + $(RM) test + +.PHONY: all clean diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..b4f2f67 --- /dev/null +++ b/test/test.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2012 Pierre Habouzit + * Copyright (C) 2012 Intersec SAS + * + * This file is part of the Linux Pthread Workqueue Regulator tests. + * + * The Linux Pthread Workqueue Regulator is free software: you can + * redistribute it and/or modify it under the terms of the GNU Lesser + * General Public License as published by the Free Software Foundation, + * either version 2.1 of the License, or (at your option) any later version. + * + * The Linux Pthread Workqueue Regulator is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The Linux Pthread Workqueue Regultaor. + * If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../kernel/pwqr.h" + +/* pwqr wrapping {{{ */ + +static int pwqr_create(int flags) +{ + if (flags & ~PWQR_FL__SET) { + errno = -EINVAL; + return -1; + } + return open("/dev/"PWQR_DEVICE_NAME, O_RDWR | flags); +} + +static int pwqr_ctl(int fd, int op, int val, void *uaddr) +{ + struct pwqr_ioc_wait wait; + + switch (op) { + case PWQR_CTL_GET_CONC: + case PWQR_CTL_REGISTER: + case PWQR_CTL_UNREGISTER: + case PWQR_CTL_PARK: + return ioctl(fd, op); + case PWQR_CTL_SET_CONC: + case PWQR_CTL_WAKE: + case PWQR_CTL_WAKE_OC: + return ioctl(fd, op, val); + case PWQR_CTL_WAIT: + wait.pwqr_ticket = val; + wait.pwqr_uaddr = uaddr; + return ioctl(fd, op, &wait); + default: + errno = EINVAL; + return -1; + } +} + +/* }}} */ + +static int pwqr_fd_g = -1; +static int pi_g; + +static void *thr_main(void *unused) +{ + if (pwqr_ctl(pwqr_fd_g, PWQR_CTL_REGISTER, 0, NULL) < 0) + err(-1, "pwqr_ctl(PWQR_CTL_REGISTER)"); + + /* busy-loop */ + for (;;) + pthread_testcancel(); + return NULL; +} + +static uint64_t tv_diff(const struct timeval *t1, const struct timeval *t2) +{ + return (t1->tv_sec - t2->tv_sec) * 1000000ULL + t1->tv_usec - t2->tv_usec; +} + +int main(void) +{ + pthread_t tids[32]; + struct pollfd pfd; + struct timeval start, tv; + int rc; + + pwqr_fd_g = pwqr_create(PWQR_FL_NONBLOCK); + if (pwqr_fd_g < 0) + err(-1, "pwqr_create"); + + pi_g = pwqr_ctl(pwqr_fd_g, PWQR_CTL_GET_CONC, 0, NULL); + if (pi_g < 1) + err(-1, "pwqr_ctl(PWQR_CTL_GET_CONC)"); + + for (int i = 0; i < pi_g + 1; i++) { + pthread_create(&tids[i], NULL, thr_main, NULL); + } + + pfd.fd = pwqr_fd_g; + pfd.events = POLLIN; + gettimeofday(&start, NULL); + for (;;) { + pfd.revents = 0; + rc = poll(&pfd, 1, -1); + if (rc < 0) { + warn("poll"); + continue; + } + if (rc == 1) { + if (pfd.revents & POLLIN) { + if (read(pwqr_fd_g, &rc, sizeof(rc)) != sizeof(rc)) { + warn("read"); + } else { + gettimeofday(&tv, NULL); + warnx("[%06jd.%06jd] overcommit of %d", + tv_diff(&tv, &start) / 1000000, + tv_diff(&tv, &start) % 1000000, rc); + } + } + if (pfd.revents & POLLHUP) { + errx(-1, "poll returned POLLHUP"); + } + } + } + + for (int i = 0; i < pi_g + 1; i++) { + pthread_join(tids[i], NULL); + } + return 0; +}