25 #if defined(ENABLE_UNUSED_FUNCTION) 35 #if defined(SERVER_MODE) 40 static const int WFG_PRUNE_CYCLES_IN_CYCLE_GROUP = 10;
41 static const int WFG_MAX_CYCLES_TO_REPORT = 100;
54 typedef struct wfg_edge WFG_EDGE;
57 int waiter_tran_index;
58 int holder_tran_index;
59 struct wfg_edge *next_holder_edge_p;
60 struct wfg_edge *next_waiter_edge_p;
64 typedef struct wfg_node WFG_NODE;
67 WFG_STACK_STATUS status;
74 int (*cycle_fun) (
int tran_index,
void *args);
76 WFG_EDGE *first_holder_edge_p;
77 WFG_EDGE *last_holder_edge_p;
78 WFG_EDGE *first_waiter_edge_p;
79 WFG_EDGE *last_waiter_edge_p;
83 typedef struct wfg_stack WFG_STACK;
87 WFG_EDGE *current_holder_edge_p;
91 typedef struct wfg_trans_list WFG_TRANS_LIST;
95 struct wfg_trans_list *next;
99 typedef struct wfg_tran_group WFG_TRAN_GROUP;
100 struct wfg_tran_group
104 WFG_TRANS_LIST *holder_tran_list_p;
105 WFG_TRANS_LIST *waiter_tran_list_p;
108 static WFG_NODE *wfg_Nodes =
NULL;
109 static int wfg_Total_nodes = 0;
110 static int wfg_Total_edges = 0;
111 static int wfg_Total_waiters = 0;
114 static WFG_TRAN_GROUP *wfg_Tran_group =
NULL;
115 static int wfg_Total_tran_groups = 0;
117 static int wfg_initialize_node (WFG_NODE * node_p);
118 static int wfg_free_group_list (
void);
120 static int wfg_push_stack (WFG_STACK ** top_p,
int node);
121 static int wfg_pop_stack (WFG_STACK ** top_p, WFG_STACK ** bottom_p);
122 static int wfg_internal_detect_cycle (
THREAD_ENTRY * thread_p, WFG_CYCLE_CASE * cycle_case_p,
123 WFG_CYCLE ** list_cycles_p,
const int max_cycles_in_cycle_group,
124 const int max_cycles);
125 static int wfg_detect_ordinary_cycle (
THREAD_ENTRY * thread_p, WFG_CYCLE_CASE * cycle_case_p,
126 WFG_CYCLE ** list_cycles_p,
const int max_cycles_in_group,
const int max_cycles);
127 static int wfg_add_waiters_of_tg (
int *smallest_onstack,
int holder_node,
int tg_index);
128 static int wfg_add_waiters_normal_wfg (
int *smallest_onstack,
int node_index);
129 static int wfg_get_all_waiting_and_add_waiter (
bool * all_waiting,
bool * add_waiter,
int tg_index);
130 static WFG_CYCLE *wfg_detect_tran_group_cycle_internal (WFG_CYCLE_CASE * cycle_case_p, WFG_TRANS_LIST * w_tran_list_p,
131 bool add_waiter,
int tg_index,
int num_tran_groups_holders);
132 static int wfg_detect_tran_group_cycle (
THREAD_ENTRY * thread_p, WFG_CYCLE_CASE * cycle_case_p,
133 WFG_CYCLE ** list_cycles);
135 static int wfg_dump_given_cycles (FILE * out_fp, WFG_CYCLE * list_cycles_p);
136 static void wfg_dump_holder_waiter (FILE * out_fp,
int node_index);
137 static void wfg_dump_holder_waiter_of_tran_group (FILE * out_fp,
int group_index);
139 #if defined(WFG_DEBUG) 140 static int wfg_valid_tran_index (
const int holder_index,
const int holder_tran_index,
const int waiter_tran_index);
141 static int check_duplication_holders (
const int holder_index,
const int *holder_tran_indices,
const int num_holders,
142 const int waiter_tran_index);
143 static int wfg_check_insert_out_edges (
const int waiter_tran_index,
int num_holders,
const int *holder_tran_indeces);
144 static int wfg_check_remove_out_edges (
const int waiter_tran_index,
int num_holders,
const int *holder_tran_indeces);
147 static int wfg_allocate_edges (WFG_EDGE ** first_edge_p, WFG_EDGE ** last_edge_p,
const int *holder_tran_indices,
148 const int num_holders,
const int waiter_tran_index);
149 static int wfg_link_edge_holders_waiter_list (WFG_EDGE * first_edge_p, WFG_EDGE * last_edge_p,
150 const int waiter_tran_index);
151 static int wfg_remove_waiter_list_of_holder_edge (WFG_NODE * node_p, WFG_EDGE ** holder_p);
163 wfg_push_stack (WFG_STACK ** top_p,
int node)
166 (*top_p)->wait_tran_index = node;
167 (*top_p)->current_holder_edge_p = wfg_Nodes[node].first_holder_edge_p;
181 wfg_pop_stack (WFG_STACK ** top_p, WFG_STACK ** bottom_p)
184 if ((*top_p) - (*bottom_p) < 0)
188 (*top_p)->current_holder_edge_p = (*top_p)->current_holder_edge_p->next_holder_edge_p;
203 wfg_initialize_node (WFG_NODE * node_p)
210 node_p->cycle_group_no = -1;
211 node_p->cycle_fun =
NULL;
213 node_p->first_holder_edge_p =
NULL;
214 node_p->last_holder_edge_p =
NULL;
215 node_p->first_waiter_edge_p =
NULL;
216 node_p->last_waiter_edge_p =
NULL;
232 wfg_alloc_nodes (
THREAD_ENTRY * thread_p,
const int num_trans)
234 WFG_NODE *temp_node_p;
238 #if defined(WFG_DEBUG) 254 if (wfg_Nodes ==
NULL)
256 temp_node_p = (WFG_NODE *) malloc (
sizeof (WFG_NODE) * num_trans);
257 if (temp_node_p ==
NULL)
266 if (num_trans < wfg_Total_nodes)
271 temp_node_p = (WFG_NODE *) realloc (wfg_Nodes,
sizeof (WFG_NODE) * num_trans);
272 if (temp_node_p ==
NULL)
281 for (i = wfg_Total_nodes; i < num_trans; i++)
283 error_code = wfg_initialize_node (temp_node_p + i);
290 wfg_Total_nodes = num_trans;
291 wfg_Nodes = temp_node_p;
306 wfg_free_group_list (
void)
308 WFG_TRANS_LIST *tran_list_p, *temp_p;
312 for (i = 0; i < wfg_Total_tran_groups; i++)
314 for (tran_list_p = wfg_Tran_group[i].holder_tran_list_p; tran_list_p !=
NULL;)
316 temp_p = tran_list_p;
317 tran_list_p = tran_list_p->next;
320 for (tran_list_p = wfg_Tran_group[i].waiter_tran_list_p; tran_list_p !=
NULL;)
322 temp_p = tran_list_p;
323 tran_list_p = tran_list_p->next;
350 if (wfg_Total_nodes > 0)
353 for (i = 0; i < wfg_Total_nodes; i++)
356 for (edge_p = wfg_Nodes[i].first_holder_edge_p; edge_p !=
NULL;)
359 edge_p = edge_p->next_holder_edge_p;
364 wfg_Total_nodes = wfg_Total_edges = wfg_Total_waiters = 0;
368 error_code = wfg_free_group_list ();
374 #if defined(WFG_DEBUG) 376 wfg_check_insert_out_edges (
const int waiter_tran_index,
int num_holders,
const int *holder_tran_indeces)
384 if (waiter_tran_index < 0 || waiter_tran_index > wfg_Total_nodes - 1)
387 "wfg_insert_out_edges: value" " waiter_tran_index = %d should be between 0 and %d\n" 388 " ** OPERATION HAS BEEN IGNORED **\n", waiter_tran_index, wfg_Total_nodes - 1);
393 for (i = 0; i < num_holders; i++)
396 error_code = wfg_valid_tran_index (i, holder_tran_indices[i], waiter_tran_index);
403 error_code = check_duplication_holders (i, holder_tran_indeces);
433 wfg_insert_out_edges (
THREAD_ENTRY * thread_p,
const int waiter_tran_index,
int num_holders,
434 const int *holder_tran_indeces,
int (*cycle_resolution_fn) (
int tran_index,
void *args),
437 WFG_EDGE *first_edge_p;
438 WFG_EDGE *last_edge_p;
451 #if defined(WFG_DEBUG) 452 error_code = wfg_check_insert_out_edges (waiter_tran_index, num_holders, holder_tran_indeces);
461 error_code = wfg_allocate_edges (&first_edge_p, &last_edge_p, holder_tran_indeces, num_holders, waiter_tran_index);
469 wfg_Nodes[waiter_tran_index].cycle_fun = cycle_resolution_fn;
470 wfg_Nodes[waiter_tran_index].args = args;
472 error_code = wfg_link_edge_holders_waiter_list (first_edge_p, last_edge_p, waiter_tran_index);
478 wfg_Total_edges += num_holders;
486 #if defined(WFG_DEBUG) 497 wfg_valid_tran_index (
const int holder_index,
const int holder_tran_index,
const int waiter_tran_index)
499 if (holder_tran_index < 0 || holder_tran_index > wfg_Total_nodes - 1)
502 "wfg_insert_out_edges: value" " holder_tran_indices[%d] = %d should be between 0 and %d\n" 503 " ** OPERATION HAS BEEN IGNORED **\n", holder_index, holder_tran_index, wfg_Total_nodes - 1);
507 if (holder_tran_index == waiter_tran_index)
510 "wfg_insert_out_edges: value" " holder_tran_indices[%d] = %d is equal to waiter_tran_index = %d\n" 511 " ** OPERATION HAS BEEN IGNORED **\n", holder_index, holder_tran_index, waiter_tran_index);
531 check_duplication_holders (
const int holder_index,
const int *holder_tran_indices,
const int num_holders,
532 const int waiter_tran_index)
537 for (i = holder_index + 1; i < num_holders; i++)
539 if (holder_tran_indices[holder_index] == holder_tran_indices[i])
542 "wfg_insert_outedges: value holder_tran_indices[%d] = %d is" 543 " duplcated with holder_tran_indices[%d] = %d\n" "** OPERATION HAS BEEN IGNORED **\n",
544 holder_index, holder_tran_indices[holder_index], i, holder_tran_indices[i]);
549 for (edge_p = wfg_Nodes[waiter_tran_index].first_holder_edge_p; edge_p !=
NULL; edge_p = edge_p->next_holder_edge_p)
551 if (holder_tran_indices[holder_index] == edge_p->holder_tran_index)
554 "wfg_insert_outedges: value holder_tran_indices[%d] = %d" " is already a holders\n" 555 " ** OPERATION HAS BEEN IGNORED **\n", holder_index, holder_tran_indices[holder_index]);
577 wfg_allocate_edges (WFG_EDGE ** first_edge_p, WFG_EDGE ** last_edge_p,
const int *holder_tran_indices,
578 const int num_holders,
const int waiter_tran_index)
584 *first_edge_p = *last_edge_p =
NULL;
586 for (i = num_holders - 1; i >= 0; i--)
588 edge_p = (WFG_EDGE *) malloc (
sizeof (WFG_EDGE));
592 while (*first_edge_p !=
NULL)
594 temp_p = *first_edge_p;
595 *first_edge_p = (*first_edge_p)->next_holder_edge_p;
607 edge_p->waiter_tran_index = waiter_tran_index;
608 edge_p->holder_tran_index = holder_tran_indices[
i];
609 edge_p->next_holder_edge_p = *first_edge_p;
610 edge_p->next_waiter_edge_p =
NULL;
612 *first_edge_p = edge_p;
613 if (*last_edge_p ==
NULL)
615 *last_edge_p = *first_edge_p;
635 wfg_link_edge_holders_waiter_list (WFG_EDGE * first_edge_p, WFG_EDGE * last_edge_p,
const int waiter)
643 if (first_edge_p !=
NULL)
645 if (wfg_Nodes[waiter].last_holder_edge_p ==
NULL)
648 wfg_Nodes[waiter].first_holder_edge_p = first_edge_p;
653 wfg_Nodes[waiter].last_holder_edge_p->next_holder_edge_p = first_edge_p;
655 wfg_Nodes[waiter].last_holder_edge_p = last_edge_p;
661 for (edge_p = first_edge_p; edge_p; edge_p = edge_p->next_holder_edge_p)
663 holder = edge_p->holder_tran_index;
664 if (wfg_Nodes[holder].last_waiter_edge_p ==
NULL)
667 wfg_Nodes[holder].first_waiter_edge_p = edge_p;
671 wfg_Nodes[holder].last_waiter_edge_p->next_waiter_edge_p = edge_p;
673 wfg_Nodes[holder].last_waiter_edge_p = edge_p;
679 #if defined(WFG_DEBUG) 681 wfg_check_remove_out_edges (
const int waiter_tran_index,
const int num_holders,
const int *holder_tran_indices_p)
690 if (waiter_tran_index < 0 || waiter_tran_index > wfg_Total_nodes - 1)
693 "wfg_remove_outedges: value waiter = %d should" 694 " be between 0 and %d\n ** OPERATION HAS BEEN IGNORED **\n", waiter_tran_index,
695 wfg_Total_nodes - 1);
701 for (i = 0; i < num_holders; i++)
703 if (holder_tran_indices_p[i] < 0 || holder_tran_indices_p[i] > wfg_Total_nodes - 1)
706 "wfg_remove_outedges: value holder[%d] = %d" 707 " should be between 0 and %d\n ** OPERATION HAS BEEN" " IGNORED **", i, htran_indices_p[i],
708 wfg_Total_nodes - 1);
712 for (edge_p = wfg_Nodes[waiter_tran_index].first_holder_edge_p; edge_p !=
NULL;
713 edge_p = edge_p->next_holder_edge_p)
715 if (holder_tran_indices_p[i] == edge_p->holder_tran_index)
718 "wfg_remove_outedges:" " value holder[%d] = %d is NOT holder of waiter = %d\n" 719 " ** THE HOLDER SKIPPED **", i, htran_indices_p[i], waiter_tran_index);
738 wfg_remove_waiter_list_of_holder_edge (WFG_NODE * node_p, WFG_EDGE ** holder_p)
742 for (waiter_p = &(node_p->first_waiter_edge_p); *waiter_p !=
NULL; waiter_p = &((*waiter_p)->next_waiter_edge_p))
744 if (*waiter_p == *holder_p)
747 *waiter_p = (*waiter_p)->next_waiter_edge_p;
748 if (*waiter_p ==
NULL)
751 if (node_p->first_waiter_edge_p ==
NULL)
754 node_p->last_waiter_edge_p =
NULL;
759 node_p->last_waiter_edge_p =
760 (WFG_EDGE *) ((
char *) waiter_p - offsetof (WFG_EDGE, next_waiter_edge_p));
788 wfg_remove_out_edges (
THREAD_ENTRY * thread_p,
const int waiter_tran_index,
const int num_holders,
789 const int *holder_tran_indices_p)
793 WFG_EDGE **prev_holder_p;
801 #if defined(WFG_DEBUG) 802 error_code = wfg_check_remove_out_edges (waiter_tran_index, num_holders, holder_tran_indices_p);
808 for (prev_holder_p = &(wfg_Nodes[waiter_tran_index].first_holder_edge_p); *prev_holder_p !=
NULL;)
811 if (num_holders > 0 && holder_tran_indices_p !=
NULL)
813 for (i = 0; i < num_holders; i++)
815 if (holder_tran_indices_p[i] == (*prev_holder_p)->holder_tran_index)
835 wfg_remove_waiter_list_of_holder_edge (&wfg_Nodes[(*prev_holder_p)->holder_tran_index], prev_holder_p);
842 edge_p = *prev_holder_p;
843 *prev_holder_p = (*prev_holder_p)->next_holder_edge_p;
849 prev_holder_p = &((*prev_holder_p)->next_holder_edge_p);
853 if (prev_holder_p == &(wfg_Nodes[waiter_tran_index].first_holder_edge_p))
856 wfg_Nodes[waiter_tran_index].last_holder_edge_p =
NULL;
861 wfg_Nodes[waiter_tran_index].last_holder_edge_p =
862 (WFG_EDGE *) ((
char *) prev_holder_p - offsetof (WFG_EDGE, next_holder_edge_p));
880 wfg_get_status (
int *num_edges_p,
int *num_waiters_p)
885 *num_edges_p = wfg_Total_edges;
886 *num_waiters_p = wfg_Total_waiters;
910 wfg_detect_cycle (
THREAD_ENTRY * thread_p, WFG_CYCLE_CASE * cycle_case, WFG_CYCLE ** list_cycles_p)
913 return wfg_internal_detect_cycle (thread_p, cycle_case, list_cycles_p, WFG_PRUNE_CYCLES_IN_CYCLE_GROUP,
914 WFG_MAX_CYCLES_TO_REPORT);
937 wfg_internal_detect_cycle (
THREAD_ENTRY * thread_p, WFG_CYCLE_CASE * cycle_case_p, WFG_CYCLE ** list_cycles_p,
938 const int max_cycles_in_cycle_group,
const int max_cycles)
940 WFG_CYCLE **next_cycle_p;
941 WFG_CYCLE *ordinary_cycles_p =
NULL;
942 WFG_CYCLE *tran_group_cycles_p =
NULL;
943 WFG_CYCLE_CASE cycle_tran_group_case;
946 *list_cycles_p =
NULL;
949 wfg_detect_ordinary_cycle (thread_p, cycle_case_p, &ordinary_cycles_p, max_cycles_in_cycle_group, max_cycles);
955 if (ordinary_cycles_p !=
NULL)
957 *list_cycles_p = ordinary_cycles_p;
960 error_code = wfg_detect_tran_group_cycle (thread_p, &cycle_tran_group_case, &tran_group_cycles_p);
966 if (tran_group_cycles_p !=
NULL)
969 for (next_cycle_p = list_cycles_p; *next_cycle_p !=
NULL; next_cycle_p = &((*next_cycle_p)->next))
973 *next_cycle_p = tran_group_cycles_p;
976 switch (*cycle_case_p)
978 case WFG_CYCLE_YES_PRUNE:
982 if (cycle_tran_group_case == WFG_CYCLE_YES_PRUNE)
984 *cycle_case_p = cycle_tran_group_case;
989 *cycle_case_p = cycle_tran_group_case;
1001 if (ordinary_cycles_p !=
NULL)
1003 wfg_free_cycle (ordinary_cycles_p);
1006 if (tran_group_cycles_p !=
NULL)
1008 wfg_free_cycle (tran_group_cycles_p);
1011 *list_cycles_p =
NULL;
1013 *cycle_case_p = WFG_CYCLE_ERROR;
1027 wfg_free_cycle (WFG_CYCLE * list_cycles_p)
1029 WFG_CYCLE *current_cycle_p;
1032 if (list_cycles_p !=
NULL)
1034 for (current_cycle_p = list_cycles_p; current_cycle_p !=
NULL;)
1036 if (current_cycle_p->waiters !=
NULL)
1041 temp_p = current_cycle_p;
1042 current_cycle_p = current_cycle_p->next;
1060 wfg_dump_given_cycles (FILE * out_fp, WFG_CYCLE * list_cycles_p)
1063 WFG_CYCLE *current_cycle_p;
1065 fprintf (out_fp,
"----------------- CYCLES ------------------\n");
1073 for (current_cycle_p = list_cycles_p; current_cycle_p !=
NULL; current_cycle_p = current_cycle_p->next)
1075 fprintf (out_fp,
"Cycle: ");
1076 for (i = 0; i < current_cycle_p->num_trans; i++)
1080 fprintf (out_fp,
", ");
1083 fprintf (out_fp,
"\n ");
1086 fprintf (out_fp,
"%d", current_cycle_p->waiters[i].tran_index);
1088 fprintf (out_fp,
"\n");
1104 wfg_dump_holder_waiter (FILE * out_fp,
int node_index)
1109 fprintf (out_fp,
"\t holders = { ");
1110 for (edge_p = wfg_Nodes[node_index].first_holder_edge_p; edge_p !=
NULL; edge_p = edge_p->next_holder_edge_p)
1112 fprintf (out_fp,
"%03d ", edge_p->holder_tran_index);
1114 fprintf (out_fp,
"}\n");
1117 fprintf (out_fp,
"\t\t waiters = { ");
1118 for (edge_p = wfg_Nodes[node_index].first_waiter_edge_p; edge_p !=
NULL; edge_p = edge_p->next_waiter_edge_p)
1120 fprintf (out_fp,
"%03d ", edge_p->waiter_tran_index);
1122 fprintf (out_fp,
"}\n");
1124 if (wfg_Nodes[node_index].last_holder_edge_p ==
NULL)
1126 fprintf (out_fp,
"\t\t last holder = null,");
1130 fprintf (stdout,
"\t\t last holder = %03d,", wfg_Nodes[node_index].last_holder_edge_p->holder_tran_index);
1133 if (wfg_Nodes[node_index].last_waiter_edge_p ==
NULL)
1135 fprintf (out_fp,
"\t\t last waiter = null\n");
1139 fprintf (out_fp,
"\t\t last waiter = %03d\n", wfg_Nodes[node_index].last_waiter_edge_p->waiter_tran_index);
1153 wfg_dump_holder_waiter_of_tran_group (FILE * out_fp,
int group_index)
1155 WFG_TRANS_LIST *tran_list_p;
1157 if (wfg_Tran_group[group_index].holder_tran_list_p)
1160 fprintf (out_fp,
"\t holders = { ");
1161 for (tran_list_p = wfg_Tran_group[group_index].holder_tran_list_p; tran_list_p !=
NULL;
1162 tran_list_p = tran_list_p->next)
1164 fprintf (out_fp,
"%d ", tran_list_p->tran_index);
1166 fprintf (out_fp,
"}\n");
1168 if (wfg_Tran_group[group_index].waiter_tran_list_p)
1171 fprintf (out_fp,
"\t waiters = { ");
1172 for (tran_list_p = wfg_Tran_group[group_index].waiter_tran_list_p; tran_list_p !=
NULL;
1173 tran_list_p = tran_list_p->next)
1175 fprintf (out_fp,
"%d ", tran_list_p->tran_index);
1177 fprintf (out_fp,
"}\n");
1192 WFG_CYCLE *cycles_p;
1193 WFG_CYCLE_CASE cycle_case;
1195 fprintf (stdout,
"--------------- WFG contents --------------\n");
1196 fprintf (stdout,
"total_nodes = %d, total_edges = %d, total_waiters = %d\n", wfg_Total_nodes, wfg_Total_edges,
1199 fprintf (stdout,
"\n");
1200 fprintf (stdout,
"---------- Ordinary WFG contents ----------\n");
1202 for (i = 0; i < wfg_Total_nodes; i++)
1204 fprintf (stdout,
"[node_%03d]:", i);
1205 wfg_dump_holder_waiter (stdout, i);
1208 if (wfg_Total_tran_groups > 0)
1210 fprintf (stdout,
"\n");
1211 fprintf (stdout,
"------------- WFG_TG contents -------------\n");
1213 for (i = 0; i < wfg_Total_tran_groups; i++)
1215 fprintf (stdout,
"TG[%d]:\t Num_holders %d, Num_waiters %d\n", i, wfg_Tran_group[i].num_holders,
1216 wfg_Tran_group[i].num_waiters);
1218 wfg_dump_holder_waiter_of_tran_group (stdout, i);
1223 if (wfg_internal_detect_cycle (thread_p, &cycle_case, &cycles_p, -1, -1) ==
NO_ERROR && cycle_case == WFG_CYCLE_YES)
1225 fprintf (stdout,
"\n");
1226 wfg_dump_given_cycles (stdout, cycles_p);
1227 wfg_free_cycle (cycles_p);
1243 WFG_TRAN_GROUP *temp_p;
1252 bytes =
sizeof (WFG_TRAN_GROUP) * (wfg_Total_tran_groups + 1);
1253 if (wfg_Total_tran_groups == 0)
1255 temp_p = (WFG_TRAN_GROUP *) malloc (bytes);
1259 temp_p = (WFG_TRAN_GROUP *) realloc (wfg_Tran_group, bytes);
1269 wfg_Tran_group = temp_p;
1272 wfg_Tran_group[wfg_Total_tran_groups].num_holders = 0;
1273 wfg_Tran_group[wfg_Total_tran_groups].num_waiters = 0;
1274 wfg_Tran_group[wfg_Total_tran_groups].holder_tran_list_p =
NULL;
1275 wfg_Tran_group[wfg_Total_tran_groups].waiter_tran_list_p =
NULL;
1277 wfg_Total_tran_groups++;
1282 return (wfg_Total_tran_groups - 1);
1299 wfg_insert_holder_tran_group (
THREAD_ENTRY * thread_p,
const int tran_group_index,
const int holder_tran_index)
1301 WFG_TRANS_LIST *tran_list_p;
1305 tran_list_p = (WFG_TRANS_LIST *) malloc (
sizeof (WFG_TRANS_LIST));
1306 if (tran_list_p ==
NULL)
1318 #if defined(WFG_DEBUG) 1319 if (tran_group_index < 0 || tran_group_index > wfg_Total_tran_groups - 1)
1322 "wfg_tg_insert_holder: value tg_index = %d" " should be between 0 and %d\n" 1323 "** OPERATION HAS BEEN IGNORED **", tran_group_index, wfg_Total_tran_groups - 1);
1328 if (holder_tran_index < 0 || holder_tran_index > wfg_Total_nodes - 1)
1331 "wfg_tg_insert_holder: value htran_index = %d" " should be between 0 and %d\n" 1332 " ** OPERATION HAS BEEN IGNORED **", holder_tran_index, wfg_Total_nodes - 1);
1337 for (tran_list_p = wfg_Tran_group[tran_group_index].holder_tran_list_p; tran_list_p !=
NULL;
1338 tran_list_p = tran_list_p->next)
1339 if (tran_list_p->tran_index == holder_tran_index)
1342 "wfg_tg_insert_holder: value" " htran_index = %d is already in holder list\n" 1343 " ** OPERATION HAS BEEN IGNORED **", tran_index);
1349 tran_list_p->tran_index = holder_tran_index;
1350 tran_list_p->next = wfg_Tran_group[tran_group_index].holder_tran_list_p;
1351 wfg_Tran_group[tran_group_index].holder_tran_list_p = tran_list_p;
1352 wfg_Tran_group[tran_group_index].num_holders++;
1354 #if defined(WFG_DEBUG) 1377 wfg_remove_holder_tran_group (
THREAD_ENTRY * thread_p,
const int tran_group_index,
const int holder_tran_index)
1379 WFG_TRANS_LIST **tran_list_p;
1380 WFG_TRANS_LIST *temp_p;
1388 #if defined(WFG_DEBUG) 1389 if (tran_group_index < 0 || tran_group_index > wfg_Total_tran_groups - 1)
1392 "wfg_tg_remove_holder: value tg_index = %d" " should be between 0 and %d\n" 1393 " ** OPERATION HAS BEEN IGNORED **", tran_group_index, wfg_Total_tran_groups - 1);
1398 if (holder_tran_index < 0 || holder_tran_index > wfg_Total_nodes - 1)
1401 "wfg_tg_remove_holder: value htran_index = %d" " should be between 0 and %d\n" 1402 " ** OPERATION HAS BEEN IGNORED **", holder_tran_index, wfg_Total_nodes - 1);
1407 for (temp_p = wfg_Tran_group[tran_group_index].holder_tran_list_p; temp_p !=
NULL; temp_p = temp_p->next)
1409 if (temp_p->tran_index == holder_tran_index)
1412 "wfg_tg_remove_holder: value" " htran_index = %d is NOT in holder list\n" 1413 " ** OPERATION HAS NO EFFECT **", holder_tran_index);
1420 if (wfg_Tran_group[tran_group_index].holder_tran_list_p !=
NULL)
1422 for (tran_list_p = &wfg_Tran_group[tran_group_index].holder_tran_list_p; *tran_list_p !=
NULL;
1423 tran_list_p = &((*tran_list_p)->next))
1425 if ((*tran_list_p)->tran_index == holder_tran_index)
1428 temp_p = *tran_list_p;
1429 *tran_list_p = (*tran_list_p)->next;
1431 wfg_Tran_group[tran_group_index].num_holders--;
1437 #if defined(WFG_DEBUG) 1465 wfg_insert_waiter_tran_group (
THREAD_ENTRY * thread_p,
const int tran_group_index,
const int waiter_tran_index,
1466 int (*cycle_resolution_fn) (
int tran_index,
void *args),
void *args)
1468 WFG_TRANS_LIST *tran_list_p;
1476 #if defined(WFG_DEBUG) 1477 if (tran_group_index < 0 || tran_group_index > wfg_Total_tran_groups - 1)
1480 "wfg_tg_insert_waiter: value tg_index = %d should" 1481 " be between 0 and %d\n ** OPERATION HAS BEEN IGNORED **", tran_group_index,
1482 wfg_Total_tran_groups - 1);
1487 if (waiter_tran_index < 0 || waiter_tran_index > wfg_Total_nodes - 1)
1490 "wfg_tg_insert_waiter: value tran_index = %d" " should be between 0 and %d\n" 1491 " ** OPERATION HAS BEEN IGNORED **", waiter_tran_index, wfg_Total_nodes - 1);
1496 for (tran_list_p = wfg_Tran_group[tran_group_index].waiter_tran_list_p; tran_list_p !=
NULL;
1497 tran_list_p = tran_list_p->next)
1499 if (tran_list_p->tran_index == waiter_tran_index)
1502 "wfg_tg_insert_waiter: value tran_index = %d" " is already in waiters\n" 1503 " ** OPERATION HAS BEEN IGNORED **", waiter_tran_index);
1514 tran_list_p = (WFG_TRANS_LIST *) malloc (
sizeof (WFG_TRANS_LIST));
1515 if (tran_list_p ==
NULL)
1522 tran_list_p->tran_index = waiter_tran_index;
1523 tran_list_p->next = wfg_Tran_group[tran_group_index].waiter_tran_list_p;
1524 wfg_Tran_group[tran_group_index].waiter_tran_list_p = tran_list_p;
1525 wfg_Tran_group[tran_group_index].num_waiters++;
1528 wfg_Nodes[waiter_tran_index].cycle_fun = cycle_resolution_fn;
1529 wfg_Nodes[waiter_tran_index].args = args;
1555 wfg_remove_waiter_tran_group (
THREAD_ENTRY * thread_p,
const int tran_group_index,
const int waiter_tran_index)
1557 WFG_TRANS_LIST **tran_list_p;
1558 WFG_TRANS_LIST *temp_p;
1566 #if defined(WFG_DEBUG) 1567 if (tran_group_index < 0 || tran_group_index > wfg_Total_tran_groups - 1)
1570 "wfg_tg_remove_waiter: value tg_index = %d should" 1571 " be between 0 and %d\n ** OPERATION HAS BEEN IGNORED **", tran_group_index,
1572 wfg_Total_tran_groups - 1);
1577 if (waiter_tran_index < 0 || waiter_tran_index > wfg_Total_nodes - 1)
1580 "wfg_tg_remove_waiter: value tran_index = %d" " should be between 0 and %d\n" 1581 " ** OPERATION HAS BEEN IGNORED **", waiter_tran_index, wfg_Total_nodes - 1);
1586 for (tran_list_p = &wfg_Tran_group[tran_group_index].waiter_tran_list_p; tran_list_p !=
NULL;
1587 tran_list_p = &((*tran_list_p)->next))
1589 if ((*tran_list_p)->tran_index == waiter_tran_index)
1592 "wfg_tg_remove_waiter: value tran_index = %d" 1593 " is NOT in waiters\n ** OPERATION HAS NO EFFECT **", waiter_tran_index);
1600 for (tran_list_p = &wfg_Tran_group[tran_group_index].waiter_tran_list_p; tran_list_p !=
NULL;
1601 tran_list_p = &((*tran_list_p)->next))
1603 if ((*tran_list_p)->tran_index == waiter_tran_index)
1606 temp_p = *tran_list_p;
1607 *tran_list_p = (*tran_list_p)->next;
1609 wfg_Tran_group[tran_group_index].num_waiters--;
1614 #if defined(WFG_DEBUG) 1648 wfg_detect_ordinary_cycle (
THREAD_ENTRY * thread_p, WFG_CYCLE_CASE * cycle_case_p, WFG_CYCLE ** list_cycles_p,
1649 const int max_cycles_in_group,
const int max_cycles)
1652 WFG_CYCLE **last_cycle_p;
1653 WFG_STACK *bottom_p =
NULL;
1655 WFG_STACK *stack_elem_p;
1656 WFG_CYCLE *cycle_p =
NULL;
1657 WFG_WAITER *waiter_p;
1660 int num_cycles_in_group;
1661 int num_total_cycles = 0;
1664 *cycle_case_p = WFG_CYCLE_NO;
1665 *list_cycles_p =
NULL;
1666 last_cycle_p = list_cycles_p;
1673 if (wfg_Total_waiters < 2)
1679 for (i = 0; i < wfg_Total_nodes; i++)
1681 wfg_Nodes[
i].status = WFG_NOT_VISITED;
1682 wfg_Nodes[
i].cycle_group_no = -1;
1686 bottom_p = (WFG_STACK *) malloc (
sizeof (WFG_STACK) * wfg_Total_waiters);
1687 if (bottom_p ==
NULL)
1693 top_p = bottom_p - 1;
1696 for (i = 0; i < wfg_Total_nodes; i++)
1698 if (max_cycles > 0 && num_total_cycles > max_cycles)
1704 *cycle_case_p = WFG_CYCLE_YES_PRUNE;
1708 if (wfg_Nodes[i].status != WFG_NOT_VISITED)
1715 num_cycles_in_group = 0;
1720 if (wfg_Nodes[i].first_holder_edge_p ==
NULL)
1722 wfg_Nodes[
i].status = WFG_OFF_STACK;
1727 wfg_Nodes[
i].status = WFG_ON_STACK;
1728 wfg_push_stack (&top_p, i);
1730 while (top_p >= bottom_p)
1736 for (; top_p->current_holder_edge_p !=
NULL;
1737 top_p->current_holder_edge_p = top_p->current_holder_edge_p->next_holder_edge_p)
1739 htran_index = top_p->current_holder_edge_p->holder_tran_index;
1741 switch (wfg_Nodes[htran_index].status)
1743 case WFG_NOT_VISITED:
1745 if (wfg_Nodes[htran_index].first_holder_edge_p ==
NULL)
1747 wfg_Nodes[htran_index].status = WFG_OFF_STACK;
1752 wfg_Nodes[htran_index].status = WFG_ON_STACK;
1753 wfg_push_stack (&top_p, htran_index);
1762 wfg_Nodes[htran_index].cycle_group_no = cycle_group_no;
1764 for (stack_elem_p = top_p; stack_elem_p->wait_tran_index != htran_index; stack_elem_p--)
1766 wfg_Nodes[stack_elem_p->wait_tran_index].cycle_group_no = cycle_group_no;
1770 cycle_p = (WFG_CYCLE *) malloc (
sizeof (WFG_CYCLE));
1771 if (cycle_p ==
NULL)
1778 cycle_p->num_trans = (int) ((top_p - stack_elem_p) + 1);
1779 cycle_p->next =
NULL;
1780 cycle_p->waiters = (WFG_WAITER *) malloc (
sizeof (WFG_WAITER) * cycle_p->num_trans);
1781 if (cycle_p->waiters ==
NULL)
1784 sizeof (WFG_WAITER) * cycle_p->num_trans);
1791 for (stack_elem_p = top_p, waiter_p = cycle_p->waiters; j < cycle_p->num_trans;
1792 j++, stack_elem_p--, waiter_p++)
1794 waiter_p->tran_index = stack_elem_p->wait_tran_index;
1795 waiter_p->cycle_fun = wfg_Nodes[waiter_p->tran_index].cycle_fun;
1796 waiter_p->args = wfg_Nodes[waiter_p->tran_index].args;
1799 *last_cycle_p = cycle_p;
1800 last_cycle_p = &cycle_p->next;
1802 num_cycles_in_group++;
1804 if (max_cycles > 0 && num_total_cycles + num_cycles_in_group >= max_cycles)
1806 *cycle_case_p = WFG_CYCLE_YES_PRUNE;
1808 else if (*cycle_case_p == WFG_CYCLE_NO)
1810 *cycle_case_p = WFG_CYCLE_YES;
1817 if (wfg_Nodes[htran_index].cycle_group_no == cycle_group_no)
1828 if ((max_cycles_in_group > 0
1829 && (num_cycles_in_group > wfg_Total_nodes || num_cycles_in_group >= max_cycles_in_group))
1830 || (max_cycles > 0 && (num_total_cycles + num_cycles_in_group) >= max_cycles))
1832 *cycle_case_p = WFG_CYCLE_YES_PRUNE;
1836 wfg_Nodes[htran_index].status = WFG_RE_ON_STACK;
1837 wfg_push_stack (&top_p, htran_index);
1842 case WFG_RE_ON_STACK:
1847 #if defined(WFG_DEBUG) 1848 (void) fprintf (stdout,
"wfg_detect_ordinary_cycle():");
1849 (void) fprintf (stdout,
"interal switch error\n");
1856 wfg_Nodes[top_p->wait_tran_index].status = WFG_OFF_STACK;
1857 error_code = wfg_pop_stack (&top_p, &bottom_p);
1865 num_total_cycles += num_cycles_in_group;
1874 if (*list_cycles_p !=
NULL)
1876 wfg_free_cycle (*list_cycles_p);
1877 *list_cycles_p =
NULL;
1880 if (bottom_p !=
NULL)
1901 wfg_add_waiters_of_tg (
int *smallest_onstack,
int holder_node,
int tg_index)
1903 WFG_TRANS_LIST *h_tran_list_p;
1904 WFG_TRANS_LIST *w_tran_list_p;
1905 WFG_TRAN_GROUP *tg_tmp;
1912 for (; tg_index < wfg_Total_tran_groups; tg_index++)
1914 tg_tmp = &wfg_Tran_group[tg_index];
1915 for (h_tran_list_p = tg_tmp->holder_tran_list_p; h_tran_list_p !=
NULL; h_tran_list_p = h_tran_list_p->next)
1917 if (h_tran_list_p->tran_index == holder_node)
1923 if (h_tran_list_p !=
NULL)
1926 for (w_tran_list_p = tg_tmp->waiter_tran_list_p; w_tran_list_p !=
NULL; w_tran_list_p = w_tran_list_p->next)
1928 w_node_p = &wfg_Nodes[w_tran_list_p->tran_index];
1929 if (w_node_p->status == WFG_NOT_VISITED)
1931 w_node_p->status = WFG_ON_STACK;
1932 if (*smallest_onstack > w_tran_list_p->tran_index)
1934 *smallest_onstack = w_tran_list_p->tran_index;
1955 wfg_add_waiters_normal_wfg (
int *smallest_onstack,
int node_index)
1960 for (edge_p = wfg_Nodes[node_index].first_waiter_edge_p; edge_p !=
NULL; edge_p = edge_p->next_waiter_edge_p)
1962 if (wfg_Nodes[edge_p->waiter_tran_index].status == WFG_NOT_VISITED)
1964 wfg_Nodes[edge_p->waiter_tran_index].status = WFG_ON_STACK;
1965 if (*smallest_onstack > edge_p->waiter_tran_index)
1967 *smallest_onstack = edge_p->waiter_tran_index;
1988 wfg_get_all_waiting_and_add_waiter (
bool * all_waiting,
bool * add_waiter,
int tg_index)
1990 WFG_TRANS_LIST *w_tran_list_p;
1991 WFG_TRANS_LIST *h_tran_list_p;
1992 WFG_TRAN_GROUP *tg_tmp;
1994 bool tg_connected, tg_all_waiting;
2003 *all_waiting =
true;
2006 for (i = tg_index; i < wfg_Total_tran_groups && *all_waiting ==
true; i++)
2008 tg_tmp = &wfg_Tran_group[
i];
2011 tg_connected =
true;
2015 tg_connected =
false;
2017 for (w_tran_list_p = tg_tmp->waiter_tran_list_p; w_tran_list_p !=
NULL && tg_connected ==
false;
2018 w_tran_list_p = w_tran_list_p->next)
2020 w_node_p = &wfg_Nodes[w_tran_list_p->tran_index];
2021 if (w_node_p->status != WFG_NOT_VISITED)
2023 tg_connected =
true;
2027 if (tg_connected ==
false)
2032 tg_all_waiting =
true;
2033 for (h_tran_list_p = tg_tmp->holder_tran_list_p; h_tran_list_p !=
NULL && tg_all_waiting ==
true;
2034 h_tran_list_p = h_tran_list_p->next)
2036 if (wfg_Nodes[h_tran_list_p->tran_index].status != WFG_OFF_STACK)
2038 tg_all_waiting =
false;
2040 else if (w_tran_list_p !=
NULL && w_tran_list_p->tran_index == h_tran_list_p->tran_index)
2046 *add_waiter =
false;
2049 if (tg_connected ==
true && tg_all_waiting ==
false)
2051 *all_waiting =
false;
2070 wfg_detect_tran_group_cycle_internal (WFG_CYCLE_CASE * cycle_case_p, WFG_TRANS_LIST * w_tran_list_p,
bool add_waiter,
2071 int tg_index,
int num_tran_groups_holders)
2073 WFG_WAITER *waiter_p;
2074 WFG_TRANS_LIST *h_tran_list_p;
2082 if (*cycle_case_p == WFG_CYCLE_NO)
2084 *cycle_case_p = WFG_CYCLE_YES;
2087 cycle_p = (WFG_CYCLE *) malloc (
sizeof (WFG_CYCLE));
2088 if (cycle_p ==
NULL)
2095 cycle_p->num_trans = num_tran_groups_holders;
2097 if (add_waiter ==
true)
2099 cycle_p->num_trans++;
2102 cycle_p->next =
NULL;
2103 cycle_p->waiters = (WFG_WAITER *) malloc (
sizeof (WFG_WAITER) * cycle_p->num_trans);
2104 if (cycle_p->waiters ==
NULL)
2112 cycle_p->num_trans = 0;
2113 waiter_p = cycle_p->waiters;
2115 for (i = tg_index; i < wfg_Total_tran_groups; i++)
2117 for (h_tran_list_p = wfg_Tran_group[i].holder_tran_list_p; h_tran_list_p !=
NULL;
2118 h_tran_list_p = h_tran_list_p->next)
2120 if (wfg_Nodes[h_tran_list_p->tran_index].status == WFG_OFF_STACK)
2122 waiter_p->tran_index = h_tran_list_p->tran_index;
2123 waiter_p->cycle_fun = wfg_Nodes[waiter_p->tran_index].cycle_fun;
2124 waiter_p->args = wfg_Nodes[waiter_p->tran_index].args;
2125 cycle_p->num_trans++;
2130 wfg_Nodes[h_tran_list_p->tran_index].status = WFG_ON_TG_CYCLE;
2140 if (add_waiter ==
true)
2142 if (wfg_Nodes[w_tran_list_p->tran_index].status == WFG_OFF_STACK)
2144 wfg_Nodes[w_tran_list_p->tran_index].status = WFG_ON_TG_CYCLE;
2145 waiter_p->tran_index = w_tran_list_p->tran_index;
2146 waiter_p->cycle_fun = wfg_Nodes[waiter_p->tran_index].cycle_fun;
2147 waiter_p->args = wfg_Nodes[waiter_p->tran_index].args;
2177 wfg_detect_tran_group_cycle (
THREAD_ENTRY * thread_p, WFG_CYCLE_CASE * cycle_case_p, WFG_CYCLE ** list_cycles_p)
2179 int smallest_onstack;
2181 WFG_CYCLE **last_cycle_p;
2182 WFG_TRANS_LIST *w_tran_list_p;
2186 int num_tran_groups_holders = 0;
2189 *cycle_case_p = WFG_CYCLE_NO;
2191 *list_cycles_p =
NULL;
2192 last_cycle_p = list_cycles_p;
2194 if (wfg_Total_tran_groups < 1)
2204 for (tg1_index = 0; tg1_index < wfg_Total_tran_groups; tg1_index++)
2206 num_tran_groups_holders += wfg_Tran_group[tg1_index].num_holders;
2207 if (num_tran_groups_holders > wfg_Total_nodes)
2209 num_tran_groups_holders = wfg_Total_nodes;
2213 for (i = 0; i < wfg_Total_nodes; i++)
2215 wfg_Nodes[
i].status = WFG_NOT_VISITED;
2219 for (tg1_index = 0; tg1_index < wfg_Total_tran_groups; tg1_index++)
2224 if (wfg_Tran_group[tg1_index].holder_tran_list_p ==
NULL || wfg_Tran_group[tg1_index].waiter_tran_list_p ==
NULL)
2232 for (w_tran_list_p = wfg_Tran_group[tg1_index].waiter_tran_list_p; w_tran_list_p !=
NULL;
2233 w_tran_list_p = w_tran_list_p->next)
2239 if (wfg_Nodes[w_tran_list_p->tran_index].status == WFG_ON_TG_CYCLE)
2244 for (i = 0; i < wfg_Total_nodes; i++)
2246 if (wfg_Nodes[i].status != WFG_ON_TG_CYCLE)
2248 wfg_Nodes[
i].status = WFG_NOT_VISITED;
2252 wfg_Nodes[w_tran_list_p->tran_index].status = WFG_ON_STACK;
2253 smallest_onstack = w_tran_list_p->tran_index;
2256 while (smallest_onstack < wfg_Total_nodes)
2258 i = smallest_onstack;
2259 smallest_onstack = wfg_Total_nodes;
2260 for (; i < wfg_Total_nodes && i < smallest_onstack; i++)
2262 if (wfg_Nodes[i].status == WFG_ON_STACK)
2264 wfg_add_waiters_of_tg (&smallest_onstack, i, tg1_index);
2265 wfg_add_waiters_normal_wfg (&smallest_onstack, i);
2268 wfg_Nodes[
i].status = WFG_OFF_STACK;
2273 wfg_get_all_waiting_and_add_waiter (&all_waiting, &add_waiter, tg1_index);
2275 if (all_waiting ==
true)
2278 wfg_detect_tran_group_cycle_internal (cycle_case_p, w_tran_list_p, add_waiter, tg1_index,
2279 num_tran_groups_holders);
2280 if (cycle_p ==
NULL)
2284 *last_cycle_p = cycle_p;
2285 last_cycle_p = &cycle_p->next;
2295 if (*list_cycles_p !=
NULL)
2297 wfg_free_cycle (*list_cycles_p);
2298 *list_cycles_p =
NULL;
2311 wfg_is_waiting (
THREAD_ENTRY * thread_p,
const int tran_index)
2322 if (wfg_Total_waiters > 0)
2324 for (i = 0; i < wfg_Total_nodes; i++)
2326 for (edge_p = wfg_Nodes[i].first_waiter_edge_p; edge_p !=
NULL; edge_p = edge_p->next_waiter_edge_p)
2328 if (tran_index == edge_p->waiter_tran_index)
2336 error_code = wfg_is_tran_group_waiting (thread_p, tran_index);
2353 wfg_is_tran_group_waiting (
THREAD_ENTRY * thread_p,
const int tran_index)
2356 WFG_TRANS_LIST *tran_list_p;
2364 for (i = 0; i < wfg_Total_tran_groups; i++)
2366 for (tran_list_p = wfg_Tran_group[i].waiter_tran_list_p; tran_list_p !=
NULL; tran_list_p = tran_list_p->next)
2368 if (tran_index == tran_list_p->tran_index)
2391 wfg_get_tran_entries (
THREAD_ENTRY * thread_p,
const int tran_index)
2400 for (i = 0; i < wfg_Total_nodes; i++)
2404 for (e = wfg_Nodes[i].first_holder_edge_p; e; e = e->next_holder_edge_p)
2406 n += (tran_index == e->waiter_tran_index);
2408 for (e = wfg_Nodes[i].first_waiter_edge_p; e; e = e->next_waiter_edge_p)
2410 n += (tran_index == e->waiter_tran_index);
2414 for (i = 0; i < wfg_Total_tran_groups; i++)
2418 for (tl = wfg_Tran_group[i].holder_tran_list_p; tl; tl = tl->next)
2420 n += (tran_index == tl->tran_index);
2422 for (tl = wfg_Tran_group[i].waiter_tran_list_p; tl; tl = tl->next)
2424 n += (tran_index == tl->tran_index);
#define csect_enter(a, b, c)
#define er_log_debug(...)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define ER_OUT_OF_VIRTUAL_MEMORY
static void error(const char *msg)
#define csect_enter_as_reader(a, b, c)
#define free_and_init(ptr)