I need to control the priorities of various longrunning jobs - some of which kick off threads with nonstandard priority settings which cause some to hog the cpu, others to get none - this Perl utility is intended to keep them running at uniform settings.
I have been given the source of a C program that adjusts thread priority. The relevant code :-
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
THREADENTRY32 te32 = {0};
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return (FALSE);
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32);
// Get first process information
Thread32First(hProcessSnap, &te32)
// get the thread priority
HANDLE hThread;
hThread = OpenThread(THREAD_SET_INFORMATION|THREAD_QUERY_INFORMATI
+ON, FALSE, te32.th32ThreadID);
// set new priority class
if (SetThreadPriority(hThread, threadPriority) != TRUE)
{
cerr << "SetThreadPriority() ";
printError();
}
CloseHandle(hThread);
I can't see why the last parameter to CreateToolhelp32Snapshot is 0, as that means current process Id, in this case Perl - I would have thought this should be PID of the process whose thread I want to change. ??
I converted the above to Perl calls to Win32::API as follows :-
$pid = 952;
# 952 is a running job pid
use threads;
use threads::shared;
use Win32::API;
Win32::API->Import( 'Kernel32', q[ DWORD GetLastError( ) ] );
Win32::API->Import( 'Kernel32',
q[ HANDLE CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32Pr
+ocessID ) ] );
$hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, $pid);
+
print "hProcessSnap = $hProcessSnap \n";
580 output, presumably an open handle to the snapshot
Win32::API->Import( 'Kernel32',
q[ BOOL Thread32First( HANDLE hSnapshot, THREADENTRY32 lpte)] );
$retcode = GetLastError();
print "import threadfirst error was $retcode \n";
WARNING Unknown parameter type THREADENTRY32 ??
0 output, import OK ??
The following is my attempt to define the C THREADENTRY32 structure - not to sure about this.
# typedef for THREADENTRY32
typedef Win32::API::Struct AA => qw{
DWORD dwSize;
DWORD cntUsage;
DWORD th32ThreadID;
DWORD th32OwnerProcessID;
LONG tpBasePri;
LONG tpDeltaPri;
DWORD dwFlags;
};
my $Point = Win32::API::Struct->new( AA );
$Point->{dwSize} = 24;
##$size=Win32::API::Struct->sizeof(AA);
##always returns 0. ??
Thread32First($hProcessSnap, LPAA);
$retcode = GetLastError();
print "threadfirst error was $retcode \n";
error code 24 is output, indicating incorrect command length.
Acording to the Win32::API::Struct Pod, LPAA is a pointer to AA generated automatically by Win32::API::Struct, but I don't think it's getting a correct address. Any Perl way to get the address of AA to pass to Thread32First ?
The rest of the Perl code will be :-
Win32::API->Import( 'Kernel32', q[HANDLE OpenThread( DWORD dwDesiredAc
+cess, BOOL bInheritHandle, DWORD dwThreadId) ] );
$hThread = OpenThread(THREAD_SET_INFORMATION|THREAD_QUERY_INFORMATION,
FALSE, $point->{th32ThreadID});
Win32::API->Import( 'Kernel32', q[ BOOL SetThreadPriority( HANDLE hThr
+ead, int nPriority ) ] );
SetThreadPriority( hThread, $threadpriority );
But I'm stuck at Thread32First |