extern int main(void) { cl_thread_settings_t* thread_p = NULL; cl_thread_settings_t* dummy_thread_p = NULL; int count = 0; /* setup thread list */ cl_thread_list_setup(&thread_list,"thread list"); /* setup first thread */ cl_thread_list_create_thread(thread_list, &dummy_thread_p,NULL, "1st thread", 1, my_thread, NULL, NULL, CL_TT_USER1); /* setup second thread */ cl_thread_list_create_thread(thread_list, &dummy_thread_p, NULL, "2nd thread", 2, my_thread, NULL, NULL, CL_TT_USER1); thread_p = cl_thread_list_get_thread_by_id(thread_list, 1); printf("first thread (%s) has id: %d\n", thread_p->thread_name, thread_p->thread_id); thread_p = cl_thread_list_get_thread_by_name(thread_list, "2nd thread"); printf("second thread (%s) has id: %d\n" , thread_p->thread_name, thread_p->thread_id); while (count++ < 10) { int id; printf("we have %ld threads.\n", cl_raw_list_get_elem_count(thread_list)); thread_p = cl_thread_list_get_first_thread(thread_list); id = thread_p->thread_id; printf("-----------> delete thread %d ...\n", id); cl_thread_list_delete_thread_by_id(thread_list, id); printf("<----------- delete thread %d done\n", id); printf("-----------> add thread ...\n"); cl_thread_list_create_thread(thread_list, &dummy_thread_p, NULL,"new thread", id, my_thread, NULL, NULL, CL_TT_USER1); printf("<----------- add thread done\n"); } /* delete all threads */ while ( (thread_p=cl_thread_list_get_first_thread(thread_list)) != NULL ) { int id = thread_p->thread_id; printf("-----------> delete thread %d ...\n",id ); cl_thread_list_delete_thread(thread_list, thread_p); printf("<----------- delete thread %d done\n",id ); } cl_thread_list_cleanup(&thread_list); printf("main done\n"); return 0; }
void sge_event_master_terminate(void) { cl_thread_settings_t* thread = NULL; DENTER(TOP_LAYER, "sge_event_master_terminate"); thread = cl_thread_list_get_first_thread(Main_Control.event_master_thread_pool); while (thread != NULL) { DPRINTF((SFN" gets canceled\n", thread->thread_name)); cl_thread_list_delete_thread(Main_Control.event_master_thread_pool, thread); thread = cl_thread_list_get_first_thread(Main_Control.event_master_thread_pool); } DPRINTF(("all "SFN" threads terminated\n", threadnames[DELIVERER_THREAD])); DRETURN_VOID; }
void sge_signaler_initiate_termination(void) { cl_thread_settings_t* thread = NULL; DENTER(TOP_LAYER, "sge_signaler_initiate_termination"); thread = cl_thread_list_get_first_thread(Main_Control.signal_thread_pool); if (thread != NULL) { pthread_kill(*(thread->thread_pointer), SIGINT); INFO((SGE_EVENT, "send SIGINT to "SFN, thread->thread_name)); } DRETURN_VOID; }
void sge_signaler_terminate(void) { cl_thread_settings_t* thread = NULL; DENTER(TOP_LAYER, "sge_signaler_terminate"); thread = cl_thread_list_get_first_thread(Main_Control.signal_thread_pool); if (thread != NULL) { DPRINTF(("getting canceled\n")); cl_thread_list_delete_thread(Main_Control.signal_thread_pool, thread); } DRETURN_VOID; }
/****** qmaster/threads/sge_scheduler_terminate() **************************** * NAME * sge_scheduler_terminate() -- terminate the scheduler * * SYNOPSIS * void sge_scheduler_terminate(sge_gdi_ctx_class_t *ctx) * * FUNCTION * Terminates the scheduler if it was started previousely. This * function will return only when it is sure that the pthread canceled. * * 'Master_Scheduler' is accessed by this function. * * INPUTS * sge_gdi_ctx_class_t *ctx - context object * lList **answer_list - answer list * * RESULT * void - None * * NOTES * MT-NOTE: sge_scheduler_terminate() is MT safe * * SEE ALSO * qmaster/threads/sge_scheduler_initialize() * qmaster/threads/sge_scheduler_cleanup_thread() * qmaster/threads/sge_scheduler_terminate() * qmaster/threads/sge_scheduler_main() *******************************************************************************/ void sge_scheduler_terminate(sge_gdi_ctx_class_t *ctx, lList **answer_list) { DENTER(TOP_LAYER, "sge_scheduler_terminate"); sge_mutex_lock("master scheduler struct", SGE_FUNC, __LINE__, &(Master_Scheduler.mutex)); if (Master_Scheduler.is_running) { pthread_t thread_id; cl_thread_settings_t* thread = NULL; /* * store thread id to use it later on */ thread = cl_thread_list_get_first_thread(Main_Control.scheduler_thread_pool); thread_id = *(thread->thread_pointer); /* * send cancel signal */ pthread_cancel(thread_id); /* * wakeup scheduler thread which might be blocked by wait for events */ pthread_cond_signal(&Scheduler_Control.cond_var); /* * cl_thread deletion and cl_thread_pool deletion will be done at * schedulers cancelation point in sge_scheduler_cleanup_thread() ... * ... therefore we have nothing more to do. */ ; sge_mutex_unlock("master scheduler struct", SGE_FUNC, __LINE__, &(Master_Scheduler.mutex)); INFO((SGE_EVENT, MSG_THREAD_XTERMINATED_S, threadnames[SCHEDD_THREAD])); answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_INFO); } else { sge_mutex_unlock("master scheduler struct", SGE_FUNC, __LINE__, &(Master_Scheduler.mutex)); ERROR((SGE_EVENT, MSG_THREAD_XNOTRUNNING_S, threadnames[SCHEDD_THREAD])); answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); } DRETURN_VOID; }
/****** qmaster/threads/sge_scheduler_cleanup_thread() ******************** * NAME * sge_scheduler_cleanup_thread() -- cleanup the scheduler thread * * SYNOPSIS * void sge_scheduler_cleanup_thread(void) * * FUNCTION * Cleanup the scheduler thread. * * This function has to be executed only by the scheduler thread. * Ideally it should be the last function executed when the * pthread cancelation point is passed. * * 'Master_Scheduler' is accessed by this function. * * INPUTS * void - None * * RESULT * void - none * * NOTES * MT-NOTE: sge_scheduler_cleanup_thread() is MT safe * * SEE ALSO * qmaster/threads/sge_scheduler_initialize() * qmaster/threads/sge_scheduler_cleanup_thread() * qmaster/threads/sge_scheduler_terminate() * qmaster/threads/sge_scheduler_main() *******************************************************************************/ void sge_scheduler_cleanup_thread(void *ctx_ref) { DENTER(TOP_LAYER, "sge_scheduler_cleanup_thread"); sge_mutex_lock("master scheduler struct", SGE_FUNC, __LINE__, &(Master_Scheduler.mutex)); if (Master_Scheduler.is_running) { cl_thread_settings_t* thread = NULL; /* * The scheduler thread itself executes this function (sge_scheduler_cleanup_thread()) * at the cancelation point as part of the cleanup. * Therefore it has to unset the thread config before the * cl_thread is deleted. Otherwise we might run into a race condition when logging * is used after the call of cl_thread_list_delete_thread_without_join() */ cl_thread_unset_thread_config(); /* * Delete the scheduler thread but don't wait for termination */ thread = cl_thread_list_get_first_thread(Main_Control.scheduler_thread_pool); cl_thread_list_delete_thread_without_join(Main_Control.scheduler_thread_pool, thread); /* * Trash the thread pool */ cl_thread_list_cleanup(&Main_Control.scheduler_thread_pool); /* * now a new scheduler can start */ Master_Scheduler.is_running = false; /* ** free the ctx too */ sge_gdi_ctx_class_destroy((sge_gdi_ctx_class_t **)ctx_ref); } sge_mutex_unlock("master scheduler struct", SGE_FUNC, __LINE__, &(Master_Scheduler.mutex)); DRETURN_VOID; }
void sge_worker_terminate(sge_gdi_ctx_class_t *ctx) { bool do_final_spooling; DENTER(TOP_LAYER, "sge_worker_terminate"); sge_tq_wakeup_waiting(Master_Task_Queue); /* * trigger pthread_cancel for each thread so that further * shutdown process will be faster */ { cl_thread_list_elem_t *thr = NULL; cl_thread_list_elem_t *thr_nxt = NULL; thr_nxt = cl_thread_list_get_first_elem(Main_Control.worker_thread_pool); while ((thr = thr_nxt) != NULL) { thr_nxt = cl_thread_list_get_next_elem(thr); cl_thread_shutdown(thr->thread_config); } } /* * Shutdown/delete the threads and wait for termination */ { cl_thread_settings_t *thread = NULL; thread = cl_thread_list_get_first_thread(Main_Control.worker_thread_pool); while (thread != NULL) { DPRINTF(("gets canceled\n")); cl_thread_list_delete_thread(Main_Control.worker_thread_pool, thread); thread = cl_thread_list_get_first_thread(Main_Control.worker_thread_pool); } DPRINTF(("all "SFN" threads terminated\n", threadnames[WORKER_THREAD])); } do_final_spooling = sge_qmaster_do_final_spooling(); /* shutdown and remove JSV instances */ jsv_list_remove_all(); reporting_shutdown(ctx, NULL, do_final_spooling); DPRINTF(("accounting and reporting module has been shutdown\n")); /* * final spooling is only done if the shutdown of the current instance * of this master process is not triggered due to the fact that * shadowed started another instance which is currently running ... * * ... in that case we would overwrite data which might have already * changed in the second instance of the master */ if (do_final_spooling == true) { sge_store_job_number(ctx, NULL, NULL); sge_store_ar_id(ctx, NULL, NULL); DPRINTF(("job/ar counter made persistent\n")); sge_job_spool(ctx); /* store qmaster jobs to database */ sge_userprj_spool(ctx); /* spool the latest usage */ DPRINTF(("final job and user/project spooling has been triggered\n")); } sge_shutdown_persistence(NULL); DPRINTF(("persistence module has been shutdown\n")); DRETURN_VOID; }
extern int main(int argc, char** argv) { cl_raw_list_t* log_list = NULL; cl_thread_settings_t* thread_p = NULL; cl_thread_settings_t* log_thread = NULL; cl_thread_settings_t* dummy_thread_p = NULL; int count = 2; if (argc != 2) { printf("please enter 0 for standard log function, 1 for special\n"); exit(1); } /* setup log list */ if (atoi(argv[1]) == 0) { cl_log_list_setup(&log_list,"application",0,CL_LOG_IMMEDIATE, NULL); } else { cl_log_list_setup(&log_list,"application",0,CL_LOG_IMMEDIATE, my_log_flush_list); } /* setup log thread */ log_thread = (cl_thread_settings_t*) malloc(sizeof(cl_thread_settings_t)); cl_thread_setup(log_thread, log_list, "log thread", 1,my_log_thread, NULL, NULL, CL_TT_USER1); cl_log_list_set_log_level(log_list,CL_LOG_DEBUG ); /* setup thread list */ cl_thread_list_setup(&thread_list,"thread list"); /* setup first thread */ cl_thread_list_create_thread(thread_list, &dummy_thread_p, log_list, "1st thread", 1, my_test_thread, NULL, NULL, CL_TT_USER1); /* setup second thread */ cl_thread_list_create_thread(thread_list, &dummy_thread_p, log_list, "2nd thread", 2, my_test_thread, NULL, NULL, CL_TT_USER1); thread_p = cl_thread_list_get_thread_by_id(thread_list, 1); CL_LOG_STR( CL_LOG_INFO, "My thread name is ", thread_p->thread_name ); thread_p = cl_thread_list_get_thread_by_name(thread_list, "2nd thread"); CL_LOG_STR( CL_LOG_INFO, "My thread name is ", thread_p->thread_name ); while ( count < 10 ) { int id; char new_thread_name[255]; count++; CL_LOG_INT(CL_LOG_INFO, "number of threads: ", (int)cl_raw_list_get_elem_count(thread_list) ); thread_p = cl_thread_list_get_first_thread(thread_list); id = thread_p->thread_id; CL_LOG_INT( CL_LOG_INFO, "delete thread: ", id ); cl_thread_list_delete_thread_by_id(thread_list, id); CL_LOG_INT(CL_LOG_INFO, "thread deleted, id: ", id ); sprintf(new_thread_name,"thread nr %d", count); CL_LOG( CL_LOG_INFO, "adding thread ..."); cl_thread_list_create_thread(thread_list,&dummy_thread_p, log_list,new_thread_name, id, my_test_thread, NULL, NULL, CL_TT_USER1); CL_LOG( CL_LOG_INFO, "adding thread done"); } /* remove all threads from thread list */ while ( (thread_p=cl_thread_list_get_first_thread(thread_list)) != NULL ) { int id = thread_p->thread_id; CL_LOG_INT( CL_LOG_INFO, "delete thread: ", id ); CL_LOG_INT( CL_LOG_INFO, "event calls: ", (int)thread_p->thread_event_count ); cl_thread_list_delete_thread_by_id(thread_list, id); CL_LOG_INT( CL_LOG_INFO, "thread deleted, id: ", id ); } CL_LOG_INT( CL_LOG_INFO, "log event calls: ", (int)log_thread->thread_event_count ); CL_LOG( CL_LOG_INFO, "cleaning up thread list"); cl_thread_list_cleanup(&thread_list); /* shutdown of log thread */ cl_thread_shutdown(log_thread); cl_thread_join(log_thread); cl_thread_cleanup(log_thread); free(log_thread); /* cleanup log list */ CL_LOG( CL_LOG_INFO, "cleaning up log list"); printf( "cl_log_list_cleanup() returned: %s\n", cl_get_error_text(cl_log_list_cleanup(&log_list))); printf("main done\n"); return 0; }