@@ -457,6 +457,7 @@ bool CLIClient::can_connect(const tms::Identity& id1, tms::DeviceRole role1,
457457 return false ;
458458 }
459459
460+ std::lock_guard<std::mutex> guard (data_m_);
460461 const bool dev1_is_not_connected = power_connections_.count (id1) == 0 || power_connections_.at (id1).empty ();
461462 const bool dev2_is_not_connected = power_connections_.count (id2) == 0 || power_connections_.at (id2).empty ();
462463
@@ -472,6 +473,7 @@ bool CLIClient::can_connect(const tms::Identity& id1, tms::DeviceRole role1,
472473void CLIClient::connect (const tms::Identity& id1, tms::DeviceRole role1,
473474 const tms::Identity& id2, tms::DeviceRole role2)
474475{
476+ std::lock_guard<std::mutex> guard (data_m_);
475477 power_connections_[id1].insert (powersim::ConnectedDevice{id2, role2});
476478 power_connections_[id2].insert (powersim::ConnectedDevice{id1, role1});
477479}
@@ -498,25 +500,36 @@ void CLIClient::consolidate_power_devices()
498500// Each connection simulates a physical connection using a power cable.
499501void CLIClient::connect_power_devices ()
500502{
501- std::lock_guard<std::mutex> guard (data_m_);
502- if (power_devices_.empty ()) {
503- consolidate_power_devices ();
503+ // Reading input from user for connecting devices can take long.
504+ // So we work on a copy of the power devices list and release the lock
505+ // so that the CLI can continue processing heartbeats from MCs and
506+ // does not incorrectly report available MCs as unavailable.
507+ PowerDevices local_pds;
508+ {
509+ std::lock_guard<std::mutex> guard (data_m_);
510+ if (power_devices_.empty ()) {
511+ consolidate_power_devices ();
512+ }
513+ local_pds = power_devices_;
504514 }
505515
506- for (auto it1 = power_devices_ .begin (); it1 != power_devices_ .end (); ++it1) {
516+ for (auto it1 = local_pds .begin (); it1 != local_pds .end (); ++it1) {
507517 const tms::Identity& id1 = it1->first ;
508518 const tms::DeviceRole role1 = it1->second .device_info ().role ();
509519 auto it2 = it1;
510520 ++it2;
511- std::cout << " Select devices to connect to device Id: " << id1 << std::endl;
512- for (; it2 != power_devices_.end (); ++it2) {
521+ if (it2 != local_pds.end ()) {
522+ std::cout << " === Connections for device Id: " << id1 << std::endl;
523+ }
524+
525+ for (; it2 != local_pds.end (); ++it2) {
513526 const tms::Identity& id2 = it2->first ;
514527 const tms::DeviceRole role2 = it2->second .device_info ().role ();
515528 if (!can_connect (id1, role1, id2, role2)) {
516529 continue ;
517530 }
518531
519- std::cout << " Connect to device Id: " << id2 << " (Y/n)" ;
532+ std::cout << " Connect to device Id: " << id2 << " (Y/n)> " ;
520533 while (true ) {
521534 std::string line;
522535 std::getline (std::cin, line);
@@ -535,6 +548,7 @@ void CLIClient::connect_power_devices()
535548
536549 // Send the power topology to the current controller which then
537550 // distributes the power connections to its managed power devices.
551+ std::lock_guard<std::mutex> guard (data_m_);
538552 powersim::PowerTopology pt;
539553 pt.connections ().reserve (power_connections_.size ());
540554 CORBA::ULong i = 0 ;
0 commit comments