2 * Copyright (C) 2012 Pierre Habouzit <pierre.habouzit@intersec.com>
3 * Copyright (C) 2012 Intersec SAS
5 * This file is part of the Linux Pthread Workqueue Regulator tests.
7 * The Linux Pthread Workqueue Regulator is free software: you can
8 * redistribute it and/or modify it under the terms of the GNU Lesser
9 * General Public License as published by the Free Software Foundation,
10 * either version 2.1 of the License, or (at your option) any later version.
12 * The Linux Pthread Workqueue Regulator is distributed in the hope that it
13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with The Linux Pthread Workqueue Regultaor.
19 * If not, see <http://www.gnu.org/licenses/>.
31 #include <sys/ioctl.h>
34 #include <sys/types.h>
37 #include "../kernel/pwqr.h"
39 /* pwqr wrapping {{{ */
41 static int pwqr_create(int flags)
43 if (flags & ~PWQR_FL__SET) {
47 return open("/dev/"PWQR_DEVICE_NAME, O_RDWR | flags);
50 static int pwqr_ctl(int fd, int op, int val, void *uaddr)
52 struct pwqr_ioc_wait wait;
55 case PWQR_CTL_GET_CONC:
56 case PWQR_CTL_REGISTER:
57 case PWQR_CTL_UNREGISTER:
60 case PWQR_CTL_SET_CONC:
62 case PWQR_CTL_WAKE_OC:
63 return ioctl(fd, op, val);
65 wait.pwqr_ticket = val;
66 wait.pwqr_uaddr = uaddr;
67 return ioctl(fd, op, &wait);
76 static int pwqr_fd_g = -1;
80 #define trace(fmt, ...) fprintf(stderr, fmt"\n", ##__VA_ARGS__)
82 static void *thr_main(void *_who)
86 if (pwqr_ctl(pwqr_fd_g, PWQR_CTL_REGISTER, 0, NULL) < 0)
87 err(-1, "%d: pwqr_ctl(PWQR_CTL_REGISTER)", who);
90 trace("%d: loop1", who);
95 trace("%d: tries to park", who);
96 if (pwqr_ctl(pwqr_fd_g, PWQR_CTL_PARK, 0, NULL) < 0)
97 trace("pwqr_ctl(PWQR_CTL_PARK)");
98 trace("%d: unparked", who);
101 trace("%d: loop2", who);
103 pthread_testcancel();
109 static uint64_t tv_diff(const struct timeval *t1, const struct timeval *t2)
111 return (t1->tv_sec - t2->tv_sec) * 1000000ULL + t1->tv_usec - t2->tv_usec;
118 struct timeval start, tv;
123 pwqr_fd_g = pwqr_create(PWQR_FL_NONBLOCK);
125 err(-1, "pwqr_create");
127 pi_g = pwqr_ctl(pwqr_fd_g, PWQR_CTL_GET_CONC, 0, NULL);
129 err(-1, "pwqr_ctl(PWQR_CTL_GET_CONC)");
131 for (int i = 0; i < pi_g + 1; i++) {
132 pthread_create(&tids[i], NULL, thr_main, (void *)(long)i);
137 gettimeofday(&start, NULL);
140 rc = poll(&pfd, 1, -1);
146 if (pfd.revents & POLLIN) {
147 if (read(pwqr_fd_g, &rc, sizeof(rc)) != sizeof(rc)) {
150 gettimeofday(&tv, NULL);
151 trace("[%06jd.%06jd] overcommit of %d",
152 tv_diff(&tv, &start) / 1000000,
153 tv_diff(&tv, &start) % 1000000, rc);
157 if (pfd.revents & POLLHUP) {
158 errx(-1, "poll returned POLLHUP");
163 for (int i = 0; i < pi_g + 1; i++) {
164 pthread_join(tids[i], NULL);