2019-01-28 20:05:51 C

cell.c マルチスレッド版

Copy Copied! Full
#include <pthread.h> #include <stdlib.h> #include <unistd.h> #include "cassl1.h" #define DEFAULT_THREAD_NUM 8 #define MIN_BUCKET_SIZE 20 typedef enum thread_status {NOT_READY, READY} thread_status; typedef struct thread_parameter{ state_num_t *start_pos; size_t sub_array_size; state_num_t left_end; state_num_t right_end; thread_status status; int result; pthread_t thread_id; } thread_parameter; static pthread_once_t once_control = PTHREAD_ONCE_INIT; static pthread_mutex_t status_lock; static pthread_cond_t wait_cond_v; static int done_thread; static thread_parameter *thread_params; static int thread_num = DEFAULT_THREAD_NUM; static int translate_subarray(state_num_t *cell_array, size_t size, state_num_t left_end, state_num_t right_end); static void initialize_thread(void); static void* translation_thread(void *arg); int translate_array(state_num_t *cell_array, size_t size) { int i; int active_thread_num; int sub_array_size; int count_sync; state_num_t *start_pos; pthread_once(&once_control, initialize_thread); if (size < 3) { return ERR_TOO_SMALL; } if ((size - 2) / MIN_BUCKET_SIZE + 1 > thread_num) { active_thread_num = thread_num; } else { active_thread_num = (size - 2) / MIN_BUCKET_SIZE + 1; } if (active_thread_num == 1) { return translate_subarray(cell_array + 1, size - 2 , cell_array[0], cell_array[size + 1]); } if (thread_params == NULL) { return ERR_THREAD_ERROR; } pthread_mutex_lock(&status_lock); start_pos = cell_array + 1; sub_array_size = (size - 2) / active_thread_num; for (i = 0; i < active_thread_num; i++) { thread_params[i].start_pos = start_pos; if (i == active_thread_num - 1) { sub_array_size += (size - 2) % active_thread_num; } thread_params[i].sub_array_size = sub_array_size; thread_params[i].left_end = *(start_pos - 1); thread_params[i].right_end = *(start_pos + sub_array_size); thread_params[i].status = READY; thread_params[i].result = 0; start_pos += sub_array_size; } done_thread = 0; pthread_cond_broadcast(&wait_cond_v); pthread_mutex_unlock(&status_lock); pthread_mutex_lock(&status_lock); while(done_thread != active_thread_num) { pthread_cond_wait(&wait_cond_v, &status_lock); } pthread_mutex_unlock(&status_lock); count_sync = 0; for (i = 0; i < active_thread_num; i++) { switch (thread_params[i].result) { case ERR_NOT_SYNCHRONIZE: case ERR_UNDEFINED_RULE: return thread_params[i].result; case SYNCHRONIZE: count_sync++; } } if (count_sync == 0) { return SUCCESS; } else if (count_sync == active_thread_num) { return SYNCHRONIZE; } else { return ERR_NOT_SYNCHRONIZE; } } static void initialize_thread(void) { int i; int ret; thread_num = sysconf(_SC_NPROCESSORS_ONLN); if (thread_num == -1) { thread_num = DEFAULT_THREAD_NUM; } if (pthread_mutex_init(&status_lock, NULL) != 0) { return; } if (pthread_cond_init(&wait_cond_v, NULL) != 0) { return; } thread_params = (thread_parameter*)malloc(sizeof(thread_parameter) * thread_num); if (thread_params == NULL) { return; } for (i = 0; i < thread_num; i++) { thread_params[i].status = NOT_READY; ret = pthread_create(&(thread_params[i].thread_id), NULL, translation_thread, (void *)&thread_params[i]); if (ret != 0) { free(thread_params); thread_params = NULL; return; } } } static void* translation_thread(void *arg) { thread_parameter *param = (thread_parameter *)arg; while (1) { pthread_mutex_lock(&status_lock); while (param->status != READY) { pthread_cond_wait(&wait_cond_v, &status_lock); } pthread_mutex_unlock(&status_lock); param->result = translate_subarray(param->start_pos, param->sub_array_size, param->left_end, param->right_end); pthread_mutex_lock(&status_lock); param->status = NOT_READY; done_thread++; pthread_cond_broadcast(&wait_cond_v); pthread_mutex_unlock(&status_lock); } return NULL; } static int translate_subarray(state_num_t *cell_array, size_t size, state_num_t left_end, state_num_t right_end) { state_num_t save; state_num_t next; int i; int count_undefined = 0; int count_firing = 0; for (i = 0, save = left_end; i < size; i++) { next = get_next_state(save, cell_array[i], i == size - 1 ? right_end : cell_array[i + 1]); if (next == FIRING) { count_firing++; } else if (next == EXTERNAL) { count_undefined++; } save = cell_array[i]; cell_array[i] = next; } if (count_undefined != 0) { return ERR_UNDEFINED_RULE; } if (count_firing != 0) { if (count_firing == size) { return SYNCHRONIZE; } else { return ERR_NOT_SYNCHRONIZE; } } return SUCCESS; }
cell.c マルチスレッド版
RECOMMEND