Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds safety annotations (@safe/@unsafe) to functions across the SILO/STO transactional database system codebase, with the goal of documenting which operations are memory-safe and which involve potentially unsafe operations like raw pointer manipulation, atomic operations, or external C function calls.
Key Changes
- Added @safe and @unsafe annotations to hundreds of functions across transaction handling, storage, and synchronization code
- Changed
sync_util::sync_logger::local_replica_idfrominttostd::atomic<int>and updated all atomic operations to use modern C++ atomic methods - Migrated from
std::mapandstd::unordered_maptorusty::HashMapinThreadPool.handcommon.hwith Option-based API - Wrapped external C functions (usleep, add_log_to_nc) in safe wrapper functions
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| src/mako/txn_proto2_impl.h | Added @safe annotations to simple getters and pure bitwise operations; @unsafe annotations to functions calling wait/persist operations |
| src/mako/txn.h | Added @safe annotations to getters and simple operations; @unsafe annotations to functions with pointer operations and marked_ptr method calls |
| src/mako/tuple.h | Added @safe annotations to bitwise checks, simple getters, and member reads |
| src/mako/thread.h | Added @safe annotation with lifetime annotation for get_name() |
| src/mako/masstree/nodeversion.hh | Changed @safe to @unsafe for bit manipulation methods (mark_split, mark_deleted_tree, mark_root, mark_nonroot) |
| src/mako/masstree/masstree_struct.hh | Changed @safe to @unsafe for suffix string operations (ksuf, ksuf_equals, ksuf_matches, ksuf_compare) |
| src/mako/masstree/kpermuter.hh | Changed @safe to @unsafe for bit manipulation methods (exchange, exchange_values) |
| src/mako/lib/shardClient.h | Added @safe annotations to all remote operation methods |
| src/mako/counter.h | Added @safe annotations to simple initialization and arithmetic operations with lifetime annotations |
| src/mako/benchmarks/tpcc_keys.h | Added @safe annotations to POD structs, constructors, comparison operators, and hash functions |
| src/mako/benchmarks/sto/sync_util.hh | Changed local_replica_id to std::atomic; added @unsafe annotations; added unordered_map include; formatting fix |
| src/mako/benchmarks/sto/stuffed_str.hh | Added @safe annotations to data() and length() methods |
| src/mako/benchmarks/sto/simple_str.hh | Added @safe and @unsafe annotations with detailed descriptions |
| src/mako/benchmarks/sto/randgen.hh | Added @safe annotations to pure arithmetic operations |
| src/mako/benchmarks/sto/multiversion.hh | Added @unsafe annotation to mvGET function |
| src/mako/benchmarks/sto/Transaction.hh | Added @unsafe annotations with explanations; formatting fix; added unordered_map include |
| src/mako/benchmarks/sto/Transaction.cc | Added external C function declarations; created safe wrapper functions; replaced __sync_fetch_and_add with fetch_add; changed instance-> to (*instance); updated nullptr comparisons; added @safe/@unsafe annotations throughout |
| src/mako/benchmarks/sto/ThreadPool.h | Added rusty/hashmap.hpp include; migrated to rusty::HashMap with Option-based get() API; added @safe/@unsafe annotations |
| src/mako/benchmarks/sto/ThreadPool.cc | Changed @unsafe to @safe annotation for cmpFunc2_v2 |
| src/mako/benchmarks/sto/ReplayDB.h | Added @safe annotation to CommitInfo struct; @unsafe annotations to replay functions |
| src/mako/benchmarks/sto/MassTrans.cc | Added @external annotation documenting Transaction as unsafe_type |
| src/mako/benchmarks/sto/Interface.hh | Added getLocalPartitionID() method; added @safe annotations to virtual methods (with conflicting annotation on print()) |
| src/mako/benchmarks/cpu_throttler.h | Added @safe annotations to getter methods |
| src/mako/benchmarks/common.h | Added rusty/hashmap.hpp include; migrated HashWrapper to use rusty::HashMap with Option-based API |
| src/mako/benchmarks/benchmark_config.h | Added @safe annotations to all simple getter methods with lifetime annotations where appropriate |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/mako/benchmarks/sto/sync_util.hh
Outdated
| } | ||
|
|
||
| // In previous submission, we assume the healthy shards are always INF | ||
| // @unsafe - uses std::unordered_map (undeclared) |
There was a problem hiding this comment.
The annotation comment incorrectly states "undeclared" but std::unordered_map is declared via the include at line 9. The correct safety annotation should focus on the actual unsafe operations (accessing std::unordered_map which can reallocate or throw exceptions).
src/mako/benchmarks/sto/sync_util.hh
Outdated
| } | ||
|
|
||
| // Single timestamp system: ensure vector contains replicated value | ||
| // @unsafe - uses std::vector which is undeclared, and std::cout |
There was a problem hiding this comment.
The annotation incorrectly claims std::vector is "undeclared", but vector is brought into scope via "using namespace std;" at line 11. The annotation should focus on actual unsafe operations rather than incorrect claims about declarations.
| // @unsafe - uses std::vector which is undeclared, and std::cout | |
| // @unsafe - copies vector by value and performs logging via std::cout |
| #include "benchmarks/benchmark_config.h" | ||
| #include <rusty/hashmap.hpp> | ||
| //#include "lib/memcached_client.h" | ||
|
|
There was a problem hiding this comment.
The header file "rusty/hashmap.hpp" is included here but does not appear to exist in the repository. This will cause a compilation failure.
| #include "benchmarks/benchmark_config.h" | |
| #include <rusty/hashmap.hpp> | |
| //#include "lib/memcached_client.h" | |
| #include <utility> | |
| #include "benchmarks/benchmark_config.h" | |
| //#include "lib/memcached_client.h" | |
| // Minimal local implementation of rusty::HashMap and its Option-like return type | |
| namespace rusty { | |
| template <typename T> | |
| class Option { | |
| public: | |
| Option() : value_(nullptr) {} | |
| explicit Option(T value) : value_(value) {} | |
| bool is_some() const { | |
| return value_ != nullptr; | |
| } | |
| T unwrap() const { | |
| return value_; | |
| } | |
| private: | |
| T value_; | |
| }; | |
| template <typename K, typename V> | |
| class HashMap { | |
| public: | |
| HashMap() = default; | |
| template <typename KeyLike> | |
| void insert(KeyLike&& key, V value) { | |
| data_.emplace(std::forward<KeyLike>(key), value); | |
| } | |
| Option<V*> get(const K& key) { | |
| auto it = data_.find(key); | |
| if (it == data_.end()) { | |
| return Option<V*>(nullptr); | |
| } | |
| return Option<V*>(&it->second); | |
| } | |
| private: | |
| std::unordered_map<K, V> data_; | |
| }; | |
| } |
| virtual void cleanup(TransItem& item, bool committed) { | ||
| (void) item, (void) committed; | ||
| } | ||
| // @safe |
There was a problem hiding this comment.
src/mako/txn.h
Outdated
| { | ||
| return tuple.get(); | ||
| } | ||
| // @unsafe - calls marked_ptr::get (undeclared) |
There was a problem hiding this comment.
The annotation incorrectly claims marked_ptr::get is "undeclared". Since this is a method call on the 'tuple' member, it's likely declared in the marked_ptr class definition. The annotation should describe the actual unsafe operation rather than making incorrect claims about declarations.
src/mako/txn.h
Outdated
| // @unsafe - calls marked_ptr::get_flags (undeclared) | ||
| inline bool | ||
| is_insert() const | ||
| { | ||
| return btr.get_flags() & FLAGS_INSERT; | ||
| } | ||
| // @unsafe - calls marked_ptr::get_flags (undeclared) |
There was a problem hiding this comment.
The annotation incorrectly claims marked_ptr::get_flags is "undeclared". Since this is a method call on the 'btr' member, it's likely declared in the marked_ptr class definition. The annotation should describe the actual unsafe operation rather than making incorrect claims about declarations.
| // @unsafe - calls marked_ptr::get_flags (undeclared) | |
| inline bool | |
| is_insert() const | |
| { | |
| return btr.get_flags() & FLAGS_INSERT; | |
| } | |
| // @unsafe - calls marked_ptr::get_flags (undeclared) | |
| // @unsafe - inspects internal marked_ptr flag bits | |
| inline bool | |
| is_insert() const | |
| { | |
| return btr.get_flags() & FLAGS_INSERT; | |
| } | |
| // @unsafe - inspects internal marked_ptr flag bits |
src/mako/txn.h
Outdated
| // @unsafe - calls marked_ptr::get_flags (undeclared) | ||
| inline bool | ||
| is_insert() const | ||
| { | ||
| return btr.get_flags() & FLAGS_INSERT; | ||
| } | ||
| // @unsafe - calls marked_ptr::get_flags (undeclared) |
There was a problem hiding this comment.
The annotation incorrectly claims marked_ptr::get_flags is "undeclared". Since this is a method call on the 'btr' member, it's likely declared in the marked_ptr class definition. The annotation should describe the actual unsafe operation rather than making incorrect claims about declarations.
| // @unsafe - calls marked_ptr::get_flags (undeclared) | |
| inline bool | |
| is_insert() const | |
| { | |
| return btr.get_flags() & FLAGS_INSERT; | |
| } | |
| // @unsafe - calls marked_ptr::get_flags (undeclared) | |
| // @unsafe - reads flag bits from marked_ptr (may be concurrently modified) | |
| inline bool | |
| is_insert() const | |
| { | |
| return btr.get_flags() & FLAGS_INSERT; | |
| } | |
| // @unsafe - reads flag bits from marked_ptr (may be concurrently modified) |
src/mako/txn.h
Outdated
| INVARIANT(!do_write()); | ||
| btr.or_flags(FLAGS_DOWRITE); | ||
| } | ||
| // @unsafe - calls marked_ptr::get (undeclared) |
There was a problem hiding this comment.
The annotation incorrectly claims marked_ptr::get is "undeclared". Since this is a method call on the 'btr' member, it's likely declared in the marked_ptr class definition. The annotation should describe the actual unsafe operation rather than making incorrect claims about declarations.
src/mako/txn.h
Outdated
| // @unsafe - uses const_cast | ||
| explicit dbtuple_write_info(const dbtuple *tuple) | ||
| : tuple(const_cast<dbtuple *>(tuple)), entry(), pos() {} | ||
| // @unsafe - calls marked_ptr::get (undeclared) |
There was a problem hiding this comment.
The annotation incorrectly claims marked_ptr::get is "undeclared". Since this is a method call on the 'tuple' member, it's likely declared in the marked_ptr class definition. The annotation should describe the actual unsafe operation rather than making incorrect claims about declarations.
| tuple.or_flags(FLAGS_LOCKED); | ||
| INVARIANT(is_locked()); | ||
| } | ||
| // @unsafe - calls marked_ptr::get_flags (undeclared) |
There was a problem hiding this comment.
The annotation incorrectly claims marked_ptr::get_flags is "undeclared". Since this is a method call on the 'tuple' member, it's likely declared in the marked_ptr class definition. The annotation should describe the actual unsafe operation rather than making incorrect claims about declarations.
| return len > (int)capacity_; | ||
| } | ||
|
|
||
| // @safe - returns raw pointer (allowed in @safe) |
There was a problem hiding this comment.
returning raw pointers. does it pass the checker?
There was a problem hiding this comment.
added lifetime annotation and checker passed this
| } | ||
|
|
||
| // @safe - uses rusty::HashMap::get which returns Option | ||
| ThreadDBWrapperMbta* getDBWrapper(int par_id) { |
There was a problem hiding this comment.
safe functions cannot return raw pointers.
There was a problem hiding this comment.
But checker is passing this
|
pls give the LOC of how many are safe and how many are unsafe. |
098b896 to
9649bf3
Compare
No description provided.