#include #include #include #include ////////// //#include //#include ///////// /* * range of the chars in the randomly generated string * * 33 = '!' * 127 = '~' * */ #define CHAR_START '1' #define CHAR_END '9' #define MEASURE_FUNC string_bit_count //#define MEASURE_FUNC string_bit_count2 //#define MEASURE_FUNC string_bit_count3 //#define MEASURE_FUNC sha1_int_from_string void mem_flush(const void *p, unsigned int allocation_size) { const size_t cache_line = 64; const char *cp = (const char *)p; size_t i = 0; if (p == NULL || allocation_size <= 0) return; for (i = 0; i < allocation_size; i += cache_line) { asm volatile("clflush (%0)\n\t" : : "r"(&cp[i]) : "memory"); } asm volatile("sfence\n\t" : : : "memory"); } /* * returns dynamically allocated random string * with a strlen between minLen and maxLen * the memory size is strlen + 1 * */ char* rand_word(unsigned minLen, unsigned maxLen); /* * uses rand returned value >= min and value <= max */ unsigned rand_between(unsigned min, unsigned max); /* * returns an array of dynamically allocated strings * length of array is n + 1, the last value is NULL */ char** random_strings(size_t n, unsigned minLen, unsigned maxLen); /* * returns strlen without newline * removes terminates string at newline position */ size_t remove_newline(char* str); /*max line size with newline and terminating 0*/ #define MAX_LINE_SIZE 1024 /* * nRead, out: allowed to be NULL * nRead represents actually read strings, without trailing NULL * e.g. if 0 strings are read, nRead will be 0, and the returned array will be {NULL} * returns string array, null terminated * */ char** read_strings(const char* fileName, size_t* nRead); /* * count set bits in string s */ int string_bit_count(char* s); int string_bit_count2(const char* s); int string_bit_count3(const char* s); int sha1_int_from_string(const char* s); /* * returns malloced memory of size memSize * if it fails, it exits with 7 the programm * */ void* non_null_malloc(size_t memSize); int string_sort_func(const void* a, const void* b); void usage_and_exit(); #define PRE_STR_HELPER(token) #token #define PRE_STR(token) PRE_STR_HELPER(token) void usage_and_exit() { printf("usage\n"); printf(" measure \n"); printf(" sort \n"); printf(" generate \n"); exit(1); } int main(int argc, char* argv[]) { _Bool generate = 0; _Bool measure = 0; _Bool sort = 0; if(argc < 2 ) { usage_and_exit(); } measure = strcmp(argv[1], "measure") == 0; generate = strcmp(argv[1], "generate") == 0; sort = strcmp(argv[1], "sort") == 0; if((!generate) && (!measure) && (!sort)) { usage_and_exit(); } if(measure) { if(argc != 3 ) { usage_and_exit(); } char** array = read_strings(argv[2], NULL); char** p = array; unsigned long long counter = 0; clock_t t1, t0 = clock(); for(; *p; ++p) { size_t len = strlen(*p); mem_flush(*p, len+1); counter += MEASURE_FUNC(*p); } t1 = clock(); printf("measure file: <%s>\n", argv[2]); printf("measure function: <%s>\n", PRE_STR(MEASURE_FUNC)); printf("counter = %llu\n", counter); printf("time = %lf ms\n", (t1 - t0) / (double) CLOCKS_PER_SEC * 1000.0); } else if(generate) { if(argc != 5 ) { usage_and_exit(); } unsigned n, minLen, maxLen; sscanf(argv[2], "%u", &n); sscanf(argv[3], "%u", &minLen); sscanf(argv[4], "%u", &maxLen); char** words = random_strings(n, minLen, maxLen); for(int i=0; i\n", s); int count = 0; int len = strlen(s); for(int i=0; i 0) { sp = non_null_malloc(len+1); memcpy(sp, buff, len+1); if(out_array_pos + 1 > out_array_len / sizeof(char*)) { out_array_len = out_array_len * 2; out_array = realloc(out_array, out_array_len); if(! out_array) { perror("allocation failed"); exit(1); } } out_array[out_array_pos++] = sp; out_array[out_array_pos] = NULL; } } fclose(f); if(nRead) *nRead = out_array_pos; return out_array; } /* int sha1_int_from_string(const char* s) { SHA_CTX c; SHA1_Init(&c); char sha1_bytes[20]; SHA1_Update(&c, s, strlen(s)); SHA1_Final(sha1_bytes, &c); int count = 0; for(int i=0; i<20; ++i) { count += sha1_bytes[i]; } return count; } */