* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ------------------------------------------------------------------------- */
#include "race_alg_impl.h"
namespace Sanitizer {
RaceAlgImpl::RaceAlgImpl(KernelType kernelType, DeviceType deviceType, uint32_t blockDim)
: RaceAlgBase(kernelType, deviceType, blockDim)
{
uint32_t totalBlockNum = NeedExpandBlockDim(kernelType, deviceType) ? blockDim * C220_MIX_SUB_BLOCKDIM : 1;
vc_.resize(totalBlockNum * static_cast<uint8_t>(PipeType::SIZE));
for (auto &it : vc_) {
it.resize(totalBlockNum * static_cast<uint8_t>(PipeType::SIZE), 1);
}
eventContainer_.Init(totalBlockNum);
crossCoreSyncInfoContainer_.Init(totalBlockNum, kernelType);
memChecker_.Init(kernelType, deviceType, RaceCheckType::SINGLE_BLOCK_CHECK);
}
void RaceAlgImpl::Do(const SanEvent& event)
{
if (event.type != EventType::SANITIZER_CONTROL_EVENT ||
event.eventInfo.sanitizerControlInfo.type != SanitizerControlType::KERNEL_FINISH) {
CacheMstxCrossSet(event);
auto blockIndex = GetEventBlockIndex(event, kernelType_, deviceType_, RaceCheckType::SINGLE_BLOCK_CHECK);
eventContainer_.Push(event, PipeType::PIPE_S, blockIndex);
return;
}
PipeLine pipeLine(eventContainer_);
pipeLine.RegisterEventFunc(std::bind(&RaceAlgImpl::ProcessEvent, this, std::placeholders::_1));
pipeLine.Run();
memChecker_.RunAlgorithm();
isFinished_ = true;
}
bool RaceAlgImpl::IsFinished() const
{
return isFinished_;
}
std::shared_ptr<std::vector<RaceDispInfo>> RaceAlgImpl::GetResult() const
{
return memChecker_.GetResult();
}
uint32_t RaceAlgImpl::GetRaceCount() const
{
return memChecker_.GetRaceCount();
}
ReturnType RaceAlgImpl::ProcessEvent(const SanEvent& event)
{
PipeType curPipe = eventContainer_.GetPipeIndex();
if (curPipe != event.pipe) {
uint32_t curPipeIdx = eventContainer_.GetQueIndex();
VectorClock::UpdateLogicTime(vc_[curPipeIdx], curPipeIdx);
SanEvent e;
e.type = EventType::TIME_EVENT;
e.pipe = event.pipe;
e.timeInfo = vc_[curPipeIdx];
auto blockIndex = GetEventBlockIndex(event, kernelType_, deviceType_, RaceCheckType::SINGLE_BLOCK_CHECK);
eventContainer_.Push(e, e.pipe, blockIndex);
eventContainer_.Push(event, event.pipe, blockIndex);
return ReturnType::PROCESS_OK;
}
switch (event.type) {
case EventType::SYNC_EVENT:
return ProcessSyncEvent(event);
case EventType::MEM_EVENT:
return ProcessMemEvent(event);
case EventType::TIME_EVENT:
return ProcessTimeEvent(event);
case EventType::CROSS_CORE_SYNC_EVENT:
return ProcessBlockSyncEvent(event, RaceCheckType::SINGLE_BLOCK_CHECK);
case EventType::MSTX_CROSS_SYNC_EVENT:
return ProcessMstxCrossSyncEvent(event);
case EventType::BUF_SYNC_EVENT:
return ProcessGetRlsBufSyncEvent(event, RaceCheckType::SINGLE_BLOCK_CHECK);
case EventType::DYNAMIC_MEM_EVENT:
return ProcessDynamicMemEvent(event);
default:
break;
}
return ReturnType::PROCESS_OK;
}
ReturnType RaceAlgImpl::ProcessMemEvent(const SanEvent& event)
{
auto e = MemEvent(event);
uint32_t curPipe = eventContainer_.GetQueIndex();
VectorClock::UpdateLogicTime(vc_[curPipe], curPipe);
e.vt = vc_[curPipe];
memChecker_.PushEvent(e);
return ReturnType::PROCESS_OK;
}
ReturnType RaceAlgImpl::ProcessDynamicMemEvent(const SanEvent& event)
{
uint32_t curPipe = eventContainer_.GetQueIndex();
VectorClock::UpdateLogicTime(vc_[curPipe], curPipe);
auto e = MemEvent(event);
e.vt = vc_[curPipe];
memChecker_.PushEvent(e);
return ReturnType::PROCESS_OK;
}
ReturnType RaceAlgImpl::ProcessSyncEvent(const SanEvent& event)
{
auto e = SyncEvent {};
e.info.srcPipe = static_cast<uint8_t>(event.eventInfo.syncInfo.srcPipe);
e.info.dstPipe = static_cast<uint8_t>(event.eventInfo.syncInfo.dstPipe);
e.info.eventId = static_cast<uint8_t>(event.eventInfo.syncInfo.eventId);
e.info.memType = static_cast<uint8_t>(event.eventInfo.syncInfo.memType);
e.info.isRetrogress = event.eventInfo.syncInfo.isRetrogress;
if (event.eventInfo.syncInfo.opType == SyncType::SET_FLAG) {
uint32_t curPipe = eventContainer_.GetQueIndex();
VectorClock::UpdateLogicTime(vc_[curPipe], curPipe);
syncDB_.Set(e, vc_[curPipe]);
return ReturnType::PROCESS_OK;
}
if (event.eventInfo.syncInfo.opType == SyncType::WAIT_FLAG) {
VectorTime vt;
if (syncDB_.Get(e, vt)) {
uint32_t curPipe = eventContainer_.GetQueIndex();
VectorClock::UpdateVectorTime(vt, vc_[curPipe]);
VectorClock::UpdateLogicTime(vc_[curPipe], curPipe);
return ReturnType::PROCESS_OK;
} else {
return ReturnType::PROCESS_STALLED;
}
}
return ReturnType::PROCESS_OK;
}
ReturnType RaceAlgImpl::ProcessTimeEvent(const SanEvent& event)
{
uint32_t curPipe = eventContainer_.GetQueIndex();
VectorClock::UpdateVectorTime(event.timeInfo, vc_[curPipe]);
VectorClock::UpdateLogicTime(vc_[curPipe], curPipe);
return ReturnType::PROCESS_OK;
}
}