Need to produce a stable 10mSec interrupt - windows

I have an application that I need to run at a 10mSec rate (100hz) on a Windows 7/32 bit computer (that will also be running other applications at the same time). This interrupt can have some minimally late (100uSec) responses, but must not drift over a prolonged time. I have a program where I have loaded and used the NtSetTimerResolution to set the timers to 10msec resolution, and then created a timer using the CreateTimerQueue/CreateTimereQueueTimer functions with a callback routine that toggles a GPIO pin (for the time being) - this produces the expected square wave, so long as I am not doing anything else with the system. When I start a couple of other processes, the accuracy of my square wave goes out the window. Is there any way to get a higher priority level on the timer interrupt (or is there another timer that I can use) that will produce a more stable output (perhaps the SMI)? My code is below, and is built using the x86 checked build environment of the Windows DDK, and run from a command shell with administrator rights:
/*
Abstract:
Simple console test app for a 10mSec timer interrupt service
Enviroment:
Administrator Mode
*/
/* INCLUDES */
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <strsafe.h>
#include <stdlib.h>
#include <stdio.h>
#include <winsock2.h>
#include <mswsock.h>
#pragma warning(disable:4127) // condition expression is constant
FARPROC pNtQueryTimerResolution;
FARPROC pNtSetTimerResolution;
static HANDLE NTDLLModuleHandle;
static HINSTANCE hInpOutDll;
typedef void ( __stdcall *lpOut32 )( short , short );
typedef short ( __stdcall *lpInp32 )( short );
typedef BOOL ( __stdcall *lpIsInpOutDriverOpen )( void );
//Some global function pointers (messy but fine for an example)
lpOut32 gfpOut32;
lpInp32 gfpInp32;
lpIsInpOutDriverOpen gfpIsInpOutDriverOpen;
void CALLBACK TimerProc(void* lpParameter,
BOOLEAN TimerOrWaitFired);
// MAIN
VOID __cdecl main( void )
{
ULONG ulMinRes = 0;
ULONG ulMaxRes = 0;
ULONG ulCurRes = 0;
HANDLE phNewQueue;
HANDLE phNewTimer;
phNewQueue = CreateTimerQueue( );
NTDLLModuleHandle = LoadLibrary( "NTDLL.DLL" );
if( NULL == NTDLLModuleHandle )
{
return;
}
// Get the function pointers,
pNtQueryTimerResolution = GetProcAddress( NTDLLModuleHandle, "NtQueryTimerResolution" );
pNtSetTimerResolution = GetProcAddress( NTDLLModuleHandle, "NtSetTimerResolution" );
if( ( pNtQueryTimerResolution == NULL ) || ( pNtSetTimerResolution == NULL ) )
{
printf( "unable to link to ddl\n\n\n\n\n\n" );
return;
}
pNtQueryTimerResolution( &ulMinRes, &ulMaxRes, &ulCurRes );
printf( "MMR: %d %d %d\n", ulMinRes, ulMaxRes, ulCurRes );
ulMaxRes = 100000;
pNtSetTimerResolution( ulMaxRes, TRUE, &ulCurRes );
pNtQueryTimerResolution( &ulMinRes, &ulMaxRes, &ulCurRes );
printf( "MMR: %d %d %d\n", ulMinRes, ulMaxRes, ulCurRes );
//Dynamically load the DLL at runtime (not linked at compile time)
hInpOutDll = LoadLibrary( "InpOut32.DLL" );
if( hInpOutDll != NULL )
{
gfpOut32 = ( lpOut32 )GetProcAddress( hInpOutDll, "Out32" );
gfpInp32 = ( lpInp32 )GetProcAddress( hInpOutDll, "Inp32" );
gfpIsInpOutDriverOpen
= ( lpIsInpOutDriverOpen )GetProcAddress( hInpOutDll, "IsInpOutDriverOpen" );
if( gfpIsInpOutDriverOpen( ) )
{
gfpOut32( 0xA01, 0x00 );
}
else
{
printf( "unable to create timer system\n\n\n\n\n\n" );
return;
}
}
CreateTimerQueueTimer( &phNewTimer, phNewQueue, TimerProc, NULL, 0, 10,
WT_EXECUTEINTIMERTHREAD );
do
{
Sleep( 1 );
} while( TRUE );
}
void CALLBACK TimerProc(void* lpParameter,
BOOLEAN TimerOrWaitFired)
{
WORD wData;
UNREFERENCED_PARAMETER ( lpParameter );
UNREFERENCED_PARAMETER ( TimerOrWaitFired );
wData = gfpInp32( 0xA00 );
wData++;
gfpOut32( 0xA00, wData );
}

You can use SetThreadPriority to give priority to the critical thread. In this case, you'll probably need to create a thread explicitly and use CreateWaitableTimerEx, SetWaitableTimerEx, and WaitForSingleObjectEx instead of CreateTimerQueueTimer. Make sure the critical thread never spends too long executing between waits, or Windows may stop working properly.
This may not be enough, if the maximum lag is 100 microseconds. You might need to set your process priority class to REALTIME_PRIORITY_CLASS using the SetPriorityClass function, but make sure your program never holds the CPU for long or Windows will stop working properly. In particular, if your program hangs, the entire OS will hang; in this situation, there is no way to stop the program short of turning the power off.
Even this may not be enough. Windows is not a real-time operating system, and it may not be possible to get it do what you're asking for.

My experience with Windows and milli second is that it is not reliable.
I measured the Sleep api with an Oscilloscope via the Nusbio device.
And Sleep(0) is different from not calling the method at all.
Sleep(5) and Sleep(15) give inconsistent result sometime some time the wait is the same.
If you want this accuracy you need a micro controller, that can talk to your Windows application.

Related

Windows memory metric to detect memory leak

We have large old legacy server code running as a 64bit windows service.
The service has a memory leak which, at the moment, we do not have the resources to fix.
As the service is resilient to restart, a temporary terrible 'solution' we want is to detect when the service's memory exceeded, e.g., 5GB, and exit the service (which has auto restart for such cases).
My question is which metric should I go for? Is using GlobalMemoryStatusEx to get
MEMORYSTATUSEX.ullTotalVirtual- MEMORYSTATUSEX.ullAvailVirtual right?
GlobalMemoryStatusEx is wrong. You do not want to fill up the machine memory until 5 GB are left in total.
You need GetProcessMemoryInfo.
BOOL WINAPI GetProcessMemoryInfo(
__in HANDLE Process,
__out PPROCESS_MEMORY_COUNTERS ppsmemCounters,
__in DWORD cb
);
From an example using GetProcessMemoryInfo:
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1
void PrintMemoryInfo( DWORD processID )
{
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
// Print the process identifier.
printf( "\nProcess ID: %u\n", processID );
// Print information about the memory usage of the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return;
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );
}
CloseHandle( hProcess );
}
int main( void )
{
// Get the list of process identifiers.
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
{
return 1;
}
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the memory usage for each process
for ( i = 0; i < cProcesses; i++ )
{
PrintMemoryInfo( aProcesses[i] );
}
return 0;
}
Although unintuitive you need to read PagefileUsage which gets you the committed memory which was allocated by your process. WorkingSetSize is unreliable because if the machine gets tight on memory the OS will write all data to the page file. That can cause WorkingSetSize to be small (e.g. 100 MB) but in reality you leaked already 20 GB of memory. This would result in a saw tooth pattern in memory consumption until the page file is full. Working set is only the actively used memory which might hide the multi GB memory leak if the machine is under memory pressure.

Disable core dump for SIGHUP signal

I'm trying to disable core dumps being generated for individual signals in my application.
ulimit -c 0 wont work in my case, since it needs to be executed before application start and will completely disable core dumps for all signals.
Is it possible to make such an exception for a single signal or at least disable core dump generation for a certain amount of time (eg. during sending the SIGHUP signal)?
#include <setjmp.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <unistd.h>
static sigjmp_buf sigjmp;
static void sighup_handler(int signo) {
siglongjmp(&sigjmp, signo);
}
int main(int argc, char **argv) {
struct sigaction sighup_action = {
.sa_handler = &sighup_handler,
.sa_flags = SA_RESETHAND,
};
sigset_t sigset;
int signo;
sigemptyset(&sighup_action.sa_mask);
sigaddset(&sighup_action.sa_mask, SIGHUP);
sigprocmask(SIG_BLOCK, &sighup_action.sa_mask, &sigset);
sigaction(SIGHUP, &sighup_action, NULL);
signo = sigsetjmp(&sigjmp, 1);
if (signo) {
struct rlimit rl = { .rlim_cur = 0, .rlim_max = 0 };
setrlimit(RLIMIT_CORE, &rl);
sigprocmask(SIG_SETMASK, &sigset, NULL);
kill(getpid(), signo);
abort(); /* just in case */
_exit(128 | signo);
}
sigprocmask(SIG_SETMASK, &sigset, NULL);
pause(); /* or whatever the rest of your program does */
}
You can install a signal handler which sets RLIMIT_CORE to 0, then proceeds with the default signal action. If you use SA_RESETHAND, the default signal handler is automatically reinstalled right before the signal handler is run. However, setrlimit is not async-signal-safe, so we should not call it from inside a signal handler, hence using siglongjmp to return to normal code and performing it there.
Just add an empty signal handler for SIGHUP, or ignore it like this:
signal(SIGHUP, SIG_IGN);

ABM_GETTASKBARPOS window handle [duplicate]

Is there a WinAPI function to retrieve a handle to the Task Bar?
The purpose is to determine the Task Bar docking setting (ABE_LEFT, ABE_RIGHT, ABE_BOTTOM, ABE_TOP). The function SHAppBarMessage requires the taskbar handle to retrieve the docking information. Unless there is another way to determine the task bar docking setting without needing the handle?
I'm aware of this method which works ok but I am not sure it works on all Windows versions:
HWND taskBar = FindWindow("Shell_TrayWnd", NULL);
That appears to be a documentation bug. You don't need to provide a window handle in the APPBARDATA structure for the ABM_GETTASKBARPOS when calling SHAppBarMessage1).
The following code properly returns the location of the taskbar (tested on Windows 10 x64):
#include <shellapi.h>
#pragma comment(lib, "Shell32.lib")
#include <stdexcept>
RECT GetTaskbarPos() {
APPBARDATA abd = { 0 };
abd.cbSize = sizeof( abd );
if ( !::SHAppBarMessage( ABM_GETTASKBARPOS, &abd ) ) {
throw std::runtime_error( "SHAppBarMessage failed." );
}
return abd.rc;
}
Update: The question was really asking for the docking enumeration value. That is returned as well:
#include <shellapi.h>
#pragma comment(lib, "Shell32.lib")
#include <stdexcept>
UINT GetTaskbarDockingEdge() {
APPBARDATA abd = { 0 };
abd.cbSize = sizeof( abd );
if ( !::SHAppBarMessage( ABM_GETTASKBARPOS, &abd ) ) {
throw std::runtime_error( "SHAppBarMessage failed." );
}
return abd.uEdge;
}
1) It would be awkward if you needed the well hidden window handle of the taskbar to send this message. If you had the window handle already, you could simply call GetWindowRect instead.

Just want an executable to enumarate processes and enumarate loaded .dlls

I want to make like a function with an argument stdvector::<std::string> of process names and std::vector<std::string> of .dll's to find in them and feed it into a function and get like PROCESSENTRY32 info std::vector<PROCESSENTRY32> returned of anything that matches the names.
You can google but won't find much as I have thanks for helping new to winapi but not to figuring things out
There is a perfect example to do exactly what you want on MSDN here. The relevant code is copied below. As the introduction to the sample says
To determine which processes have loaded a particular DLL, you must enumerate the modules for each process. The following sample code uses the EnumProcessModules function to enumerate the modules of current processes in the system.
Now the sample code
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1
int PrintModules( DWORD processID )
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
// Print the process identifier.
printf( "\nProcess ID: %u\n", processID );
// Get a handle to the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return 1;
// Get a list of all the modules in this process.
if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
TCHAR szModName[MAX_PATH];
// Get the full path to the module's file.
if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
sizeof(szModName) / sizeof(TCHAR)))
{
// Print the module name and handle value.
_tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
}
}
}
// Release the handle to the process.
CloseHandle( hProcess );
return 0;
}
int main( void )
{
DWORD aProcesses[1024];
DWORD cbNeeded;
DWORD cProcesses;
unsigned int i;
// Get the list of process identifiers.
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return 1;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the names of the modules for each process.
for ( i = 0; i < cProcesses; i++ )
{
PrintModules( aProcesses[i] );
}
return 0;
}
The only change you will need to make is to push-back the module names of interest to your std::vector<std::string> beforehand and then search that vector with the enumerated module names instead of printing them.

Create MPI processes on the fly with fork?

If I use MPI, I have a number of processes specified when I run the main program. However I would like to start with one process and dynamically decide at runtime if and when I need more, to fork more processes off. Is that or something similar possible?
Otherwise I would have to reinvent MPI which I would very much like to avoid.
It is not possible to use fork() as the child process will not be able to use MPI functions. There is a simple mechanism in MPI to create dynamically new processes. You must use the MPI_Comm_spawn function or the MPI_Comm_spawn_mutliple
OpenMPI doc: http://www.open-mpi.org/doc/v1.4/man3/MPI_Comm_spawn.3.php
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#define NUM_SPAWNS 2
int main( int argc, char *argv[] )
{
int np = NUM_SPAWNS;
int errcodes[NUM_SPAWNS];
MPI_Comm parentcomm, intercomm;
MPI_Init( &argc, &argv );
MPI_Comm_get_parent( &parentcomm );
if (parentcomm == MPI_COMM_NULL) {
MPI_Comm_spawn( "spawn_example", MPI_ARGV_NULL, np, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm, errcodes );
printf("I'm the parent.\n");
} else {
printf("I'm the spawned.\n");
}
fflush(stdout);
MPI_Finalize();
return 0;
}

Resources