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