/****** sge_advance_reservation/ar_list_locate() ******************************* * NAME * ar_list_locate() -- locate a advance reservation by id * * SYNOPSIS * lListElem* ar_list_locate(lList *ar_list, u_long32 ar_id) * * FUNCTION * This function returns a ar object with the selected id from the * given list. * * INPUTS * lList *ar_list - list to be searched in * u_long32 ar_id - id of interest * * RESULT * lListElem* - if found the reference to the ar object, else NULL * * NOTES * MT-NOTE: ar_list_locate() is MT safe *******************************************************************************/ lListElem *ar_list_locate(lList *ar_list, u_long32 ar_id) { lListElem *ep = NULL; DENTER(TOP_LAYER, "ar_list_locate"); ep = lGetElemUlong(ar_list, AR_id, ar_id); DRETURN(ep); }
/* * * NOTES * MT-NOTE: sge_qwaittid() is not MT safe * */ int sge_qwaittid(sge_gdi_ctx_class_t *ctx, sge_tid_t tid, int *status, int options) { lListElem *rt = NULL; int ret, rcv_opt = 0; DENTER(TOP_LAYER, "sge_qwaittid"); if (!(options&WNOHANG)) rcv_opt |= OPT_SYNCHRON; if (tid != NULL && !(rt=LOCATE_RTASK(tid))) { sprintf(lasterror, MSG_GDI_TASKNOTEXIST_S , tid); DEXIT; return -1; } while ((rt && /* definite one searched */ lGetUlong(rt, RT_state)!=RT_STATE_EXITED && /* not exited */ lGetUlong(rt, RT_state)==RT_STATE_WAIT4ACK) /* waiting for ack */ || (!rt && /* anybody searched */ !lGetElemUlong(remote_task_list, RT_state, RT_STATE_EXITED) && /* none exited */ lGetElemUlong(remote_task_list, RT_state, RT_STATE_WAIT4ACK))) { /* but one is waiting for ack */ /* wait for incoming messeges about exited tasks */ if ((ret=rcv_from_execd(ctx, rcv_opt, TAG_TASK_EXIT))) { DEXIT; return (ret<0)?-1:0; } } if (status) *status = lGetUlong(rt, RT_status); lSetUlong(rt, RT_state, RT_STATE_WAITED); DEXIT; return 0; }
static void sge_scheduler_wait_for_event(sge_evc_class_t *evc, lList **event_list) { int wait_ret; bool do_ack = false; DENTER(TOP_LAYER, "sge_scheduler_wait_for_event"); sge_mutex_lock("event_control_mutex", SGE_FUNC, __LINE__, &Scheduler_Control.mutex); if (!Scheduler_Control.triggered) { struct timespec ts; u_long32 current_time = sge_get_gmt(); ts.tv_sec = (long) current_time + SCHEDULER_TIMEOUT_S; ts.tv_nsec = SCHEDULER_TIMEOUT_N; wait_ret = pthread_cond_timedwait(&Scheduler_Control.cond_var, &Scheduler_Control.mutex, &ts); /* * if pthread_cond_timedwait returns 0, we were triggered by event master * otherwise we ran into a timeout or an error */ if (wait_ret != 0) { DPRINTF(("pthread_cond_timedwait for events failed %d\n", wait_ret)); } } if (Scheduler_Control.triggered) { *event_list = Scheduler_Control.new_events; Scheduler_Control.new_events = NULL; Scheduler_Control.triggered = false; do_ack = true; } sge_mutex_unlock("event_control_mutex", SGE_FUNC, __LINE__, &Scheduler_Control.mutex); if (do_ack) { if (lGetElemUlong(*event_list, ET_type, sgeE_ACK_TIMEOUT) != NULL) { evc->ec_mark4registration(evc); } evc->ec_ack(evc); } DRETURN_VOID; }
/****** qmaster/threads/sge_scheduler_main() ********************************** * NAME * sge_scheduler_main() -- main function of the scheduler thread * * SYNOPSIS * void * sge_scheduler_main(void *arg) * * FUNCTION * Main function of the scheduler thread, * * INPUTS * void *arg - pointer to the thread function (type cl_thread_settings_t*) * * RESULT * void * - always NULL * * NOTES * MT-NOTE: sge_scheduler_main() is MT safe * * MT-NOTE: this is a thread function. Do NOT use this function * MT-NOTE: in any other way! * * 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_main(void *arg) { time_t next_prof_output = 0; monitoring_t monitor; sge_gdi_ctx_class_t *ctx = NULL; sge_evc_class_t *evc = NULL; lList *alp = NULL; sge_where_what_t where_what; cl_thread_settings_t *thread_config = (cl_thread_settings_t*)arg; bool do_shutdown = false; bool do_endlessly = true; bool local_ret = true; DENTER(TOP_LAYER, "sge_scheduler_main"); memset(&where_what, 0, sizeof(where_what)); /* * startup */ if (local_ret) { /* initialize commlib thread */ cl_thread_func_startup(thread_config); /* initialize monitoring */ sge_monitor_init(&monitor, thread_config->thread_name, SCH_EXT, SCT_WARNING, SCT_ERROR); sge_qmaster_thread_init(&ctx, SCHEDD, SCHEDD_THREAD, true); /* register at profiling module */ set_thread_name(pthread_self(), "Scheduler Thread"); conf_update_thread_profiling("Scheduler Thread"); DPRINTF((SFN" started\n", thread_config->thread_name)); /* initialize schedd_runnlog logging */ schedd_set_schedd_log_file(ctx); } /* set profiling parameters */ prof_set_level_name(SGE_PROF_EVENTMASTER, NULL, NULL); prof_set_level_name(SGE_PROF_SPOOLING, NULL, NULL); prof_set_level_name(SGE_PROF_CUSTOM0, "scheduler", NULL); prof_set_level_name(SGE_PROF_CUSTOM1, "pending ticket calculation", NULL); prof_set_level_name(SGE_PROF_CUSTOM3, "job sorting", NULL); prof_set_level_name(SGE_PROF_CUSTOM4, "job dispatching", NULL); prof_set_level_name(SGE_PROF_CUSTOM5, "send orders", NULL); prof_set_level_name(SGE_PROF_CUSTOM6, "scheduler event loop", NULL); prof_set_level_name(SGE_PROF_CUSTOM7, "copy lists", NULL); prof_set_level_name(SGE_PROF_SCHEDLIB4, NULL, NULL); /* set-up needed for 'schedule' file */ serf_init(schedd_serf_record_func, schedd_serf_newline); schedd_set_serf_log_file(ctx); /* * prepare event client/mirror mechanism */ if (local_ret) { local_ret = sge_gdi2_evc_setup(&evc, ctx, EV_ID_SCHEDD, &alp, "scheduler"); DPRINTF(("prepared event client/mirror mechanism\n")); } /* * register as event mirror */ if (local_ret) { sge_mirror_initialize(evc, EV_ID_SCHEDD, "scheduler", false, &event_update_func, &sge_mod_event_client, &sge_add_event_client, &sge_remove_event_client, &sge_handle_event_ack); evc->ec_register(evc, false, NULL, &monitor); evc->ec_set_busy_handling(evc, EV_BUSY_UNTIL_RELEASED); DPRINTF(("registered at event mirror\n")); } /* * subscribe necessary data */ if (local_ret) { ensure_valid_what_and_where(&where_what); subscribe_scheduler(evc, &where_what); DPRINTF(("subscribed necessary data from event master\n")); } /* * schedulers main loop */ if (local_ret) { while (do_endlessly) { bool handled_events = false; lList *event_list = NULL; int execute = 0; double prof_copy = 0.0; double prof_total = 0.0; double prof_init = 0.0; double prof_free = 0.0; double prof_run = 0.0; lList *orders = NULL; if (sconf_get_profiling()) { prof_start(SGE_PROF_OTHER, NULL); prof_start(SGE_PROF_PACKING, NULL); prof_start(SGE_PROF_EVENTCLIENT, NULL); prof_start(SGE_PROF_MIRROR, NULL); prof_start(SGE_PROF_GDI, NULL); prof_start(SGE_PROF_HT_RESIZE, NULL); prof_start(SGE_PROF_CUSTOM0, NULL); prof_start(SGE_PROF_CUSTOM1, NULL); prof_start(SGE_PROF_CUSTOM3, NULL); prof_start(SGE_PROF_CUSTOM4, NULL); prof_start(SGE_PROF_CUSTOM5, NULL); prof_start(SGE_PROF_CUSTOM6, NULL); prof_start(SGE_PROF_CUSTOM7, NULL); prof_start(SGE_PROF_SCHEDLIB4, NULL); } else { prof_stop(SGE_PROF_OTHER, NULL); prof_stop(SGE_PROF_PACKING, NULL); prof_stop(SGE_PROF_EVENTCLIENT, NULL); prof_stop(SGE_PROF_MIRROR, NULL); prof_stop(SGE_PROF_GDI, NULL); prof_stop(SGE_PROF_HT_RESIZE, NULL); prof_stop(SGE_PROF_CUSTOM0, NULL); prof_stop(SGE_PROF_CUSTOM1, NULL); prof_stop(SGE_PROF_CUSTOM3, NULL); prof_stop(SGE_PROF_CUSTOM4, NULL); prof_stop(SGE_PROF_CUSTOM5, NULL); prof_stop(SGE_PROF_CUSTOM6, NULL); prof_stop(SGE_PROF_CUSTOM7, NULL); prof_stop(SGE_PROF_SCHEDLIB4, NULL); } /* * Wait for new events */ MONITOR_IDLE_TIME(sge_scheduler_wait_for_event(evc, &event_list), (&monitor), mconf_get_monitor_time(), mconf_is_monitor_message()); /* If we lost connection we have to register again */ if (evc->ec_need_new_registration(evc)) { lFreeList(&event_list); if (evc->ec_register(evc, false, NULL, &monitor) == true) { DPRINTF(("re-registered at event master!\n")); } } if (event_list != NULL) { /* check for shutdown */ do_shutdown = (lGetElemUlong(event_list, ET_type, sgeE_SHUTDOWN) != NULL) ? true : false; /* update mirror and free data */ if (do_shutdown == false && sge_mirror_process_event_list(evc, event_list) == SGE_EM_OK) { handled_events = true; DPRINTF(("events handled\n")); } else { DPRINTF(("events contain shutdown event - ignoring events\n")); } lFreeList(&event_list); } /* if we actually got events, start the scheduling run and further event processing */ if (handled_events == true) { lList *answer_list = NULL; scheduler_all_data_t copy; lList *master_cqueue_list = *(object_type_get_master_list(SGE_TYPE_CQUEUE)); lList *master_job_list = *object_type_get_master_list(SGE_TYPE_JOB); lList *master_userset_list = *object_type_get_master_list(SGE_TYPE_USERSET); lList *master_project_list = *object_type_get_master_list(SGE_TYPE_PROJECT); lList *master_exechost_list= *object_type_get_master_list(SGE_TYPE_EXECHOST); lList *master_rqs_list= *object_type_get_master_list(SGE_TYPE_RQS); lList *master_centry_list = *object_type_get_master_list(SGE_TYPE_CENTRY); lList *master_ckpt_list = *object_type_get_master_list(SGE_TYPE_CKPT); lList *master_user_list = *object_type_get_master_list(SGE_TYPE_USER); lList *master_ar_list = *object_type_get_master_list(SGE_TYPE_AR); lList *master_pe_list = *object_type_get_master_list(SGE_TYPE_PE); lList *master_hgrp_list = *object_type_get_master_list(SGE_TYPE_HGROUP); lList *master_sharetree_list = *object_type_get_master_list(SGE_TYPE_SHARETREE); /* delay scheduling for test purposes, see issue GE-3306 */ if (SGE_TEST_DELAY_SCHEDULING > 0) { sleep(SGE_TEST_DELAY_SCHEDULING); } PROF_START_MEASUREMENT(SGE_PROF_CUSTOM6); PROF_START_MEASUREMENT(SGE_PROF_CUSTOM7); if (__CONDITION(INFOPRINT)) { dstring ds; char buffer[128]; sge_dstring_init(&ds, buffer, sizeof(buffer)); DPRINTF(("================[SCHEDULING-EPOCH %s]==================\n", sge_at_time(0, &ds))); sge_dstring_free(&ds); } /* * If there were new events then * copy/filter data necessary for the scheduler run * and run the scheduler method */ memset(©, 0, sizeof(copy)); copy.dept_list = lSelect("", master_userset_list, where_what.where_dept, where_what.what_acldept); copy.acl_list = lSelect("", master_userset_list, where_what.where_acl, where_what.what_acldept); DPRINTF(("RAW CQ:%d, J:%d, H:%d, C:%d, A:%d, D:%d, P:%d, CKPT:%d," " US:%d, PR:%d, RQS:%d, AR:%d, S:nd:%d/lf:%d\n", lGetNumberOfElem(master_cqueue_list), lGetNumberOfElem(master_job_list), lGetNumberOfElem(master_exechost_list), lGetNumberOfElem(master_centry_list), lGetNumberOfElem(copy.acl_list), lGetNumberOfElem(copy.dept_list), lGetNumberOfElem(master_project_list), lGetNumberOfElem(master_ckpt_list), lGetNumberOfElem(master_user_list), lGetNumberOfElem(master_project_list), lGetNumberOfElem(master_rqs_list), lGetNumberOfElem(master_ar_list), lGetNumberOfNodes(NULL, master_sharetree_list, STN_children), lGetNumberOfLeafs(NULL, master_sharetree_list, STN_children) )); sge_rebuild_job_category(master_job_list, master_userset_list, master_project_list, master_rqs_list); PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM7); prof_init = prof_get_measurement_wallclock(SGE_PROF_CUSTOM7, true, NULL); PROF_START_MEASUREMENT(SGE_PROF_CUSTOM7); sge_before_dispatch(evc); /* prepare data for the scheduler itself */ copy.host_list = lCopyList("", master_exechost_list); /* * Within the scheduler we do only need QIs */ { lListElem *cqueue = NULL; lEnumeration *what_queue3 = NULL; for_each(cqueue, master_cqueue_list) { lList *qinstance_list = lGetList(cqueue, CQ_qinstances); lList *t; if (!qinstance_list) { continue; } /* all_queue_list contains all queue instances with state and full queue name only */ if (!what_queue3) { what_queue3 = lWhat("%T(%I%I)", lGetListDescr(qinstance_list), QU_full_name, QU_state); } t = lSelect("t", qinstance_list, NULL, what_queue3); if (t) { if (copy.all_queue_list == NULL) { copy.all_queue_list = lCreateList("all", lGetListDescr(t)); } lAppendList(copy.all_queue_list, t); lFreeList (&t); } t = lSelect("t", qinstance_list, where_what.where_queue, where_what.what_queue2); if (t) { if (copy.queue_list == NULL) { copy.queue_list = lCreateList("enabled", lGetListDescr(t)); } lAppendList(copy.queue_list, t); lFreeList (&t); } t = lSelect("t", qinstance_list, where_what.where_queue2, where_what.what_queue2); if (t) { if (copy.dis_queue_list == NULL) { copy.dis_queue_list = lCreateList("disabled", lGetListDescr(t)); } lAppendList(copy.dis_queue_list, t); lFreeList (&t); } } if (what_queue3) { lFreeWhat(&what_queue3); } } if (sconf_is_job_category_filtering()) { copy.job_list = sge_category_job_copy(copy.queue_list, &orders, evc->monitor_next_run); } else { copy.job_list = lCopyList("", master_job_list); } /* no need to copy these lists, they are read only used */ copy.centry_list = master_centry_list; copy.ckpt_list = master_ckpt_list; copy.hgrp_list = master_hgrp_list; /* these lists need to be copied because they are modified during scheduling run */ copy.share_tree = lCopyList("", master_sharetree_list); copy.pe_list = lCopyList("", master_pe_list); copy.user_list = lCopyList("", master_user_list); copy.project_list = lCopyList("", master_project_list); copy.rqs_list = lCopyList("", master_rqs_list); copy.ar_list = lCopyList("", master_ar_list); /* report number of reduced and raw (in brackets) lists */ DPRINTF(("Q:%d, AQ:%d J:%d(%d), H:%d(%d), C:%d, A:%d, D:%d, P:%d, CKPT:%d," " US:%d, PR:%d, RQS:%d, AR:%d, S:nd:%d/lf:%d \n", lGetNumberOfElem(copy.queue_list), lGetNumberOfElem(copy.all_queue_list), lGetNumberOfElem(copy.job_list), lGetNumberOfElem(master_job_list), lGetNumberOfElem(copy.host_list), lGetNumberOfElem(master_exechost_list), lGetNumberOfElem(copy.centry_list), lGetNumberOfElem(copy.acl_list), lGetNumberOfElem(copy.dept_list), lGetNumberOfElem(copy.pe_list), lGetNumberOfElem(copy.ckpt_list), lGetNumberOfElem(copy.user_list), lGetNumberOfElem(copy.project_list), lGetNumberOfElem(copy.rqs_list), lGetNumberOfElem(copy.ar_list), lGetNumberOfNodes(NULL, copy.share_tree, STN_children), lGetNumberOfLeafs(NULL, copy.share_tree, STN_children) )); if (getenv("SGE_ND")) { printf("Q:%d, AQ:%d J:%d(%d), H:%d(%d), C:%d, A:%d, D:%d, " "P:%d, CKPT:%d, US:%d, PR:%d, RQS:%d, AR:%d, S:nd:%d/lf:%d \n", lGetNumberOfElem(copy.queue_list), lGetNumberOfElem(copy.all_queue_list), lGetNumberOfElem(copy.job_list), lGetNumberOfElem(master_job_list), lGetNumberOfElem(copy.host_list), lGetNumberOfElem(master_exechost_list), lGetNumberOfElem(copy.centry_list), lGetNumberOfElem(copy.acl_list), lGetNumberOfElem(copy.dept_list), lGetNumberOfElem(copy.pe_list), lGetNumberOfElem(copy.ckpt_list), lGetNumberOfElem(copy.user_list), lGetNumberOfElem(copy.project_list), lGetNumberOfElem(copy.rqs_list), lGetNumberOfElem(copy.ar_list), lGetNumberOfNodes(NULL, copy.share_tree, STN_children), lGetNumberOfLeafs(NULL, copy.share_tree, STN_children) ); } else { schedd_log("-------------START-SCHEDULER-RUN-------------", NULL, evc->monitor_next_run); } PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM7); prof_copy = prof_get_measurement_wallclock(SGE_PROF_CUSTOM7, true, NULL); PROF_START_MEASUREMENT(SGE_PROF_CUSTOM7); scheduler_method(evc, &answer_list, ©, &orders); answer_list_output(&answer_list); PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM7); prof_run = prof_get_measurement_wallclock(SGE_PROF_CUSTOM7, true, NULL); PROF_START_MEASUREMENT(SGE_PROF_CUSTOM7); /* .. which gets deleted after using */ lFreeList(&(copy.host_list)); lFreeList(&(copy.queue_list)); lFreeList(&(copy.dis_queue_list)); lFreeList(&(copy.all_queue_list)); lFreeList(&(copy.job_list)); lFreeList(&(copy.acl_list)); lFreeList(&(copy.dept_list)); lFreeList(&(copy.pe_list)); lFreeList(&(copy.share_tree)); lFreeList(&(copy.user_list)); lFreeList(&(copy.project_list)); lFreeList(&(copy.rqs_list)); lFreeList(&(copy.ar_list)); PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM7); prof_free = prof_get_measurement_wallclock(SGE_PROF_CUSTOM7, true, NULL); /* * need to sync with event master thread * if schedd configuration changed then settings in evm can be adjusted */ if (sconf_is_new_config()) { /* set scheduler interval / event delivery interval */ u_long32 interval = sconf_get_schedule_interval(); if (evc->ec_get_edtime(evc) != interval) { evc->ec_set_edtime(evc, interval); } /* set job / ja_task event flushing */ set_job_flushing(evc); /* no need to ec_commit here - we do it when resetting the busy state */ /* now we handled the new schedd config - no need to do it twice */ sconf_reset_new_config(); } /* block till master handled all GDI orders */ sge_schedd_block_until_orders_processed(evc->get_gdi_ctx(evc), NULL); schedd_order_destroy(); /* * Stop profiling for "schedd run total" and the subcategories */ PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM6); prof_total = prof_get_measurement_wallclock(SGE_PROF_CUSTOM6, true, NULL); if (prof_is_active(SGE_PROF_CUSTOM6)) { PROFILING((SGE_EVENT, "PROF: schedd run took: %.3f s (init: %.3f s, copy: %.3f s, " "run:%.3f, free: %.3f s, jobs: %d, categories: %d/%d)", prof_total, prof_init, prof_copy, prof_run, prof_free, lGetNumberOfElem(*object_type_get_master_list(SGE_TYPE_JOB)), sge_category_count(), sge_cs_category_count() )); } if (getenv("SGE_ND") != NULL) { printf("--------------STOP-SCHEDULER-RUN-------------\n"); } else { schedd_log("--------------STOP-SCHEDULER-RUN-------------", NULL, evc->monitor_next_run); } thread_output_profiling("scheduler thread profiling summary:\n", &next_prof_output); sge_monitor_output(&monitor); } /* reset the busy state */ evc->ec_set_busy(evc, 0); evc->ec_commit(evc, NULL); /* stop logging into schedd_runlog (enabled via -tsm) */ evc->monitor_next_run = false; /* * pthread cancelation point * * sge_scheduler_cleanup_thread() is the last function which should * be called so it is pushed first */ pthread_cleanup_push(sge_scheduler_cleanup_thread, (void *) &ctx); pthread_cleanup_push((void (*)(void *))sge_scheduler_cleanup_monitor, (void *)&monitor); pthread_cleanup_push((void (*)(void *))sge_scheduler_cleanup_event_client, (void *)evc); cl_thread_func_testcancel(thread_config); pthread_cleanup_pop(execute); pthread_cleanup_pop(execute); pthread_cleanup_pop(execute); DPRINTF(("passed cancelation point\n")); }
static void do_test(bool unique_hash, bool non_unique_hash, int num_objects, int num_names) { lList *lp = NULL; lList *copy; lListElem *ep; clock_t now, start; struct tms tms_buffer; #ifdef MALLINFO struct mallinfo meminfo; #endif int i; #ifdef HASH_STATISTICS cull_htable cht; dstring stat_dstring = DSTRING_INIT; #endif /* measurement data */ double prof_create, /* create objects */ prof_copy, /* copy list including all hashtables */ prof_rau, /* random access by unique attrib */ prof_inu, /* iterate by non unique attrib */ prof_curo, /* change unique attrib of random object */ prof_cnuro, /* change non unique attrib of random object */ prof_dru, /* delete random object by unique attribute */ prof_dinu; /* delete by iterating over non unique attrib */ int objs_dru, /* objects deleted by random unique */ objs_dinu; /* objects deleted by iterate non unique */ /* create list and hash tables */ lp = lCreateList("test list ", DESCR); if (unique_hash) { cull_hash_new(lp, NM_ULONG, true); } if (non_unique_hash) { cull_hash_new(lp, NM_STRING, false); } #ifdef HASH_STATISTICS cht = lp->descr[1].ht; printf("%s\n", cull_hash_statistics(cht, &stat_dstring)); #endif start = times(&tms_buffer); /* TEST: build objects */ for (i = 0; i < num_objects; i++) { ep = lAddElemUlong(&lp, NM_ULONG, i, DESCR); lSetString(ep, NM_STRING, names[rand() % num_names]); } /* measure time */ now = times(&tms_buffer); prof_create = (now - start) * 1.0 / clk_tck; #ifdef HASH_STATISTICS printf("%s\n", cull_hash_statistics(cht, &stat_dstring)); #endif /* measure memory usage */ #ifdef MALLINFO meminfo = mallinfo(); #endif /* TEST: copy list */ start = times(&tms_buffer); copy = lCopyList("copy", lp); /* measure time */ now = times(&tms_buffer); prof_copy = (now - start) * 1.0 / clk_tck; lFreeList(©); /* TEST: random access by unique attrib */ start = times(&tms_buffer); for (i = 0; i < num_objects; i++) { ep = lGetElemUlong(lp, NM_ULONG, rand() % num_objects); } /* measure time */ now = times(&tms_buffer); prof_rau = (now - start) * 1.0 / clk_tck; start = now; /* TEST: iterate by non unique attrib */ for (i = 0; i < num_names; i++) { const void *iterator = NULL; lListElem *next_ep; next_ep = lGetElemStrFirst(lp, NM_STRING, names[i], &iterator); while ((ep = next_ep) != NULL) { next_ep = lGetElemStrNext(lp, NM_STRING, names[i], &iterator); } } /* measure time */ now = times(&tms_buffer); prof_inu = (now - start) * 1.0 / clk_tck; start = now; /* TEST: change unique attribute of random object */ /* measure time */ for (i = 0; i < num_objects; i++) { /* object to access */ int unique = rand() % num_objects; /* new value to set, make sure we stay unique */ int newval = unique + num_objects; /* search object */ ep = lGetElemUlong(lp, NM_ULONG, unique); /* set a new value */ lSetUlong(ep, NM_ULONG, newval); /* restore old value */ lSetUlong(ep, NM_ULONG, unique); } now = times(&tms_buffer); prof_curo = (now - start) * 1.0 / clk_tck; start = now; /* TEST: change non unique attribute of random object */ for (i = 0; i < num_objects; i++) { /* search object */ ep = lGetElemUlong(lp, NM_ULONG, rand() % num_objects); /* set a new value */ lSetString(ep, NM_STRING, names[rand() % num_names]); } /* measure time */ now = times(&tms_buffer); prof_cnuro = (now - start) * 1.0 / clk_tck; start = now; /* TEST: delete random object */ objs_dru = 0; for (i = 0; i < num_objects / 2; i++) { /* search object */ ep = lGetElemUlong(lp, NM_ULONG, rand() % num_objects); /* if same rand showed up earlier, object does no longer exist! */ if (ep != NULL) { lRemoveElem(lp, &ep); objs_dru++; } } /* measure time */ now = times(&tms_buffer); prof_dru = (now - start) * 1.0 / clk_tck; start = now; /* TEST: delete all objects having the same non unique attribute */ objs_dinu = 0; for (i = 0; i < num_names; i++) { const void *iterator = NULL; lListElem *next_ep; next_ep = lGetElemStrFirst(lp, NM_STRING, names[i], &iterator); while ((ep = next_ep) != NULL) { next_ep = lGetElemStrNext(lp, NM_STRING, names[i], &iterator); lRemoveElem(lp, &ep); objs_dinu++; } } /* measure time */ now = times(&tms_buffer); prof_dinu = (now - start) * 1.0 / clk_tck; start = now; printf(DATA_FORMAT, unique_hash ? " * " : " ", non_unique_hash ? " * " : " ", prof_create, prof_copy, prof_rau, prof_inu, prof_curo, prof_cnuro, prof_dru, objs_dru, prof_dinu, objs_dinu, #ifdef MALLINFO (meminfo.usmblks + meminfo.uordblks) / 1024 #else 0L #endif ); #ifdef HASH_STATISTICS printf("%s\n", cull_hash_statistics(cht, &stat_dstring)); sge_dstring_free(&stat_dstring); #endif lFreeList(&lp); }