| 397 | } |
| 398 | |
| 399 | CompNode::Impl* AtlasCompNode::load_atlas( |
| 400 | const Locator& locator, const Locator& locator_logical) { |
| 401 | auto&& sdptr = AtlasCompNodeImpl::sd; |
| 402 | { |
| 403 | MGB_LOCK_GUARD(AtlasCompNodeImpl::sd_mtx); |
| 404 | if (!sdptr) { |
| 405 | // use static storage so object can be safely accessed even after |
| 406 | // global finalize |
| 407 | using T = AtlasCompNodeImpl::StaticData; |
| 408 | static std::aligned_storage_t<sizeof(T), alignof(T)> storage; |
| 409 | sdptr = new (&storage) T; |
| 410 | } |
| 411 | } |
| 412 | auto&& sd = *sdptr; |
| 413 | MGB_LOCK_GUARD(sd.mtx); |
| 414 | |
| 415 | CompNodeImpl* available_node = nullptr; |
| 416 | for (int i = 0; i < sd.nr_node; ++i) { |
| 417 | auto&& cur = sd.node[i]; |
| 418 | if (cur.m_initialized) { |
| 419 | if (cur.m_locator == locator && cur.m_locator_logical == locator_logical) { |
| 420 | return &cur; |
| 421 | } |
| 422 | } else { |
| 423 | available_node = &cur; |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | if (!available_node) { |
| 428 | mgb_assert(sd.nr_node < sd.MAX_NR_COMP_NODE, "too many CompNode allocated"); |
| 429 | mgb_assert(locator.device < sd.MAX_NR_COMP_NODE, "device number too large"); |
| 430 | available_node = &sd.node[sd.nr_node++]; |
| 431 | } |
| 432 | |
| 433 | mgb_assert(!available_node->m_initialized); |
| 434 | available_node->init(locator, locator_logical); |
| 435 | log_comp_node_created(locator, locator_logical); |
| 436 | |
| 437 | return available_node; |
| 438 | } |
| 439 | |
| 440 | void AtlasCompNode::sync_all() { |
| 441 | auto sd = AtlasCompNodeImpl::sd; |