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