3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-05-31 06:07:47 +00:00

Make it safe to access .c_str() for autoidx IDs in a multithreaded context

This commit is contained in:
Robert O'Callahan 2025-11-25 01:02:01 +00:00
parent 948001f39f
commit b23dc345ae
3 changed files with 14 additions and 9 deletions

View file

@ -276,7 +276,6 @@ void RTLIL::OwningIdString::collect_garbage()
++it; ++it;
continue; continue;
} }
delete[] it->second.full_str;
it = global_autoidx_id_storage_.erase(it); it = global_autoidx_id_storage_.erase(it);
} }

View file

@ -139,7 +139,11 @@ struct RTLIL::IdString
// the real string. The prefix strings must live forever. // the real string. The prefix strings must live forever.
const std::string *prefix; const std::string *prefix;
// Cache of the full string, or nullptr if not cached yet. // Cache of the full string, or nullptr if not cached yet.
char *full_str; std::atomic<char *> full_str;
AutoidxStorage(const std::string *prefix) : prefix(prefix), full_str(nullptr) {}
AutoidxStorage(AutoidxStorage&& other) : prefix(other.prefix), full_str(other.full_str.exchange(nullptr, std::memory_order_relaxed)) {}
~AutoidxStorage() { delete[] full_str.load(std::memory_order_acquire); }
}; };
// the global id string cache // the global id string cache
@ -209,7 +213,7 @@ struct RTLIL::IdString
static IdString new_autoidx_with_prefix(const std::string *prefix) { static IdString new_autoidx_with_prefix(const std::string *prefix) {
log_assert(!Multithreading::active()); log_assert(!Multithreading::active());
int index = -(autoidx++); int index = -(autoidx++);
global_autoidx_id_storage_.insert({index, {prefix, nullptr}}); global_autoidx_id_storage_.insert({index, prefix});
return from_index(index); return from_index(index);
} }
@ -244,15 +248,18 @@ struct RTLIL::IdString
return global_id_storage_.at(index_).buf; return global_id_storage_.at(index_).buf;
AutoidxStorage &s = global_autoidx_id_storage_.at(index_); AutoidxStorage &s = global_autoidx_id_storage_.at(index_);
if (s.full_str != nullptr) char *full_str = s.full_str.load(std::memory_order_acquire);
return s.full_str; if (full_str != nullptr)
return full_str;
const std::string &prefix = *s.prefix; const std::string &prefix = *s.prefix;
std::string suffix = std::to_string(-index_); std::string suffix = std::to_string(-index_);
char *c = new char[prefix.size() + suffix.size() + 1]; char *c = new char[prefix.size() + suffix.size() + 1];
memcpy(c, prefix.data(), prefix.size()); memcpy(c, prefix.data(), prefix.size());
memcpy(c + prefix.size(), suffix.c_str(), suffix.size() + 1); memcpy(c + prefix.size(), suffix.c_str(), suffix.size() + 1);
s.full_str = c; if (s.full_str.compare_exchange_strong(full_str, c, std::memory_order_acq_rel))
return c; return c;
delete[] c;
return full_str;
} }
inline std::string str() const { inline std::string str() const {

View file

@ -164,8 +164,7 @@ pyosys_headers = [
{ {
"global_id_storage_", "global_id_storage_",
"global_id_index_", "global_id_index_",
"global_negative_id_storage_", "global_autoidx_id_storage_",
"global_negative_id_prefix_storage_",
"global_refcount_storage_", "global_refcount_storage_",
"global_free_idx_list_", "global_free_idx_list_",
"builtin_ff_cell_types", "builtin_ff_cell_types",