00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef lint
00013 #define lint
00014 static char copyright[] =
00015 "@(#) Copyright (c) 1996 John C. Gyllenhaal, Wen-mei Hwu and The Board of \n\
00016 Trustees of the University of Illinois. All rights reserved.\n";
00017 #endif
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include "sm_mdes.h"
00023 #include "mdes2.h"
00024 #include "l_alloc_new.h"
00025 #include "l_punt.h"
00026
00027 #define DEBUG_MDES 0
00028
00029 static L_Alloc_Pool *SM_Mdes_pool = NULL;
00030
00031 int SM_add_ids_to_entries (MD_Section *section)
00032 {
00033 MD_Entry *entry;
00034 MD_Field_Decl *id_field_decl;
00035 MD_Field *id_field;
00036 int id;
00037
00038
00039 if ((id_field_decl = MD_find_field_decl (section, "id")) != NULL)
00040 L_punt ("SM_add_ids_to_entries: Section '%s' already has id field!",
00041 section->name);
00042
00043
00044 id_field_decl = MD_new_field_decl (section, "id", MD_REQUIRED_FIELD);
00045 MD_require_int (id_field_decl, 0);
00046
00047
00048 id = 0;
00049 for (entry = MD_first_entry (section); entry != NULL;
00050 entry = MD_next_entry (entry))
00051 {
00052
00053 id_field = MD_new_field (entry, id_field_decl, 1);
00054 MD_set_int (id_field, 0, id);
00055
00056 id++;
00057 }
00058
00059
00060 return (id);
00061 }
00062
00063 void SM_build_resources (SM_Mdes *sm_mdes)
00064 {
00065 SM_Resource *resource, *resource_array;
00066 MD_Section *resource_section;
00067 MD_Entry *resource_entry;
00068 MD_Field_Decl *map_location_field_decl;
00069 MD_Field *map_location_field;
00070 int num_resources, size, index, id;
00071 int time_shift, max_offset;
00072
00073
00074 resource_section = MD_find_section (sm_mdes->md_mdes, "Resource");
00075 map_location_field_decl = MD_find_field_decl (resource_section,
00076 "map_location");
00077
00078
00079
00080
00081 num_resources = SM_add_ids_to_entries (resource_section);
00082
00083
00084 size = num_resources * sizeof (SM_Resource);
00085 if ((resource_array = (SM_Resource *) malloc (size)) == NULL)
00086 L_punt ("SM_build_resources: Out of memory");
00087
00088
00089
00090
00091 id = 0;
00092 max_offset = -1;
00093 for (resource_entry = MD_first_entry (resource_section);
00094 resource_entry != NULL;
00095 resource_entry = MD_next_entry (resource_entry))
00096 {
00097
00098 resource = &resource_array[id];
00099
00100
00101 resource->name = strdup (resource_entry->name);
00102
00103
00104 map_location_field = MD_find_field (resource_entry,
00105 map_location_field_decl);
00106
00107
00108 resource->offset = MD_get_int (map_location_field, 0);
00109
00110 if (resource->offset > max_offset)
00111 max_offset = resource->offset;
00112
00113
00114 index = MD_get_int (map_location_field, 0);
00115
00116
00117 resource->mask = (1 << index);
00118
00119 #if DEBUG_MDES
00120 printf ("Resource %s: %i offset %x mask\n", resource->name,
00121 resource->offset, resource->mask);
00122 #endif
00123
00124
00125 id++;
00126 }
00127
00128
00129 if (id != num_resources)
00130 {
00131 L_punt("SM_build_resources: id (%i) and # resources (%i) should agree",
00132 id, num_resources);
00133 }
00134
00135
00136
00137
00138
00139 time_shift = 0;
00140 while ((max_offset + 1) > (1 << time_shift))
00141 time_shift++;
00142
00143 sm_mdes->map_width = 1 << time_shift;
00144 sm_mdes->time_shift = time_shift;
00145
00146 #if 0
00147 sm_mdes->time_shift += 0;
00148 printf ("Increasing time shift to %i\n", sm_mdes->time_shift);
00149 #endif
00150
00151
00152
00153 sm_mdes->resource = resource_array;
00154 sm_mdes->num_resources = num_resources;
00155 }
00156
00157 void SM_build_units (SM_Mdes *sm_mdes)
00158 {
00159 SM_Resource *resource_array, *resource;
00160 SM_Option *unit_array, *unit;
00161 SM_Usage *usage_array, *usage;
00162 MD_Section *unit_section, *usage_section, *resource_section;
00163 MD_Entry *unit_entry, *ru_entry, *resource_entry;
00164 MD_Field_Decl *unit_use_field_decl, *resource_id_field_decl;
00165 MD_Field_Decl *ru_use_field_decl, *ru_time_field_decl;
00166 MD_Field *unit_use_field, *ru_use_field, *ru_time_field;
00167 MD_Field *resource_id_field;
00168 int num_units, array_size, num_usages;
00169 int index1, index2, id;
00170 int resources_used, map_offset, resource_offset;
00171 int usage_time, resource_id, time_shift;
00172
00173
00174 resource_array = sm_mdes->resource;
00175
00176
00177 time_shift = sm_mdes->time_shift;
00178
00179
00180 unit_section = MD_find_section (sm_mdes->md_mdes, "Resource_Unit");
00181 unit_use_field_decl = MD_find_field_decl (unit_section, "use");
00182
00183
00184 usage_section = MD_find_section (sm_mdes->md_mdes, "Resource_Usage");
00185 ru_use_field_decl = MD_find_field_decl (usage_section, "use");
00186 ru_time_field_decl = MD_find_field_decl (usage_section, "time");
00187
00188
00189 resource_section = MD_find_section (sm_mdes->md_mdes, "Resource");
00190 resource_id_field_decl = MD_find_field_decl (resource_section, "id");
00191
00192
00193
00194
00195 num_units = SM_add_ids_to_entries (unit_section);
00196
00197
00198 array_size = num_units * sizeof (SM_Option);
00199 if ((unit_array = (SM_Option *) malloc (array_size)) == NULL)
00200 L_punt ("SM_build_units: Out of memory");
00201
00202
00203
00204
00205
00206 id = 0;
00207 for (unit_entry = MD_first_entry (unit_section);
00208 unit_entry != NULL;
00209 unit_entry = MD_next_entry (unit_entry))
00210 {
00211
00212 unit = &unit_array[id];
00213
00214 #if DEBUG_MDES
00215 printf ("Building %s:\n", unit_entry->name);
00216 #endif
00217
00218
00219 unit_use_field = MD_find_field (unit_entry, unit_use_field_decl);
00220
00221
00222 num_usages = unit_use_field->max_element_index + 1;
00223 array_size = num_usages * sizeof (SM_Usage);
00224 if ((usage_array = (SM_Usage *) malloc (array_size)) == NULL)
00225 L_punt ("SM_build_units: Out of memory");
00226
00227
00228 for (index1 = 0; index1 < num_usages; index1++)
00229 {
00230
00231 usage = &usage_array[index1];
00232
00233
00234 ru_entry = MD_get_link (unit_use_field, index1);
00235
00236
00237 ru_time_field = MD_find_field (ru_entry, ru_time_field_decl);
00238 usage_time = MD_get_int (ru_time_field, 0);
00239
00240
00241 resources_used = 0;
00242 resource_offset = -1;
00243 ru_use_field = MD_find_field (ru_entry, ru_use_field_decl);
00244 for (index2 = 0; index2 <= ru_use_field->max_element_index;
00245 index2++)
00246 {
00247
00248 resource_entry = MD_get_link (ru_use_field, index2);
00249
00250
00251 resource_id_field = MD_find_field (resource_entry,
00252 resource_id_field_decl);
00253 resource_id = MD_get_int (resource_id_field, 0);
00254
00255
00256 resource = &resource_array[resource_id];
00257
00258
00259 resources_used |= resource->mask;
00260
00261
00262
00263
00264 if (index2 == 0)
00265 resource_offset = resource->offset;
00266 else if (resource_offset != resource->offset)
00267 {
00268 L_punt ("SM_build_units: Offset mismatch (%i != %i)",
00269 resource_offset, resource->offset);
00270 }
00271 }
00272
00273
00274
00275
00276 map_offset = (usage_time << time_shift) + resource_offset;
00277
00278
00279 usage->resources_used = resources_used;
00280 usage->map_offset = map_offset;
00281
00282 #if DEBUG_MDES
00283 printf (" %x at offset %i\n", resources_used, map_offset);
00284 #endif
00285 }
00286
00287
00288 unit->first_usage = usage_array;
00289 unit->last_usage = &usage_array[num_usages - 1];
00290
00291
00292 id++;
00293 }
00294
00295
00296 if (id != num_units)
00297 L_punt ("SM_build_units: id (%i) and num_units (%i) should agree!",
00298 id, num_units);
00299
00300
00301
00302 sm_mdes->unit_array = unit_array;
00303 sm_mdes->unit_array_size = num_units;
00304 }
00305
00306 void SM_build_choices (SM_Mdes *sm_mdes)
00307 {
00308 SM_Choice *choice_array, *choice;
00309 SM_Option *option_array, *option, *unit;
00310 MD_Section *option_section, *unit_section;
00311 MD_Entry *option_entry, *unit_entry;
00312 MD_Field_Decl *one_of_field_decl, *unit_id_field_decl;
00313 MD_Field *one_of_field, *unit_id_field;
00314 int num_choices, num_options, unit_id;
00315 int id, array_size, index1;
00316
00317
00318 unit_section = MD_find_section (sm_mdes->md_mdes, "Resource_Unit");
00319 unit_id_field_decl = MD_find_field_decl (unit_section, "id");
00320
00321
00322
00323
00324 option_section = MD_find_section (sm_mdes->md_mdes, "Table_Option");
00325 one_of_field_decl = MD_find_field_decl (option_section, "one_of");
00326
00327
00328
00329
00330 num_choices = SM_add_ids_to_entries (option_section);
00331
00332
00333 array_size = num_choices * sizeof (SM_Choice);
00334 if ((choice_array = (SM_Choice *)malloc (array_size)) == NULL)
00335 L_punt ("SM_build_choices: Out of memory");
00336
00337
00338 id = 0;
00339 for (option_entry = MD_first_entry (option_section); option_entry != NULL;
00340 option_entry = MD_next_entry (option_entry))
00341 {
00342
00343 choice = &choice_array[id];
00344
00345 #if DEBUG_MDES
00346 printf ("Building choice %s:\n", option_entry->name);
00347 #endif
00348
00349
00350 one_of_field = MD_find_field (option_entry, one_of_field_decl);
00351
00352
00353 num_options = one_of_field->max_element_index + 1;
00354 array_size = num_options * sizeof (SM_Option);
00355 if ((option_array = (SM_Option *) malloc (array_size)) == NULL)
00356 L_punt ("SM_build_choices: Out of memory");
00357
00358
00359 for (index1 = 0; index1 < num_options; index1 ++)
00360 {
00361
00362 option = &option_array[index1];
00363
00364
00365 unit_entry = MD_get_link (one_of_field, index1);
00366 unit_id_field = MD_find_field (unit_entry, unit_id_field_decl);
00367 unit_id = MD_get_int (unit_id_field, 0);
00368 unit = &sm_mdes->unit_array[unit_id];
00369
00370
00371 option->first_usage = unit->first_usage;
00372 option->last_usage = unit->last_usage;
00373 #if DEBUG_MDES
00374 printf (" Option %i: unit %s, offset %i to %i\n",
00375 index1,
00376 unit_entry->name,
00377 option->first_usage->map_offset,
00378 option->last_usage->map_offset);
00379 #endif
00380 }
00381
00382
00383 choice->first_option = option_array;
00384 choice->last_option = &option_array[num_options -1];
00385
00386
00387 id++;
00388 }
00389
00390
00391 if (id != num_choices)
00392 L_punt ("SM_build_choices: id (%i) and num_choices (%i) should agree!",
00393 id, num_choices);
00394
00395
00396
00397 sm_mdes->choice_array = choice_array;
00398 sm_mdes->choice_array_size = num_choices;
00399 }
00400
00401 void SM_build_tables (SM_Mdes *sm_mdes)
00402 {
00403 SM_Table *table_array, *table;
00404 SM_Choice *choice_array, *choice, *target_choice;
00405 MD_Section *table_section, *option_section, *unit_section;
00406 MD_Entry *table_entry, *option_entry, *unit_entry, *slot_specifier;
00407 MD_Field_Decl *one_of_field_decl, *option_id_field_decl;
00408 MD_Field_Decl *table_use_field_decl, *slot_specifier_field_decl;
00409 MD_Field_Decl *slot_field_decl, *max_time_field_decl;
00410 MD_Field *one_of_field, *option_id_field;
00411 MD_Field *table_use_field, *slot_specifier_field, *max_time_field;
00412 MD_Field *slot_field;
00413 unsigned short *slot_options;
00414 int num_tables, num_choices, num_options, option_id;
00415 int id, array_size, index1, slot_index;
00416 unsigned int max_usage_time, time_shift;
00417 int max_num_choices;
00418
00419
00420
00421
00422
00423 table_section = MD_find_section (sm_mdes->md_mdes, "Reservation_Table");
00424 table_use_field_decl = MD_find_field_decl (table_section, "use");
00425 slot_specifier_field_decl = MD_find_field_decl (table_section,
00426 "slot_specifier");
00427 max_time_field_decl = MD_find_field_decl (table_section,
00428 "max_usage_time");
00429
00430
00431 option_section = MD_find_section (sm_mdes->md_mdes, "Table_Option");
00432 option_id_field_decl = MD_find_field_decl (option_section, "id");
00433 one_of_field_decl = MD_find_field_decl (option_section, "one_of");
00434
00435
00436 unit_section = MD_find_section (sm_mdes->md_mdes, "Resource_Unit");
00437 slot_field_decl = MD_find_field_decl (unit_section, "slot");
00438
00439
00440 time_shift = sm_mdes->time_shift;
00441
00442
00443
00444
00445 num_tables = SM_add_ids_to_entries (table_section);
00446
00447
00448 array_size = num_tables * sizeof (SM_Table);
00449 if ((table_array = (SM_Table *) malloc (array_size)) == NULL)
00450 L_punt ("SM_build_tables: Out of memory");
00451
00452
00453
00454
00455 max_num_choices = 0;
00456
00457
00458 id = 0;
00459 for (table_entry = MD_first_entry (table_section); table_entry != NULL;
00460 table_entry = MD_next_entry (table_entry))
00461 {
00462
00463 table = &table_array[id];
00464
00465 #if DEBUG_MDES
00466 printf ("Building table %s:\n", table_entry->name);
00467 #endif
00468
00469
00470 table_use_field = MD_find_field (table_entry, table_use_field_decl);
00471
00472
00473 slot_specifier_field = MD_find_field (table_entry,
00474 slot_specifier_field_decl);
00475 slot_specifier = MD_get_link (slot_specifier_field, 0);
00476
00477
00478 num_choices = table_use_field->max_element_index + 1;
00479 array_size = num_choices * sizeof (SM_Choice);
00480 if ((choice_array = (SM_Choice *) malloc (array_size)) == NULL)
00481 L_punt ("SM_build_tables: Out of memory");
00482
00483
00484 if (num_choices > max_num_choices)
00485 max_num_choices = num_choices;
00486
00487
00488
00489
00490 slot_index = -1;
00491 for (index1 = 0; index1 < num_choices; index1 ++)
00492 {
00493
00494 choice = &choice_array[index1];
00495
00496
00497 option_entry = MD_get_link (table_use_field, index1);
00498 option_id_field = MD_find_field (option_entry,
00499 option_id_field_decl);
00500 option_id = MD_get_int (option_id_field, 0);
00501 target_choice = &sm_mdes->choice_array[option_id];
00502
00503
00504 choice->first_option = target_choice->first_option;
00505 choice->last_option = target_choice->last_option;
00506
00507 #if DEBUG_MDES
00508 printf (" Choice %i: option %s id %i %x to %x (%i options)\n",
00509 index1,
00510 option_entry->name, option_id,
00511 choice->first_option, choice->last_option,
00512 (choice->last_option - choice->first_option) + 1);
00513 #endif
00514
00515
00516 if (option_entry == slot_specifier)
00517 {
00518 slot_index = index1;
00519 #if DEBUG_MDES
00520 printf (" Slot specifier %s found.\n",
00521 slot_specifier->name);
00522 #endif
00523 }
00524
00525 }
00526 table->first_choice = choice_array;
00527 table->last_choice = &choice_array[num_choices -1];
00528 table->num_choices = num_choices;
00529
00530
00531 if (slot_index == -1)
00532 {
00533 L_punt ("SM_build_tables: slot specifier %s not found in %s!\n",
00534 slot_specifier->name, table_entry->name);
00535 }
00536 table->slot_choice = &choice_array[slot_index];
00537
00538
00539
00540
00541 one_of_field = MD_find_field (slot_specifier, one_of_field_decl);
00542 num_options = one_of_field->max_element_index + 1;
00543 array_size = num_options * sizeof (unsigned short);
00544 if ((slot_options = (unsigned short *) malloc (array_size)) == NULL)
00545 L_punt ("SM_build_tables: Out of memory");
00546
00547 #if DEBUG_MDES
00548 printf (" Slot options:");
00549 #endif
00550
00551 for (index1 = 0; index1 <= one_of_field->max_element_index; index1++)
00552 {
00553 unit_entry = MD_get_link (one_of_field, index1);
00554 slot_field = MD_find_field (unit_entry, slot_field_decl);
00555 slot_options[index1] =
00556 (unsigned short) MD_get_int (slot_field, 0);
00557 #if DEBUG_MDES
00558 printf (" %i", slot_options[index1]);
00559 #endif
00560 }
00561 #if DEBUG_MDES
00562 printf ("\n");
00563 #endif
00564
00565
00566 table->slot_options = slot_options;
00567
00568
00569 max_time_field = MD_find_field (table_entry, max_time_field_decl);
00570 max_usage_time = MD_get_int (max_time_field, 0);
00571
00572
00573
00574
00575
00576
00577 table->max_usage_offset = ((max_usage_time + 1) << time_shift) - 1;
00578
00579 #if DEBUG_OPTI
00580 printf (" %s max_usage_time = %i\n", table_entry->name,
00581 table->max_usage_time);
00582 #endif
00583
00584
00585 id++;
00586 }
00587
00588
00589 if (id != num_tables)
00590 L_punt ("SM_build_tables: id (%i) and num_tables (%i) should agree!",
00591 id, num_tables);
00592
00593
00594 sm_mdes->table_array = table_array;
00595 sm_mdes->table_array_size = num_tables;
00596
00597
00598 sm_mdes->max_num_choices = max_num_choices;
00599 }
00600
00601 SM_Mdes *SM_build_mdes (Mdes2 *mdes2)
00602 {
00603 SM_Mdes *sm_mdes;
00604
00605
00606
00607 if (SM_Mdes_pool == NULL)
00608 SM_Mdes_pool = L_create_alloc_pool ("SM_Mdes", sizeof (SM_Mdes), 1);
00609
00610
00611 sm_mdes = (SM_Mdes *) L_alloc (SM_Mdes_pool);
00612
00613
00614 sm_mdes->mdes2 = mdes2;
00615 sm_mdes->md_mdes = mdes2->md_mdes;
00616
00617
00618
00619
00620 SM_build_resources (sm_mdes);
00621
00622
00623 SM_build_units (sm_mdes);
00624
00625
00626 SM_build_choices (sm_mdes);
00627
00628
00629 SM_build_tables (sm_mdes);
00630
00631
00632 return (sm_mdes);
00633 }
00634
00635
00636