You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.5 KiB

/*
* Copyright 2002-2019 Intel Corporation.
*
* This software is provided to you as Sample Source Code as defined in the accompanying
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
* section 1.L.
*
* This software and the related documents are provided as is, with no express or implied
* warranties, other than those that are expressly stated in the License.
*/
/*
* Utility application that creates threads on Windows().
*/
#include <cstdlib>
#include <cstring>
#include <climits>
#include <iostream>
#include <windows.h>
#include "types.h"
extern "C" __declspec(dllexport) void GlobalFunction();
typedef void (*FUNPTR)();
static bool PrintAddress = false;
static unsigned NumThreads;
static bool ParseArgs(int, char **);
static DWORD WINAPI Worker(LPVOID);
int main(int argc, char **argv)
{
if (!ParseArgs(argc, argv))
return 1;
if (PrintAddress)
{
PTRINT fp = reinterpret_cast<PTRINT>(GlobalFunction);
std::cout << "0x" << std::hex << std::noshowbase << fp << "\n";
return 0;
}
HANDLE *workers = new HANDLE[NumThreads];
for (unsigned i = 0; i < NumThreads; i++)
{
workers[i] = CreateThread(0, 0, Worker, 0, 0, 0);
if (!workers[i])
{
std::cerr << "Unable to create thread\n";
return 1;
}
}
for (unsigned i = 0; i < NumThreads; i++)
WaitForSingleObject(workers[i], INFINITE);
delete workers;
return 0;
}
static bool ParseArgs(int argc, char **argv)
{
if (argc == 3 && std::strcmp(argv[1], "-threads") == 0)
{
char *end;
unsigned long val = std::strtoul(argv[2], &end, 10);
if (*(argv[2]) == '\0' || val > UINT_MAX || val == 0 || *end != '\0')
{
std::cerr << "Invalid parameter to -threads: " << argv[2] << std::endl;
return false;
}
NumThreads = static_cast<unsigned>(val);
return true;
}
else if (argc == 2 && std::strcmp(argv[1], "-print-address") == 0)
{
PrintAddress = true;
return true;
}
std::cerr << "Usage: thread-windows -threads <number-threads>\n";
std::cerr << " thread-windows -print-address\n";
return false;
}
static DWORD WINAPI Worker(LPVOID)
{
// Call through a volatile pointer to prevent the compiler from in-lining.
//
volatile FUNPTR fp = GlobalFunction;
fp();
return 0;
}
extern "C" void GlobalFunction()
{
/*
* This is a good place to put Pin instrumentation or to set a breakpoint.
*/
}