mirror of
https://gitlab.com/Nils_Kasulke/spectre_project.git
synced 2026-04-04 11:37:25 +00:00
299 lines
8.3 KiB
C
299 lines
8.3 KiB
C
#include<stdio.h>
|
|
#include<stdlib.h>
|
|
#include<string.h>
|
|
#include<time.h>
|
|
|
|
//////////
|
|
//#include <openssl/sha.h>
|
|
//#include <openssl/bio.h>
|
|
/////////
|
|
|
|
/*
|
|
* 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("<prog> measure <filename>\n");
|
|
printf("<prog> sort <filename>\n");
|
|
printf("<prog> generate <n> <min> <max>\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; ++i) {
|
|
printf("%s\n", words[i]);
|
|
}
|
|
} else if(sort) {
|
|
if(argc != 3 ) {
|
|
usage_and_exit();
|
|
}
|
|
size_t nRead = 0;
|
|
char** array = read_strings(argv[2], &nRead);
|
|
qsort(array, nRead, sizeof(char*), string_sort_func);
|
|
|
|
for(size_t i=0; i < nRead; ++i) {
|
|
printf("%s\n", array[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t remove_newline(char* str) {
|
|
size_t pos = 0;
|
|
while(str[pos] && str[pos] != '\n') ++pos;
|
|
str[pos] = '\0';
|
|
return pos;
|
|
}
|
|
|
|
|
|
char** random_strings(size_t n, unsigned minLen, unsigned maxLen) {
|
|
char** array = (char**) non_null_malloc(sizeof(char*) * (n+1));
|
|
for(size_t i=0; i<n; ++i) {
|
|
array[i] = rand_word(minLen, maxLen);
|
|
}
|
|
array[n] = NULL;
|
|
return array;
|
|
}
|
|
|
|
void* non_null_malloc(size_t memSize) {
|
|
char* m = malloc(memSize);
|
|
if(!m) {
|
|
perror("non_malloc_failed");
|
|
exit(7);
|
|
}
|
|
return m;
|
|
}
|
|
unsigned rand_between(unsigned min, unsigned max) {
|
|
int rv = rand();
|
|
unsigned urv = rv < 0? -1*rv : rv;
|
|
unsigned v = (rv % ((max+1) - min)) + min;
|
|
return v;
|
|
}
|
|
char* rand_word(unsigned minLen, unsigned maxLen) {
|
|
unsigned len = rand_between(minLen, maxLen);
|
|
char* s = non_null_malloc(len+1);
|
|
for(size_t i=0; i<len; ++i) {
|
|
s[i] = rand_between(CHAR_START, CHAR_END);
|
|
}
|
|
s[len] = '\0';
|
|
return s;
|
|
}
|
|
int string_bit_count(char* s) {
|
|
//printf("<%s>\n", s);
|
|
int count = 0;
|
|
int len = strlen(s);
|
|
for(int i=0; i<len; ++i) {
|
|
for(int k=0; k<8; ++k) {
|
|
if(s[i] & (1 << k)) {
|
|
++count;
|
|
}
|
|
}
|
|
}
|
|
//printf("count = %d\n", count);
|
|
return count;
|
|
}
|
|
int string_bit_count3(const char* s) {
|
|
static const unsigned char lookup[] ={0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
|
|
int len = strlen(s);
|
|
int count = 0;
|
|
for(int i=0; i<len; ++i) {
|
|
count += lookup[s[i]];
|
|
}
|
|
return count;
|
|
}
|
|
int string_bit_count2(const char* s) {
|
|
static const unsigned char lookup[] ={0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
|
|
int count = 0;
|
|
const char* p = s;
|
|
for(; *p; ++p) {
|
|
count += lookup[*p];
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int string_sort_func(const void* a, const void* b) {
|
|
char* sa = *((char**) a);
|
|
char* sb = *((char**) b);
|
|
return strcmp(sa, sb);
|
|
}
|
|
char** read_strings(const char* fileName, size_t* nRead) {
|
|
size_t len;
|
|
char* sp;
|
|
FILE* f = fopen(fileName, "r");
|
|
if(!f) { perror("unable to open file"); exit(1); }
|
|
char* buff = non_null_malloc(MAX_LINE_SIZE);
|
|
size_t out_array_len = 16 * sizeof(char*);
|
|
size_t out_array_pos = 0;
|
|
char** out_array = non_null_malloc(out_array_len);
|
|
out_array[0] = NULL;
|
|
while(! feof(f)) {
|
|
buff[0] = '\0';
|
|
if(! fgets(buff, MAX_LINE_SIZE, f)) {
|
|
break;
|
|
}
|
|
len = remove_newline(buff);
|
|
if(len > 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;
|
|
}
|
|
*/
|