equal
deleted
inserted
replaced
117 } |
117 } |
118 |
118 |
119 inline ZForwardingEntry ZForwarding::find(uintptr_t from_index, ZForwardingCursor* cursor) const { |
119 inline ZForwardingEntry ZForwarding::find(uintptr_t from_index, ZForwardingCursor* cursor) const { |
120 // Reading entries in the table races with the atomic CAS done for |
120 // Reading entries in the table races with the atomic CAS done for |
121 // insertion into the table. This is safe because each entry is at |
121 // insertion into the table. This is safe because each entry is at |
122 // most updated once (from -1 to something else). |
122 // most updated once (from zero to something else). |
123 ZForwardingEntry entry = first(from_index, cursor); |
123 ZForwardingEntry entry = first(from_index, cursor); |
124 while (!entry.is_empty()) { |
124 while (entry.populated()) { |
125 if (entry.from_index() == from_index) { |
125 if (entry.from_index() == from_index) { |
126 // Match found, return matching entry |
126 // Match found, return matching entry |
127 return entry; |
127 return entry; |
128 } |
128 } |
129 |
129 |
138 const ZForwardingEntry new_entry(from_index, to_offset); |
138 const ZForwardingEntry new_entry(from_index, to_offset); |
139 const ZForwardingEntry old_entry; // Empty |
139 const ZForwardingEntry old_entry; // Empty |
140 |
140 |
141 for (;;) { |
141 for (;;) { |
142 const ZForwardingEntry prev_entry = Atomic::cmpxchg(new_entry, entries() + *cursor, old_entry); |
142 const ZForwardingEntry prev_entry = Atomic::cmpxchg(new_entry, entries() + *cursor, old_entry); |
143 if (prev_entry.is_empty()) { |
143 if (!prev_entry.populated()) { |
144 // Success |
144 // Success |
145 return to_offset; |
145 return to_offset; |
146 } |
146 } |
147 |
147 |
148 // Find next empty or matching entry |
148 // Find next empty or matching entry |
149 ZForwardingEntry entry = at(cursor); |
149 ZForwardingEntry entry = at(cursor); |
150 while (!entry.is_empty()) { |
150 while (entry.populated()) { |
151 if (entry.from_index() == from_index) { |
151 if (entry.from_index() == from_index) { |
152 // Match found, return already inserted address |
152 // Match found, return already inserted address |
153 return entry.to_offset(); |
153 return entry.to_offset(); |
154 } |
154 } |
155 |
155 |