1 /*
2 * cIntegratedScheduleNode.cc
3 * Avida
4 *
5 * Called "integrated_schedule_node.cc" prior to 12/7/05.
6 * Copyright 1999-2011 Michigan State University. All rights reserved.
7 * Copyright 1993-2003 California Institute of Technology.
8 *
9 *
10 * This file is part of Avida.
11 *
12 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14 *
15 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License along with Avida.
19 * If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #include "cIntegratedScheduleNode.h"
24
25
OK()26 bool cIntegratedScheduleNode::OK()
27 {
28 bool result = true;
29
30 // Make sure the active_array is setup correctly.
31
32 int size_check = 0;
33 int next_check = first_entry;
34 for (int i = 0; i < active_array.GetSize(); i++) {
35 if (active_array[i] != 0) {
36 size_check++;
37 assert(next_check == i); // Node entries do no match!
38 next_check = active_array[i];
39 }
40 }
41 assert(next_check == -1); // Node array not properly terminated.
42
43 // Make sure the sizes line up...
44 assert(size == size_check); // size and active node count mismatch.
45
46 return result;
47 }
48
Insert(int item_id)49 void cIntegratedScheduleNode::Insert(int item_id)
50 {
51 assert(item_id >= 0 && item_id < active_array.GetSize()); // Illegal ID
52
53 // If this item is already active in this node, ignore this call...
54 if (active_array[item_id] != 0) return;
55
56 // See if we're dealing with a new first_entry...
57 if (first_entry == -1 || item_id < first_entry) {
58 active_array[item_id] = first_entry;
59 first_entry = item_id;
60 }
61 else {
62 // Otherwise find the predecessor to this item in the list...
63 int prev_item;
64 for (prev_item = item_id - 1; prev_item >= 0; prev_item--) {
65 if (active_array[prev_item] != 0) break;
66 }
67 assert(prev_item >= 0); // prev_item is first, but not identified.
68
69 // Make the predecessor point to it, and have it point to the CPU that
70 // the old predecessor pointed to.
71 active_array[item_id] = active_array[prev_item];
72 active_array[prev_item] = item_id;
73 }
74
75 size++;
76 }
77
Remove(int item_id)78 void cIntegratedScheduleNode::Remove(int item_id)
79 {
80 assert(item_id >= 0 && item_id < active_array.GetSize()); // Illegal ID
81
82 // If this item is already inactive, ignore this call...
83 if (active_array[item_id] == 0) return;
84
85 // If this is the first_entry, adjust it!
86 if (first_entry == item_id) {
87 first_entry = active_array[item_id];
88 }
89 else {
90 // Find the predecessor to this item in the list...
91 int prev_item;
92 for (prev_item = item_id - 1; prev_item >= 0; prev_item--) {
93 if (active_array[prev_item] != 0) break;
94 }
95 assert(prev_item >= 0); // prev_item is first, but not identified.
96
97 // Make the predecessor point to the item removed used to point to.
98 active_array[prev_item] = active_array[item_id];
99 }
100
101 active_array[item_id] = 0;
102 size--;
103 }
104
105
106 // Execute everything on list, and then shift to calling the next node.
107 // Wait for the next node to return a -1 before shifting back to this one.
108
GetNextID()109 int cIntegratedScheduleNode::GetNextID()
110 {
111 // Alternate between this node's Process and the next's.
112 if (execute == false) {
113 // If there is a next node, we may be working on it...
114 int next_id = -1;
115 if (next != NULL) next_id = next->GetNextID();
116
117 // If next_id is a -1, either we don't have a next node, or else it
118 // is finished with its execution.
119
120 if (next_id == -1) {
121 execute = true;
122 process_count = 0;
123 active_entry = -1;
124 }
125
126 return next_id;
127 }
128
129 // Find the next active_entry...
130
131 // If we were at the end of the list, start over...
132 if (active_entry == -1) active_entry = first_entry;
133
134 // If this entry no longer exists, hunt for the next active entry manually...
135 else if (active_array[active_entry] == 0) {
136 while (active_entry < active_array.GetSize() &&
137 active_array[active_entry] == 0) {
138 active_entry++;
139 }
140 if (active_entry == active_array.GetSize()) active_entry = -1;
141 }
142
143 // Otherwise, if the entry does exist, we can just look the next one up.
144 else active_entry = active_array[active_entry];
145
146
147 // If we have now hit the end of this list, move on to the next node.
148
149 if (active_entry == -1) {
150 process_count++;
151 if (process_count >= process_size) execute = false;
152 }
153
154 return active_entry;
155 }
156