| 193 | } |
| 194 | |
| 195 | void id_status(bthread_id_t id, std::ostream &os) { |
| 196 | bthread::Id* const meta = address_resource(bthread::get_slot(id)); |
| 197 | if (!meta) { |
| 198 | os << "Invalid id=" << id.value << '\n'; |
| 199 | return; |
| 200 | } |
| 201 | const uint32_t id_ver = bthread::get_version(id); |
| 202 | uint32_t* butex = meta->butex; |
| 203 | bool valid = true; |
| 204 | void* data = NULL; |
| 205 | int (*on_error)(bthread_id_t, void*, int) = NULL; |
| 206 | int (*on_error2)(bthread_id_t, void*, int, const std::string&) = NULL; |
| 207 | uint32_t first_ver = 0; |
| 208 | uint32_t locked_ver = 0; |
| 209 | uint32_t unlockable_ver = 0; |
| 210 | uint32_t contended_ver = 0; |
| 211 | const char *lock_location = NULL; |
| 212 | SmallQueue<PendingError, 2> pending_q; |
| 213 | uint32_t butex_value = 0; |
| 214 | |
| 215 | meta->mutex.lock(); |
| 216 | if (meta->has_version(id_ver)) { |
| 217 | data = meta->data; |
| 218 | on_error = meta->on_error; |
| 219 | on_error2 = meta->on_error2; |
| 220 | first_ver = meta->first_ver; |
| 221 | locked_ver = meta->locked_ver; |
| 222 | unlockable_ver = meta->unlockable_ver(); |
| 223 | contended_ver = meta->contended_ver(); |
| 224 | lock_location = meta->lock_location; |
| 225 | const size_t size = meta->pending_q.size(); |
| 226 | for (size_t i = 0; i < size; ++i) { |
| 227 | PendingError front; |
| 228 | meta->pending_q.pop(&front); |
| 229 | meta->pending_q.push(front); |
| 230 | pending_q.push(front); |
| 231 | } |
| 232 | butex_value = *butex; |
| 233 | } else { |
| 234 | valid = false; |
| 235 | } |
| 236 | meta->mutex.unlock(); |
| 237 | |
| 238 | if (valid) { |
| 239 | os << "First id: " |
| 240 | << bthread::make_id(first_ver, bthread::get_slot(id)).value << '\n' |
| 241 | << "Range: " << locked_ver - first_ver << '\n' |
| 242 | << "Status: "; |
| 243 | if (butex_value != first_ver) { |
| 244 | os << "LOCKED at " << lock_location; |
| 245 | if (butex_value == contended_ver) { |
| 246 | os << " (CONTENDED)"; |
| 247 | } else if (butex_value == unlockable_ver) { |
| 248 | os << " (ABOUT TO DESTROY)"; |
| 249 | } else { |
| 250 | os << " (UNCONTENDED)"; |
| 251 | } |
| 252 | } else { |