это правильный подход?
C++:
volatile LONG PerformanceCounter = 0;
#define PERFORMANCE_AUTO_COUNT InterlockedIncrement(&PerformanceCounter);
static FORCEINLINE uint32_t CountBitsV(uint64_t Bits)
{
return _mm_popcnt_u64(Bits);
}
class TSingleProcessorMode2
{
volatile LONG Hub;
KDPC DpcArray[MAXIMUM_PROCESSORS];
static void DpcRoutine(KDPC* pDpc, void* pContext, void* pArg1, void* pArg2);
public:
void Initialize();
void Execute(void(__fastcall* Routine)(void*), void* pContext);
};
void TSingleProcessorMode2::Initialize()
{
RtlZeroMemory(this, sizeof(TSingleProcessorMode2));
if (KeQueryActiveProcessorCount(nullptr) > 1)
for (int i = 0; i < MAXIMUM_PROCESSORS; i++)
{
KeInitializeDpc(&DpcArray[i], DpcRoutine, this);
KeSetTargetProcessorDpc(&DpcArray[i], (CCHAR)i);
KeSetImportanceDpc(&DpcArray[i], HighImportance);
}
}
void TSingleProcessorMode2::DpcRoutine(KDPC* pDpc, void* pContext, void* pArg1, void* pArg2)
{
TSingleProcessorMode2* pThis = (TSingleProcessorMode2*)pContext;
#if _WIN32_WINNT < 0x0502
KeRaiseIrqlToSynchLevel();
#else
//KIRQL DummyIrql;
//KeRaiseIrql(12, &DummyIrql);
KeRaiseIrqlToSynchLevel();
#endif
while (true)
{
KIRQL DummyIrql;
KeRaiseIrql(HIGH_LEVEL, &DummyIrql);
_disable();
LONG probe, level = InterlockedDecrement(&pThis->Hub) << 8;
if (level == 0)
{
((void(__fastcall*)(void*))pArg1)(pArg2);
//DbgPrint("DPC executing on processor: %d\n", KeGetCurrentProcessorNumber());
InterlockedExchange(&pThis->Hub, -1);
exit:
_enable();
KeLowerIrql(DISPATCH_LEVEL);
return;
}
do
{
PERFORMANCE_AUTO_COUNT;
_mm_pause();
probe = pThis->Hub;
if (probe < 0)
KeMemoryBarrier();
goto exit;
} while (probe == 0 || --level >= 0
|| InterlockedCompareExchange(&pThis->Hub, probe + 1, probe) != probe);
KeLowerIrql(12);
PERFORMANCE_AUTO_COUNT;
_mm_pause();
}
}
void TSingleProcessorMode2::Execute(void(__fastcall* pRoutine)(void*), void* pContext)
{
KeEnterCriticalRegion();
KeFlushQueuedDpcs();
if (KeQueryActiveProcessorCount(nullptr) > 1)
{
KAFFINITY ActiveProcessors = KeQueryActiveProcessors();
KIRQL Irql;
KeRaiseIrql(DISPATCH_LEVEL, &Irql);
{
Hub = CountBitsV(ActiveProcessors);
unsigned long i;
while (_BitScanReverse64(&i, ActiveProcessors))
{
do
{
KAFFINITY Mask = 1ull << i;
if ((ActiveProcessors & Mask) != 0
&& (i != KeGetCurrentProcessorNumber() || ActiveProcessors == Mask))
{
ActiveProcessors &= ~Mask;
KeInsertQueueDpc(&DpcArray[i], pRoutine, pContext);
}
} while ((int)--i >= 0);
}
}
KeLowerIrql(Irql);
}
else
{
KIRQL DummyIrqlx;
KeRaiseIrql(HIGH_LEVEL, &DummyIrqlx);
_disable();
pRoutine(pContext);
_enable();
KeLowerIrql(DummyIrqlx);
}
KeFlushQueuedDpcs();
KeLeaveCriticalRegion();
}
void __fastcall MyCallbackFunction(void* context)
{
// код
}
void core0(){
TSingleProcessorMode2 OK;
OK.Initialize();
OK.Execute(MyCallbackFunction, nullptr);
}