@ -186,6 +186,7 @@ static int opt_queue;
int opt_vectors ;
int opt_vectors ;
int opt_worksize ;
int opt_worksize ;
int opt_scantime = 60 ;
int opt_scantime = 60 ;
int opt_bench_algo = - 1 ;
static const bool opt_time = true ;
static const bool opt_time = true ;
# if defined(WANT_X8664_SSE4) && defined(__SSE4_1__)
# if defined(WANT_X8664_SSE4) && defined(__SSE4_1__)
static enum sha256_algos opt_algo = ALGO_SSE4_64 ;
static enum sha256_algos opt_algo = ALGO_SSE4_64 ;
@ -587,8 +588,149 @@ static double bench_algo_stage2(
perror ( " close - failed to close read end of pipe for --algo auto " ) ;
perror ( " close - failed to close read end of pipe for --algo auto " ) ;
exit ( 1 ) ;
exit ( 1 ) ;
}
}
r = close ( pfd [ 1 ] ) ;
if ( r < 0 ) {
perror ( " close - failed to close read end of pipe for --algo auto " ) ;
exit ( 1 ) ;
}
# elif defined(WIN32)
// Get handle to current exe
HINSTANCE module = GetModuleHandle ( 0 ) ;
if ( ! module ) {
applog ( LOG_ERR , " failed to retrieve module handle " ) ;
exit ( 1 ) ;
}
// Create a unique name
char unique_name [ 32 ] ;
snprintf (
unique_name ,
sizeof ( unique_name ) - 1 ,
" cgminer-%p " ,
( void * ) module
) ;
// Create and init a chunked of shared memory
HANDLE map_handle = CreateFileMapping (
INVALID_HANDLE_VALUE , // use paging file
NULL , // default security attributes
PAGE_READWRITE , // read/write access
0 , // size: high 32-bits
4096 , // size: low 32-bits
unique_name // name of map object
) ;
if ( NULL = = map_handle ) {
applog ( LOG_ERR , " could not create shared memory " ) ;
exit ( 1 ) ;
}
void * shared_mem = MapViewOfFile (
map_handle , // object to map view of
FILE_MAP_WRITE , // read/write access
0 , // high offset: map from
0 , // low offset: beginning
0 // default: map entire file
) ;
if ( NULL = = shared_mem ) {
applog ( LOG_ERR , " could not map shared memory " ) ;
exit ( 1 ) ;
}
SetEnvironmentVariable ( " CGMINER_SHARED_MEM " , unique_name ) ;
CopyMemory ( shared_mem , & rate , sizeof ( rate ) ) ;
// Get path to current exe
char cmd_line [ 256 + MAX_PATH ] ;
const size_t n = sizeof ( cmd_line ) - 200 ;
DWORD size = GetModuleFileName ( module , cmd_line , n ) ;
if ( 0 = = size ) {
applog ( LOG_ERR , " failed to retrieve module path " ) ;
exit ( 1 ) ;
}
// Construct new command line based on that
char * p = strlen ( cmd_line ) + cmd_line ;
sprintf ( p , " --bench-algo %d " , algo ) ;
SetEnvironmentVariable ( " CGMINER_BENCH_ALGO " , " 1 " ) ;
// Launch a debug copy of cgminer
STARTUPINFO startup_info ;
PROCESS_INFORMATION process_info ;
ZeroMemory ( & startup_info , sizeof ( startup_info ) ) ;
ZeroMemory ( & process_info , sizeof ( process_info ) ) ;
startup_info . cb = sizeof ( startup_info ) ;
BOOL ok = CreateProcess (
NULL , // No module name (use command line)
cmd_line , // Command line
NULL , // Process handle not inheritable
NULL , // Thread handle not inheritable
FALSE , // Set handle inheritance to FALSE
DEBUG_ONLY_THIS_PROCESS , // We're going to debug the child
NULL , // Use parent's environment block
NULL , // Use parent's starting directory
& startup_info , // Pointer to STARTUPINFO structure
& process_info // Pointer to PROCESS_INFORMATION structure
) ;
if ( ! ok ) {
applog ( LOG_ERR , " CreateProcess failed with error %d \n " , GetLastError ( ) ) ;
exit ( 1 ) ;
}
// Debug the child (only clean way to catch exceptions)
while ( 1 ) {
// Wait for child to do something
DEBUG_EVENT debug_event ;
ZeroMemory ( & debug_event , sizeof ( debug_event ) ) ;
BOOL ok = WaitForDebugEvent ( & debug_event , 60 * 1000 ) ;
if ( ! ok )
break ;
// Decide if event is "normal"
int go_on =
CREATE_PROCESS_DEBUG_EVENT = = debug_event . dwDebugEventCode | |
CREATE_THREAD_DEBUG_EVENT = = debug_event . dwDebugEventCode | |
EXIT_THREAD_DEBUG_EVENT = = debug_event . dwDebugEventCode | |
EXCEPTION_DEBUG_EVENT = = debug_event . dwDebugEventCode | |
LOAD_DLL_DEBUG_EVENT = = debug_event . dwDebugEventCode | |
OUTPUT_DEBUG_STRING_EVENT = = debug_event . dwDebugEventCode | |
UNLOAD_DLL_DEBUG_EVENT = = debug_event . dwDebugEventCode ;
if ( ! go_on )
break ;
// Some exceptions are also "normal", apparently.
if ( EXCEPTION_DEBUG_EVENT = = debug_event . dwDebugEventCode ) {
int go_on =
EXCEPTION_BREAKPOINT = = debug_event . u . Exception . ExceptionRecord . ExceptionCode ;
if ( ! go_on )
break ;
}
// If nothing unexpected happened, let child proceed
ContinueDebugEvent (
debug_event . dwProcessId ,
debug_event . dwThreadId ,
DBG_CONTINUE
) ;
}
// Clean up child process
TerminateProcess ( process_info . hProcess , 1 ) ;
CloseHandle ( process_info . hProcess ) ;
CloseHandle ( process_info . hThread ) ;
// Reap return value and cleanup
CopyMemory ( & rate , shared_mem , sizeof ( rate ) ) ;
( void ) UnmapViewOfFile ( shared_mem ) ;
( void ) CloseHandle ( map_handle ) ;
# else
# else
// Not on linux, just run the risk of an illegal instruction
// Not linux, not unix, not WIN32 ... do our best
rate = bench_algo_stage3 ( algo ) ;
rate = bench_algo_stage3 ( algo ) ;
# endif // defined(unix)
# endif // defined(unix)
@ -4226,6 +4368,14 @@ int main (int argc, char *argv[])
gettimeofday ( & total_tv_end , NULL ) ;
gettimeofday ( & total_tv_end , NULL ) ;
get_datestamp ( datestamp , & total_tv_start ) ;
get_datestamp ( datestamp , & total_tv_start ) ;
// Hack to make cgminer silent when called recursively on WIN32
int skip_to_bench = 0 ;
# if defined(WIN32)
char buf [ 32 ] ;
if ( GetEnvironmentVariable ( " CGMINER_BENCH_ALGO " , buf , 16 ) )
skip_to_bench = 1 ;
# endif // defined(WIN32)
for ( i = 0 ; i < 36 ; i + + )
for ( i = 0 ; i < 36 ; i + + )
strcat ( current_block , " 0 " ) ;
strcat ( current_block , " 0 " ) ;
current_hash = calloc ( sizeof ( current_hash ) , 1 ) ;
current_hash = calloc ( sizeof ( current_hash ) , 1 ) ;
@ -4262,6 +4412,7 @@ int main (int argc, char *argv[])
opt_n_threads = num_processors ;
opt_n_threads = num_processors ;
# ifdef HAVE_OPENCL
# ifdef HAVE_OPENCL
if ( ! skip_to_bench ) {
for ( i = 0 ; i < 16 ; i + + )
for ( i = 0 ; i < 16 ; i + + )
gpu_devices [ i ] = false ;
gpu_devices [ i ] = false ;
nDevs = clDevicesNum ( ) ;
nDevs = clDevicesNum ( ) ;
@ -4269,6 +4420,7 @@ int main (int argc, char *argv[])
applog ( LOG_ERR , " clDevicesNum returned error, none usable " ) ;
applog ( LOG_ERR , " clDevicesNum returned error, none usable " ) ;
nDevs = 0 ;
nDevs = 0 ;
}
}
}
# endif
# endif
if ( nDevs )
if ( nDevs )
opt_n_threads = 0 ;
opt_n_threads = 0 ;
@ -4285,6 +4437,42 @@ int main (int argc, char *argv[])
if ( argc ! = 1 )
if ( argc ! = 1 )
quit ( 1 , " Unexpected extra commandline arguments " ) ;
quit ( 1 , " Unexpected extra commandline arguments " ) ;
if ( 0 < = opt_bench_algo ) {
double rate = bench_algo_stage3 ( opt_bench_algo ) ;
if ( ! skip_to_bench ) {
printf ( " %.5f (%s) \n " , rate , algo_names [ opt_bench_algo ] ) ;
} else {
// Write result to shared memory for parent
# if defined(WIN32)
char unique_name [ 64 ] ;
if ( GetEnvironmentVariable ( " CGMINER_SHARED_MEM " , unique_name , 32 ) ) {
HANDLE map_handle = CreateFileMapping (
INVALID_HANDLE_VALUE , // use paging file
NULL , // default security attributes
PAGE_READWRITE , // read/write access
0 , // size: high 32-bits
4096 , // size: low 32-bits
unique_name // name of map object
) ;
if ( NULL ! = map_handle ) {
void * shared_mem = MapViewOfFile (
map_handle , // object to map view of
FILE_MAP_WRITE , // read/write access
0 , // high offset: map from
0 , // low offset: beginning
0 // default: map entire file
) ;
if ( NULL ! = shared_mem )
CopyMemory ( shared_mem , & rate , sizeof ( rate ) ) ;
( void ) UnmapViewOfFile ( shared_mem ) ;
}
( void ) CloseHandle ( map_handle ) ;
}
# endif
}
exit ( 0 ) ;
}
if ( opt_kernel ) {
if ( opt_kernel ) {
if ( strcmp ( opt_kernel , " poclbm " ) & & strcmp ( opt_kernel , " phatk " ) )
if ( strcmp ( opt_kernel , " poclbm " ) & & strcmp ( opt_kernel , " phatk " ) )
quit ( 1 , " Invalid kernel name specified - must be poclbm or phatk " ) ;
quit ( 1 , " Invalid kernel name specified - must be poclbm or phatk " ) ;