#include #include #include #include #include #include #include #include #include #include #include struct args_struct{ int tred; int iterations; int json; size_t words; int simulate_errors; int test; int mod_status; }; struct args_struct args; #include "cJSON/cJSON.h" #include "args_parser.h" #define DEBUG 0 #define jemalloc 0 #if defined(DEBUG) && DEBUG > 1 #define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \ __FILE__, __LINE__, __func__, ##args) #elif DEBUG == 1 #define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %d:%s(): " fmt, \ __LINE__, __func__, ##args) #else #define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */ #endif #define BLOCK_SIZE (1024ULL*1024ULL*1024ULL*8) uint32_t test_patterns[] = {0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555}; char* test_name[] = {"increment", "ones test", "zeros test"}; int pretest_delay = 0; int test_list[] = {2,3,4}; #define bool unsigned char struct test_info{ int error; int number_addresses; }; struct error_info{ uint32_t expected; uint32_t actual; struct error_info* error_info_next; }; struct test_local_stats{ int error_int; struct error_info* error_info; struct error_info* error_info_end; }; struct test_stats{ int len; struct test_local_stats* test_local_stats[]; }; struct struct_info{ struct test_info* test_info; struct test_stats* test_stats; }; struct struct_info info; struct tred_pizdec{ uint32_t* mem; size_t words_stop; int id; size_t words_start; int return_error; bool test_tip; struct test_stats* test_stats; }; #include "multi_tred.h" // Получить доступную память из /proc/meminfo unsigned long int get_mem_available_mb() { FILE* f = fopen("/proc/meminfo", "r"); if (!f) return 0; char line[256]; unsigned long int available = 0; while (fgets(line, sizeof(line), f)) { if (sscanf(line, "MemAvailable: %lu kB", &available) == 1) break; } fclose(f); if (!args.json){ printf("mem Gb: %lu\n",(available-available/100*10)/1024/1024); printf("mem MB: %lu\n",(available-available/100*10)/1024); } return (available - available/100*20)*1024; } void meseng_proses(int test_tipe, int p){ if (args.json != 1){ if (test_tipe == 1){ printf("\rЗапушен патерн 0x%08X", test_patterns[p]); fflush(stdout); } else{ printf("\rЗапушен патерн %s", test_name[test_tipe-2]); fflush(stdout); } } } void meseng_test_and_slip(){ if (pretest_delay!= 0){ printf("\rЖду "); fflush(stdout); usleep(pretest_delay*1000000); } if (args.json != 1){ printf("\r-- Проверяю "); fflush(stdout); } } void test_patern(struct tred_pizdec* meta,unsigned long* thread, int tred, int* err, int p){ // test_list[test_list_id] int test_tipe = p - 2; if (test_tipe<=1){ test_tipe=1; } else p = 0; meseng_proses(test_tipe, p); for (bool i = 0;(i != tred); i++){// test meta[i].id = p; meta[i].test_tip = test_tipe; DEBUG_PRINT("words_stop: %zu\n",meta[i].words_stop); DEBUG_PRINT("words_start:%zu\n",meta[i].words_start); pthread_create(&thread[i], NULL, fill_pattern_multi_tred, (void*)&meta[i]); //pthread_join(thread[i], NULL); } for (bool i = 0;(i != tred); i++) //sink tred pthread_join(thread[i], NULL); //fill_pattern(mem, words, test_patterns[p]); meseng_test_and_slip(); //int err = check_pattern(mem, words, test_patterns[p]); for (bool i = 0;(i != tred); i++){// test pthread_create(&thread[i], NULL, check_pattern_multi_tred, (void*)&meta[i]); //pthread_join(thread[i], NULL); } for (bool i = 0;(i != tred); i++){ //sink tred pthread_join(thread[i], NULL); *err += meta[i].return_error; } if (!args.json){ if (*err == 0){ printf("\rOK\n"); fflush(stdout); } else printf("Errors: %d\n", *err); } } void json_local_create(cJSON *error_info_array, struct error_info* error_info){ cJSON *error_local_info_array = cJSON_CreateObject(); { char* char_dynamic = malloc(32); sprintf(char_dynamic, "%p",(void*)&error_info->actual); DEBUG_PRINT("%s\n", char_dynamic); DEBUG_PRINT("0x%08X\n", error_info->actual); cJSON *error_adres = cJSON_CreateString(char_dynamic); cJSON_AddItemToObject(error_local_info_array, "error_adres", error_adres); }{ char* char_dynamic = malloc(11); sprintf(char_dynamic, "0x%08X",error_info->expected); cJSON *expected = cJSON_CreateString(char_dynamic); cJSON_AddItemToObject(error_local_info_array, "expected", expected); }{ char* char_dynamic = malloc(11); sprintf(char_dynamic, "0x%08X",error_info->actual); cJSON *actual = cJSON_CreateString(char_dynamic); cJSON_AddItemToObject(error_local_info_array, "actual", actual); } cJSON_AddItemToArray(error_info_array, error_local_info_array); } void json_sum_job(struct tred_pizdec* meta, cJSON *test_ob, char* char_dynamic, int i, unsigned int *error_int){ if (i < 4) sprintf(char_dynamic, "0x%08X",test_patterns[i]); else{ //sprintf(char_dynamic, "%s",test_name[i-4]); //free(char_dynamic); char_dynamic = test_name[i-4]; } cJSON *error_ob = cJSON_CreateObject(); cJSON *error_info_array = cJSON_CreateArray(); unsigned int error_int_local=0; for (int t=0; t != args.tred; t++){ struct error_info* error_info_A = meta[t].test_stats->test_local_stats[i]->error_info; error_int_local += meta[t].test_stats->test_local_stats[i]->error_int; while(NULL != error_info_A){ //for(){}; //p += meta[t].return_error; json_local_create(error_info_array, error_info_A); error_info_A = error_info_A->error_info_next; } } *error_int += error_int_local; cJSON *error_int_j = cJSON_CreateNumber(error_int_local); cJSON_AddItemToObject(error_ob, "error", error_int_j); cJSON_AddItemToObject(error_ob, "error_info", error_info_array); cJSON_AddItemToObject(test_ob, char_dynamic, error_ob); } void json_create(struct tred_pizdec* meta){ cJSON *main_ob = cJSON_CreateObject(); cJSON *test_ob = cJSON_CreateObject(); cJSON_AddItemToObject(main_ob, "test", test_ob); //char* char_dynamic = malloc(11); char* char_dynamic = malloc(16); unsigned int error_int=0; for (int i = 0;i != sizeof(test_patterns)/sizeof(test_patterns[0])+ sizeof(test_name)/sizeof(test_name[0]); ++i){ json_sum_job(meta, test_ob, char_dynamic, i, &error_int); } free(char_dynamic); cJSON *test_info_ob = cJSON_CreateObject(); cJSON_AddItemToObject(main_ob, "test_infoAAA", test_info_ob); cJSON *error_int_j = cJSON_CreateNumber(error_int); cJSON_AddItemToObject(test_info_ob, "error", error_int_j); cJSON *message_str; if (error_int) message_str = cJSON_CreateString("Тест пройден неудачно!"); else message_str = cJSON_CreateString("Тест пройден успешно!"); cJSON_AddItemToObject(test_info_ob, "message", message_str); cJSON *number_addresses_int = cJSON_CreateNumber(args.words); cJSON_AddItemToObject(test_info_ob, "number_addresses", number_addresses_int); cJSON *mod_test_str = cJSON_CreateString("user_mod"); cJSON_AddItemToObject(test_info_ob, "mod_test", mod_test_str); char *string = cJSON_Print(main_ob); printf("%s", string); } void mem_meta_create(struct tred_pizdec* meta, uint32_t *mem, int i){ //meta = malloc(sizeof(struct tred_pizdec)); meta->test_stats = malloc(sizeof(struct test_stats) + (sizeof(test_list)/sizeof(test_list[0]) + sizeof(test_patterns)/sizeof(test_patterns[0])) * sizeof(struct test_local_stats*) ); meta->test_stats->len = (sizeof(test_list)/sizeof(test_list[0]) + sizeof(test_patterns)/sizeof(test_patterns[0])); //meta->test_stats = malloc(meta[i]->test_stats->len); for (int m=0;m != meta->test_stats->len;m++){ meta->test_stats->test_local_stats[m] = malloc(sizeof(struct test_local_stats)); meta->test_stats->test_local_stats[m]->error_int = 0; meta->test_stats->test_local_stats[m]->error_info = NULL; //meta->test_stats->test_local_stats[m]-> } meta->mem = mem; meta->words_stop = args.words/args.tred*(i+1); meta->words_start = i * args.words/args.tred; meta->return_error = 0; DEBUG_PRINT("words_stop: %zu\n",meta->words_stop); DEBUG_PRINT("words_start:%zu\n",meta->words_start); } int main(int argc, char *argv[]){ args.tred = 1; args.iterations = 1; args.json = 0; args.simulate_errors = 0; args.mod_status = 0; aaa(&argc, argv, &pretest_delay); unsigned long int mem_size = get_mem_available_mb(); if (args.test){ mem_size = 100000000; } if (args.mod_status > 0){ if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { perror("mlockall ошибка!\nВозможно недостаточно прав!\n"); return 1; } } if (args.tred < 2){ if (!args.json) printf("Количество потоков изменено на 2\n"); args.tred = 2; } else if (args.tred > 250){ if (!args.json) printf("Количество потоков изменено на 250\n"); args.tred = 250; } if (!args.json) printf("threads: %d\n", args.tred); size_t words = mem_size / sizeof(uint32_t); args.words = words; uint32_t *mem = malloc(mem_size); if (!mem) { printf("Память не выделена!"); return 1; } //struct tred_pizdec* meta[]; //pthread_t thread[]; int err = 0, iterations = args.iterations; struct tred_pizdec* meta = malloc(sizeof(struct tred_pizdec) * args.tred); pthread_t *thread = malloc(sizeof(pthread_t) * args.tred); if (!args.json) printf("iterations: %i\n", iterations); for (bool i = 0;(i != args.tred); i++) mem_meta_create(&meta[i], mem, i); DEBUG_PRINT("Выделена память!\n"); for (;iterations != 0; iterations--){ for (size_t p = 0; p < sizeof(test_patterns)/sizeof(test_patterns[0])+sizeof(test_list)/sizeof(test_list[0]); ++p) test_patern(meta, thread, args.tred, &err, p); } free(mem); if (args.json) json_create(meta); free(meta); free(thread); //if(args.json) //for (bool i = 0;(args.tred != -1 || i != args.tred); i++) // free(meta[i]); return 0; }