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