xref: /isa-l_crypto/examples/saturation_test/md5_thread.c (revision 8957a389f5d64ee2efc6641cf687254ffa866864)
1 
2 #include <pthread.h>
3 #include <sys/time.h>
4 #include <sys/types.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdbool.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <openssl/evp.h>
11 
12 #include "isal_multithread_perf.h"
13 
14 #ifndef HASH_THREAD
15 /* MD5 related params and structures*/
16 #define DIGEST_NWORDS ISAL_MD5_DIGEST_NWORDS
17 #define MB_BUFS       ISAL_MD5_MAX_LANES
18 #define HASH_CTX_MGR  ISAL_MD5_HASH_CTX_MGR
19 #define HASH_CTX      ISAL_MD5_HASH_CTX
20 
21 #define OSSL_THREAD_FUNC md5_ossl_func
22 #define MB_THREAD_FUNC   md5_mb_func
23 #define CTX_MGR_INIT     isal_md5_ctx_mgr_init
24 #define CTX_MGR_SUBMIT   isal_md5_ctx_mgr_submit
25 #define CTX_MGR_FLUSH    isal_md5_ctx_mgr_flush
26 
27 #define rounds_buf ISAL_MD5_MAX_LANES
28 
29 #endif // HASH_THREAD
30 
31 typedef uint32_t hash_digests[DIGEST_NWORDS];
32 
33 void *
OSSL_THREAD_FUNC(void * arg)34 OSSL_THREAD_FUNC(void *arg)
35 {
36         int32_t id = *((int *) arg);
37         uint32_t i = 0, j = 0;
38         char *hash_buf[rounds_buf] = { NULL };  /* hash buf is used to do hash compute */
39         char *carry_buf[rounds_buf] = { NULL }; /* carry buf is used to do memory movement */
40         hash_digests digest;
41         uint64_t round = -1;
42         struct timeval start_tv, stop_tv;
43         long long secs = run_secs;
44 
45         printfv("Thread %i is started\n", id);
46         /* memory allocate */
47         for (j = 0; j < rounds_buf; j++) {
48                 carry_buf[j] = (char *) calloc((size_t) buflen, 1);
49                 if (carry_buf[j] == NULL) {
50                         printf("calloc failed test aborted\n");
51                         goto out;
52                 }
53 
54                 hash_buf[j] = (char *) calloc((size_t) buflen, 1);
55                 if (hash_buf[j] == NULL) {
56                         printf("calloc failed test aborted\n");
57                         goto out;
58                 }
59 
60                 /* Create the random data */
61                 for (i = 0; i < buflen; i += 1024) {
62                         carry_buf[j][i] = i % 256;
63                         hash_buf[j][i] = i % 256;
64                 }
65         }
66 
67         /* Initialize OpenSSL Ctx */
68         EVP_MD_CTX *ctx = EVP_MD_CTX_new();
69 
70         /* Thread sync */
71         pthread_mutex_lock(&count_lock);
72         count++;
73         if (count == num_threads) {
74                 pthread_cond_broadcast(&count_cond);
75         } else {
76                 pthread_cond_wait(&count_cond, &count_lock);
77         }
78         pthread_mutex_unlock(&count_lock);
79 
80         printfv("Thread %i is ready\n", id);
81         /* hash func starts to run */
82         round = 0;
83         gettimeofday(&start_tv, 0);
84         gettimeofday(&stop_tv, 0);
85         while (secs > (stop_tv.tv_sec - start_tv.tv_sec)) {
86                 for (j = 0; j < rounds_buf; j++) {
87                         /* Pre mem-operation */
88                         if (prememcpy)
89                                 memcpy(hash_buf[j], carry_buf[j], buflen);
90 
91                         /* Calculate hash digest */
92                         EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
93                         EVP_DigestUpdate(ctx, hash_buf[j], buflen);
94                         EVP_DigestFinal_ex(ctx, (unsigned char *) digest, NULL);
95 
96                         /* Post mem-operation */
97                         if (postmemcpy)
98                                 memcpy(carry_buf[j], hash_buf[j], buflen);
99                 }
100                 round++;
101 
102                 gettimeofday(&stop_tv, 0);
103         }
104         printfv("thread %2i, openssl_func rounds %ld\n", id, round);
105 
106 out:
107         for (j = 0; j < rounds_buf; j++) {
108                 free(carry_buf[j]);
109                 free(hash_buf[j]);
110         }
111 
112         EVP_MD_CTX_free(ctx);
113         pthread_exit((void *) round);
114 }
115 
116 void *
MB_THREAD_FUNC(void * arg)117 MB_THREAD_FUNC(void *arg)
118 {
119         int32_t id = *((int *) arg);
120         uint32_t i = 0, j = 0;
121         char *hash_buf[rounds_buf] = { NULL };  /* hash buf is used to do hash compute */
122         char *carry_buf[rounds_buf] = { NULL }; /* carry buf is used to do memory movement */
123         hash_digests *digests[rounds_buf];
124         uint64_t round = -1;
125         struct timeval start_tv, stop_tv;
126         long long secs = run_secs;
127         int ret;
128 
129         HASH_CTX_MGR *mgr = NULL;
130         HASH_CTX *ctxpool = NULL, *ctx = NULL;
131 
132         printfv("Thread %i is started\n", id);
133         /* Memory allocate */
134         for (j = 0; j < rounds_buf; j++) {
135                 carry_buf[j] = (char *) calloc((size_t) buflen, 1);
136                 if (carry_buf[j] == NULL) {
137                         printf("calloc failed test aborted\n");
138                         goto out;
139                 }
140 
141                 hash_buf[j] = (char *) calloc((size_t) buflen, 1);
142                 if (hash_buf[j] == NULL) {
143                         printf("calloc failed test aborted\n");
144                         goto out;
145                 }
146 
147                 digests[j] = (hash_digests *) calloc(sizeof(hash_digests), 1);
148 
149                 /* Create the random data */
150                 for (i = 0; i < buflen; i += 1024) {
151                         carry_buf[j][i] = i % 256;
152                         hash_buf[j][i] = i % 256;
153                 }
154         }
155 
156         ctxpool = (HASH_CTX *) calloc(rounds_buf, sizeof(HASH_CTX));
157         for (i = 0; i < rounds_buf; i++) {
158                 isal_hash_ctx_init(&ctxpool[i]);
159                 ctxpool[i].user_data = (void *) ((uint64_t) i);
160         }
161         ret = posix_memalign((void *) &mgr, 16, sizeof(HASH_CTX_MGR));
162         if ((ret != 0) || (mgr == NULL)) {
163                 printf("posix_memalign failed test aborted\n");
164                 goto out;
165         }
166         ret = CTX_MGR_INIT(mgr);
167         if (ret != 0) {
168                 printf("MD5 CTX MGR Init failed\n");
169                 goto out;
170         }
171 
172         printfv("Thread %i gets to wait\n", id);
173         /* Thread sync */
174         pthread_mutex_lock(&count_lock);
175         count++;
176         if (count == num_threads) {
177                 pthread_cond_broadcast(&count_cond);
178         } else {
179                 pthread_cond_wait(&count_cond, &count_lock);
180         }
181         pthread_mutex_unlock(&count_lock);
182 
183         printfv("Thread %i is ready\n", id);
184         /* hash func starts to run */
185         round = 0;
186         gettimeofday(&start_tv, 0);
187         gettimeofday(&stop_tv, 0);
188         while (secs > (stop_tv.tv_sec - start_tv.tv_sec)) {
189                 for (j = 0; j < rounds_buf; j += MB_BUFS) {
190                         for (i = 0; i < MB_BUFS; i++) {
191                                 /* Pre mem-operation */
192                                 if (prememcpy)
193                                         memcpy(hash_buf[j + i], carry_buf[j + i], buflen);
194 
195                                 ret = CTX_MGR_SUBMIT(mgr, &ctxpool[j + i], &ctx, hash_buf[j + i],
196                                                      buflen, ISAL_HASH_ENTIRE);
197                                 if (ret) {
198                                         printf("MD5 CTX MGR Submit failed\n");
199                                         goto out;
200                                 }
201                         }
202 
203                         /* Calculate hash digest */
204                         do {
205                                 ret = CTX_MGR_FLUSH(mgr, &ctx);
206                                 if (ret) {
207                                         printf("MD5 CTX MGR Flush failed\n");
208                                         goto out;
209                                 }
210                         } while (ctx != NULL);
211 
212                         for (i = 0; i < MB_BUFS; i++) {
213                                 /* Post mem-operation */
214                                 if (postmemcpy)
215                                         memcpy(carry_buf[j + i], hash_buf[j + i], buflen);
216                         }
217                 }
218                 round++;
219 
220                 gettimeofday(&stop_tv, 0);
221         }
222         printfv("thread %2i, multibuffer_func rounds %ld\n", id, round);
223 
224 out:
225         free(ctxpool);
226         free(mgr);
227         for (j = 0; j < rounds_buf; j++) {
228                 free(carry_buf[j]);
229                 free(digests[j]);
230                 free(hash_buf[j]);
231         }
232 
233         pthread_exit((void *) round);
234 }
235