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 MD5_DIGEST_NWORDS 17 #define MB_BUFS MD5_MAX_LANES 18 #define HASH_CTX_MGR MD5_HASH_CTX_MGR 19 #define HASH_CTX 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 md5_ctx_mgr_init 24 #define CTX_MGR_SUBMIT md5_ctx_mgr_submit 25 #define CTX_MGR_FLUSH md5_ctx_mgr_flush 26 27 #define rounds_buf 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 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 CTX_MGR_INIT(mgr); 167 168 printfv("Thread %i gets to wait\n", id); 169 /* Thread sync */ 170 pthread_mutex_lock(&count_lock); 171 count++; 172 if (count == num_threads) { 173 pthread_cond_broadcast(&count_cond); 174 } else { 175 pthread_cond_wait(&count_cond, &count_lock); 176 } 177 pthread_mutex_unlock(&count_lock); 178 179 printfv("Thread %i is ready\n", id); 180 /* hash func starts to run */ 181 round = 0; 182 gettimeofday(&start_tv, 0); 183 gettimeofday(&stop_tv, 0); 184 while (secs > (stop_tv.tv_sec - start_tv.tv_sec)) { 185 for (j = 0; j < rounds_buf; j += MB_BUFS) { 186 for (i = 0; i < MB_BUFS; i++) { 187 /* Pre mem-operation */ 188 if (prememcpy) 189 memcpy(hash_buf[j + i], carry_buf[j + i], buflen); 190 191 CTX_MGR_SUBMIT(mgr, &ctxpool[j + i], hash_buf[j + i], buflen, 192 HASH_ENTIRE); 193 } 194 195 /* Calculate hash digest */ 196 while (CTX_MGR_FLUSH(mgr)) 197 ; 198 for (i = 0; i < MB_BUFS; i++) { 199 /* Post mem-operation */ 200 if (postmemcpy) 201 memcpy(carry_buf[j + i], hash_buf[j + i], buflen); 202 } 203 } 204 round++; 205 206 gettimeofday(&stop_tv, 0); 207 } 208 printfv("thread %2i, multibuffer_func rounds %ld\n", id, round); 209 210 out: 211 free(ctxpool); 212 free(mgr); 213 for (j = 0; j < rounds_buf; j++) { 214 free(carry_buf[j]); 215 free(digests[j]); 216 free(hash_buf[j]); 217 } 218 219 pthread_exit((void *) round); 220 } 221