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