Jump to content

Setting CPU Affinity


 Share

Recommended Posts

I'm trying to figure out how to get AutoIt to set the CPU affinity of a running process.

(Right Click on a Process in Task Mgr - And you can tell it what processors its allowed to run on.)

I've been tooling around the web and I have not seen any script examples (a few compiled tools)

Basically, I have a few apps that will not run correctly if they are allowed to run on both processors.

What I want to do is scan memory and when such a process is launched set the affinity.

Scanning the memory and taking action is well documented on this site.

What I dont know is any type of command that I could issue to set affinity.

If any of you wise folks know a way to do this, you would make my Christmas merry.

Link to comment
Share on other sites

I'm trying to figure out how to get AutoIt to set the CPU affinity of a running process.

(Right Click on a Process in Task Mgr - And you can tell it what processors its allowed to run on.)

I've been tooling around the web and I have not seen any script examples (a few compiled tools)

Basically, I have a few apps that will not run correctly if they are allowed to run on both processors.

What I want to do is scan memory and when such a process is launched set the affinity.

Scanning the memory and taking action is well documented on this site.

What I dont know is any type of command that I could issue to set affinity.

If any of you wise folks know a way to do this, you would make my Christmas merry.

Grab a copy of Auto3Lib from my signature and try this:

#include <A3LLibrary.au3>

Global Const $PROCESS_ALL_ACCESS = 0x1F0FFF

Global $hProcess, $iProcessID, $aMask

; =================================================================================================
; Main
; =================================================================================================

; Get current process handle
$iProcessID = _API_GetCurrentProcessId()
$hProcess = _API_OpenProcess($PROCESS_ALL_ACCESS, False, $iProcessID)

; Get the current affinity information
$aMask = _API_GetProcessAffinityMask($hProcess)
ShowAffinity()

; Set this process to run only on processor #1
_API_SetProcessAffinityMask($hProcess, 1)
$aMask = _API_GetProcessAffinityMask($hProcess)
ShowAffinity()

; Close process handle
_API_CloseHandle($hProcess)

; =================================================================================================
; Show affinity mask array
; =================================================================================================
Func ShowAffinity()
  _Lib_ConsoleWrite("Result ......: " & $aMask[0])
  _Lib_ConsoleWrite("Process mask : " & $aMask[1])
  _Lib_ConsoleWrite("System mask .: " & $aMask[2])
  _Lib_ConsoleWrite("")
EndFunc

; =================================================================================================
; Description ..: Obtains a process affinity mask for the specified process and  the  system  affinity
;                 mask for the system.
; Parameters ...: $hProcess     - An open handle to the process whose affinity mask is desired.
; Return values : Array formatted as follows:
;                   $aMask[0] - True on success, otherwise False
;                   $aMask[1] - Process affinity mask
;                   $aMask[2] - System affinity mask
; Author .......: Paul Campbell (PaulIA)
; Notes ........: An affinity mask is a bit mask in which each bit represents a processor on which the
;                 threads of the process are allowed to run.  For example, if you pass a mask of 0x05,
;                 processors 1 and 3 are allowed to run.
; =================================================================================================
Func _API_GetProcessAffinityMask($hProcess)
  Local $rBuffer, $pProcess, $aResult, $pSystem, $aMask[3]

  $rBuffer  = DllStructCreate("int;int")
  $pProcess = DllStructGetPtr($rBuffer, 1)
  $pSystem  = DllStructGetPtr($rBuffer, 2)
  $aResult  = DllCall("Kernel32.dll", "int", "GetProcessAffinityMask", "hwnd", $hProcess, "ptr", _
                      $pProcess, "ptr", $pSystem)
  _Lib_Check("_API_SetProcessAffinityMask", ($aResult[0] = 0), 0, True)
  $aMask[0] = $aResult[0] <> 0
  $aMask[1] = DllStructGetData($rBuffer, 1)
  $aMask[2] = DllStructGetData($rBuffer, 2)
  Return $aMask
EndFunc

; =================================================================================================
; Description ..: Sets a processor affinity mask for the threads of a specified process.
; Parameters ...: $hProcess     - A handle to the process whose affinity mask the function sets.  This
;                   handle must have the PROCESS_SET_INFORMATION access right.
;                 $iMask        - Affinity mask
; Return values : True on success, False otherwise
; Author .......: Paul Campbell (PaulIA)
; Notes ........: An affinity mask is a bit mask in which each bit represents a processor on which the
;                 threads of the process are allowed to run.  For example, if you pass a mask of 0x05,
;                 processors 1 and 3 are allowed to run.
; =================================================================================================
Func _API_SetProcessAffinityMask($hProcess, $iMask)
  Local $iResult
  $iResult = DllCall("Kernel32.dll", "int", "SetProcessAffinityMask", "hwnd", $hProcess, "int", $iMask)
  _Lib_Check("_API_SetProcessAffinityMask", ($iResult[0] = 0), 0, True)
  Return $iResult[0] <> 0
EndFunc
Edited by PaulIA
Auto3Lib: A library of over 1200 functions for AutoIt
Link to comment
Share on other sites

simplicated version

;CPU0 and CPU1 selected - BinToDec(11)=3 result $affinity=3
;CPU0 selected - BinToDec(01) = 1 result $affinity=1
;CPU1 selected - BinToDec(10) = 2 result $affinity=2
;
;$action - 'Show'  return affinity state
;   - 'Set'   return affinity after modification
;
;Return = Process Mask / System Mask

MsgBox(0, '', ProcessAffinity('Set', 1))
MsgBox(0, '', ProcessAffinity('Set', 2))
MsgBox(0, '', ProcessAffinity('Set', 3))

Func ProcessAffinity($aaction, $affinity = '', $pid_process = @AutoItPID)
    Local $hprocess = DllCall("Kernel32.dll", "int", "OpenProcess", "int", 0x1F0FFF, "int", False, "int", $pid_process)
    Local $amask[3], $rbuffer, $psystem, $aresult, $pprocess, $iresult
    $rbuffer = DllStructCreate("int;int")
    $pprocess = DllStructGetPtr($rbuffer, 1)
    $psystem = DllStructGetPtr($rbuffer, 2)
    $aresult = DllCall("Kernel32.dll", "int", "GetProcessAffinityMask", "hwnd", $hprocess[0], "ptr", $pprocess, "ptr", $psystem)
    $amask[0] = $aresult[0] <> 0
    $amask[1] = DllStructGetData($rbuffer, 1)
    $amask[2] = DllStructGetData($rbuffer, 2)
    If $affinity - 0 = 0 Or $affinity > $amask[2] Then $affinity = $amask[2]
    Select
        Case $aaction = 'Show'
            DllCall("Kernel32.dll", "int", "CloseHandle", "int", $hprocess[0])
            Return $amask[1] & '/' & $amask[2]
        Case $aaction = 'Set'
            $iresult = DllCall("Kernel32.dll", "int", "SetProcessAffinityMask", "hwnd", $hprocess[0], "int", $affinity)
            $aresult = DllCall("Kernel32.dll", "int", "GetProcessAffinityMask", "hwnd", $hprocess[0], "ptr", $pprocess, "ptr", $psystem)
            $amask[1] = DllStructGetData($rbuffer, 1)
            $amask[2] = DllStructGetData($rbuffer, 2)
            DllCall("Kernel32.dll", "int", "CloseHandle", "int", $hprocess[0])
            Return $amask[1] & '/' & $amask[2]
    EndSelect
EndFunc   ;==>ProcessAffinity
Link to comment
Share on other sites

  • 2 years later...

Yes sorry it does. How would I go about setting it for a process other than the running AutoIT script though?

Guess I need to just use that and feed it the PID for the program rather than AutoITs own, but stuck as how to get that.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...