Sign in to follow this  
Followers 0
zenmaster

Setting CPU Affinity

12 posts in this topic

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.

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

Thx!

Im gonna give this a whirl today.

You guys need a PayPal Link in your tags :P

You guys are AWESOME!

Share this post


Link to post
Share on other sites

Thx!

Im gonna give this a whirl today.

You guys need a PayPal Link in your tags :P

You guys are AWESOME!

You're welcome. Happy holidays.

Auto3Lib: A library of over 1200 functions for AutoIt

Share this post


Link to post
Share on other sites

You're welcome. Happy holidays.

Just a Thanks again. :P

I just had a chance to fiddle around with the posted code and it does just what I need.

PS - Thanks for your Add-On Library! I just found them. More Cool Stuff to examine when I have time!

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Apologies for the mega thread bump here, but does anyone know how to do this in the current (or Beta) AutoIT versions since A3LLibrary no longer works?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

I searched and I found this, do the functions there work ?

http://www.autoitscript.com/forum/index.php?showtopic=59277&st=0&p=446503&hl=CPU%20Affinity&fromsearch=1&#entry446503

Share this post


Link to post
Share on other sites

Sorted thanks :)

Share this post


Link to post
Share on other sites

Look up

_WinAPI_GetProcessAffinityMask()

_WinAPI_SetProcessAffinityMask()

in the UDF help-file. Also this example thread contains more info on how to use these functions.

Share this post


Link to post
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
Sign in to follow this  
Followers 0