How can I use SetProcessAffinityMask to select more than one logical processor?
In Windows Task Manager you can do this as an example:

I updated my CreateProcess procedure to do this:
type
TProcessPriority = (ptLow = $00000040,
ptBelowNormal = $00004000,
ptNormal = $00000020,
ptAboveNormal = $00008000,
ptHigh = $00000080,
ptRealtime = $00000100);
procedure RunProcess(FileName: string; Priority: TProcessPriority);
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: string;
Done: Boolean;
begin
FillChar(StartInfo, SizeOf(TStartupInfo), #0);
FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
StartInfo.cb := SizeOf(TStartupInfo);
CmdLine := FileName;
UniqueString(CmdLine);
try
Done := CreateProcess(nil, PChar(CmdLine), nil, nil, False,
CREATE_NEW_PROCESS_GROUP + Integer(Priority),
nil, nil, StartInfo, ProcInfo);
if Done then
begin
// Todo: Get actual cpu core count before attempting to set affinity!
// 0 = <All Processors>
// 1 = CPU 0
// 2 = CPU 1
// 3 = CPU 2
// 4 = CPU 3
// 5 = CPU 5
// 6 = CPU 6
// 7 = CPU 6
// 8 = CPU 7
// this sets to CPU 0 - but how to allow multiple parameters to
// set more than one logical processor?
SetProcessAffinityMask(ProcInfo.hProcess, 1);
end else
MessageDlg('Could not run ' + FileName, mtError, [mbOk], 0)
finally
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;
Note the comments I put in there. It would be good to update my procedure to include a new Affinity parameter which I can pass to SetProcessAffinityMask.
Calling any of these won’t select the corresponding processors for obvious reasons, they give the idea of what I am wanting to do:
SetProcessAffinityMask(ProcInfo.hProcess, 1 + 2);
SetProcessAffinityMask(ProcInfo.hProcess, 1 and 2);
eg, select any of the CPU’s for a process, as shown in Task Manager.
How should I do this, using an Array, Set or something else? I cannot get it to work with multiple values.
Thanks.
It is a bitmask as described in the documentation.
And so on. You can use logical
orto combine them. So processors 0 and 1 would be$01or$02which equals$03.I would use the shift operator
shlto create values for specific processors. Like this:You can readily extend this to generate masks for lists of processors using logical
orin a loop.You can test for a processor being in a bit mask like this:
Note: I’m using
DWORD_PTRbecause for 64 bit targets the bitmask is 64 bits wide. That nuance doesn’t matter for you on XE but it’s worth getting it right to make any future code porting easier.