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