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 * 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 * 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