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