Modify Request Manager Duplication Checks - #311
Conversation
Qualcomm AI ReviewClick to expand Code ReviewReviewed Commits: 25c7093
Signed-off-by: Kartik Nema kartnema@qti.qualcomm.com Pull Request OverviewThis PR adds a new Files Changed Summary
Critical Issues Identified
Positive Changes
[Concurrency - High Severity] Race condition in getRequestProcessingStatus methodThe In a multi-threaded environment, this can lead to:
The method should acquire Fixed Code Snippet: int8_t RequestManager::getRequestProcessingStatus(int64_t handle) {
this->mRequestMapMutex.lock_shared();
if(this->mActiveRequests.find(handle) != this->mActiveRequests.end()) {
int8_t status = this->mActiveRequests[handle].second;
this->mRequestMapMutex.unlock_shared();
return status;
}
this->mRequestMapMutex.unlock_shared();
return REQ_NOT_FOUND;
}[Performance - Medium Severity] Redundant map lookup in requestMatch methodIn the This results in:
The code should be refactored to retrieve both the status and the request pointer in a single lookup operation, or Fixed Code Snippet: for(int64_t handle: *clientHandles) {
auto it = this->mActiveRequests.find(handle);
if(it == this->mActiveRequests.end()) {
continue;
}
int8_t requestProcessingStatus = it->second.second;
// Only check for requests which haven't been completed or cancelled
if((requestProcessingStatus & REQ_CANCELLED) || (requestProcessingStatus & REQ_COMPLETED)) {
continue;
}
Request* targetRequest = it->second.first;
if(targetRequest == nullptr) {
continue;
}
// ... rest of the logic
} |
| // If it is, we can use multiple threads from the pool for faster checking | ||
|
|
||
| for(int64_t handle: *clientHandles) { | ||
| Request* targetRequest = this->mActiveRequests[handle].first; | ||
| int8_t requestProcessingStatus = this->getRequestProcessingStatus(handle); | ||
| if(requestProcessingStatus == REQ_NOT_FOUND) { | ||
| continue; | ||
| } | ||
|
|
||
| // Only check for requests which haven't been completed or cancelled |
There was a problem hiding this comment.
[Performance - Medium Severity] Redundant map lookup in requestMatch method
In the requestMatch() method at line 107-109, the code performs a find() operation on mActiveRequests and then immediately accesses the element using it->second.first. However, this lookup is redundant because getRequestProcessingStatus() was just called at line 97, which also performs a lookup on the same map with the same key.
This results in:
- Unnecessary hash computation and map traversal
- Degraded performance when checking multiple handles
- Inefficient use of CPU cycles
The code should be refactored to retrieve both the status and the request pointer in a single lookup operation, or getRequestProcessingStatus() should be modified to return both pieces of information.
Fixed Code Snippet
for(int64_t handle: *clientHandles) {
auto it = this->mActiveRequests.find(handle);
if(it == this->mActiveRequests.end()) {
continue;
}
int8_t requestProcessingStatus = it->second.second;
// Only check for requests which haven't been completed or cancelled
if((requestProcessingStatus & REQ_CANCELLED) || (requestProcessingStatus & REQ_COMPLETED)) {
continue;
}
Request* targetRequest = it->second.first;
if(targetRequest == nullptr) {
continue;
}
// ... rest of the logic
}Signed-off-by: Kartik Nema <kartnema@qti.qualcomm.com>
25c7093 to
384143f
Compare
Qualcomm AI ReviewClick to expand Code ReviewReviewed commit: 384143f "Modify Request Manager Duplication Checks Signed-off-by: Kartik Nema kartnema@qti.qualcomm.com" [CONCURRENCY] Race condition in requestMatch() - High SeverityIn The Fixed Code Snippet: int8_t RequestManager::requestMatch(Request* request) {
int32_t clientTID = request->getClientTID();
std::shared_ptr<ClientDataManager> clientDataManager =
ClientDataManager::getInstance();
std::unordered_set<int64_t>* clientHandles =
clientDataManager->getRequestsByClientID(clientTID);
if(clientHandles == nullptr || clientHandles->size() == 0) {
return false;
}
// Acquire lock before accessing mActiveRequests
this->mRequestMapMutex.lock_shared();
for(int64_t handle: *clientHandles) {
auto it = this->mActiveRequests.find(handle);
if(it == this->mActiveRequests.end()) {
continue;
}
int8_t requestProcessingStatus = it->second.second;
int8_t clientPermission =
clientDataManager->getClientLevelByID(request->getClientPID());
if(clientPermission == PERMISSION_SYSTEM) {
if((requestProcessingStatus & REQ_CANCELLED) ||
(requestProcessingStatus & REQ_COMPLETED)) {
continue;
}
}
Request* targetRequest = it->second.first;
if(targetRequest == nullptr) {
continue;
}
if(request->getSource() != targetRequest->getSource()) {
continue;
}
if(request->getResourcesCount() != targetRequest->getResourcesCount()) {
continue;
}
if(!request->getResDlMgr()->matchAgainst(
targetRequest->getResDlMgr(), resourceCmpPolicy)) {
continue;
}
this->mRequestMapMutex.unlock_shared();
return true;
}
this->mRequestMapMutex.unlock_shared();
return false;
}[FUNCTIONALITY] Incorrect duplicate detection logic in shouldRequestBeAdded() - High SeverityIn The current implementation has Fixed Code Snippet: int8_t RequestManager::shouldRequestBeAdded(Request* request) {
//sanity check.
if(!isSane(request)) return false;
this->mRequestMapMutex.lock_shared();
if(this->mActiveRequests.size() >= UrmSettings::metaConfigs.mMaxConcurrentRequests) {
this->mRequestMapMutex.unlock_shared();
return false;
}
this->mRequestMapMutex.unlock_shared();
// Check for duplicates - requestMatch handles its own locking
int8_t duplicateFound = this->requestMatch(request);
return !duplicateFound;
} |
No description provided.