mirror of
https://github.com/martijnvanbrummelen/nwipe.git
synced 2026-02-20 13:42:14 +00:00
Temperature Thread
Due to significant delays in obtaining drive temperature from some drives especially SAS which was causing a noticeable freeze of a second or two or more in the GUI wipe status screen, being made worse the more drives that were being simultaneously wiped. The temperature update code was separated from the GUI code by placing the temperature update in it's own thread.
This commit is contained in:
10
src/gui.c
10
src/gui.c
@@ -827,7 +827,7 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
wprintw( main_window, "[%s] ", c[i + offset]->device_size_text );
|
||||
|
||||
/* Read the drive temperature values */
|
||||
nwipe_update_temperature( c[i + offset] );
|
||||
// nwipe_update_temperature( c[i + offset] );
|
||||
|
||||
/* print the temperature */
|
||||
wprintw_temperature( c[i + offset] );
|
||||
@@ -6716,10 +6716,10 @@ int compute_stats( void* ptr )
|
||||
nwipe_misc_thread_data->errors += c[i]->fsyncdata_errors;
|
||||
|
||||
/* Read the drive temperature values */
|
||||
if( nwipe_time_now > ( c[i]->temp1_time + 60 ) )
|
||||
{
|
||||
nwipe_update_temperature( c[i] );
|
||||
}
|
||||
// if( nwipe_time_now > ( c[i]->temp1_time + 60 ) )
|
||||
// {
|
||||
// nwipe_update_temperature( c[i] );
|
||||
// }
|
||||
|
||||
} /* for statistics */
|
||||
|
||||
|
||||
38
src/nwipe.c
38
src/nwipe.c
@@ -70,6 +70,7 @@ int main( int argc, char** argv )
|
||||
int any_threads_still_running; // used in wipe thread cancellation wait loop
|
||||
int thread_timeout_counter; // timeout thread cancellation after THREAD_CANCELLATION_TIMEOUT seconds
|
||||
pthread_t nwipe_gui_thread = 0; // The thread ID of the GUI thread.
|
||||
pthread_t nwipe_temperature_thread = 0; // The thread ID of the temperature update thread
|
||||
pthread_t nwipe_sigint_thread; // The thread ID of the sigint handler.
|
||||
|
||||
char modprobe_command[] = "modprobe %s";
|
||||
@@ -346,7 +347,7 @@ int main( int argc, char** argv )
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "hwmon: Device %s hwmon path = %s", c1[i]->device_name, c1[i]->temp1_path );
|
||||
}
|
||||
|
||||
nwipe_update_temperature( c1[i] );
|
||||
// nwipe_update_temperature( c1[i] );
|
||||
|
||||
/* Log the temperature crtical, highest, lowest and lowest critical temperature
|
||||
* limits to nwipes log file using the INFO catagory
|
||||
@@ -363,6 +364,15 @@ int main( int argc, char** argv )
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set up the data structures to pass the temperature thread the data it needs */
|
||||
nwipe_thread_data_ptr_t nwipe_temperature_thread_data;
|
||||
nwipe_temperature_thread_data.c = c1;
|
||||
nwipe_temperature_thread_data.nwipe_misc_thread_data = &nwipe_misc_thread_data;
|
||||
|
||||
/* Fork the temperature thread */
|
||||
errno = pthread_create(
|
||||
&nwipe_temperature_thread, NULL, nwipe_update_temperature_thread, &nwipe_temperature_thread_data );
|
||||
|
||||
/* Start the ncurses interface. */
|
||||
if( !nwipe_options.nogui )
|
||||
nwipe_gui_init();
|
||||
@@ -694,6 +704,32 @@ int main( int argc, char** argv )
|
||||
}
|
||||
}
|
||||
|
||||
/* Kill the temperature update thread */
|
||||
if( nwipe_temperature_thread )
|
||||
{
|
||||
if( nwipe_options.verbose )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_INFO, "Cancelling the temperature thread." );
|
||||
}
|
||||
|
||||
/* We don't want to use pthread_cancel as our temperature thread is aware of the control-c
|
||||
* signal and will exit itself we just join the temperature thread and wait for confirmation
|
||||
*/
|
||||
r = pthread_join( nwipe_temperature_thread, NULL );
|
||||
if( r != 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING,
|
||||
"main()>pthread_join():Error when waiting for temperature thread to cancel." );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nwipe_options.verbose )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_INFO, "temperature thread has been cancelled" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the gui. */
|
||||
if( !nwipe_options.nogui )
|
||||
{
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include "temperature.h"
|
||||
#include "miscellaneous.h"
|
||||
|
||||
extern int terminate_signal;
|
||||
|
||||
int nwipe_init_temperature( nwipe_context_t* c )
|
||||
{
|
||||
/* See header definition for description of function
|
||||
@@ -223,9 +225,63 @@ float timedifference_msec( struct timeval tv_start, struct timeval tv_end )
|
||||
return ( tv_end.tv_sec - tv_start.tv_sec ) * 1000.0f + ( tv_end.tv_usec - tv_start.tv_usec ) / 1000.0f;
|
||||
}
|
||||
|
||||
void* nwipe_update_temperature_thread( void* ptr )
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Set up the structs we will use for the data required. */
|
||||
nwipe_thread_data_ptr_t* nwipe_thread_data_ptr;
|
||||
nwipe_context_t** c;
|
||||
nwipe_misc_thread_data_t* nwipe_misc_thread_data;
|
||||
|
||||
/* Retrieve from the pointer passed to the function. */
|
||||
nwipe_thread_data_ptr = (nwipe_thread_data_ptr_t*) ptr;
|
||||
c = nwipe_thread_data_ptr->c;
|
||||
nwipe_misc_thread_data = nwipe_thread_data_ptr->nwipe_misc_thread_data;
|
||||
|
||||
/* mark start second of update */
|
||||
time_t nwipe_timemark = time( NULL );
|
||||
|
||||
/* update immediately on entry to thread */
|
||||
for( i = 0; i < nwipe_misc_thread_data->nwipe_enumerated; i++ )
|
||||
{
|
||||
nwipe_update_temperature( c[i] );
|
||||
if( terminate_signal == 1 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while( terminate_signal != 1 )
|
||||
{
|
||||
/* Update all drive/s but never repeat checking the
|
||||
* set of drive/s faster than once every 2 seconds */
|
||||
if( time( NULL ) > ( nwipe_timemark + 1 ) )
|
||||
{
|
||||
nwipe_timemark = time( NULL );
|
||||
|
||||
for( i = 0; i < nwipe_misc_thread_data->nwipe_enumerated; i++ )
|
||||
{
|
||||
nwipe_update_temperature( c[i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sleep( 1 );
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nwipe_update_temperature( nwipe_context_t* c )
|
||||
{
|
||||
/* For the given drive context obtain the path to it's hwmon temperature settings
|
||||
/* Warning !! This function should only be called by nwipe_update_temperature_thread()
|
||||
* Due to delays of upto 2 seconds with some drives, especially SAS in obtaining
|
||||
* temperatures while wiping, the delays being worse the more drives you are wiping. Updating
|
||||
* temperatures are performed within it's own thread so it doesn't cause momentary freezes
|
||||
* in the GUI interface.
|
||||
*
|
||||
* For the given drive context obtain the path to it's hwmon temperature settings
|
||||
* and read then write the temperature values back to the context. A numeric ascii to integer conversion is
|
||||
* performed. The temperaures should be updated no more frequently than every 60 seconds
|
||||
*/
|
||||
@@ -331,7 +387,10 @@ void nwipe_update_temperature( nwipe_context_t* c )
|
||||
|
||||
gettimeofday( &tv_end, 0 );
|
||||
delta_t = timedifference_msec( tv_start, tv_end );
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "get temperature for %s took %f ms", c->device_name, delta_t );
|
||||
if( nwipe_options.verbose )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "get temperature for %s took %f ms", c->device_name, delta_t );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ void nwipe_update_temperature( nwipe_context_t* );
|
||||
int nwipe_init_scsi_temperature( nwipe_context_t* );
|
||||
int nwipe_get_scsi_temperature( nwipe_context_t* );
|
||||
void nwipe_shut_scsi_temperature( nwipe_context_t* );
|
||||
void* nwipe_update_temperature_thread( void* ptr );
|
||||
|
||||
/**
|
||||
* This function is normally called only once. It's called after both the
|
||||
|
||||
Reference in New Issue
Block a user