00001
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <errno.h>
00028 #include "gridlabd.h"
00029 #include "eventgen.h"
00030
00031 #include <string.h>
00032 #include <iostream>
00033 using namespace::std;
00034
00035 #define TSNVRDBL 9223372036854775808.0
00036
00037 CLASS *eventgen::oclass = NULL;
00038 eventgen *eventgen::defaults = NULL;
00040
00041 eventgen::eventgen(MODULE *module)
00042 {
00043 if (oclass==NULL)
00044 {
00045 oclass = gl_register_class(module,"eventgen",sizeof(eventgen),PC_PRETOPDOWN|PC_POSTTOPDOWN|PC_AUTOLOCK);
00046 if (oclass==NULL)
00047 throw "unable to register class eventgen";
00048 else
00049 oclass->trl = TRL_DEMONSTRATED;
00050
00051 if (gl_publish_variable(oclass,
00052 PT_char1024, "target_group", PADDR(target_group),
00053 PT_char256, "fault_type", PADDR(fault_type),
00054 PT_enumeration, "failure_dist", PADDR(failure_dist),
00055 PT_KEYWORD, "UNIFORM", (enumeration)UNIFORM,
00056 PT_KEYWORD, "NORMAL", (enumeration)NORMAL,
00057 PT_KEYWORD, "LOGNORMAL", (enumeration)LOGNORMAL,
00058 PT_KEYWORD, "BERNOULLI", (enumeration)BERNOULLI,
00059 PT_KEYWORD, "PARETO", (enumeration)PARETO,
00060 PT_KEYWORD, "EXPONENTIAL", (enumeration)EXPONENTIAL,
00061 PT_KEYWORD, "RAYLEIGH", (enumeration)RAYLEIGH,
00062 PT_KEYWORD, "WEIBULL", (enumeration)WEIBULL,
00063 PT_KEYWORD, "GAMMA", (enumeration)GAMMA,
00064 PT_KEYWORD, "BETA", (enumeration)BETA,
00065 PT_KEYWORD, "TRIANGLE", (enumeration)TRIANGLE,
00066 PT_enumeration, "restoration_dist", PADDR(restore_dist),
00067 PT_KEYWORD, "UNIFORM", (enumeration)UNIFORM,
00068 PT_KEYWORD, "NORMAL", (enumeration)NORMAL,
00069 PT_KEYWORD, "LOGNORMAL", (enumeration)LOGNORMAL,
00070 PT_KEYWORD, "BERNOULLI", (enumeration)BERNOULLI,
00071 PT_KEYWORD, "PARETO", (enumeration)PARETO,
00072 PT_KEYWORD, "EXPONENTIAL", (enumeration)EXPONENTIAL,
00073 PT_KEYWORD, "RAYLEIGH", (enumeration)RAYLEIGH,
00074 PT_KEYWORD, "WEIBULL", (enumeration)WEIBULL,
00075 PT_KEYWORD, "GAMMA", (enumeration)GAMMA,
00076 PT_KEYWORD, "BETA", (enumeration)BETA,
00077 PT_KEYWORD, "TRIANGLE", (enumeration)TRIANGLE,
00078 PT_double, "failure_dist_param_1", PADDR(fail_dist_params[0]),
00079 PT_double, "failure_dist_param_2", PADDR(fail_dist_params[1]),
00080 PT_double, "restoration_dist_param_1", PADDR(rest_dist_params[0]),
00081 PT_double, "restoration_dist_param_2", PADDR(rest_dist_params[1]),
00082 PT_char1024, "manual_outages", PADDR(manual_fault_list),
00083 PT_double, "max_outage_length[s]", PADDR(max_outage_length_dbl),
00084 PT_int32, "max_simultaneous_faults", PADDR(max_simult_faults),
00085 PT_char256, "controlled_switch", PADDR(controlled_switch),PT_DESCRIPTION,"Name of a switch to manually fault/un-fault",
00086 PT_int32, "switch_state", PADDR(switch_state),PT_DESCRIPTION,"Current state (1=closed, 0=open) for the controlled switch",
00087 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00088 if (gl_publish_function(oclass, "add_event", (FUNCTIONADDR)add_event)==NULL)
00089 GL_THROW("Unable to publish reliability event adding function");
00090 if (gl_publish_function(oclass, "interupdate_event_object", (FUNCTIONADDR)interupdate_eventgen)==NULL)
00091 GL_THROW("Unable to publish reliability deltamode function");
00092 }
00093 }
00094
00095
00096 int eventgen::create(void)
00097 {
00098 target_group[0] = '\0';
00099 fault_type[0] = '\0';
00100 manual_fault_list[0] = '\0';
00101 controlled_switch[0] = '\0';
00102 switch_state = 1;
00103 last_switch_state = 1;
00104
00105
00106 failure_dist = EXPONENTIAL;
00107 restore_dist = PARETO;
00108
00109
00110 fail_dist_params[0] = 1.0/2592000.0;
00111 fail_dist_params[1] = 0.0;
00112
00113 rest_dist_params[0] = 1.0;
00114 rest_dist_params[1] = 1.00027785496;
00115
00116 UnreliableObjs = NULL;
00117 UnreliableObjCount = 0;
00118
00119 metrics_obj_hdr = NULL;
00120
00121 max_outage_length_dbl = 432000.0;
00122
00123 next_event_time = 0;
00124 next_event_time_dbl = 0.0;
00125
00126 max_simult_faults = -1;
00127 faults_in_prog = 0;
00128
00129 fault_implement_mode = false;
00130
00131 curr_time_interrupted = 0;
00132 curr_time_interrupted_sec = 0;
00133 diff_count_needed = false;
00134
00135 secondary_interruption_cnt = NULL;
00136
00137
00138 Unhandled_Events.prev = NULL;
00139 Unhandled_Events.next = NULL;
00140
00141
00142 glob_min_timestep = 0.0;
00143 off_nominal_time = false;
00144
00145
00146 deltamode_inclusive=false;
00147
00148 metrics_object_event_ended = NULL;
00149 metrics_object_event_ended_sec = NULL;
00150 metrics_get_interrupted_count = NULL;
00151 metrics_get_interrupted_count_sec = NULL;
00152
00153 return 1;
00154 }
00155
00156
00157 int eventgen::init(OBJECT *parent)
00158 {
00159 OBJECT *hdr = OBJECTHDR(this);
00160 int index, comma_count;
00161 TIMESTAMP tempTime, globStartTimeVal;
00162 FINDLIST *ObjListVals;
00163 OBJECT *temp_obj;
00164 double temp_double, temp_val, temp_time_double;
00165 char *token_a, *token_a1;
00166 TIMESTAMP temp_time_A, temp_time_B;
00167 unsigned int temp_time_A_nano, temp_time_B_nano;
00168 double temp_time_A_dbl, temp_time_B_dbl;
00169 char temp_buff[128];
00170
00171
00172
00173 gl_global_getvar("minimum_timestep",temp_buff,sizeof(temp_buff));
00174
00175
00176 index = 0;
00177
00178
00179 while ((index < 128) && (temp_buff[index] != '\0'))
00180 {
00181 glob_min_timestep *= 10;
00182 temp_val = (double)(temp_buff[index]-48);
00183 glob_min_timestep += temp_val;
00184
00185 index++;
00186 }
00187
00188 if (glob_min_timestep > 1)
00189 {
00190 off_nominal_time=true;
00191 gl_warning("eventgen:%s - minimum_timestep set - all events at least 1 minimum step long",hdr->name);
00192
00193
00194
00195
00196
00197 }
00198
00199
00200 globStartTimeVal = gl_globalclock;
00201
00202
00203 if (off_nominal_time == true)
00204 {
00205 if (max_outage_length_dbl < glob_min_timestep)
00206 max_outage_length_dbl = glob_min_timestep;
00207
00208 if (event_max_duration < glob_min_timestep)
00209 event_max_duration = glob_min_timestep;
00210 }
00211
00212
00213 if ((hdr->flags & OF_DELTAMODE) == OF_DELTAMODE)
00214 {
00215 if (enable_subsecond_models == true)
00216 {
00217 deltamode_inclusive = true;
00218 }
00219 else
00220 {
00221 gl_warning("Eventgen:%s is flagged for deltamode, but reliability deltamode is not enabled",hdr->name);
00222
00223
00224
00225
00226
00227 }
00228 }
00229
00230
00231 if ((deltamode_inclusive == true) && (off_nominal_time == true))
00232 {
00233 GL_THROW("event_gen:%s is flagged for deltamode, but minimum timesteps are enabled!",hdr->name);
00234
00235
00236
00237
00238 }
00239
00240
00241 if (max_outage_length_dbl > event_max_duration)
00242 {
00243 max_outage_length_dbl = event_max_duration;
00244
00245 gl_warning("Maximum outage for %s was above global max - restricted to global max",hdr->name);
00246
00247
00248
00249
00250
00251 }
00252
00253
00254 if (hdr->parent == NULL)
00255 {
00256 gl_warning("event_gen:%s does not have a metrics object as a parent -- metrics are not calculated.",hdr->name);
00257
00258
00259
00260
00261
00262
00263
00264 metrics_obj_hdr = NULL;
00265 secondary_interruption_cnt = NULL;
00266 }
00267 else
00268 {
00269
00270
00271 if (gl_object_isa(hdr->parent,"metrics","reliability"))
00272 {
00273
00274 metrics_obj_hdr = hdr->parent;
00275
00276
00277 metrics_object_event_ended = (FUNCTIONADDR)(gl_get_function(metrics_obj_hdr,"metrics_event_ended"));
00278
00279
00280 if (metrics_object_event_ended == NULL)
00281 {
00282 GL_THROW("Eventgen:%d - %s - Unable to map link power calculation function",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
00283
00284
00285
00286
00287 }
00288
00289
00290 metrics_object_event_ended_sec = (FUNCTIONADDR)(gl_get_function(metrics_obj_hdr,"metrics_event_ended_secondary"));
00291
00292
00293 if (metrics_object_event_ended_sec == NULL)
00294 {
00295 GL_THROW("Eventgen:%d - %s - Unable to map link power calculation function",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
00296
00297 }
00298
00299
00300 metrics_get_interrupted_count = (FUNCTIONADDR)(gl_get_function(metrics_obj_hdr,"metrics_get_interrupted_count"));
00301
00302
00303 if (metrics_get_interrupted_count == NULL)
00304 {
00305 GL_THROW("Eventgen:%d - %s - Unable to map link power calculation function",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
00306
00307 }
00308
00309
00310 metrics_get_interrupted_count_sec = (FUNCTIONADDR)(gl_get_function(metrics_obj_hdr,"metrics_get_interrupted_count_secondary"));
00311
00312
00313 if (metrics_get_interrupted_count_sec == NULL)
00314 {
00315 GL_THROW("Eventgen:%d - %s - Unable to map link power calculation function",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
00316
00317 }
00318 }
00319 else
00320 {
00321 GL_THROW("event_gen:%s must be parented to a metrics object to properly function.",hdr->name);
00322
00323 }
00324
00325
00326
00327
00328 secondary_interruption_cnt = new gld_property(metrics_obj_hdr,"perform_secondary_interruptions_count");
00329
00330
00331 if ((secondary_interruption_cnt->is_valid() != true) || (secondary_interruption_cnt->is_bool() != true))
00332 {
00333 GL_THROW("event_gen:%d - %s - Unable to map property for remote object",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
00334
00335
00336
00337
00338 }
00339 }
00340
00341
00342
00343 max_outage_length = (TIMESTAMP)(max_outage_length_dbl);
00344
00345
00346 max_outage_length_dbl = (double)(max_outage_length);
00347
00348
00349 if (target_group[0] == '\0')
00350 {
00351 fault_implement_mode = true;
00352
00353
00354 index=0;
00355 comma_count=1;
00356 while ((manual_fault_list[index] != '\0') && (index < 1024))
00357 {
00358 if (manual_fault_list[index] == ',')
00359 comma_count++;
00360
00361 index++;
00362 }
00363
00364
00365 if ((comma_count == 1) && (manual_fault_list[0] == '\0'))
00366 {
00367 GL_THROW("Manual event generation specified, but no events listed in event_gen:%s",hdr->name);
00368
00369
00370
00371
00372 }
00373
00374
00375 UnreliableObjCount = (int)(comma_count / 3);
00376 temp_double = (double)(comma_count)/3.0 - (double)(UnreliableObjCount);
00377
00378 if (temp_double != 0.0)
00379 {
00380 GL_THROW("event_gen:%s has an invalid manual list",hdr->name);
00381
00382
00383
00384
00385
00386 }
00387
00388
00389 UnreliableObjs = (OBJEVENTDETAILS*)gl_malloc(UnreliableObjCount * sizeof(OBJEVENTDETAILS));
00390
00391
00392 if (UnreliableObjs==NULL)
00393 {
00394 GL_THROW("Failed to allocate memory for object list in %s",hdr->name);
00395
00396
00397
00398
00399
00400 }
00401
00402
00403 token_a = manual_fault_list;
00404 for (index=0; index<UnreliableObjCount; index++)
00405 {
00406
00407 token_a1 = obj_token(token_a, &temp_obj);
00408
00409
00410 if (temp_obj == NULL)
00411 {
00412 if (token_a1 != NULL)
00413 {
00414
00415 *--token_a1 = '\0';
00416 }
00417
00418
00419 GL_THROW("eventgen:%s: fault object %s was not found!",hdr->name,token_a);
00420
00421
00422
00423
00424
00425 }
00426
00427
00428 token_a = token_a1;
00429
00430
00431 token_a1 = time_token(token_a,&temp_time_A,&temp_time_A_nano,&temp_time_A_dbl);
00432
00433 token_a = token_a1;
00434
00435
00436 token_a1 = time_token(token_a,&temp_time_B,&temp_time_B_nano,&temp_time_B_dbl);
00437
00438 token_a = token_a1;
00439
00440
00441 UnreliableObjs[index].obj_of_int = temp_obj;
00442
00443
00444 UnreliableObjs[index].obj_made_int = NULL;
00445
00446
00447 if (temp_time_A >= globStartTimeVal)
00448 {
00449
00450 UnreliableObjs[index].fail_time = temp_time_A;
00451 UnreliableObjs[index].fail_time_ns = temp_time_A_nano;
00452 UnreliableObjs[index].fail_time_dbl = temp_time_A_dbl;
00453 }
00454 else
00455 {
00456 GL_THROW("Manual event time in %s must be AFTER the simulation start time",hdr->name);
00457
00458
00459
00460
00461 }
00462
00463
00464 UnreliableObjs[index].rest_time = temp_time_B;
00465 UnreliableObjs[index].rest_time_ns = temp_time_B_nano;
00466 UnreliableObjs[index].rest_time_dbl = temp_time_B_dbl;
00467
00468
00469 UnreliableObjs[index].fail_length = 0;
00470
00471 if (deltamode_inclusive == true)
00472 {
00473
00474 temp_time_double = temp_time_B_dbl - temp_time_A_dbl;
00475
00476
00477 if (temp_time_double > max_outage_length_dbl)
00478 {
00479 gl_warning("outage length for object:%s in eventgen:%s exceeds the defined maximum outage.",temp_obj->name,hdr->name);
00480
00481 }
00482
00483
00484 UnreliableObjs[index].rest_length_dbl = temp_time_double;
00485 UnreliableObjs[index].rest_length = (TIMESTAMP)(temp_time_double);
00486 UnreliableObjs[index].rest_length_ns = (unsigned int)(1.0e9*(temp_time_double - (double)(UnreliableObjs[index].rest_length))+0.5);
00487 }
00488 else
00489 {
00490
00491 tempTime = temp_time_B - temp_time_A;
00492
00493
00494 if (tempTime > max_outage_length)
00495 {
00496 gl_warning("outage length for object:%s in eventgen:%s exceeds the defined maximum outage.",temp_obj->name,hdr->name);
00497
00498
00499
00500
00501 }
00502
00503
00504 if ((off_nominal_time == true) && (((double)(tempTime)) < glob_min_timestep))
00505 {
00506
00507 tempTime = (TIMESTAMP)(glob_min_timestep);
00508
00509
00510 UnreliableObjs[index].rest_time = UnreliableObjs[index].fail_time + tempTime;
00511
00512
00513 gl_warning("Outage length for object:%s is less than the minimum timestep of %.0f seconds, rounded to minimum timestep",temp_obj->name,glob_min_timestep);
00514
00515
00516
00517
00518 }
00519
00520
00521 UnreliableObjs[index].rest_length = tempTime;
00522 }
00523
00524
00525 UnreliableObjs[index].in_fault = false;
00526
00527
00528 UnreliableObjs[index].implemented_fault = -1;
00529
00530
00531 UnreliableObjs[index].customers_affected = 0;
00532
00533
00534 UnreliableObjs[index].customers_affected_sec = 0;
00535 }
00536
00537
00538 curr_fail_dist_params[0]=0;
00539 curr_fail_dist_params[1]=0;
00540 curr_rest_dist_params[0]=0;
00541 curr_rest_dist_params[1]=0;
00542 curr_fail_dist = NONE;
00543 curr_rest_dist = NONE;
00544
00545 }
00546 else
00547 {
00548
00549 ObjListVals = gl_find_objects(FL_GROUP,target_group.get_string());
00550 if (ObjListVals==NULL)
00551 {
00552 GL_THROW("Failure to find devices for %s specified as: %s",hdr->name,target_group.get_string());
00553
00554
00555
00556
00557
00558 }
00559
00560
00561 if (ObjListVals->hit_count == 0)
00562 {
00563 GL_THROW("Failure to find devices for %s specified as: %s",hdr->name,target_group.get_string());
00564
00565 }
00566
00567
00568 UnreliableObjCount = ObjListVals->hit_count;
00569
00570
00571 UnreliableObjs = (OBJEVENTDETAILS*)gl_malloc(UnreliableObjCount * sizeof(OBJEVENTDETAILS));
00572
00573
00574 if (UnreliableObjs==NULL)
00575 {
00576 GL_THROW("Failed to allocate memory for object list in %s",hdr->name);
00577
00578 }
00579
00580
00581 temp_obj = NULL;
00582 for (index=0; index<UnreliableObjCount; index++)
00583 {
00584
00585 temp_obj = gl_find_next(ObjListVals, temp_obj);
00586
00587 if (temp_obj == NULL)
00588 {
00589 GL_THROW("Failed to populate object list in eventgen: %s",hdr->name);
00590
00591
00592
00593
00594
00595 }
00596
00597 UnreliableObjs[index].obj_of_int = temp_obj;
00598
00599
00600 UnreliableObjs[index].obj_made_int = NULL;
00601
00602
00603 UnreliableObjs[index].fail_time = 0;
00604
00605
00606 UnreliableObjs[index].rest_time = TS_NEVER;
00607 UnreliableObjs[index].rest_time_ns = 0;
00608 UnreliableObjs[index].rest_time_dbl = TSNVRDBL;
00609
00610
00611 gen_random_time(failure_dist,fail_dist_params[0],fail_dist_params[1],&UnreliableObjs[index].fail_length,&UnreliableObjs[index].fail_length_ns,&UnreliableObjs[index].fail_length_dbl);
00612
00613
00614 gen_random_time(restore_dist,rest_dist_params[0],rest_dist_params[1],&temp_time_A,&temp_time_A_nano,&temp_time_A_dbl);
00615
00616
00617 if (temp_time_A_dbl > max_outage_length_dbl)
00618 {
00619 UnreliableObjs[index].rest_length = max_outage_length;
00620 UnreliableObjs[index].rest_length_ns = 0;
00621 UnreliableObjs[index].rest_length_dbl = max_outage_length_dbl;
00622 }
00623 else
00624 {
00625 UnreliableObjs[index].rest_length = temp_time_A;
00626 UnreliableObjs[index].rest_length_ns = temp_time_A_nano;
00627 UnreliableObjs[index].rest_length_dbl = temp_time_A_dbl;
00628 }
00629
00630
00631 UnreliableObjs[index].in_fault = false;
00632
00633
00634 UnreliableObjs[index].implemented_fault = -1;
00635
00636
00637 UnreliableObjs[index].customers_affected = 0;
00638
00639
00640 UnreliableObjs[index].customers_affected_sec = 0;
00641 }
00642
00643
00644 gl_free(ObjListVals);
00645
00646
00647 curr_fail_dist_params[0]=fail_dist_params[0];
00648 curr_fail_dist_params[1]=fail_dist_params[1];
00649 curr_rest_dist_params[0]=rest_dist_params[0];
00650 curr_rest_dist_params[1]=rest_dist_params[1];
00651 curr_fail_dist = failure_dist;
00652 curr_rest_dist = restore_dist;
00653 }
00654
00655
00656 if (((max_simult_faults == -1) || (max_simult_faults > 1)) && (metrics_obj_hdr != NULL))
00657 {
00658 gl_warning("event_gen:%s has the ability to generate more than 1 simultaneous fault - metrics may not be accurate",hdr->name);
00659
00660
00661
00662
00663 }
00664 else if ((max_simult_faults == 0) || (max_simult_faults < -1))
00665 {
00666 GL_THROW("event_gen:%s must have a valid maximum simultaneous fault count number",hdr->name);
00667
00668
00669
00670
00671
00672 }
00673
00674
00675
00676 if (deltamode_inclusive)
00677 {
00678
00679 if (enable_subsecond_models!=true)
00680 {
00681 gl_warning("eventgen:%s indicates it wants to run deltamode, but the module-level flag is not set!",hdr->name?hdr->name:"unnamed");
00682
00683
00684
00685
00686 }
00687 else
00688 {
00689 eventgen_object_count++;
00690 }
00691 }
00692
00693 return 1;
00694 }
00695
00696
00697 TIMESTAMP eventgen::presync(TIMESTAMP t0, TIMESTAMP t1)
00698 {
00699 OBJECT *hdr = OBJECTHDR(this);
00700 int index;
00701 double t1_dbl;
00702 double gld_stoptime;
00703
00704
00705 t1_dbl = (double)t1;
00706
00707
00708 curr_time_interrupted = 0;
00709 curr_time_interrupted_sec = 0;
00710 diff_count_needed = false;
00711
00712
00713 if (strlen(controlled_switch) > 0) {
00714 if (switch_state != last_switch_state) {
00715 cout << "Switch " << controlled_switch << " changing status to " << switch_state << " at " << t0 << " going to " << t1 << endl;
00716 OBJECT *swt = gl_get_object(controlled_switch);
00717 if (switch_state == 1) {
00718 add_unhandled_event (swt, "SW-ABC", t0 - 50, 50, 24, true);
00719 } else {
00720 add_unhandled_event (swt, "SW-ABC", t0, TS_NEVER, -1, false);
00721 }
00722 last_switch_state = switch_state;
00723 }
00724 }
00725
00726
00727 if (next_event_time==0)
00728 {
00729
00730 next_event_time = TS_NEVER;
00731 next_event_time_dbl = TSNVRDBL;
00732
00733
00734 for (index=0; index<UnreliableObjCount; index++)
00735 {
00736
00737 if (fault_implement_mode == false)
00738 {
00739
00740 if (deltamode_inclusive == true)
00741 {
00742 UnreliableObjs[index].fail_time_dbl = t1_dbl + UnreliableObjs[index].fail_length_dbl;
00743 UnreliableObjs[index].fail_time = (TIMESTAMP)(floor(UnreliableObjs[index].fail_time_dbl));
00744 UnreliableObjs[index].fail_time_ns = (unsigned int)((UnreliableObjs[index].fail_time_dbl - (double)(UnreliableObjs[index].fail_time))*1.0e9 + 0.5);
00745 }
00746 else
00747 {
00748 UnreliableObjs[index].fail_time = t1 + UnreliableObjs[index].fail_length;
00749 }
00750 }
00751
00752
00753 if (UnreliableObjs[index].fail_time < next_event_time)
00754 {
00755 next_event_time = UnreliableObjs[index].fail_time;
00756 if (deltamode_inclusive == true)
00757 next_event_time_dbl = UnreliableObjs[index].fail_time_dbl;
00758 }
00759 }
00760
00761
00762 if (deltamode_inclusive && enable_subsecond_models)
00763 {
00764 if ((eventgen_object_current == -1) || (delta_objects==NULL))
00765 {
00766
00767 delta_objects = (OBJECT**)gl_malloc(eventgen_object_count*sizeof(OBJECT*));
00768
00769
00770 if (delta_objects == NULL)
00771 {
00772 GL_THROW("Failed to allocate deltamode objects array for reliability module!");
00773
00774
00775
00776
00777
00778 }
00779
00780
00781 delta_functions = (FUNCTIONADDR*)gl_malloc(eventgen_object_count*sizeof(FUNCTIONADDR));
00782
00783
00784 if (delta_functions == NULL)
00785 {
00786 GL_THROW("Failed to allocate deltamode objects function array for reliability module!");
00787
00788
00789
00790
00791
00792 }
00793
00794
00795 eventgen_object_current = 0;
00796 }
00797
00798
00799 if (eventgen_object_current>=eventgen_object_count)
00800 {
00801 GL_THROW("Too many objects tried to populate deltamode objects array in the reliability module!");
00802
00803
00804
00805
00806
00807 }
00808
00809
00810 delta_objects[eventgen_object_current] = hdr;
00811
00812
00813 delta_functions[eventgen_object_current] = (FUNCTIONADDR)(gl_get_function(hdr,"interupdate_event_object"));
00814
00815
00816 if (delta_functions[eventgen_object_current] == NULL)
00817 {
00818 GL_THROW("Failure to map deltamode function for device:%s",hdr->name);
00819
00820
00821
00822
00823
00824 }
00825
00826
00827 eventgen_object_current++;
00828
00829 }
00830 }
00831
00832
00833 if ((next_event_time == t1) && deltamode_inclusive)
00834 {
00835
00836 gld_stoptime = (double)gl_globalstoptime;
00837
00838 if (next_event_time_dbl <= gld_stoptime)
00839 {
00840 schedule_deltamode_start(next_event_time);
00841
00842
00843
00844
00845
00846
00847 return -next_event_time;
00848 }
00849 else
00850 {
00851 next_event_time++;
00852
00853
00854 return -next_event_time;
00855 }
00856 }
00857
00858
00859 regen_events(t1,t1_dbl);
00860
00861 if(t1 >= next_event_time)
00862 {
00863
00864 do_event(t1,t1_dbl,false);
00865 }
00866
00867
00868 if (next_event_time == TS_NEVER)
00869 {
00870 return TS_NEVER;
00871 }
00872 else
00873 {
00874 return -next_event_time;
00875 }
00876 }
00877
00878 TIMESTAMP eventgen::postsync(TIMESTAMP t0, TIMESTAMP t1)
00879 {
00880 int after_count, after_count_sec, differential_count, differential_count_sec, index;
00881 RELEVANTSTRUCT *temp_struct;
00882 bool temp_bool;
00883 gld_rlock *test_rlock;
00884 STATUS temp_status;
00885 OBJECT *hdr = OBJECTHDR(this);
00886
00887
00888 if ((diff_count_needed == true) && (metrics_obj_hdr != NULL))
00889 {
00890
00891 secondary_interruption_cnt->getp<bool>(temp_bool,*test_rlock);
00892
00893 if (temp_bool == true)
00894 {
00895
00896 wlock(metrics_obj_hdr);
00897
00898
00899 temp_status = ((STATUS (*)(OBJECT *,int *,int *))(*metrics_get_interrupted_count_sec))(metrics_obj_hdr,&after_count,&after_count_sec);
00900
00901
00902 wunlock(metrics_obj_hdr);
00903
00904 if (temp_status == FAILED)
00905 {
00906 GL_THROW("Eventgen:%d - %s - an error occurred while trying to get the object interruption count",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
00907
00908
00909
00910
00911 }
00912
00913
00914 differential_count = after_count - curr_time_interrupted;
00915 differential_count_sec = after_count_sec - curr_time_interrupted_sec;
00916
00917
00918 if (differential_count < 0)
00919 {
00920 gl_warning("Afflicted object count went negative - using after fault count");
00921
00922
00923
00924
00925
00926
00927
00928
00929 differential_count = after_count;
00930 }
00931
00932
00933
00934 if (differential_count_sec < 0)
00935 {
00936 gl_warning("Afflicted secondary object count went negative - using after fault count");
00937
00938
00939
00940
00941
00942
00943
00944
00945 differential_count_sec = after_count_sec;
00946 }
00947
00948
00949 for (index=0; index<UnreliableObjCount; index++)
00950 {
00951 if (UnreliableObjs[index].customers_affected == -1)
00952 UnreliableObjs[index].customers_affected = differential_count;
00953
00954 if (UnreliableObjs[index].customers_affected_sec == -1)
00955 UnreliableObjs[index].customers_affected_sec = differential_count_sec;
00956 }
00957
00958
00959 if (Unhandled_Events.next != NULL)
00960 {
00961
00962 temp_struct = &Unhandled_Events;
00963
00964
00965 while (temp_struct->next != NULL)
00966 {
00967
00968 temp_struct = temp_struct->next;
00969
00970 if (temp_struct->objdetails.customers_affected == -1)
00971 temp_struct->objdetails.customers_affected = differential_count;
00972
00973 if (temp_struct->objdetails.customers_affected_sec == -1)
00974 temp_struct->objdetails.customers_affected_sec = differential_count_sec;
00975 }
00976 }
00977 }
00978 else
00979 {
00980
00981 wlock(metrics_obj_hdr);
00982
00983
00984 temp_status = ((STATUS (*)(OBJECT *,int *))(*metrics_get_interrupted_count))(metrics_obj_hdr,&after_count);
00985
00986
00987 wunlock(metrics_obj_hdr);
00988
00989 if (temp_status == FAILED)
00990 {
00991 GL_THROW("Eventgen:%d - %s - an error occurred while trying to get the object interruption count",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
00992
00993 }
00994
00995
00996 differential_count = after_count - curr_time_interrupted;
00997
00998
00999 if (differential_count < 0)
01000 {
01001
01002 differential_count = after_count;
01003 }
01004
01005
01006 for (index=0; index<UnreliableObjCount; index++)
01007 {
01008 if (UnreliableObjs[index].customers_affected == -1)
01009 UnreliableObjs[index].customers_affected = differential_count;
01010 }
01011
01012
01013 if (Unhandled_Events.next != NULL)
01014 {
01015
01016 temp_struct = &Unhandled_Events;
01017
01018
01019 while (temp_struct->next != NULL)
01020 {
01021
01022 temp_struct = temp_struct->next;
01023
01024 if (temp_struct->objdetails.customers_affected == -1)
01025 temp_struct->objdetails.customers_affected = differential_count;
01026 }
01027 }
01028 }
01029 }
01030
01031 return TS_NEVER;
01032 }
01033
01034
01035 void eventgen::gen_random_time(enumeration rand_dist_type, double param_1, double param_2, TIMESTAMP *event_time, unsigned int *event_nanoseconds, double *event_double)
01036 {
01037 TIMESTAMP random_time = 0;
01038 double dbl_random_time = 0.0;
01039 unsigned int ns_random_time = 0;
01040 OBJECT *obj = OBJECTHDR(this);
01041
01042 switch(rand_dist_type)
01043 {
01044 case UNIFORM:
01045 {
01046 dbl_random_time = gl_random_uniform(RNGSTATE,param_1,param_2);
01047 break;
01048 }
01049 case NORMAL:
01050 {
01051 dbl_random_time = gl_random_normal(RNGSTATE,param_1,param_2);
01052 break;
01053 }
01054 case LOGNORMAL:
01055 {
01056 dbl_random_time = gl_random_lognormal(RNGSTATE,param_1,param_2);
01057 break;
01058 }
01059 case BERNOULLI:
01060 {
01061 dbl_random_time = gl_random_bernoulli(RNGSTATE,param_1);
01062 break;
01063 }
01064 case PARETO:
01065 {
01066 dbl_random_time = gl_random_pareto(RNGSTATE,param_1,param_2);
01067 break;
01068 }
01069 case EXPONENTIAL:
01070 {
01071 dbl_random_time = gl_random_exponential(RNGSTATE,param_1);
01072 break;
01073 }
01074 case RAYLEIGH:
01075 {
01076 dbl_random_time = gl_random_rayleigh(RNGSTATE,param_1);
01077 break;
01078 }
01079 case WEIBULL:
01080 {
01081 dbl_random_time = gl_random_weibull(RNGSTATE,param_1,param_2);
01082 break;
01083 }
01084 case GAMMA:
01085 {
01086 dbl_random_time = gl_random_gamma(RNGSTATE,param_1,param_2);
01087 break;
01088 }
01089 case BETA:
01090 {
01091 dbl_random_time = gl_random_beta(RNGSTATE,param_1, param_2);
01092 break;
01093 }
01094 case TRIANGLE:
01095 {
01096 dbl_random_time = gl_random_triangle(RNGSTATE,param_1, param_2);
01097 break;
01098 }
01099 default:
01100 {
01101 GL_THROW("Undefined distribution in eventgen %s",obj->name);
01102
01103
01104
01105
01106
01107 }
01108 }
01109
01110
01111 if ((off_nominal_time == true) && (dbl_random_time < glob_min_timestep))
01112 {
01113 dbl_random_time = glob_min_timestep;
01114
01115
01116 gl_warning("Outage length is less than the minimum timestep of %.0f seconds, rounded to minimum timestep",glob_min_timestep);
01117
01118 }
01119
01120
01121 random_time = (int64)(dbl_random_time);
01122
01123
01124 *event_time = random_time;
01125
01126
01127 if (deltamode_inclusive == true)
01128 {
01129
01130 ns_random_time = (unsigned int)((dbl_random_time - (double)(random_time))*1e9+0.5);
01131
01132
01133 *event_double = dbl_random_time;
01134
01135
01136 *event_nanoseconds = ns_random_time;
01137 }
01138 else
01139 {
01140
01141 *event_double = (double)(random_time);
01142
01143
01144 *event_nanoseconds = 0;
01145 }
01146 }
01147
01148
01149
01150
01151
01152
01153 char *eventgen::time_token(char *start_token, TIMESTAMP *time_val, unsigned int *micro_time_val, double *dbl_time_val)
01154 {
01155 char workArray[64];
01156 char *outIndex, *workIndex, *end_token;
01157 char index;
01158
01159
01160 for (index=0; index<64; index++)
01161 workArray[index] = 0;
01162
01163
01164 workIndex = workArray;
01165
01166
01167 outIndex = strchr(start_token,',');
01168
01169 if (outIndex == NULL)
01170 {
01171 while (*start_token != '\0')
01172 {
01173 *workIndex++ = *start_token++;
01174 }
01175
01176 end_token = NULL;
01177 }
01178 else
01179 {
01180 while (start_token < outIndex)
01181 {
01182 *workIndex++ = *start_token++;
01183 }
01184
01185 end_token = start_token+1;
01186 }
01187
01188
01189 workIndex = workArray;
01190
01191
01192 *time_val = gl_delta_parsetime(workIndex,micro_time_val,dbl_time_val);
01193
01194
01195 return end_token;
01196 }
01197
01198
01199 char *eventgen::obj_token(char *start_token, OBJECT **obj_val)
01200 {
01201 char workArray[128];
01202 char *outIndex, *workIndex, *end_token;
01203 unsigned char index;
01204
01205
01206 for (index=0; index<128; index++)
01207 workArray[index] = 0;
01208
01209
01210 workIndex = workArray;
01211
01212
01213 outIndex = strchr(start_token,',');
01214
01215 if (outIndex == NULL)
01216 {
01217 while (*start_token != '\0')
01218 {
01219 *workIndex++ = *start_token++;
01220 }
01221
01222 end_token = NULL;
01223 }
01224 else
01225 {
01226 while (start_token < outIndex)
01227 {
01228 *workIndex++ = *start_token++;
01229 }
01230
01231 end_token = start_token+1;
01232 }
01233
01234
01235 workIndex = workArray;
01236
01237
01238 *obj_val = gl_get_object(workIndex);
01239
01240
01241 return end_token;
01242 }
01243
01244
01245 int eventgen::add_unhandled_event(OBJECT *obj_to_fault, char *event_type, TIMESTAMP fail_time, TIMESTAMP rest_length, int implemented_fault, bool fault_state)
01246 {
01247 OBJECT *obj = OBJECTHDR(this);
01248 RELEVANTSTRUCT *new_struct;
01249 TIMESTAMP rest_time;
01250 double fail_time_dbl, rest_time_dbl;
01251
01252
01253 new_struct = (RELEVANTSTRUCT*)gl_malloc(sizeof(RELEVANTSTRUCT));
01254
01255
01256 if (new_struct == NULL)
01257 {
01258 GL_THROW("Eventgen:%s - Failed to allocate memory for new reliability event!",obj->name);
01259
01260
01261
01262
01263
01264 }
01265
01266
01267 if ((off_nominal_time == true) && (((double)(rest_length)) < glob_min_timestep))
01268 {
01269 rest_length = (TIMESTAMP)(glob_min_timestep);
01270
01271
01272 gl_warning("Outage length for object:%s is less than the minimum timestep of %.0f seconds, rounded to minimum timestep",obj_to_fault->name,glob_min_timestep);
01273
01274 }
01275
01276
01277 fail_time_dbl = (double)(fail_time);
01278
01279
01280 if ((fault_state == false) && (rest_length == TS_NEVER))
01281 {
01282 rest_time = TS_NEVER;
01283 rest_time_dbl = TSNVRDBL;
01284 }
01285 else
01286 {
01287 rest_time = fail_time + rest_length;
01288 rest_time_dbl = (double)(fail_time) + (double)(rest_length);
01289 }
01290
01291
01292 if (fault_state == false)
01293 new_struct->objdetails.implemented_fault = -1;
01294 else
01295 new_struct->objdetails.implemented_fault = implemented_fault;
01296
01297
01298 memcpy(new_struct->event_type,event_type,33*sizeof(char));
01299 new_struct->objdetails.obj_of_int = obj_to_fault;
01300 new_struct->objdetails.obj_made_int = NULL;
01301 new_struct->objdetails.fail_time = fail_time;
01302 new_struct->objdetails.fail_time_dbl = fail_time_dbl;
01303 new_struct->objdetails.fail_length_ns = 0;
01304 new_struct->objdetails.rest_time = rest_time;
01305 new_struct->objdetails.rest_time_dbl = rest_time_dbl;
01306 new_struct->objdetails.rest_time_ns = 0;
01307 new_struct->objdetails.fail_length = TS_NEVER;
01308 new_struct->objdetails.fail_length_dbl = TSNVRDBL;
01309 new_struct->objdetails.fail_length_ns = 0;
01310 new_struct->objdetails.rest_length = rest_length;
01311 new_struct->objdetails.rest_length_dbl = (double)(rest_length);
01312 new_struct->objdetails.rest_length_ns = 0;
01313
01314
01315 new_struct->objdetails.in_fault = fault_state;
01316 new_struct->objdetails.customers_affected = 0;
01317 new_struct->objdetails.customers_affected_sec = 0;
01318
01319
01320 new_struct->next = Unhandled_Events.next;
01321 new_struct->prev = &Unhandled_Events;
01322 Unhandled_Events.next = new_struct;
01323
01324
01325 if (fault_state == false)
01326 {
01327
01328 if (fail_time < next_event_time)
01329 next_event_time = fail_time;
01330
01331
01332 if (deltamode_inclusive == true)
01333 {
01334 if (fail_time_dbl < next_event_time_dbl)
01335 {
01336 next_event_time_dbl = fail_time_dbl;
01337 }
01338 }
01339 }
01340 else
01341 {
01342
01343 if (rest_time < next_event_time)
01344 next_event_time = rest_time;
01345
01346
01347 if (deltamode_inclusive == true)
01348 {
01349 if (rest_time_dbl < next_event_time_dbl)
01350 {
01351 next_event_time_dbl = rest_time_dbl;
01352 }
01353 }
01354 }
01355
01356 return 1;
01357 }
01358
01359
01360 void eventgen::regen_events(TIMESTAMP t1_ts, double t1_dbl){
01361 OBJECT *hdr = OBJECTHDR(this);
01362 TIMESTAMP temp_time_A;
01363 double temp_time_A_dbl;
01364 unsigned int temp_time_A_nano;
01365 int index;
01366
01367
01368
01369 if ((fault_implement_mode==false) && ((curr_fail_dist_params[0]!=fail_dist_params[0])
01370 || (curr_fail_dist_params[1]!=fail_dist_params[1]) || (curr_rest_dist_params[0]!=rest_dist_params[0])
01371 || (curr_rest_dist_params[1]!=rest_dist_params[1]) || (curr_fail_dist!=failure_dist) || (curr_rest_dist!=restore_dist)))
01372 {
01373
01374 curr_fail_dist_params[0]=fail_dist_params[0];
01375 curr_fail_dist_params[1]=fail_dist_params[1];
01376 curr_rest_dist_params[0]=rest_dist_params[0];
01377 curr_rest_dist_params[1]=rest_dist_params[1];
01378 curr_fail_dist = failure_dist;
01379 curr_rest_dist = restore_dist;
01380
01381
01382 gl_verbose("Distribution parameters changed for %s",hdr->name);
01383
01384
01385
01386
01387 next_event_time = TS_NEVER;
01388 next_event_time_dbl = TSNVRDBL;
01389
01390 for (index=0; index<UnreliableObjCount; index++)
01391 {
01392 if (UnreliableObjs[index].in_fault == false)
01393 {
01394
01395 gen_random_time(failure_dist,fail_dist_params[0],fail_dist_params[1],&UnreliableObjs[index].fail_length,&UnreliableObjs[index].fail_length_ns,&UnreliableObjs[index].fail_length_dbl);
01396
01397
01398 gen_random_time(restore_dist,rest_dist_params[0],rest_dist_params[1],&temp_time_A,&temp_time_A_nano,&temp_time_A_dbl);
01399
01400
01401 if (temp_time_A_dbl > max_outage_length_dbl)
01402 {
01403 UnreliableObjs[index].rest_length = max_outage_length;
01404 UnreliableObjs[index].rest_length_ns = 0;
01405 UnreliableObjs[index].rest_length_dbl = max_outage_length_dbl;
01406 }
01407 else
01408 {
01409 UnreliableObjs[index].rest_length = temp_time_A;
01410 UnreliableObjs[index].rest_length_ns = temp_time_A_nano;
01411 UnreliableObjs[index].rest_length_dbl = temp_time_A_dbl;
01412 }
01413
01414 if (deltamode_inclusive == true)
01415 {
01416
01417 UnreliableObjs[index].fail_time_dbl = t1_dbl + UnreliableObjs[index].fail_length_dbl;
01418 UnreliableObjs[index].fail_time = (TIMESTAMP)(floor(UnreliableObjs[index].fail_time_dbl));
01419 UnreliableObjs[index].fail_time_ns = (unsigned int)((UnreliableObjs[index].fail_time_dbl - (double)(UnreliableObjs[index].fail_time))*1.0e9 + 0.5);
01420 }
01421 else
01422 {
01423
01424 UnreliableObjs[index].fail_time = t1_ts + UnreliableObjs[index].fail_length;
01425 }
01426
01427
01428 if (UnreliableObjs[index].fail_time < next_event_time)
01429 {
01430 next_event_time = UnreliableObjs[index].fail_time;
01431 }
01432
01433
01434 if (deltamode_inclusive == true)
01435 {
01436 if (UnreliableObjs[index].fail_time_dbl < next_event_time_dbl)
01437 {
01438 next_event_time_dbl = UnreliableObjs[index].fail_time_dbl;
01439 }
01440 }
01441
01442
01443 UnreliableObjs[index].rest_time = TS_NEVER;
01444 UnreliableObjs[index].rest_time_ns = 0;
01445 UnreliableObjs[index].rest_time_dbl = TSNVRDBL;
01446
01447
01448 UnreliableObjs[index].in_fault = false;
01449
01450 }
01451 else
01452 {
01453
01454 if (UnreliableObjs[index].rest_time < next_event_time)
01455 {
01456 next_event_time = UnreliableObjs[index].rest_time;
01457 }
01458
01459
01460 if (deltamode_inclusive == true)
01461 {
01462 if (UnreliableObjs[index].rest_time_dbl < next_event_time_dbl)
01463 {
01464 next_event_time_dbl = UnreliableObjs[index].rest_time_dbl;
01465 }
01466 }
01467 }
01468 }
01469 }
01470 }
01471
01472
01473
01474 void eventgen::do_event(TIMESTAMP t1_ts, double t1_dbl, bool entry_type)
01475 {
01476 OBJECT *hdr = OBJECTHDR(this);
01477 TIMESTAMP temp_time_A;
01478 double temp_time_A_dbl;
01479 unsigned int temp_time_A_nano;
01480 TIMESTAMP mean_repair_time;
01481 FUNCTIONADDR funadd = NULL;
01482 int returnval, index;
01483 char impl_fault[257];
01484 RELEVANTSTRUCT *temp_struct, *temp_struct_b;
01485 bool temp_bool;
01486 gld_rlock *test_rlock;
01487 STATUS temp_status;
01488
01489
01490 next_event_time = TS_NEVER;
01491 next_event_time_dbl = TSNVRDBL;
01492
01493
01494 for (index=0; index<UnreliableObjCount; index++)
01495 {
01496
01497 if ((((UnreliableObjs[index].fail_time <= t1_ts) && (entry_type == false)) || ((UnreliableObjs[index].fail_time_dbl <= t1_dbl) && (entry_type == true))) && (UnreliableObjs[index].in_fault == false))
01498 {
01499
01500 if ((faults_in_prog < max_simult_faults) || (max_simult_faults == -1))
01501 {
01502
01503 if ((diff_count_needed == false) && (metrics_obj_hdr != NULL))
01504 {
01505
01506 secondary_interruption_cnt->getp<bool>(temp_bool,*test_rlock);
01507
01508 if (temp_bool == true)
01509 {
01510
01511 wlock(metrics_obj_hdr);
01512
01513
01514 temp_status = ((STATUS (*)(OBJECT *,int *,int *))(*metrics_get_interrupted_count_sec))(metrics_obj_hdr,&curr_time_interrupted,&curr_time_interrupted_sec);
01515
01516
01517 wunlock(metrics_obj_hdr);
01518
01519 if (temp_status == FAILED)
01520 {
01521 GL_THROW("Eventgen:%d - %s - an error occurred while trying to get the object interruption count",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
01522
01523 }
01524 }
01525 else
01526 {
01527
01528 wlock(metrics_obj_hdr);
01529
01530
01531 temp_status = ((STATUS (*)(OBJECT *,int *))(*metrics_get_interrupted_count))(metrics_obj_hdr,&curr_time_interrupted);
01532
01533
01534 wunlock(metrics_obj_hdr);
01535
01536 if (temp_status == FAILED)
01537 {
01538 GL_THROW("Eventgen:%d - %s - an error occurred while trying to get the object interruption count",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
01539
01540 }
01541 }
01542 diff_count_needed = true;
01543 }
01544
01545
01546 funadd = (FUNCTIONADDR)(gl_get_function(UnreliableObjs[index].obj_of_int,"create_fault"));
01547
01548
01549 if (funadd == NULL)
01550 {
01551 GL_THROW("Unable to induce event on %s",UnreliableObjs[index].obj_of_int->name);
01552
01553
01554
01555
01556
01557 }
01558
01559
01560 wlock(UnreliableObjs[index].obj_of_int);
01561
01562 if (metrics_obj_hdr != NULL)
01563 {
01564 returnval = ((int (*)(OBJECT *, OBJECT **, char *, int *, TIMESTAMP *))(*funadd))(UnreliableObjs[index].obj_of_int,&UnreliableObjs[index].obj_made_int,fault_type.get_string(),&UnreliableObjs[index].implemented_fault,&mean_repair_time);
01565 }
01566 else
01567 {
01568 returnval = ((int (*)(OBJECT *, OBJECT **, char *, int *, TIMESTAMP *))(*funadd))(UnreliableObjs[index].obj_of_int,&UnreliableObjs[index].obj_made_int,fault_type.get_string(),&UnreliableObjs[index].implemented_fault,&mean_repair_time);
01569 }
01570
01571
01572 wunlock(UnreliableObjs[index].obj_of_int);
01573
01574 if (returnval == 0)
01575 {
01576 GL_THROW("Failed to induce event on %s",UnreliableObjs[index].obj_of_int->name);
01577
01578
01579
01580
01581
01582 }
01583
01584
01585 if (fault_implement_mode == false)
01586 {
01587
01588
01589 if (deltamode_inclusive == true)
01590 {
01591 UnreliableObjs[index].rest_time_dbl = t1_dbl + UnreliableObjs[index].rest_length_dbl;
01592 UnreliableObjs[index].rest_time = (TIMESTAMP)(floor(UnreliableObjs[index].rest_time_dbl));
01593 UnreliableObjs[index].rest_time_ns = (unsigned int)((UnreliableObjs[index].rest_time_dbl - (double)(UnreliableObjs[index].rest_time))*1.0e9 + 0.5);
01594 }
01595 else
01596 {
01597 UnreliableObjs[index].rest_time = t1_ts + UnreliableObjs[index].rest_length;
01598 }
01599 }
01600
01601
01602 if (mean_repair_time != 0)
01603 {
01604 UnreliableObjs[index].rest_time += mean_repair_time;
01605 UnreliableObjs[index].rest_time_dbl += (double)mean_repair_time;
01606 }
01607
01608
01609 if (UnreliableObjs[index].rest_time < next_event_time)
01610 {
01611 next_event_time = UnreliableObjs[index].rest_time;
01612 }
01613
01614
01615 if (deltamode_inclusive == true)
01616 {
01617 if (UnreliableObjs[index].rest_time_dbl < next_event_time_dbl)
01618 {
01619 next_event_time_dbl = UnreliableObjs[index].rest_time_dbl;
01620 }
01621 }
01622
01623
01624 UnreliableObjs[index].in_fault = true;
01625
01626
01627 UnreliableObjs[index].customers_affected = -1;
01628
01629
01630 UnreliableObjs[index].customers_affected_sec = -1;
01631
01632
01633 faults_in_prog++;
01634 }
01635 else
01636 {
01637 if (fault_implement_mode == false)
01638 {
01639
01640 gen_random_time(failure_dist,fail_dist_params[0],fail_dist_params[1],&UnreliableObjs[index].fail_length,&UnreliableObjs[index].fail_length_ns,&UnreliableObjs[index].fail_length_dbl);
01641
01642
01643
01644 if (deltamode_inclusive == true)
01645 {
01646 UnreliableObjs[index].fail_time_dbl = t1_dbl + UnreliableObjs[index].fail_length_dbl;
01647 UnreliableObjs[index].fail_time = (TIMESTAMP)(floor(UnreliableObjs[index].fail_time_dbl));
01648 UnreliableObjs[index].fail_time_ns = (unsigned int)((UnreliableObjs[index].fail_time_dbl - (double)(UnreliableObjs[index].fail_time))*1.0e9 + 0.5);
01649 }
01650 else
01651 {
01652 UnreliableObjs[index].fail_time = t1_ts + UnreliableObjs[index].fail_length;
01653 }
01654
01655
01656 if (UnreliableObjs[index].fail_time < next_event_time)
01657 {
01658 next_event_time = UnreliableObjs[index].fail_time;
01659 }
01660
01661
01662 if (deltamode_inclusive == true)
01663 {
01664 if (UnreliableObjs[index].fail_time_dbl < next_event_time_dbl)
01665 {
01666 next_event_time_dbl = UnreliableObjs[index].fail_time_dbl;
01667 }
01668 }
01669 }
01670 else
01671 {
01672
01673 gl_warning("Manual event %d of eventgen:%s exceeded the simultaneous fault limit and was ignored",index,hdr->name);
01674
01675
01676
01677
01678
01679
01680 UnreliableObjs[index].rest_time = TS_NEVER;
01681 UnreliableObjs[index].rest_time_dbl = TSNVRDBL;
01682 UnreliableObjs[index].rest_length_ns = 0;
01683
01684 UnreliableObjs[index].fail_time = TS_NEVER;
01685 UnreliableObjs[index].fail_time_dbl = TSNVRDBL;
01686 UnreliableObjs[index].fail_time_ns = 0;
01687 }
01688 }
01689 }
01690 else if (((UnreliableObjs[index].rest_time <= t1_ts) && (entry_type == false)) || ((UnreliableObjs[index].rest_time_dbl <= t1_dbl) && (entry_type == true)))
01691 {
01692
01693 funadd = (FUNCTIONADDR)(gl_get_function(UnreliableObjs[index].obj_of_int,"fix_fault"));
01694
01695
01696 if (funadd == NULL)
01697 {
01698 GL_THROW("Unable to induce event on %s",UnreliableObjs[index].obj_of_int->name);
01699
01700 }
01701
01702
01703 wlock(UnreliableObjs[index].obj_of_int);
01704
01705 if (metrics_obj_hdr != NULL)
01706 {
01707 returnval = ((int (*)(OBJECT *, int *, char *))(*funadd))(UnreliableObjs[index].obj_of_int,&UnreliableObjs[index].implemented_fault,impl_fault);
01708 }
01709 else
01710 {
01711 returnval = ((int (*)(OBJECT *, int *, char *))(*funadd))(UnreliableObjs[index].obj_of_int,&UnreliableObjs[index].implemented_fault,impl_fault);
01712 }
01713
01714
01715 wunlock(UnreliableObjs[index].obj_of_int);
01716
01717 if (returnval == 0)
01718 {
01719 GL_THROW("Failed to induce repair on %s",UnreliableObjs[index].obj_of_int->name);
01720
01721
01722
01723
01724
01725 }
01726
01727 if (metrics_obj_hdr != NULL)
01728 {
01729
01730 secondary_interruption_cnt->getp<bool>(temp_bool,*test_rlock);
01731
01732
01733 wlock(metrics_obj_hdr);
01734
01735
01736 if (temp_bool == true)
01737 {
01738 temp_status = ((STATUS (*)(OBJECT *,OBJECT *,OBJECT *,OBJECT *,TIMESTAMP,TIMESTAMP,char *,char *,int, int))(*metrics_object_event_ended_sec))(metrics_obj_hdr,hdr,UnreliableObjs[index].obj_of_int,UnreliableObjs[index].obj_made_int,UnreliableObjs[index].fail_time,UnreliableObjs[index].rest_time,fault_type.get_string(),impl_fault,UnreliableObjs[index].customers_affected,UnreliableObjs[index].customers_affected_sec);
01739 }
01740 else
01741 {
01742 temp_status = ((STATUS (*)(OBJECT *,OBJECT *,OBJECT *,OBJECT *,TIMESTAMP,TIMESTAMP,char *,char *,int))(*metrics_object_event_ended))(metrics_obj_hdr,hdr,UnreliableObjs[index].obj_of_int,UnreliableObjs[index].obj_made_int,UnreliableObjs[index].fail_time,UnreliableObjs[index].rest_time,fault_type.get_string(),impl_fault,UnreliableObjs[index].customers_affected);
01743 }
01744
01745
01746 wunlock(metrics_obj_hdr);
01747
01748 if (temp_status == FAILED)
01749 {
01750 GL_THROW("Eventgen:%d - %s - an error occurred while trying to end an event",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
01751
01752
01753
01754
01755 }
01756 }
01757
01758
01759 if (fault_implement_mode == false)
01760 {
01761
01762 gen_random_time(failure_dist,fail_dist_params[0],fail_dist_params[1],&UnreliableObjs[index].fail_length,&UnreliableObjs[index].fail_length_ns,&UnreliableObjs[index].fail_length_dbl);
01763
01764
01765 gen_random_time(restore_dist,rest_dist_params[0],rest_dist_params[1],&temp_time_A,&temp_time_A_nano,&temp_time_A_dbl);
01766
01767
01768 if (temp_time_A_dbl > max_outage_length_dbl)
01769 {
01770 UnreliableObjs[index].rest_length = max_outage_length;
01771 UnreliableObjs[index].rest_length_ns = 0;
01772 UnreliableObjs[index].rest_length_dbl = max_outage_length_dbl;
01773 }
01774 else
01775 {
01776 UnreliableObjs[index].rest_length = temp_time_A;
01777 UnreliableObjs[index].rest_length_ns = temp_time_A_nano;
01778 UnreliableObjs[index].rest_length_dbl = temp_time_A_dbl;
01779 }
01780
01781
01782
01783 if (deltamode_inclusive == true)
01784 {
01785 UnreliableObjs[index].fail_time_dbl = t1_dbl + UnreliableObjs[index].fail_length_dbl;
01786 UnreliableObjs[index].fail_time = (TIMESTAMP)(floor(UnreliableObjs[index].fail_time_dbl));
01787 UnreliableObjs[index].fail_time_ns = (unsigned int)((UnreliableObjs[index].fail_time_dbl - (double)(UnreliableObjs[index].fail_time))*1.0e9 + 0.5);
01788 }
01789 else
01790 {
01791 UnreliableObjs[index].fail_time = t1_ts + UnreliableObjs[index].fail_length;
01792 }
01793
01794
01795 if (UnreliableObjs[index].fail_time < next_event_time)
01796 next_event_time = UnreliableObjs[index].fail_time;
01797
01798
01799 if (deltamode_inclusive == true)
01800 {
01801 if (UnreliableObjs[index].fail_time_dbl < next_event_time_dbl)
01802 {
01803 next_event_time_dbl = UnreliableObjs[index].fail_time_dbl;
01804 }
01805 }
01806
01807
01808 UnreliableObjs[index].rest_time = TS_NEVER;
01809 UnreliableObjs[index].rest_time_ns = 0;
01810 UnreliableObjs[index].rest_time_dbl = TSNVRDBL;
01811
01812 }
01813 else
01814 {
01815 UnreliableObjs[index].fail_time = TS_NEVER;
01816 UnreliableObjs[index].fail_time_dbl = TSNVRDBL;
01817 UnreliableObjs[index].fail_time_ns = 0;
01818
01819 UnreliableObjs[index].rest_time = TS_NEVER;
01820 UnreliableObjs[index].rest_time_dbl = TSNVRDBL;
01821 UnreliableObjs[index].rest_time_ns = 0;
01822 }
01823
01824
01825 UnreliableObjs[index].in_fault = false;
01826
01827
01828 faults_in_prog--;
01829 }
01830 else
01831 {
01832
01833 if (UnreliableObjs[index].in_fault == false)
01834 {
01835
01836 if (UnreliableObjs[index].fail_time < next_event_time)
01837 {
01838 next_event_time = UnreliableObjs[index].fail_time;
01839 }
01840
01841
01842 if (deltamode_inclusive == true)
01843 {
01844 if (UnreliableObjs[index].fail_time_dbl < next_event_time_dbl)
01845 {
01846 next_event_time_dbl = UnreliableObjs[index].fail_time_dbl;
01847 }
01848 }
01849 }
01850 else
01851 {
01852
01853 if (UnreliableObjs[index].rest_time < next_event_time)
01854 {
01855 next_event_time = UnreliableObjs[index].rest_time;
01856 }
01857
01858
01859 if (deltamode_inclusive == true)
01860 {
01861 if (UnreliableObjs[index].rest_time_dbl < next_event_time_dbl)
01862 {
01863 next_event_time_dbl = UnreliableObjs[index].rest_time_dbl;
01864 }
01865 }
01866 }
01867
01868 }
01869 }
01870
01871
01872 if (Unhandled_Events.next != NULL)
01873 {
01874
01875 temp_struct = &Unhandled_Events;
01876
01877
01878 while (temp_struct->next != NULL)
01879 {
01880
01881 temp_struct = temp_struct->next;
01882
01883
01884
01885
01886 if ((((temp_struct->objdetails.fail_time <= t1_ts) && (entry_type == false)) || ((temp_struct->objdetails.fail_time_dbl <= t1_dbl) && (entry_type == true))) && (temp_struct->objdetails.in_fault == false))
01887 {
01888
01889
01890 if ((diff_count_needed == false) && (metrics_obj_hdr != NULL))
01891 {
01892
01893 secondary_interruption_cnt->getp<bool>(temp_bool,*test_rlock);
01894
01895 if (temp_bool == true)
01896 {
01897
01898 wlock(metrics_obj_hdr);
01899
01900
01901 temp_status = ((STATUS (*)(OBJECT *,int *,int *))(*metrics_get_interrupted_count_sec))(metrics_obj_hdr,&curr_time_interrupted,&curr_time_interrupted_sec);
01902
01903
01904 wunlock(metrics_obj_hdr);
01905
01906 if (temp_status == FAILED)
01907 {
01908 GL_THROW("Eventgen:%d - %s - an error occurred while trying to get the object interruption count",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
01909
01910 }
01911 }
01912 else
01913 {
01914
01915 wlock(metrics_obj_hdr);
01916
01917
01918 temp_status = ((STATUS (*)(OBJECT *,int *))(*metrics_get_interrupted_count))(metrics_obj_hdr,&curr_time_interrupted);
01919
01920
01921 wunlock(metrics_obj_hdr);
01922
01923 if (temp_status == FAILED)
01924 {
01925 GL_THROW("Eventgen:%d - %s - an error occurred while trying to get the object interruption count",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
01926
01927 }
01928 }
01929 diff_count_needed = true;
01930 }
01931
01932
01933 funadd = (FUNCTIONADDR)(gl_get_function(temp_struct->objdetails.obj_of_int,"create_fault"));
01934
01935
01936 if (funadd == NULL)
01937 {
01938 GL_THROW("Unable to induce event on %s",temp_struct->objdetails.obj_of_int->name);
01939
01940 }
01941
01942
01943 wlock(temp_struct->objdetails.obj_of_int);
01944
01945 if (metrics_obj_hdr != NULL)
01946 {
01947 returnval = ((int (*)(OBJECT *, OBJECT **, char *, int *, TIMESTAMP *))(*funadd))(temp_struct->objdetails.obj_of_int,&temp_struct->objdetails.obj_made_int,temp_struct->event_type,&temp_struct->objdetails.implemented_fault,&mean_repair_time);
01948 }
01949 else
01950 {
01951 returnval = ((int (*)(OBJECT *, OBJECT **, char *, int *, TIMESTAMP *))(*funadd))(temp_struct->objdetails.obj_of_int,&temp_struct->objdetails.obj_made_int,temp_struct->event_type,&temp_struct->objdetails.implemented_fault,&mean_repair_time);
01952 }
01953
01954
01955 wunlock(temp_struct->objdetails.obj_of_int);
01956
01957 if (returnval == 0)
01958 {
01959 GL_THROW("Failed to induce event on %s",temp_struct->objdetails.obj_of_int->name);
01960
01961 }
01962
01963
01964 if ((mean_repair_time != 0) && (temp_struct->objdetails.rest_time != TS_NEVER))
01965 {
01966 temp_struct->objdetails.rest_time += mean_repair_time;
01967
01968
01969 if (deltamode_inclusive == true)
01970 {
01971 temp_struct->objdetails.rest_time_dbl += (double)(mean_repair_time);
01972 }
01973 }
01974
01975
01976 if (temp_struct->objdetails.rest_time < next_event_time)
01977 {
01978 next_event_time = temp_struct->objdetails.rest_time;
01979 }
01980
01981
01982 if (deltamode_inclusive == true)
01983 {
01984 if (temp_struct->objdetails.rest_time_dbl < next_event_time_dbl)
01985 {
01986 next_event_time_dbl = temp_struct->objdetails.rest_time_dbl;
01987 }
01988 }
01989
01990
01991 temp_struct->objdetails.in_fault = true;
01992
01993
01994 temp_struct->objdetails.customers_affected = -1;
01995
01996
01997 temp_struct->objdetails.customers_affected_sec = -1;
01998
01999
02000 faults_in_prog++;
02001
02002
02003 if (temp_struct->objdetails.rest_time == TS_NEVER)
02004 {
02005
02006 temp_struct_b = temp_struct->prev;
02007
02008
02009 temp_struct_b->next = temp_struct->next;
02010
02011
02012 gl_free(temp_struct);
02013
02014
02015 if (temp_struct_b->next != NULL)
02016 temp_struct = temp_struct_b->next;
02017 else
02018 temp_struct = temp_struct_b;
02019 }
02020 }
02021 else if (((temp_struct->objdetails.rest_time <= t1_ts) && (entry_type == false)) || ((temp_struct->objdetails.rest_time_dbl <= t1_dbl) && (entry_type == true)))
02022 {
02023
02024 funadd = (FUNCTIONADDR)(gl_get_function(temp_struct->objdetails.obj_of_int,"fix_fault"));
02025
02026
02027 if (funadd == NULL)
02028 {
02029 GL_THROW("Unable to induce event on %s",temp_struct->objdetails.obj_of_int->name);
02030
02031 }
02032
02033
02034 wlock(temp_struct->objdetails.obj_of_int);
02035
02036 if (metrics_obj_hdr != NULL)
02037 {
02038 returnval = ((int (*)(OBJECT *, int *, char *))(*funadd))(temp_struct->objdetails.obj_of_int,&temp_struct->objdetails.implemented_fault,impl_fault);
02039 }
02040 else
02041 {
02042 returnval = ((int (*)(OBJECT *, int *, char *))(*funadd))(temp_struct->objdetails.obj_of_int,&temp_struct->objdetails.implemented_fault,impl_fault);
02043 }
02044
02045
02046 wunlock(temp_struct->objdetails.obj_of_int);
02047
02048 if (returnval == 0)
02049 {
02050 GL_THROW("Failed to induce repair on %s",temp_struct->objdetails.obj_of_int->name);
02051
02052 }
02053
02054 if (metrics_obj_hdr != NULL)
02055 {
02056
02057 secondary_interruption_cnt->getp<bool>(temp_bool,*test_rlock);
02058
02059
02060 wlock(metrics_obj_hdr);
02061
02062
02063 if (temp_bool == true)
02064 {
02065 temp_status = ((STATUS (*)(OBJECT *,OBJECT *,OBJECT *,OBJECT *,TIMESTAMP,TIMESTAMP,char *,char *,int, int))(*metrics_object_event_ended_sec))(metrics_obj_hdr,hdr,temp_struct->objdetails.obj_of_int,temp_struct->objdetails.obj_made_int,temp_struct->objdetails.fail_time,temp_struct->objdetails.rest_time,temp_struct->event_type,impl_fault,temp_struct->objdetails.customers_affected,temp_struct->objdetails.customers_affected_sec);
02066 }
02067 else
02068 {
02069 temp_status = ((STATUS (*)(OBJECT *,OBJECT *,OBJECT *,OBJECT *,TIMESTAMP,TIMESTAMP,char *,char *,int))(*metrics_object_event_ended))(metrics_obj_hdr,hdr,temp_struct->objdetails.obj_of_int,temp_struct->objdetails.obj_made_int,temp_struct->objdetails.fail_time,temp_struct->objdetails.rest_time,temp_struct->event_type,impl_fault,temp_struct->objdetails.customers_affected);
02070 }
02071
02072
02073 wunlock(metrics_obj_hdr);
02074
02075 if (temp_status == FAILED)
02076 {
02077 GL_THROW("Eventgen:%d - %s - an error occurred while trying to end an event",hdr->id,(hdr->name ? hdr->name : "Unnamed"));
02078
02079 }
02080 }
02081
02082
02083
02084 temp_struct_b = temp_struct->prev;
02085
02086
02087 temp_struct_b->next = temp_struct->next;
02088
02089
02090 gl_free(temp_struct);
02091
02092
02093 faults_in_prog--;
02094
02095
02096 if (temp_struct_b->next != NULL)
02097 temp_struct = temp_struct_b->next;
02098 else
02099 temp_struct = temp_struct_b;
02100
02101 }
02102 else
02103 {
02104
02105 if (temp_struct->objdetails.in_fault == false)
02106 {
02107
02108 if (temp_struct->objdetails.fail_time < next_event_time)
02109 {
02110 next_event_time = temp_struct->objdetails.fail_time;
02111 }
02112
02113
02114 if (deltamode_inclusive == true)
02115 {
02116 if (temp_struct->objdetails.fail_time_dbl < next_event_time_dbl)
02117 {
02118 next_event_time_dbl = temp_struct->objdetails.fail_time_dbl;
02119 }
02120 }
02121 }
02122 else
02123 {
02124
02125 if (temp_struct->objdetails.rest_time < next_event_time)
02126 {
02127 next_event_time = temp_struct->objdetails.rest_time;
02128 }
02129
02130
02131 if (deltamode_inclusive == true)
02132 {
02133 if (temp_struct->objdetails.rest_time_dbl < next_event_time_dbl)
02134 {
02135 next_event_time_dbl = temp_struct->objdetails.rest_time_dbl;
02136 }
02137 }
02138 }
02139
02140 }
02141 }
02142 }
02143
02144
02145 faults_in_prog = 0;
02146
02147
02148 for (index=0; index<UnreliableObjCount;index++)
02149 {
02150 if (UnreliableObjs[index].in_fault == true)
02151 faults_in_prog++;
02152 }
02153
02154
02155 if (Unhandled_Events.next != NULL)
02156 {
02157
02158 temp_struct = &Unhandled_Events;
02159
02160
02161 while (temp_struct->next != NULL)
02162 {
02163
02164 temp_struct = temp_struct->next;
02165
02166
02167 if (temp_struct->objdetails.in_fault == true)
02168 faults_in_prog++;
02169 }
02170 }
02171 }
02172
02174
02176
02177 EXPORT SIMULATIONMODE interupdate_eventgen(OBJECT *obj, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
02178 {
02179 eventgen *my = OBJECTDATA(obj,eventgen);
02180 SIMULATIONMODE status = SM_ERROR;
02181 status = my->inter_deltaupdate(delta_time, dt, iteration_count_val);
02182 return status;
02183 }
02184
02185 SIMULATIONMODE eventgen::inter_deltaupdate(unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
02186 {
02187 double deltat = (double)delta_time/(double)DT_SECOND;
02188 double t1_dbl = (double)gl_globalclock + deltat;
02189 TIMESTAMP t1_ts;
02190 double delta_epsilon = (double)dt/(double)DT_SECOND/2;
02191
02192 t1_ts = (TIMESTAMP)(t1_dbl + 1.0/(2.0*((double)(DT_SECOND))));
02193
02194 if(next_event_time_dbl < ceil(t1_dbl + delta_epsilon)){
02195 if (t1_dbl < next_event_time_dbl){
02196 return SM_DELTA;
02197 }
02198
02199
02200 regen_events(t1_ts,t1_dbl);
02201
02202
02203 do_event(t1_ts,t1_dbl,true);
02204
02205
02206 if(next_event_time_dbl < ceil(t1_dbl + delta_epsilon)){
02207 return SM_DELTA;
02208 }else{ return SM_EVENT; }
02209 }
02210
02211 return SM_EVENT;
02212 }
02213
02215
02217
02218 EXPORT int create_eventgen(OBJECT **obj, OBJECT *parent)
02219 {
02220 try
02221 {
02222 *obj = gl_create_object(eventgen::oclass);
02223 if (*obj!=NULL)
02224 {
02225 eventgen *my = OBJECTDATA(*obj,eventgen);
02226 gl_set_parent(*obj,parent);
02227 return my->create();
02228 }
02229 else
02230 return 0;
02231 }
02232 CREATE_CATCHALL(eventgen);
02233 }
02234
02235 EXPORT int init_eventgen(OBJECT *obj, OBJECT *parent)
02236 {
02237 try
02238 {
02239 if (obj!=NULL)
02240 return OBJECTDATA(obj,eventgen)->init(parent);
02241 else
02242 return 0;
02243 }
02244 INIT_CATCHALL(eventgen);
02245 }
02246
02247 EXPORT TIMESTAMP sync_eventgen(OBJECT *obj, TIMESTAMP t1, PASSCONFIG pass)
02248 {
02249 try
02250 {
02251 TIMESTAMP t2 = TS_NEVER;
02252 eventgen *my = OBJECTDATA(obj,eventgen);
02253 switch (pass) {
02254 case PC_PRETOPDOWN:
02255 return my->presync(obj->clock,t1);
02256 break;
02257 case PC_BOTTOMUP:
02258 break;
02259 case PC_POSTTOPDOWN:
02260 t2 = my->postsync(obj->clock,t1);
02261 obj->clock = t1;
02262 break;
02263 default:
02264 GL_THROW("invalid pass request (%d)", pass);
02265 break;
02266 }
02267 return t2;
02268 }
02269 SYNC_CATCHALL(eventgen);
02270 }
02271
02272
02273 EXPORT int add_event(OBJECT *event_obj, OBJECT *obj_to_fault, char *event_type, TIMESTAMP fail_time, TIMESTAMP rest_length, int implemented_fault, bool fault_state)
02274 {
02275 int ret_value;
02276 eventgen *eventgenobj = OBJECTDATA(event_obj,eventgen);
02277
02278
02279 ret_value = eventgenobj->add_unhandled_event(obj_to_fault, event_type, fail_time, rest_length, implemented_fault, fault_state);
02280
02281
02282 return ret_value;
02283 }