1 /* This file tests how efficient it is to hand off data in chunks as against as
2  * one big pile
3  * -- vstr is kind of built on the idea that this isn't a problem for
4  *    reasonable sizes */
5 
6 #define VSTR_COMPILE_INCLUDE 1
7 
8 #include <vstr.h>
9 
10 #ifndef TSTSG_USE_MD5
11 # define TSTSG_USE_MD5 0
12 #endif
13 
14 #ifndef TST_SZ /* chunk size for custom Vstr */
15 # define TST_SZ ((1024 * 4) - (sizeof(Vstr_node) + 16)) /* one page each */
16 #endif
17 
18 #ifndef TST_NUM /* number of times to perform each test */
19 # define TST_NUM (256)
20 #endif
21 
22 #if TSTSG_USE_MD5
23 /* do md5 test ... */
24 #include <openssl/md5.h>
25 
26 # define TSTSG_CTX     MD5_CTX
27 # define TSTSG_INIT    MD5_Init
28 # define TSTSG_UPDATE  MD5_Update
29 # define TSTSG_FINI    MD5_Final
30 # define TSTSG_OUT_LEN MD5_DIGEST_LENGTH
31 # define TSTSG_NAME    "MD5"
32 #else
33 /* do sha1 test .. */
34 #include <openssl/sha.h>
35 
36 # define TSTSG_CTX     SHA_CTX
37 # define TSTSG_INIT    SHA_Init
38 # define TSTSG_UPDATE  SHA_Update
39 # define TSTSG_FINI    SHA_Final
40 # define TSTSG_OUT_LEN SHA_DIGEST_LENGTH
41 # define TSTSG_NAME    "SHA"
42 #endif
43 
44 #include "ex_perf.h"
45 
46 #define TST_SSL_BEG() TST_BEG(TSTSG_OUT_LEN, TST_NUM); \
47                       TSTSG_CTX ctx
48 
49 #define TST_SSL_INIT() TSTSG_INIT(&ctx)
50 
51 #define TST_SSL_END(name) \
52         		TSTSG_FINI(buf_out, &ctx); \
53                         TST_END(name)
54 
55 #include <assert.h>
56 
main(int argc,char * argv[])57 int main(int argc, char *argv[])
58 {
59   Vstr_conf *conf = NULL;
60   Vstr_base *out = NULL;
61   Vstr_base *s1 = NULL;
62   Vstr_base *s2 = NULL;
63   Vstr_base *s3 = NULL;
64   unsigned int err = 0;
65 
66   if (!vstr_init())
67     exit(EXIT_FAILURE);
68 
69   conf = vstr_make_conf();
70   if (!conf)
71     exit(EXIT_FAILURE);
72 
73   /* have a custom config. for output and s1 ... */
74   vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_NUM_BUF_SZ, TST_SZ);
75 
76   vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_LOC_CSTR_THOU_SEP, "_");
77   vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_LOC_CSTR_THOU_GRP, "\3");
78 
79   vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '$');
80   vstr_sc_fmt_add_all(conf);
81 
82 
83   out = vstr_make_base(conf); /* used as stdio/stdout */
84 
85   s1 = vstr_make_base(conf); /* configured size */
86   s2 = vstr_make_base(NULL); /* mmap */
87   s3 = vstr_make_base(NULL); /* default size */
88   vstr_free_conf(conf);
89   if (!out || !s1 || !s2 || !s3)
90     exit(EXIT_FAILURE);
91 
92   if (argc != 2)
93   {
94     vstr_add_fmt(out, out->len,
95                  " Format: %s <filename>\n", argv[0]);
96     goto failed;
97   }
98 
99   vstr_sc_mmap_file(s2, s2->len, argv[1], 0, 0, &err);
100   if (err)
101     exit (EXIT_FAILURE);
102 
103   vstr_add_vstr(s3, s1->len, s2, 1, s2->len, VSTR_TYPE_ADD_ALL_BUF);
104   vstr_add_vstr(s1, s1->len, s2, 1, s2->len, VSTR_TYPE_ADD_ALL_BUF);
105 
106   if (conf->malloc_bad)
107     exit (EXIT_FAILURE);
108 
109   /* with I/O the iovec would be valid */
110   vstr_export_iovec_ptr_all(s1, NULL, NULL);
111   vstr_export_iovec_ptr_all(s3, NULL, NULL);
112 
113   /* print table to say what config we are using ... */
114   vstr_add_fmt(out, out->len,
115                "+${rep_chr:%c%zu}"
116                "+${rep_chr:%c%zu}"
117                "+${rep_chr:%c%zu}"
118                "+${rep_chr:%c%zu}+\n",
119                '=', 17, '=', 18, '=', 18, '=', 18);
120   vstr_add_fmt(out, out->len, "|%16s | %16s | %16s | %16s |\n",
121                "name", "len", "chunks", "chunk size");
122 
123   vstr_add_fmt(out, out->len,
124                "+${rep_chr:%c%zu}"
125                "+${rep_chr:%c%zu}"
126                "+${rep_chr:%c%zu}"
127                "+${rep_chr:%c%zu}+\n",
128                '-', 17, '-', 18, '-', 18, '-', 18);
129   {
130     unsigned int sz = 0;
131 
132     vstr_cntl_conf(s1->conf, VSTR_CNTL_CONF_GET_NUM_BUF_SZ, &sz);
133     vstr_add_fmt(out, out->len,
134                  "|%16s | $16{BKMG.u:%u} | %'16zu | $16{BKMG.u:%u} |\n",
135                  "s1:  conf iovs", (unsigned int)s1->conf->buf_sz, s1->num, sz);
136 
137     vstr_add_fmt(out, out->len,
138                  "|%16s | $16{BKMG.u:%u} | %'16zu | %16s |\n",
139                  "s2:       mmap", (unsigned int)s2->len, s2->num, "N/A");
140 
141     vstr_cntl_conf(s3->conf, VSTR_CNTL_CONF_GET_NUM_BUF_SZ, &sz);
142     vstr_add_fmt(out, out->len,
143                  "|%16s | $16{BKMG.u:%u} | %'16zu | $16{BKMG.u:%u} |\n",
144                  "s3:   def iovs", (unsigned int)s3->conf->buf_sz, s3->num, sz);
145   }
146   vstr_add_fmt(out, out->len,
147                "+${rep_chr:%c%zu}"
148                "+${rep_chr:%c%zu}"
149                "+${rep_chr:%c%zu}"
150                "+${rep_chr:%c%zu}+\n",
151                '-', 17, '-', 18, '-', 18, '-', 18);
152   vstr_add_fmt(out, out->len, " Doing tests %'u times with %s:\n",
153                (unsigned int)TST_NUM, TSTSG_NAME);
154 
155   while (out->len && !err)
156     vstr_sc_write_fd(out, 1, out->len, 1 /* stdout */, &err);
157 
158   TST_HDR_BEG();
159 
160   TST_SSL_BEG();
161   struct iovec *iovs = NULL;
162   unsigned int count = 0;
163   unsigned int num = 0;
164   size_t len = 0;
165 
166   TST_SSL_INIT();
167 
168   len = vstr_export_iovec_ptr_all(s1, &iovs, &num);
169 
170   while (count < num)
171   {
172     TSTSG_UPDATE(&ctx, iovs[count].iov_base, iovs[count].iov_len);
173     ++count;
174   }
175   TST_SSL_END("s1:  conf iovs");
176 
177   TST_SSL_BEG();
178   Vstr_ref *ref = NULL;
179   size_t off = 0;
180 
181   TST_SSL_INIT();
182 
183   ref = vstr_export_ref(s2, 1, s2->len, &off);
184   assert(off == 0);
185 
186   TSTSG_UPDATE(&ctx, ref->ptr, s1->len);
187 
188   vstr_ref_del(ref);
189   TST_SSL_END("s2:       mmap");
190 
191   vstr_export_iovec_ptr_all(s3, NULL, NULL);
192   TST_SSL_BEG();
193   struct iovec *iovs = NULL;
194   unsigned int count = 0;
195   unsigned int num = 0;
196   size_t len = 0;
197 
198   TST_SSL_INIT();
199   len = vstr_export_iovec_ptr_all(s3, &iovs, &num);
200 
201   while (count < num)
202   {
203     TSTSG_UPDATE(&ctx, iovs[count].iov_base, iovs[count].iov_len);
204     ++count;
205   }
206   TST_SSL_END("s3:   def iovs");
207 
208   TST_HDR_END();
209 
210   if (s1->conf->malloc_bad || s2->conf->malloc_bad || s3->conf->malloc_bad)
211     goto failed;
212 
213   while (out->len && !err)
214     vstr_sc_write_fd(out, 1, out->len, 1 /* stdout */, &err);
215 
216   vstr_free_base(out);
217   vstr_free_base(s1);
218   vstr_free_base(s2);
219   vstr_free_base(s3);
220 
221   vstr_exit();
222 
223   exit (EXIT_SUCCESS);
224 
225  failed:
226   while (out->len && !err)
227     vstr_sc_write_fd(out, 1, out->len, 2 /* stderr */, &err);
228 
229   vstr_free_base(out);
230   vstr_free_base(s1);
231   vstr_free_base(s2);
232   vstr_free_base(s3);
233 
234   vstr_exit();
235 
236   exit (EXIT_FAILURE);
237 }
238