lab2_bst_test.c 설명
Closed this issue · 0 comments
hs-krispy commented
/*
* Operating System Lab
* Lab2 (Synchronization)
*
* lab2_bst_test.c :
* - thread-safe bst test code.
* - coarse-grained, fine-grained lock test code
*
* You can compare single thread result, coarse grained result and fine grained result.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include "lab2_sync_types.h"
#define LAB2_TYPE_FINEGRAINED 0
#define LAB2_TYPE_COARSEGRAINED 1
#define LAB2_TYPE_SINGLE 2
#define LAB2_OPTYPE_INSERT 0
#define LAB2_OPTYPE_DELETE 1
void lab2_sync_usage(char *cmd) // 입력 형식에 대한 설명
{
printf("\n Usage for %s : \n",cmd);
printf(" -t: num thread, must be bigger than 0 ( e.g. 4 )\n");
printf(" -c: test node count, must be bigger than 0 ( e.g. 10000000 ) \n");
}
void lab2_sync_example(char *cmd) // 입력 형식
{
printf("\n Example : \n");
printf(" #sudo %s -t 4 -c 10000000 \n", cmd);
printf(" #sudo %s -t 4 -c 10000000 \n", cmd);
}
static void print_result(lab2_tree *tree, int num_threads, int node_count, int is_sync, int op_type, double time){
char *cond[] = {"fine-grained BST ", "coarse-grained BST", "single thread BST"};
char *op[] = {"insert","delete"};
int result_count = 0;
printf("===== Multi thread %s %s experiment =====\n",cond[is_sync],op[op_type]);
printf("\n Experiment info \n");
printf(" test node : %d \n", node_count);
printf(" test threads : %d \n", num_threads);
printf(" execution time : %lf seconds \n\n", time);
printf("\n BST inorder iteration result : \n");
result_count = lab2_node_print_inorder(tree);
printf(" total node count : %d \n\n", node_count);
}
void* thread_job_delete(void *arg){
thread_arg *th_arg = (thread_arg *)arg;
lab2_tree *tree = th_arg->tree;
int is_sync = th_arg->is_sync;
int *data_set = th_arg->data_set; // 삭제할 데이터의 정보를 저장
int start = th_arg->start, end = th_arg->end;
int i;
for(i = start; i < end; i++ ){
if(is_sync == LAB2_TYPE_FINEGRAINED)
lab2_node_remove_fg(tree, data_set[i]);
else if(is_sync == LAB2_TYPE_COARSEGRAINED)
lab2_node_remove_cg(tree, data_set[i]);
}
}
void* thread_job_insert(void *arg){
thread_arg *th_arg = (thread_arg *)arg; // 인자로 받아온 구조체 정보를 넣어줌
lab2_tree *tree = th_arg->tree; // 루트 노드 설정
int is_sync = th_arg->is_sync;
int *data = th_arg->data_set;
int start = th_arg->start, end = th_arg->end;
int i;
for (i = start; i < end; i++) {
lab2_node* node = lab2_node_create(data[i]); // 노드 개수만큼 노드 생성
if(is_sync == LAB2_TYPE_FINEGRAINED)
lab2_node_insert_fg(tree, node);
else if(is_sync == LAB2_TYPE_COARSEGRAINED)
lab2_node_insert_cg(tree, node);
}
}
void bst_test(int num_threads, int node_count){
lab2_tree *tree;
lab2_node *node;
struct timeval tv_insert_start, tv_insert_end, tv_delete_start, tv_delete_end, tv_start, tv_end;
// timeval 구조체 변수 선언
/*
* struct timeval
{
long tv_sec; // 초
long tv_usec; // 마이크로초
}
*/
int errors, i = 0, count = 0;
int root_data = 40;
int term = node_count / num_threads, is_sync;
double exe_time = 0.0;
thread_arg *threads; // 쓰레드 구조체 배열 생성
int *data = (int*)malloc(sizeof(int)*node_count);
srand(time(NULL));
for (i=0; i < node_count; i++) { // 노드의 data에 랜덤값을 넣어줌
data[i] = rand();
}
if (!(threads = (thread_arg*)malloc(sizeof(thread_arg) * num_threads)))
abort(); // 프로그램을 비정상 종료시킴
/*
* single thread insert test.
*/
gettimeofday(&tv_start, NULL); // 시작 시간
printf("\n");
tree = lab2_tree_create(); // 루트 노드 생성
for (i=0 ; i < node_count ; i++) {
lab2_node* node = lab2_node_create(data[i]); // 노드 생성
lab2_node_insert(tree, node); //루트 노드에 새 노드 연결(트리에 노드 삽입)
}
gettimeofday(&tv_end, NULL); // 종료 시간
exe_time = get_timeval(&tv_start, &tv_end); // 종료 시간 - 시작 시간
print_result(tree, num_threads, node_count, LAB2_TYPE_SINGLE, LAB2_OPTYPE_INSERT, exe_time);
lab2_tree_delete(tree);
/*
* multi therad insert test coarse-grained
*/
is_sync = LAB2_TYPE_COARSEGRAINED;
tree = lab2_tree_create();
gettimeofday(&tv_insert_start, NULL);
for(i=0; i < num_threads ; i++){
thread_arg *th_arg = &threads[i]; // 쓰레드 구조체 배열
th_arg->tree = tree;
th_arg->is_sync = is_sync;
th_arg->data_set = data;
th_arg->start = i*term;
th_arg->end = (i+1)*term;
pthread_create(&threads[i].thread, NULL, thread_job_insert, (void*)th_arg); // 쓰레드 개수만큼 생성
}
for (i = 0; i < num_threads; i++)
pthread_join(threads[i].thread, NULL); // 해당 쓰레드가 끝날때 까지 대기
gettimeofday(&tv_insert_end, NULL);
exe_time = get_timeval(&tv_insert_start, &tv_insert_end);
print_result(tree,num_threads, node_count, is_sync, LAB2_OPTYPE_INSERT, exe_time);
lab2_tree_delete(tree);
/*
* multi thread insert test fine-grained \
*/
is_sync = LAB2_TYPE_FINEGRAINED;
tree = lab2_tree_create();
gettimeofday(&tv_insert_start, NULL);
for(i=0; i < num_threads ; i++){
thread_arg *th_arg = &threads[i];
th_arg->tree = tree;
th_arg->is_sync = is_sync;
th_arg->data_set = data;
th_arg->start = i*term;
th_arg->end = (i+1)*term;
pthread_create(&threads[i].thread,NULL,thread_job_insert,(void*)th_arg);
}
for (i = 0; i < num_threads; i++)
pthread_join(threads[i].thread, NULL);
gettimeofday(&tv_insert_end, NULL);
exe_time = get_timeval(&tv_insert_start, &tv_insert_end);
print_result(tree,num_threads, node_count, is_sync, LAB2_OPTYPE_INSERT,exe_time);
lab2_tree_delete(tree);
/*
* single thread delete test
*/
tree = lab2_tree_create();
for (i=0 ; i < node_count ; i++) {
lab2_node* node = lab2_node_create(data[i]);
lab2_node_insert(tree, node);
}
gettimeofday(&tv_start, NULL);
for(i=0 ; i < node_count ; i++){
lab2_node_remove(tree,data[i]);
}
gettimeofday(&tv_end, NULL);
exe_time = get_timeval(&tv_start, &tv_end);
print_result(tree, num_threads, node_count, LAB2_TYPE_SINGLE, LAB2_OPTYPE_DELETE,exe_time);
lab2_tree_delete(tree);
/*
* multi thread delete test coarse-grained
*/
is_sync = LAB2_TYPE_COARSEGRAINED;
tree = lab2_tree_create();
for (i=0; i < node_count; i++) {
node = lab2_node_create(data[i]);
if(is_sync == LAB2_TYPE_FINEGRAINED)
lab2_node_insert_fg(tree,node);
else if(is_sync == LAB2_TYPE_COARSEGRAINED)
lab2_node_insert_cg(tree,node);
}
gettimeofday(&tv_delete_start, NULL);
for(i=0 ; i < num_threads ; i++){
thread_arg *th_arg = &threads[i];
th_arg->tree = tree;
th_arg->is_sync = is_sync;
th_arg->data_set = data;
th_arg->start = i*term;
th_arg->end = (i+1)*term;
pthread_create(&threads[i].thread,NULL,thread_job_delete,(void*)th_arg);
}
for (i = 0; i < num_threads; i++)
pthread_join(threads[i].thread, NULL);
gettimeofday(&tv_delete_end, NULL);
exe_time = get_timeval(&tv_delete_start, &tv_delete_end);
print_result(tree,num_threads, node_count, is_sync,LAB2_OPTYPE_DELETE,exe_time);
lab2_tree_delete(tree);
/*
* multi thread delete test fine-grained
*/
is_sync = LAB2_TYPE_FINEGRAINED;
tree = lab2_tree_create();
for (i=0; i < node_count; i++) {
node = lab2_node_create(data[i]);
if(is_sync == LAB2_TYPE_FINEGRAINED)
lab2_node_insert_fg(tree,node);
else if(is_sync == LAB2_TYPE_COARSEGRAINED)
lab2_node_insert_cg(tree,node);
}
gettimeofday(&tv_delete_start, NULL);
for(i=0 ; i < num_threads ; i++){
thread_arg *th_arg = &threads[i];
th_arg->tree = tree;
th_arg->is_sync = is_sync;
th_arg->data_set = data;
th_arg->start = i*term;
th_arg->end = (i+1)*term;
pthread_create(&threads[i].thread,NULL,thread_job_delete,(void*)th_arg);
}
for (i = 0; i < num_threads; i++)
pthread_join(threads[i].thread, NULL);
gettimeofday(&tv_delete_end, NULL);
exe_time = get_timeval(&tv_delete_start, &tv_delete_end);
print_result(tree ,num_threads, node_count, is_sync, LAB2_OPTYPE_DELETE,exe_time);
lab2_tree_delete(tree);
printf("\n");
free(threads);
free(data);
}
int main(int argc, char *argv[])
{
char op;
int num_threads=0, node_count=0;
int fd;
optind = 0;
while ((op = getopt(argc, argv, "t:c:")) != -1) { // "t: 동시에 수행 할 thread의 개수, c: 노드의 개수"
switch (op) {
case 't':
num_threads = atoi(optarg); // 문자열로 저장된 옵션값을 정수로 변환
break;
case 'c':
node_count = atoi(optarg);
break;
default:
goto INVALID_ARGS;
}
}
if((num_threads > 0) && (node_count > 0)){
bst_test(num_threads, node_count);
}else{
goto INVALID_ARGS;
}
return LAB2_SUCCESS; // 0 성공 리턴 (헤더에 정의)
INVALID_ARGS:
lab2_sync_usage(argv[0]); // 인자로 실행 파일명을 넘겨줌
lab2_sync_example(argv[0]); // 인자로 실행 파일명을 넘겨줌
return LAB2_ERROR; // -1 에러 리턴
}