1*4c1e55dcSeric /* $OpenBSD: threads.c,v 1.1.1.1 2012/07/13 17:49:53 eric Exp $ */
2*4c1e55dcSeric /*
3*4c1e55dcSeric * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
4*4c1e55dcSeric *
5*4c1e55dcSeric * Permission to use, copy, modify, and distribute this software for any
6*4c1e55dcSeric * purpose with or without fee is hereby granted, provided that the above
7*4c1e55dcSeric * copyright notice and this permission notice appear in all copies.
8*4c1e55dcSeric *
9*4c1e55dcSeric * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*4c1e55dcSeric * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*4c1e55dcSeric * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*4c1e55dcSeric * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*4c1e55dcSeric * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*4c1e55dcSeric * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*4c1e55dcSeric * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*4c1e55dcSeric */
17*4c1e55dcSeric #include <sys/time.h>
18*4c1e55dcSeric #include <sys/resource.h>
19*4c1e55dcSeric
20*4c1e55dcSeric #include <assert.h>
21*4c1e55dcSeric #include <err.h>
22*4c1e55dcSeric #include <getopt.h>
23*4c1e55dcSeric #include <pthread.h>
24*4c1e55dcSeric #include <stdio.h>
25*4c1e55dcSeric #include <stdlib.h>
26*4c1e55dcSeric #include <time.h>
27*4c1e55dcSeric
28*4c1e55dcSeric #include <netdb.h>
29*4c1e55dcSeric
30*4c1e55dcSeric #define MAX_THREADS 50
31*4c1e55dcSeric
32*4c1e55dcSeric int ac;
33*4c1e55dcSeric char **av;
34*4c1e55dcSeric int loop;
35*4c1e55dcSeric int nthreads;
36*4c1e55dcSeric
37*4c1e55dcSeric int long_err;
38*4c1e55dcSeric int gai_errno;
39*4c1e55dcSeric int rrset_errno;
40*4c1e55dcSeric
41*4c1e55dcSeric void async_resolver_done(void *);
42*4c1e55dcSeric
stats(void)43*4c1e55dcSeric void stats(void)
44*4c1e55dcSeric {
45*4c1e55dcSeric struct rusage ru;
46*4c1e55dcSeric
47*4c1e55dcSeric getrusage(RUSAGE_SELF, &ru);
48*4c1e55dcSeric printf("%li\n", ru.ru_maxrss);
49*4c1e55dcSeric }
50*4c1e55dcSeric
51*4c1e55dcSeric void*
task(void * arg)52*4c1e55dcSeric task(void *arg)
53*4c1e55dcSeric {
54*4c1e55dcSeric int id, i, j, c;
55*4c1e55dcSeric struct addrinfo *ai, *n;
56*4c1e55dcSeric
57*4c1e55dcSeric id = *((int*) arg);
58*4c1e55dcSeric
59*4c1e55dcSeric n = NULL; c =0;
60*4c1e55dcSeric
61*4c1e55dcSeric for(j = 0; j < loop; j++)
62*4c1e55dcSeric for(i = 0; i < ac; i++) {
63*4c1e55dcSeric if (getaddrinfo(av[i], NULL, NULL, &ai) == 0) {
64*4c1e55dcSeric /*
65*4c1e55dcSeric for (c = 0, n = ai; n; c++, n = n->ai_next);
66*4c1e55dcSeric printf("%i:%s: ok: %i\n", id, av[i], c);
67*4c1e55dcSeric */
68*4c1e55dcSeric freeaddrinfo(ai);
69*4c1e55dcSeric } else {
70*4c1e55dcSeric /*
71*4c1e55dcSeric printf("%i:%s: fail\n", id, av[i]);
72*4c1e55dcSeric */
73*4c1e55dcSeric }
74*4c1e55dcSeric }
75*4c1e55dcSeric return (NULL);
76*4c1e55dcSeric }
77*4c1e55dcSeric
78*4c1e55dcSeric void
usage(void)79*4c1e55dcSeric usage(void)
80*4c1e55dcSeric {
81*4c1e55dcSeric extern const char *__progname;
82*4c1e55dcSeric fprintf(stderr, "usage: %s [-L loop] [-l loop] [-t threads] <host> ...\n",
83*4c1e55dcSeric __progname);
84*4c1e55dcSeric }
85*4c1e55dcSeric
86*4c1e55dcSeric int
main(int argc,char ** argv)87*4c1e55dcSeric main(int argc, char **argv)
88*4c1e55dcSeric {
89*4c1e55dcSeric pthread_t th[MAX_THREADS];
90*4c1e55dcSeric int th_args[MAX_THREADS], r, i, ch;
91*4c1e55dcSeric int n, LOOP;
92*4c1e55dcSeric
93*4c1e55dcSeric nthreads = 1;
94*4c1e55dcSeric loop = 1;
95*4c1e55dcSeric LOOP = 1;
96*4c1e55dcSeric
97*4c1e55dcSeric while ((ch = getopt(argc, argv, "L:l:t:")) != -1) {
98*4c1e55dcSeric switch (ch) {
99*4c1e55dcSeric case 'L':
100*4c1e55dcSeric LOOP = atoi(optarg);
101*4c1e55dcSeric break;
102*4c1e55dcSeric case 'l':
103*4c1e55dcSeric loop = atoi(optarg);
104*4c1e55dcSeric break;
105*4c1e55dcSeric case 't':
106*4c1e55dcSeric nthreads = atoi(optarg);
107*4c1e55dcSeric if (nthreads > MAX_THREADS)
108*4c1e55dcSeric nthreads = MAX_THREADS;
109*4c1e55dcSeric break;
110*4c1e55dcSeric default:
111*4c1e55dcSeric usage();
112*4c1e55dcSeric /* NOTREACHED */
113*4c1e55dcSeric }
114*4c1e55dcSeric }
115*4c1e55dcSeric
116*4c1e55dcSeric argc -= optind;
117*4c1e55dcSeric argv += optind;
118*4c1e55dcSeric
119*4c1e55dcSeric ac = argc;
120*4c1e55dcSeric av = argv;
121*4c1e55dcSeric
122*4c1e55dcSeric printf("%i %i %i\n", LOOP, nthreads, loop);
123*4c1e55dcSeric for (n = 0; n < LOOP; n ++) {
124*4c1e55dcSeric for (i = 0; i < nthreads; i++) {
125*4c1e55dcSeric th_args[i] = i;
126*4c1e55dcSeric r = pthread_create(&th[i], NULL, task, (void *) &th_args[i]);
127*4c1e55dcSeric if (r == -1)
128*4c1e55dcSeric errx(1, "pthread_create");
129*4c1e55dcSeric }
130*4c1e55dcSeric for (i = 0; i < nthreads; i++)
131*4c1e55dcSeric pthread_join(th[i], NULL);
132*4c1e55dcSeric
133*4c1e55dcSeric if (nthreads == 0)
134*4c1e55dcSeric task(&n);
135*4c1e55dcSeric
136*4c1e55dcSeric stats();
137*4c1e55dcSeric }
138*4c1e55dcSeric
139*4c1e55dcSeric return (0);
140*4c1e55dcSeric }
141