void myth_eco_init(void) { int i; char *env; env=getenv("MYTH_ECO_MODE"); if (env){ g_eco_mode_enabled=atoi(env); } sleeper = 0; queue_lock = myth_malloc(sizeof(pthread_mutex_t)); // thread_sem = myth_malloc(sizeof(int) * g_worker_thread_num); g_sleep_queue = NULL;// = myth_malloc(sizeof(struct sleep_queue)); for(i = 0; i < g_worker_thread_num; i++) { g_envs[i].my_sem = 0; #ifdef MYTH_ECO_TEIAN_STEAL g_envs[i].knowledge = 0; #endif } (*real_pthread_mutex_init)(queue_lock,NULL); // MAX_TRY = g_worker_thread_num * 5; // g_sleep_queue->next = NULL; // g_sleep_queue->tail = g_sleep_queue; // g_sleep_queue->head_sem = NULL; // g_sleep_queue->head_rank = g_worker_thread_num+1; #ifdef MYTH_ECO_TEIAN_STEAL task_num = 0; g_envs[0].c = RUNNING; for(i = 1; i < g_worker_thread_num; i++) g_envs[i].c = STEALING; for(i = 0; i < g_worker_thread_num; i++) g_envs[i].finish_ready=0; #endif }
int myth_sleeper_push(int *sem, int rank,int num) { int rem = sleeper; //lock (*real_pthread_mutex_lock)(queue_lock); if(num != -1) { if(num != task_num) { //unlock (*real_pthread_mutex_unlock)(queue_lock); return -1; } } if(!__sync_bool_compare_and_swap(&sleeper,rem,rem+1)) { //atomic(sleeper++;) //unlock (*real_pthread_mutex_unlock)(queue_lock); return -1; } if(g_envs[rank].exit_flag == 1) { //unlock (*real_pthread_mutex_unlock)(queue_lock); return -1; } sleep_queue_t tmp = myth_malloc(sizeof(struct sleep_queue)); tmp->head_sem = sem; tmp->head_rank = rank; tmp->tail = tmp; tmp->next = NULL; if(g_sleep_queue == NULL) { g_sleep_queue = tmp; g_sleep_queue->tail = tmp; } else if(g_sleep_queue->tail == NULL) { //real_free(g_sleep_queue); g_sleep_queue = tmp; g_sleep_queue->tail = tmp; }else { g_sleep_queue->tail->next = tmp; g_sleep_queue->tail = tmp; } //unlock (*real_pthread_mutex_unlock)(queue_lock); return 0; }
//Initialize specifying the number of worker threads //If specified less than 1, MYTH_WORKER_NUM or the number of CPU cores used instead. int myth_init_ex_body(int worker_num, size_t def_stack_size) { intptr_t nthreads; myth_init_process_affinity_info(); //Load original functions //myth_get_original_funcs(); //Decide the number of worker threads. //If environment variable is set, use it. Otherwise use the number of CPU cores. char *env; env=getenv(ENV_MYTH_WORKER_NUM); nthreads=(worker_num>0)?worker_num:-1; if (nthreads<=0 && env){nthreads=atoi(env);} if (nthreads<=0){nthreads=myth_get_cpu_num();} g_worker_thread_num=nthreads; //set default stack size size_t s; env=getenv(ENV_MYTH_DEF_STKSIZE); s=def_stack_size; if (s==0 && env){ s=atoi(env); } if (s>0){myth_set_def_stack_size_body(s);} //Initialize logger myth_log_init(); //Initialize memory allocators myth_flmalloc_init(nthreads); myth_malloc_wrapper_init(nthreads); #ifdef MYTH_WRAP_SOCKIO //Initialize I/O myth_io_init(); #endif //Initialize TLS myth_tls_init(nthreads); //Create barrier real_pthread_barrier_init(&g_worker_barrier,NULL,nthreads); //Allocate worker thread descriptors g_envs=myth_malloc(sizeof(myth_running_env)*nthreads); //Initialize TLS for worker thread descriptor myth_env_init(); return nthreads; }