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