/****** shepherd_binding/create_binding_env_linux() **************************** * NAME * create_binding_env_linux() -- Creates SGE_BINDING env variable. * * SYNOPSIS * bool create_binding_env_linux(const int* proc_id, const int amount) * * FUNCTION * Creates the SGE_BINDING environment variable on Linux operating system. * This environment variable contains a space separated list of Linux * internal processor ids given as input parameter. * * INPUTS * const int* proc_id - List of processor ids. * const int amount - Length of processor id list. * * RESULT * bool - true when SGE_BINDING env var could be generated false if not * * NOTES * MT-NOTE: create_binding_env_linux() is MT safe * *******************************************************************************/ bool create_binding_env_linux(const int* proc_id, const int amount) { bool retval = true; dstring sge_binding = DSTRING_INIT; dstring proc = DSTRING_INIT; int i; for (i = 0; i < amount; i++) { sge_dstring_clear(&proc); /* DG TODO env ends with whitespace char */ sge_dstring_sprintf(&proc, "%d ", proc_id[i]); sge_dstring_append_dstring(&sge_binding, &proc); } if (sge_setenv("SGE_BINDING", sge_dstring_get_string(&sge_binding)) != 1) { /* settting env var was not successful */ retval = false; shepherd_trace("create_binding_env_linux: Couldn't set environment variable!"); } sge_dstring_free(&sge_binding); sge_dstring_free(&proc); return retval; }
/****** uti/monitor/sge_monitor_output() *************************************** * NAME * sge_monitor_output() -- outputs the result into the message file * * SYNOPSIS * void sge_monitor_output(monitoring_t *monitor) * * FUNCTION * This function computes the output line from the gathered statistics. * The output is only generated, when the the output flag in the * monitoring structure is set. * * The monitoring line is printed to the message file in the profiling * class and it made available for the qping -f output. For the qping * output, it stores the the generation time, though that qping can * show, when the message was generated. * * If an extension is set, it calls the apropriate output function for * it. * * INPUTS * monitoring_t *monitor - the monitoring info * * NOTES * MT-NOTE: sge_monitor_output() is MT safe * *******************************************************************************/ void sge_monitor_output(monitoring_t *monitor) { DENTER(GDI_LAYER, "sge_monitor_output"); if ((monitor != NULL) && (monitor->output == true)) { struct timeval after; double time; gettimeofday(&after, NULL); time = after.tv_usec - monitor->now.tv_usec; time = after.tv_sec - monitor->now.tv_sec + (time/1000000); sge_dstring_clear(monitor->work_line); sge_dstring_sprintf_append(monitor->work_line, MSG_UTI_MONITOR_DEFLINE_SF, monitor->thread_name, monitor->message_in_count/time); if (monitor->ext_type != NONE_EXT) { sge_dstring_append(monitor->work_line, " ("); monitor->ext_output(monitor->work_line, monitor->ext_data, time); sge_dstring_append(monitor->work_line, ")"); }; sge_dstring_sprintf_append(monitor->work_line, MSG_UTI_MONITOR_DEFLINE_FFFFF, monitor->message_out_count/time, monitor->message_in_count ? (time - monitor->idle)/monitor->message_in_count: 0, monitor->idle/time*100, monitor->wait/time*100, time); /* only log into the message file, if the user wants it */ if (monitor->log_monitor_mes) { sge_log(LOG_PROF, sge_dstring_get_string(monitor->work_line),__FILE__,SGE_FUNC,__LINE__); } if (monitor->pos != -1) { dstring *tmp = NULL; sge_mutex_lock("sge_monitor_init", SGE_FUNC, __LINE__, &(Output[monitor->pos].Output_Mutex)); tmp = Output[monitor->pos].output; Output[monitor->pos].output = monitor->work_line; Output[monitor->pos].update_time = after.tv_sec; sge_mutex_unlock("sge_monitor_init", SGE_FUNC, __LINE__, &(Output[monitor->pos].Output_Mutex)); monitor->work_line = tmp; } sge_monitor_reset(monitor); } DRETURN_VOID; }
/****** uti/dstring/sge_dstring_copy_dstring() ******************************** * NAME * sge_dstring_copy_dstring() -- strcpy() for dstrings's * * SYNOPSIS * const char* sge_dstring_copy_dstring(dstring *sb1, * const dstring *sb2) * * FUNCTION * strcpy() for dstrings's * * INPUTS * dstring *sb1 - destination dstring * const dstring *sb2 - source dstring * * NOTES * MT-NOTE: sge_dstring_copy_dstring() is MT safe * * RESULT * const char* - result string buffer *******************************************************************************/ const char *sge_dstring_copy_dstring(dstring *sb1, const dstring *sb2) { const char *ret = NULL; DENTER(DSTRING_LAYER, "sge_dstring_copy_dstring"); if (sb1 != NULL) { sge_dstring_clear(sb1); ret = sge_dstring_append(sb1, sge_dstring_get_string(sb2)); } DEXIT; return ret; }
/****** uti/dstring/sge_dstring_copy_string() ********************************* * NAME * sge_dstring_copy_string() -- copy string into dstring * * SYNOPSIS * const char* sge_dstring_copy_string(dstring *sb, char* str) * * FUNCTION * Copy string into dstring * * INPUTS * dstring *sb - destination dstring * char* str - source string * * NOTES * MT-NOTE: sge_dstring_copy_string() is MT safe * * RESULT * const char* - result string *******************************************************************************/ const char *sge_dstring_copy_string(dstring *sb, const char *str) { const char *ret = NULL; DENTER(DSTRING_LAYER, "sge_dstring_copy_string"); if (sb != NULL) { sge_dstring_clear(sb); ret = sge_dstring_append(sb, str); } DEXIT; return ret; }
/****** read_defaults/get_user_home_file_path() ***************************** * NAME * get_user_home_file_path() -- get absolut path name to file in user * home * * SYNOPSIS * char *get_user_home_file_path (lList **answer_list) * * FUNCTION * This function returns the path to the file in the user's home * directory * * INPUTS * dstring - computed absoult filename * const char *filename - file name * const char *user - user name * lList* - answer list, AN_Type or NULL if everything ok * possible errors: * STATUS_ENOSUCHUSER - could not retrieve passwd info on me.user_name * STATUS_EDISK - home directory for user is missing or cwd * cannot be read or file could not be opened * (is just a warning) * STATUS_EEXIST - (parse_script_file), (is just a warning) * STATUS_EUNKNOWN - (parse_script_file), error opening or * reading from existing file, (is just a warning) * plus all other error stati returned by * parse_script_file, see there * * RETURNS * bool - true or false * * MT-NOTE: get_user_home_file_path() is MT safe *******************************************************************************/ bool get_user_home_file_path(dstring *absolut_filename, const char *filename, const char *user, lList **answer_list) { bool ret = false; DENTER (TOP_LAYER, "get_user_home_file_path"); if (absolut_filename != NULL && filename != NULL) { sge_dstring_clear(absolut_filename); if (get_user_home(absolut_filename, user, answer_list)) { sge_dstring_append(absolut_filename, "/"); sge_dstring_append(absolut_filename, filename); ret = true; } } DRETURN(ret); }
/****** test_category/test_performance() *************************************** * NAME * test_performance() -- messures and outputs the time neede for n category strings * * SYNOPSIS * double test_performance(lListElem *job_elem, int max, lList* access_list) * * INPUTS * lListElem *job_elem - job object * int max - number of generated category strings * lList* access_list - access list or NULL * * RESULT * double - time needed for the run * * NOTES * MT-NOTE: test_performance() is MT safe * *******************************************************************************/ static double test_performance(lListElem *job_elem, int max, lList* access_list, const lList *project_list, const lList *rqs_list) { int i; dstring category_str = DSTRING_INIT; struct timeval before; struct timeval after; double time_new; gettimeofday(&before, NULL); for (i = 0; i < max; i++) { sge_build_job_category_dstring(&category_str, job_elem, access_list, project_list, NULL, rqs_list); sge_dstring_clear(&category_str); } gettimeofday(&after, NULL); sge_dstring_free(&category_str); time_new = after.tv_usec - before.tv_usec; time_new = after.tv_sec - before.tv_sec + (time_new/1000000); printf("tested %d category creations: new: %.2fs\n", max, time_new); return time_new; }
/****** uti/monitor/sge_monitor_status() *************************************** * NAME * sge_monitor_status() -- generates the status for qping / commlib * * SYNOPSIS * u_long32 sge_monitor_status(char **info_message, u_long32 monitor_time) * * FUNCTION * This method creats the health monitoring output and returns the monitoring * info to the commlib. * * INPUTS * char **info_message - info_message pointer, has to point to a NULL string * u_long32 monitor_time - the configured monitoring interval * * RESULT * u_long32 - 0 : everything is okay * 1 : warning * 2 : error * 3 : init problems * * NOTES * MT-NOTE: sge_monitor_status() is MT safe * *******************************************************************************/ u_long32 sge_monitor_status(char **info_message, u_long32 monitor_time) { u_long32 ret = 0; char date[40]; dstring ddate; DENTER(GDI_LAYER, "sge_monitor_status"); if (info_message == NULL) { DEXIT; return 3; } sge_dstring_init(&ddate, date, sizeof(date)); sge_mutex_lock("sge_monitor_status", SGE_FUNC, __LINE__, &global_mutex); sge_dstring_clear(&Info_Line); {/* this is the qping info section, it checks if each thread is still alive */ int i; int error_count = 0; struct timeval now; double time; char state = 'R'; gettimeofday(&now,NULL); for (i = 0; i < MAX_OUTPUT_LINES; i++) { sge_mutex_lock("sge_monitor_status", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex)); if (Output[i].name != NULL) { time = now.tv_usec - Output[i].last_wait_time.tv_usec; time = now.tv_sec - Output[i].last_wait_time.tv_sec + (time /1000000); if (Output[i].warning_timeout != NO_WARNING) { if (Output[i].warning_timeout < time) { if (Output[i].error_timeout < time) { state = 'E'; } else { state = 'W'; } error_count++; } } sge_dstring_sprintf_append(&Info_Line, MSG_UTI_MONITOR_INFO_SCF, Output[i].name, state, time); } sge_mutex_unlock("sge_monitor_status", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex)); } if (error_count == 0) { sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_OK); } else if (error_count == 1) { ret = 1; sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_WARNING); } else { ret = 2; sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_ERROR); } sge_dstring_append(&Info_Line, "\n"); } #if defined(LINUX) || defined(AIX43) || defined(AIX51) || defined(IRIX) || defined(SOLARIS) || defined(HP11) if (mallinfo_func_pointer != NULL) { struct mallinfo mallinfo_data = mallinfo_func_pointer(); sge_dstring_sprintf_append(&Info_Line, MSG_UTI_MONITOR_SCHEXT_UUUUUUUUUU, mallinfo_data.arena, mallinfo_data.ordblks, mallinfo_data.smblks, mallinfo_data.hblks, mallinfo_data.hblkhd, mallinfo_data.usmblks, mallinfo_data.fsmblks, mallinfo_data.uordblks, mallinfo_data.fordblks, mallinfo_data.keepcost); sge_dstring_append(&Info_Line, "\n"); } #endif if (monitor_time != 0) { /* generates the output monitoring output data */ int i; sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_COLON); sge_dstring_append(&Info_Line, "\n"); for (i = 0; i < MAX_OUTPUT_LINES; i++) { sge_mutex_lock("sge_monitor_status", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex)); if (Output[i].name != NULL) { append_time(Output[i].update_time, &Info_Line, false); sge_dstring_append(&Info_Line, " | "); sge_dstring_append_dstring(&Info_Line, Output[i].output); sge_dstring_append(&Info_Line,"\n"); } sge_mutex_unlock("sge_monitor_status", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex)); } } else { sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_DISABLED); sge_dstring_append(&Info_Line, "\n"); } *info_message = strdup(sge_dstring_get_string(&Info_Line)); sge_mutex_unlock("sge_monitor_status", SGE_FUNC, __LINE__, &global_mutex); DEXIT; return ret; }
/****** uti/monitor/sge_monitor_init() ***************************************** * NAME * sge_monitor_init() -- init the monitoring structure * * SYNOPSIS * void sge_monitor_init(monitoring_t *monitor, const char *thread_name, * extension_t ext, thread_warning_t warning_timeout, thread_error_t * error_timeout) * * FUNCTION * Sets the default values and inits the structure, finds the line pos * for the comlib output * * INPUTS * monitoring_t *monitor - monitoring strucutre * const char *thread_name - the thread name * extension_t ext - the extension time (-> enum) * thread_warning_t warning_timeout - the warning timeout (-> enum) * thread_error_t error_timeout - the error timeout (-> enum) * * NOTES * MT-NOTE: sge_monitor_init() is MT safe * *******************************************************************************/ void sge_monitor_init(monitoring_t *monitor, const char *thread_name, extension_t ext, thread_warning_t warning_timeout, thread_error_t error_timeout) { DENTER(GDI_LAYER, "sge_monitor_init"); /* * initialize the mallinfo function pointer if it is available */ #if defined(LINUX) || defined(AIX43) || defined(AIX51) || defined(IRIX) || defined(SOLARIS) || defined(HP11) sge_mutex_lock("sge_monitor_status", SGE_FUNC, __LINE__, &global_mutex); if (mallinfo_initialized == false) { const char *function_name = "mallinfo"; mallinfo_initialized = true; # ifdef RTLD_NODELETE mallinfo_shlib_handle = dlopen(NULL, RTLD_LAZY | RTLD_NODELETE); # else mallinfo_shlib_handle = dlopen(NULL, RTLD_LAZY ); # endif /* RTLD_NODELETE */ if (mallinfo_shlib_handle != NULL) { mallinfo_func_pointer = (struct mallinfo (*)(void)) dlsym(mallinfo_shlib_handle, function_name); } } sge_mutex_unlock("sge_monitor_status", SGE_FUNC, __LINE__, &global_mutex); #endif monitor->thread_name = thread_name; monitor->output_line1 = (dstring*) malloc(sizeof(dstring)); monitor->output_line2 = (dstring*) malloc(sizeof(dstring)); if (monitor->output_line1 == NULL || monitor->output_line2 == NULL) { CRITICAL((SGE_EVENT, SFNMAX, MSG_UTI_MONITOR_MEMERROR)); exit(1); } memset(monitor->output_line1, 0, sizeof(dstring)); memset(monitor->output_line2, 0, sizeof(dstring)); sge_dstring_append(monitor->output_line1, thread_name); sge_dstring_append(monitor->output_line1, MSG_UTI_MONITOR_NODATA); sge_dstring_clear(monitor->output_line2); monitor->work_line = monitor->output_line2; switch(ext) { case SCH_EXT : monitor->ext_data = malloc(sizeof(m_sch_t)); if (monitor->ext_data != NULL) { monitor->ext_type = SCH_EXT; monitor->ext_data_size = sizeof(m_sch_t); monitor->ext_output = &ext_sch_output; } else { monitor->ext_type = NONE_EXT; ERROR((SGE_EVENT, SFNMAX, MSG_UTI_MONITOR_MEMERROREXT)); } break; case GDI_EXT : monitor->ext_data = malloc(sizeof(m_gdi_t)); if (monitor->ext_data != NULL) { monitor->ext_type = GDI_EXT; monitor->ext_data_size = sizeof(m_gdi_t); monitor->ext_output = &ext_gdi_output; } else { monitor->ext_type = NONE_EXT; ERROR((SGE_EVENT, SFNMAX, MSG_UTI_MONITOR_MEMERROREXT)); } break; case LIS_EXT : monitor->ext_data = malloc(sizeof(m_lis_t)); if (monitor->ext_data != NULL) { monitor->ext_type = LIS_EXT; monitor->ext_data_size = sizeof(m_lis_t); monitor->ext_output = &ext_lis_output; } else { monitor->ext_type = NONE_EXT; ERROR((SGE_EVENT, SFNMAX, MSG_UTI_MONITOR_MEMERROREXT)); } break; case EDT_EXT : monitor->ext_data = malloc(sizeof(m_edt_t)); if (monitor->ext_data != NULL) { monitor->ext_type = EDT_EXT; monitor->ext_data_size = sizeof(m_edt_t); monitor->ext_output = &ext_edt_output; } else { monitor->ext_type = NONE_EXT; ERROR((SGE_EVENT, SFNMAX, MSG_UTI_MONITOR_MEMERROREXT)); } break; case TET_EXT : monitor->ext_data = malloc(sizeof(m_tet_t)); if (monitor->ext_data != NULL) { monitor->ext_type = TET_EXT; monitor->ext_data_size = sizeof(m_tet_t); monitor->ext_output = &ext_tet_output; } else { monitor->ext_type = NONE_EXT; ERROR((SGE_EVENT, SFNMAX, MSG_UTI_MONITOR_MEMERROREXT)); } break; case NONE_EXT : monitor->ext_type = NONE_EXT; break; default : monitor->ext_type = NONE_EXT; ERROR((SGE_EVENT, MSG_UTI_MONITOR_UNSUPPORTEDEXT_D, ext)); }; if (monitor->ext_type == NONE_EXT) { monitor->ext_data_size = 0; monitor->ext_data = NULL; monitor->ext_output = NULL; } sge_monitor_reset(monitor); { int i; struct timeval time; monitor->pos = -1; gettimeofday(&time, NULL); for (i = 0; i < MAX_OUTPUT_LINES; i++) { sge_mutex_lock("sge_monitor_init", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex)); if (Output[i].name == NULL) { monitor->pos = i; Output[i].output = monitor->output_line1; Output[i].name = thread_name; Output[i].warning_timeout = warning_timeout; Output[i].error_timeout = error_timeout; Output[i].update_time = time.tv_sec; sge_mutex_unlock("sge_monitor_init", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex)); break; } sge_mutex_unlock("sge_monitor_init", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex)); } sge_set_last_wait_time(monitor, time); } if (monitor->pos == -1) { ERROR((SGE_EVENT, MSG_UTI_MONITOR_NOLINES_S, monitor->thread_name)); } DEXIT; }
/****** cull/list/lWriteListXMLTo() ********************************************** * NAME * lWriteListXMLTo() -- Write a list to a file stream * * SYNOPSIS * void lWriteListXMLTo(const lList *lp, FILE *fp) * * FUNCTION * Write a list to a file stream in XML format * * INPUTS * const lList *lp - list * int nesting_level - current nesting level * FILE *fp - file stream * * NOTE: * MT-NOTE: is thread save, works only on the objects which are passed in * *******************************************************************************/ static void lWriteListXML_(const lList *lp, int nesting_level, FILE *fp, int ignore_cull_name) { lListElem *ep; char indent[128]; int i; bool is_XML_elem = false; dstring attr = DSTRING_INIT; bool is_attr = false; DENTER(CULL_LAYER, "lWriteListXML_"); if (!lp) { LERROR(LELISTNULL); DEXIT; return; } { int max = nesting_level * 2; if (max > 128) max = 128; for (i = 0; i < max; i++) indent[i] = ' '; indent[i] = '\0'; } for_each(ep, lp) { is_XML_elem = false; is_attr = false; if (lGetPosViaElem(ep, XMLE_Attribute, SGE_NO_ABORT) != -1) { sge_dstring_clear(&attr); is_attr = lAttributesToString_(lGetList(ep, XMLE_Attribute), &attr); is_XML_elem = true; } if (is_XML_elem && (lGetBool(ep, XMLE_Print))) { lListElem *elem = lGetObject(ep, XMLE_Element); if (!fp) { if (lGetString(elem, XMLA_Value) != NULL) { DPRINTF(("%s<%s%s>", indent, lGetString(elem, XMLA_Name), (is_attr?sge_dstring_get_string(&attr):""))); DPRINTF(("%s", lGetString(elem, XMLA_Value))); lWriteListXML_(lGetList(ep, XMLE_List), nesting_level+1, fp, ignore_cull_name); DPRINTF(("</%s>\n", lGetString(elem, XMLA_Name))); } else { DPRINTF(("%s<%s%s>\n", indent, lGetString(elem, XMLA_Name), (is_attr?sge_dstring_get_string(&attr):""))); lWriteListXML_(lGetList(ep, XMLE_List), nesting_level+1, fp, ignore_cull_name); DPRINTF(("%s</%s>\n", indent,lGetString(elem, XMLA_Name))); } } else { if (lGetString(elem, XMLA_Value) != NULL) { fprintf(fp, "%s<%s%s>", indent, lGetString(elem, XMLA_Name), (is_attr?sge_dstring_get_string(&attr):"")); fprintf(fp, "%s", lGetString(elem, XMLA_Value)); lWriteListXML_(lGetList(ep, XMLE_List), nesting_level+1, fp, ignore_cull_name); fprintf(fp, "</%s>\n", lGetString(elem, XMLA_Name)); } else { fprintf(fp, "%s<%s%s>\n", indent, lGetString(elem, XMLA_Name), (is_attr?sge_dstring_get_string(&attr):"")); lWriteListXML_(lGetList(ep, XMLE_List), nesting_level+1, fp, ignore_cull_name); fprintf(fp, "%s</%s>\n", indent, lGetString(elem, XMLA_Name)); } } } else { const char* listName = lGetListName(lp); if (strcmp (listName, "No list name specified") == 0) { listName = "element"; } if (!fp) { DPRINTF(("%s<%s%s>\n", indent, listName, ((is_attr)?sge_dstring_get_string(&attr):""))); lWriteElemXML_(ep, nesting_level+1, NULL, ignore_cull_name); DPRINTF(("%s</%s>\n", indent, listName)); } else { fprintf(fp, "%s<%s%s>\n", indent, listName, ((is_attr)?sge_dstring_get_string(&attr):"")); lWriteElemXML_(ep, nesting_level+1, fp, ignore_cull_name); fprintf(fp, "%s</%s>\n", indent, listName); } } }
static bool check_all(dstring *sb) { bool ret = true; int i; /* sge_dstring_append */ printf("\nchecking sge_dstring_append\n"); sge_dstring_append(NULL, NULL); sge_dstring_append(sb, NULL); check_dstring(sb); sge_dstring_append(sb, "blah"); check_dstring(sb); sge_dstring_clear(sb); sge_dstring_append(sb, "too long string to fit into a static string buffer"); check_dstring(sb); sge_dstring_clear(sb); sge_dstring_append(sb, "long string that requires multiple chunks ....... "); check_dstring(sb); for (i = 0; i < 20; i++) { sge_dstring_append(sb, "long string that requires multiple chunks ....... "); } check_dstring(sb); /* sge_dstring_append_dstring */ printf("\nchecking sge_dstring_append_dstring\n"); sge_dstring_clear(sb); sge_dstring_append_dstring(NULL, NULL); { dstring second = DSTRING_INIT; sge_dstring_append(&second, "dstring"); sge_dstring_append_dstring(NULL, &second); sge_dstring_append_dstring(sb, NULL); sge_dstring_append_dstring(sb, &second); check_dstring(sb); sge_dstring_free(&second); } /* sge_dstring_append_char */ printf("\nchecking sge_dstring_append_char\n"); sge_dstring_clear(sb); sge_dstring_append_char(NULL, 'a'); sge_dstring_append_char(sb, '\0'); check_dstring(sb); sge_dstring_append_char(sb, 'a'); check_dstring(sb); sge_dstring_append_char(sb, 'b'); check_dstring(sb); /* sge_dstring_sprintf */ printf("\nchecking sge_dstring_sprintf\n"); sge_dstring_sprintf(NULL, "test %s", "string"); sge_dstring_sprintf(sb, NULL); sge_dstring_sprintf(sb, "test %s", "string"); check_dstring(sb); #if 0 /* does not build on irix */ /* sge_dstring_vsprintf */ printf("\nchecking sge_dstring_vsprintf\n"); { const char *args[] = { "string", NULL }; sge_dstring_clear(sb); sge_dstring_vsprintf(NULL, "test %s", args); sge_dstring_vsprintf(sb, NULL, args); sge_dstring_vsprintf(sb, "test %s", args); check_dstring(sb); } #endif /* sge_dstring_sprintf_append */ printf("\nchecking sge_dstring_sprintf_append\n"); sge_dstring_clear(sb); sge_dstring_sprintf_append(NULL, "test %s", "string"); sge_dstring_sprintf_append(sb, NULL); sge_dstring_sprintf_append(sb, "test %s", "string"); sge_dstring_sprintf_append(sb, " appended test %s", "string"); check_dstring(sb); /* sge_dstring_clear */ printf("\nchecking sge_dstring_clear\n"); sge_dstring_clear(NULL); sge_dstring_clear(sb); check_dstring(sb); /* sge_dstring_free */ printf("\nchecking sge_dstring_free\n"); sge_dstring_free(NULL); sge_dstring_free(sb); check_dstring(sb); /* sge_dstring_get_string */ printf("\nchecking sge_dstring_get_string\n"); sge_dstring_clear(sb); sge_dstring_append(sb, "test string"); { const char *result; result = sge_dstring_get_string(NULL); printf("sge_dstring_get_string(NULL) = %s\n", result == NULL ? "NULL" : result); result = sge_dstring_get_string(sb); printf("sge_dstring_get_string(sb) = %s\n", result == NULL ? "NULL" : result); } /* sge_dstring_copy_string */ printf("\nchecking sge_dstring_copy_string\n"); sge_dstring_copy_string(NULL, NULL); sge_dstring_copy_string(sb, NULL); sge_dstring_copy_string(NULL, "new test string"); sge_dstring_copy_string(sb, "new test string"); check_dstring(sb); /* sge_dstring_copy_dstring * check only NULL pointer behaviour, it just calls sge_dstring_copy_string */ printf("\nchecking sge_dstring_copy_dstring\n"); sge_dstring_copy_dstring(NULL, NULL); sge_dstring_copy_dstring(sb, NULL); check_dstring(sb); /* sge_dstring_strlen */ printf("\nchecking sge_dstring_strlen\n"); { int len; sge_dstring_copy_string(sb, "test string"); len = sge_dstring_strlen(NULL); printf("sge_dstring_strlen(NULL) = %d\n", len); len = sge_dstring_strlen(sb); printf("sge_dstring_strlen(sb) = %d\n", len); } /* sge_dstring_remaining */ printf("\nchecking sge_dstring_remaining\n"); { int len; sge_dstring_copy_string(sb, "test string"); len = sge_dstring_remaining(NULL); printf("sge_dstring_remaining(NULL) = %d\n", len); len = sge_dstring_remaining(sb); printf("sge_dstring_remaining(sb) = %d\n", len); } return ret; }
/****** shepherd_binding/binding_set_linear_linux() *************************************** * NAME * binding_set_linear_linux() -- Bind current process linear to chunk of cores. * * SYNOPSIS * bool binding_set_linear(int first_socket, int first_core, int * amount_of_cores, int offset) * * FUNCTION * Binds current process (shepherd) to a set of cores. All processes * started by the current process are inheriting the core binding (Linux). * * The core binding is done in a linear manner, that means that * the process is bound to 'amount_of_cores' cores using one core * after another starting at socket 'first_socket' (usually 0) and * core = 'first_core' (usually 0) + 'offset'. If the core number * is higher than the number of cores which are provided by socket * 'first_socket' then the next socket is taken (the core number * defines how many cores are skiped). * * INPUTS * int first_socket - The first socket (starting at 0) to bind to. * int first_core - The first core to bind. * int amount_of_cores - The amount of cores to bind to. * int offset - The user specified core number offset. * binding_type_t type - The type of binding ONLY FOR EXECD ( set | env | pe ) * * RESULT * bool - true if binding for current process was done, false if not * * NOTES * MT-NOTE: binding_set_linear() is not MT safe * *******************************************************************************/ static bool binding_set_linear_linux(int first_socket, int first_core, int amount_of_cores, int offset, const binding_type_t type) { /* sets bitmask in a linear manner */ /* first core is on exclusive host 0 */ /* first core could be set from scheduler */ /* offset is the first core to start with (make sense only with exclusive host) */ dstring error = DSTRING_INIT; if (_has_core_binding(&error) == true) { sge_dstring_clear(&error); /* bitmask for processors to turn on and off */ plpa_cpu_set_t cpuset; /* turn off all processors */ PLPA_CPU_ZERO(&cpuset); sge_dstring_free(&error); if (_has_topology_information()) { /* amount of cores set in processor binding mask */ int cores_set; /* next socket to use */ int next_socket = first_socket; /* the amount of cores of the next socket */ int socket_amount_of_cores; /* next core to use */ int next_core = first_core + offset; /* all the processor ids selected for the mask */ int* proc_id = NULL; /* size of proc_id array */ int proc_id_size = 0; /* maximal amount of sockets on this system */ int max_amount_of_sockets = get_amount_of_plpa_sockets(); /* strategy: go to the first_socket and the first_core + offset and fill up socket and go to the next one. */ /* TODO maybe better to search for using a core exclusively? */ while (get_amount_of_plpa_cores(next_socket) <= next_core) { /* TODO which kind of warning when first socket does not offer this? */ /* move on to next socket - could be that we have to deal only with cores instead of <socket><core> tuples */ next_core -= get_amount_of_plpa_cores(next_socket); next_socket++; if (next_socket >= max_amount_of_sockets) { /* we are out of sockets - we do nothing */ return false; } } add_proc_ids_linux(next_socket, next_core, &proc_id, &proc_id_size); /* collect the other processor ids with the strategy */ for (cores_set = 1; cores_set < amount_of_cores; cores_set++) { next_core++; /* jump to next socket when it is needed */ /* maybe the next socket could offer 0 cores (I can' see when, but just to be sure) */ while ((socket_amount_of_cores = get_amount_of_plpa_cores(next_socket)) <= next_core) { next_socket++; next_core = next_core - socket_amount_of_cores; if (next_socket >= max_amount_of_sockets) { /* we are out of sockets - we do nothing */ sge_free(&proc_id); return false; } } /* get processor ids */ add_proc_ids_linux(next_socket, next_core, &proc_id, &proc_id_size); } /* set the mask for all processor ids */ set_processor_binding_mask(&cpuset, proc_id, proc_id_size); /* check what to do with the processor ids (set, env or pe) */ if (type == BINDING_TYPE_PE) { /* is done outside */ } else if (type == BINDING_TYPE_ENV) { /* set the environment variable */ /* this does not show up in "environment" file !!! */ if (create_binding_env_linux(proc_id, proc_id_size) == true) { shepherd_trace("binding_set_linear_linux: SGE_BINDING env var created"); } else { shepherd_trace("binding_set_linear_linux: problems while creating SGE_BINDING env"); } } else { /* bind SET process to mask */ if (bind_process_to_mask((pid_t) 0, cpuset) == false) { /* there was an error while binding */ sge_free(&proc_id); return false; } } sge_free(&proc_id); } else { /* TODO DG strategy without topology information but with working library? */ shepherd_trace("binding_set_linear_linux: no information about topology"); return false; } } else { shepherd_trace("binding_set_linear_linux: PLPA binding not supported: %s", sge_dstring_get_string(&error)); sge_dstring_free(&error); } return true; }
/****** cull/dump_scan/lDumpElemFp() ****************************************** * NAME * lDumpElemFp() -- Dump a given element into FILE stream * * SYNOPSIS * int lDumpElemFp(FILE *fp, const lListElem *ep, int indent) * * FUNCTION * Dump a given element into FILE stream * * INPUTS * FILE *fp - file stream * const lListElem *ep - element * int indent - * * RESULT * int - error state * 0 - OK * -1 - Error * * NOTES * MT-NOTE: lDumpElemFp() is not MT safe ******************************************************************************/ int lDumpElemFp(FILE *fp, const lListElem *ep, int indent) { int i, ret = ~EOF; lList *tlp; lListElem *tep; char space[256]; const char *str; dstring dstr = DSTRING_INIT; DENTER(CULL_LAYER, "lDumpElemFp"); space[0] = '\0'; for (i = 0; i < indent; i++) strcat(space, INDENT_STRING); if (!fp) { LERROR(LEFILENULL); DEXIT; return -1; } if (!ep) { LERROR(LEELEMNULL); DEXIT; return -1; } ret = fprintf(fp, "%s{ \n", space); for (i = 0, ret = 0; ep->descr[i].nm != NoName && ret != EOF; i++) { char *tok = NULL; switch (mt_get_type(ep->descr[i].mt)) { case lIntT: ret = fprintf(fp, "%s/* %-20.20s */ %d\n", space, lNm2Str(ep->descr[i].nm), lGetPosInt(ep, i)); break; case lUlongT: ret = fprintf(fp, "%s/* %-20.20s */ " sge_u32 "\n", space, lNm2Str(ep->descr[i].nm), lGetPosUlong(ep, i)); break; case lStringT: str = lGetPosString(ep, i); /* quote " inside str */ if ((tok = sge_strtok(str, "\"")) != NULL) { sge_dstring_append(&dstr, tok); while ((tok=sge_strtok(NULL, "\"")) != NULL) { sge_dstring_append(&dstr, "\\\""); sge_dstring_append(&dstr, tok); } } str = sge_dstring_get_string(&dstr); ret = fprintf(fp, "%s/* %-20.20s */ \"%s\"\n", space, lNm2Str(ep->descr[i].nm), str != NULL ? str : ""); sge_dstring_clear(&dstr); break; case lHostT: str = lGetPosHost(ep, i); ret = fprintf(fp, "%s/* %-20.20s */ \"%s\"\n", space, lNm2Str(ep->descr[i].nm), str != NULL ? str : ""); break; case lFloatT: ret = fprintf(fp, "%s/* %-20.20s */ %f\n", space, lNm2Str(ep->descr[i].nm), lGetPosFloat(ep, i)); break; case lDoubleT: ret = fprintf(fp, "%s/* %-20.20s */ %f\n", space, lNm2Str(ep->descr[i].nm), lGetPosDouble(ep, i)); break; case lLongT: ret = fprintf(fp, "%s/* %-20.20s */%ld \n", space, lNm2Str(ep->descr[i].nm), lGetPosLong(ep, i)); break; case lCharT: ret = fprintf(fp, "%s/* %-20.20s */ %c\n", space, lNm2Str(ep->descr[i].nm), lGetPosChar(ep, i)); break; case lBoolT: ret = fprintf(fp, "%s/* %-20.20s */ %d\n", space, lNm2Str(ep->descr[i].nm), lGetPosBool(ep, i)); break; case lRefT: ret = fprintf(fp, "%s/* %-20.20s */ %ld\n", space, lNm2Str(ep->descr[i].nm), (long)lGetPosRef(ep, i)); break; case lObjectT: if ((tep = lGetPosObject(ep, i)) == NULL) ret = fprintf(fp, "%s/* %-20.20s */ none\n", space, lNm2Str(ep->descr[i].nm)); else { ret = fprintf(fp, "%s/* %-20.20s */ object\n", space, lNm2Str(ep->descr[i].nm)); if (ret != EOF) ret = lDumpObject(fp, tep, indent + 1); } break; case lListT: if ((tlp = lGetPosList(ep, i)) == NULL) ret = fprintf(fp, "%s/* %-20.20s */ empty\n", space, lNm2Str(ep->descr[i].nm)); else { ret = fprintf(fp, "%s/* %-20.20s */ full\n", space, lNm2Str(ep->descr[i].nm)); if (ret != EOF) ret = lDumpList(fp, tlp, indent + 1); } break; } } sge_dstring_free(&dstr); ret = fprintf(fp, "%s}\n", space); DEXIT; return (ret == EOF) ? -1 : 0; }