/* * Multithreaded approach cost meter * Copyright (c) 2001 by Abramo Bagnara * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program 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 Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #include #include #define BUFSIZE 64*26 struct thr { pthread_t thread; int in, out; } threads[100]; float samples[BUFSIZE]; unsigned int _count; volatile unsigned int *count = &_count; void *thread(void *data) { char buf[1]; unsigned int n = (unsigned int) data; struct thr *t = &threads[n]; int err; while (*count > 0) { unsigned int k; err = read(t->in, buf, 1); assert(err == 1); for (k = 0; k < BUFSIZE; k++) samples[k]++; if (n == 0) (*count)--; err = write(t->out, buf, 1); assert(err == 1); } return 0; } void proc(unsigned int n) { unsigned int k; for (k = 0; k < BUFSIZE; k++) samples[k]++; if (n == 0) (*count)--; } void setscheduler(void) { struct sched_param sched_param; if (sched_getparam(0, &sched_param) < 0) { printf("Scheduler getparam failed\n"); return; } sched_param.sched_priority = sched_get_priority_max(SCHED_RR); if (!sched_setscheduler(0, SCHED_RR, &sched_param)) { printf("Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority); return; } printf("Scheduler set to Round Robin with priority %i failed\n", sched_param.sched_priority); } /* Usage: ctx workers periods */ int main(int argc, char **argv) { unsigned long long begin, end, single, multi; unsigned int workers = atoi(argv[1]); unsigned int k; int err; char buf[1]; unsigned int periods = atoi(argv[2]); _count = periods; for (k = 0; k < BUFSIZE; k++) samples[k] = 0.0; for (k = 0; k < workers; ++k) { int fds[2]; err = pipe(fds); assert(err == 0); threads[k].in = fds[0]; threads[k == 0 ? workers - 1 : k - 1].out = fds[1]; err = pthread_create(&threads[k].thread, NULL, thread, (void*) k); assert(err == 0); } setscheduler(); rdtscll(begin); while (*count > 0) { int n; for (n = 0; n < workers; ++n) { proc(n); } } rdtscll(end); single = end - begin; printf("singlethread: %llu\n", single); _count = periods; rdtscll(begin); err = write(threads[workers - 1].out, buf, 1); assert(err == 1); err = pthread_join(threads[workers - 1].thread, 0); assert(err == 0); rdtscll(end); for (k = 0; k < workers - 1; ++k) { err = pthread_join(threads[k].thread, 0); assert(err == 0); } multi = end - begin; printf("multithread: %llu\n", multi); printf("Average cost per period: %lld\n", (multi - single) / periods); return 0; }