Added GUI scheduling parameters to Qt timing config window

This commit is contained in:
Matthew Budd 2020-11-27 23:42:32 -05:00
parent e154b38327
commit d5d6b32787
4 changed files with 366 additions and 56 deletions

View File

@ -1800,81 +1800,226 @@ void consoleWin_t::aboutQt(void)
return;
}
void consoleWin_t::setPriority( QThread::Priority priority_req )
int consoleWin_t::setNicePriority( int value )
{
int ret = 0;
#if defined(__linux__)
if ( value < -20 )
{
value = -20;
}
else if ( value > 19 )
{
value = 19;
}
if ( ::setpriority( PRIO_PROCESS, getpid(), value ) )
{
perror("Emulator thread setpriority error: ");
ret = -1;
}
#elif defined(__APPLE__)
if ( value < -20 )
{
value = -20;
}
else if ( value > 20 )
{
value = 20;
}
if ( ::setpriority( PRIO_PROCESS, getpid(), value ) )
{
perror("Emulator thread setpriority error: ");
ret = -1;
}
#endif
return ret;
}
int consoleWin_t::getNicePriority(void)
{
return ::getpriority( PRIO_PROCESS, getpid() );
}
int consoleWin_t::getMinSchedPriority(void)
{
int policy, prio;
if ( getSchedParam( policy, prio ) )
{
return 0;
}
return sched_get_priority_min( policy );
}
int consoleWin_t::getMaxSchedPriority(void)
{
int policy, prio;
if ( getSchedParam( policy, prio ) )
{
return 0;
}
return sched_get_priority_max( policy );
}
int consoleWin_t::getSchedParam( int &policy, int &priority )
{
int ret = 0;
#if defined(__linux__)
struct sched_param p;
policy = sched_getscheduler( getpid() );
if ( sched_getparam( getpid(), &p ) )
{
ret = -1;
}
priority = p.sched_priority;
#elif defined(__APPLE__)
struct sched_param p;
if ( pthread_getschedparam( pself, &policy, &p ) )
{
perror("GUI thread pthread_getschedparam error: ");
ret = -1;
}
#endif
return ret;
}
int consoleWin_t::setSchedParam( int policy, int priority )
{
int ret = 0;
#if defined(__linux__)
struct sched_param p;
int minPrio, maxPrio;
minPrio = sched_get_priority_min( SCHED_FIFO );
maxPrio = sched_get_priority_max( SCHED_FIFO );
minPrio = sched_get_priority_min( policy );
maxPrio = sched_get_priority_max( policy );
p.sched_priority = maxPrio;
if ( ::setpriority( PRIO_PROCESS, getpid(), -20 ) )
if ( priority < minPrio )
{
perror("Qt Window thread setpriority error: ");
priority = minPrio;
}
printf("sched_getscheduler(): %i \n", sched_getscheduler( getpid() ) );
printf("sched_get_priority_min(SCHED_FIFO): %i \n", minPrio );
printf("sched_get_priority_max(SCHED_FIFO): %i \n", maxPrio );
printf("setpriority(): %i \n", ::getpriority( PRIO_PROCESS, getpid() ) );
if ( sched_setscheduler( getpid(), SCHED_FIFO, &p ) )
else if ( priority > maxPrio )
{
perror("Qt Window thread sched_setscheduler error:");
priority = maxPrio;
}
printf("sched_getscheduler(): %i \n", sched_getscheduler( getpid() ) );
p.sched_priority = priority;
if ( sched_setscheduler( getpid(), policy, &p ) )
{
perror("GUI thread sched_setscheduler error");
ret = -1;
}
#elif defined(__APPLE__)
struct sched_param p;
int oldPolicy, newPolicy, minPrio, maxPrio;
QThread *qself;
pthread_t self;
int minPrio, maxPrio;
qself = QThread::currentThread();
minPrio = sched_get_priority_min( policy );
maxPrio = sched_get_priority_max( policy );
self = pthread_self();
newPolicy = SCHED_FIFO;
printf("QThreadID: %p \n", QThread::currentThreadId() );
printf("PThreadID: %p \n", self );
minPrio = sched_get_priority_min( SCHED_FIFO );
maxPrio = sched_get_priority_max( SCHED_FIFO );
pthread_getschedparam( self, &oldPolicy, &p );
printf("GUI pthread_getschedparam(): %i, %i \n", oldPolicy, p.sched_priority );
qself->setPriority( priority_req );
p.sched_priority = maxPrio;
//if ( ::pthread_setschedparam( self, newPolicy, &p ) != 0 )
//{
//perror("GUI thread pthread_setschedparam error: ");
//}
pthread_getschedparam( self, &oldPolicy, &p );
printf("GUI pthread_getschedparam(): %i, %i \n", oldPolicy, p.sched_priority );
if ( ::setpriority( PRIO_PROCESS, getpid(), -20 ) )
if ( priority < minPrio )
{
perror("GUI thread setpriority error: ");
priority = minPrio;
}
printf("GUI Thread setpriority(): %i \n", ::getpriority( PRIO_PROCESS, getpid() ) );
#else
QThread *mainThread;
else if ( priority > maxPrio )
{
priority = maxPrio;
}
p.sched_priority = priority;
mainThread = QThread::currentThread();
mainThread->setPriority( priority_req );
if ( ::pthread_setschedparam( pself, policy, &p ) != 0 )
{
perror("GUI thread pthread_setschedparam error: ");
}
#endif
return ret;
}
//void consoleWin_t::setPriority( QThread::Priority priority_req )
//{
//#if defined(__linux__)
// struct sched_param p;
// int minPrio, maxPrio;
//
// minPrio = sched_get_priority_min( SCHED_FIFO );
// maxPrio = sched_get_priority_max( SCHED_FIFO );
//
// p.sched_priority = maxPrio;
//
// if ( ::setpriority( PRIO_PROCESS, getpid(), -20 ) )
// {
// perror("Qt Window thread setpriority error ");
// }
// printf("sched_getscheduler(): %i \n", sched_getscheduler( getpid() ) );
// printf("sched_get_priority_min(SCHED_FIFO): %i \n", minPrio );
// printf("sched_get_priority_max(SCHED_FIFO): %i \n", maxPrio );
//
// printf("setpriority(): %i \n", ::getpriority( PRIO_PROCESS, getpid() ) );
//
// if ( sched_setscheduler( getpid(), SCHED_FIFO, &p ) )
// {
// perror("Qt Window thread sched_setscheduler error:");
// }
// printf("sched_getscheduler(): %i \n", sched_getscheduler( getpid() ) );
//
//#elif defined(__APPLE__)
//
// struct sched_param p;
// int oldPolicy, newPolicy, minPrio, maxPrio;
// QThread *qself;
// pthread_t self;
//
// qself = QThread::currentThread();
//
// self = pthread_self();
// newPolicy = SCHED_FIFO;
//
// printf("QThreadID: %p \n", QThread::currentThreadId() );
// printf("PThreadID: %p \n", self );
//
// minPrio = sched_get_priority_min( SCHED_FIFO );
// maxPrio = sched_get_priority_max( SCHED_FIFO );
//
// pthread_getschedparam( self, &oldPolicy, &p );
//
// printf("GUI pthread_getschedparam(): %i, %i \n", oldPolicy, p.sched_priority );
//
// qself->setPriority( priority_req );
//
// p.sched_priority = maxPrio;
//
// //if ( ::pthread_setschedparam( self, newPolicy, &p ) != 0 )
// //{
// //perror("GUI thread pthread_setschedparam error: ");
// //}
// pthread_getschedparam( self, &oldPolicy, &p );
//
// printf("GUI pthread_getschedparam(): %i, %i \n", oldPolicy, p.sched_priority );
//
// if ( ::setpriority( PRIO_PROCESS, getpid(), -20 ) )
// {
// perror("GUI thread setpriority error: ");
// }
// printf("GUI Thread setpriority(): %i \n", ::getpriority( PRIO_PROCESS, getpid() ) );
//#else
// QThread *mainThread;
//
// mainThread = QThread::currentThread();
//
// mainThread->setPriority( priority_req );
//#endif
//}
void consoleWin_t::syncActionConfig( QAction *act, const char *property )
{
if ( act->isCheckable() )

View File

@ -75,7 +75,14 @@ class consoleWin_t : public QMainWindow
int showListSelectDialog( const char *title, std::vector <std::string> &l );
void setPriority( QThread::Priority priority_req );
#if defined(__linux__) || defined(__APPLE__)
int setSchedParam( int policy, int priority );
int getSchedParam( int &policy, int &priority );
int setNicePriority( int value );
int getNicePriority( void );
int getMinSchedPriority(void);
int getMaxSchedPriority(void);
#endif
emulatorThread_t *emulatorThread;

View File

@ -25,7 +25,7 @@ TimingConfDialog_t::TimingConfDialog_t(QWidget *parent)
QVBoxLayout *mainLayout, *vbox;
//QHBoxLayout *hbox;
QGridLayout *grid;
QGroupBox *emuPrioBox;
QGroupBox *emuPrioBox, *guiPrioBox;
setWindowTitle("Timing Configuration");
@ -34,6 +34,7 @@ TimingConfDialog_t::TimingConfDialog_t(QWidget *parent)
emuPrioCtlEna = new QCheckBox( tr("Set Scheduling Parameters at Startup") );
emuPrioBox = new QGroupBox( tr("EMU Thread Scheduling Parameters") );
guiPrioBox = new QGroupBox( tr("GUI Thread Scheduling Parameters") );
grid = new QGridLayout();
emuPrioBox->setLayout( grid );
@ -56,6 +57,27 @@ TimingConfDialog_t::TimingConfDialog_t(QWidget *parent)
mainLayout->addWidget( emuPrioCtlEna );
mainLayout->addWidget( emuPrioBox );
grid = new QGridLayout();
guiPrioBox->setLayout( grid );
guiSchedPolicyBox = new QComboBox();
guiSchedPrioSlider = new QSlider( Qt::Horizontal );
guiSchedNiceSlider = new QSlider( Qt::Horizontal );
guiSchedPrioLabel = new QLabel( tr("Priority (RT)") );
guiSchedPolicyBox->addItem( tr("SCHED_OTHER") , SCHED_OTHER );
guiSchedPolicyBox->addItem( tr("SCHED_FIFO") , SCHED_FIFO );
guiSchedPolicyBox->addItem( tr("SCHED_RR") , SCHED_RR );
grid->addWidget( new QLabel( tr("Policy") ), 0, 0 );
grid->addWidget( guiSchedPolicyBox, 0, 1 );
grid->addWidget( guiSchedPrioLabel, 1, 0 );
grid->addWidget( guiSchedPrioSlider, 1, 1 );
grid->addWidget( new QLabel( tr("Priority (Nice)") ), 2, 0 );
grid->addWidget( guiSchedNiceSlider, 2, 1 );
mainLayout->addWidget( guiPrioBox );
setLayout( mainLayout );
updatePolicyBox();
@ -65,6 +87,9 @@ TimingConfDialog_t::TimingConfDialog_t(QWidget *parent)
connect( emuSchedPolicyBox , SIGNAL(activated(int)) , this, SLOT(emuSchedPolicyChange(int)) );
connect( emuSchedNiceSlider , SIGNAL(valueChanged(int)), this, SLOT(emuSchedNiceChange(int)) );
connect( emuSchedPrioSlider , SIGNAL(valueChanged(int)), this, SLOT(emuSchedPrioChange(int)) );
connect( guiSchedPolicyBox , SIGNAL(activated(int)) , this, SLOT(guiSchedPolicyChange(int)) );
connect( guiSchedNiceSlider , SIGNAL(valueChanged(int)), this, SLOT(guiSchedNiceChange(int)) );
connect( guiSchedPrioSlider , SIGNAL(valueChanged(int)), this, SLOT(guiSchedPrioChange(int)) );
}
//----------------------------------------------------------------------------
TimingConfDialog_t::~TimingConfDialog_t(void)
@ -181,6 +206,100 @@ void TimingConfDialog_t::emuSchedPolicyChange( int index )
fceuWrapperUnLock();
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::guiSchedNiceChange(int val)
{
if ( consoleWindow == NULL )
{
return;
}
fceuWrapperLock();
if ( consoleWindow->setNicePriority( -val ) )
{
char msg[1024];
sprintf( msg, "Error: system call setPriority Failed\nReason: %s\n", strerror(errno) );
#ifdef __linux__
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat( msg, " /etc/security/limits.conf \n\n");
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat( msg, "* - priority 99 \n");
strcat( msg, "* - rtprio 99 \n");
strcat( msg, "* - nice -20 \n");
#endif
printf("%s\n", msg );
consoleWindow->QueueErrorMsgWindow( msg );
updateSliderValues();
}
fceuWrapperUnLock();
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::guiSchedPrioChange(int val)
{
int policy, prio;
if ( consoleWindow == NULL )
{
return;
}
fceuWrapperLock();
consoleWindow->getSchedParam( policy, prio );
if ( consoleWindow->setSchedParam( policy, val ) )
{
char msg[1024];
sprintf( msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno) );
#ifdef __linux__
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat( msg, " /etc/security/limits.conf \n\n");
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat( msg, "* - priority 99 \n");
strcat( msg, "* - rtprio 99 \n");
strcat( msg, "* - nice -20 \n");
#endif
printf("%s\n", msg );
consoleWindow->QueueErrorMsgWindow( msg );
updateSliderValues();
}
fceuWrapperUnLock();
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::guiSchedPolicyChange( int index )
{
int policy, prio;
if ( consoleWindow == NULL )
{
return;
}
fceuWrapperLock();
consoleWindow->getSchedParam( policy, prio );
policy = guiSchedPolicyBox->itemData( index ).toInt();
if ( consoleWindow->setSchedParam( policy, prio ) )
{
char msg[1024];
sprintf( msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno) );
#ifdef __linux__
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat( msg, " /etc/security/limits.conf \n\n");
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat( msg, "* - priority 99 \n");
strcat( msg, "* - rtprio 99 \n");
strcat( msg, "* - nice -20 \n");
#endif
printf("%s\n", msg );
consoleWindow->QueueErrorMsgWindow( msg );
}
updatePolicyBox();
updateSliderLimits();
updateSliderValues();
fceuWrapperUnLock();
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::updatePolicyBox(void)
{
int policy, prio;
@ -200,6 +319,17 @@ void TimingConfDialog_t::updatePolicyBox(void)
}
}
consoleWindow->getSchedParam( policy, prio );
for (int j=0; j<guiSchedPolicyBox->count(); j++)
{
if ( guiSchedPolicyBox->itemData(j).toInt() == policy )
{
//printf("Found Policy %i %i\n", j , policy );
guiSchedPolicyBox->setCurrentIndex( j );
}
}
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::updateSliderValues(void)
@ -225,6 +355,22 @@ void TimingConfDialog_t::updateSliderValues(void)
emuSchedPrioLabel->setEnabled(false);
emuSchedPrioSlider->setEnabled(false);
}
consoleWindow->getSchedParam( policy, prio );
guiSchedNiceSlider->setValue( -consoleWindow->getNicePriority() );
guiSchedPrioSlider->setValue( prio );
if ( (policy == SCHED_RR) || (policy == SCHED_FIFO) )
{
guiSchedPrioLabel->setEnabled(true);
guiSchedPrioSlider->setEnabled(true);
}
else
{
guiSchedPrioLabel->setEnabled(false);
guiSchedPrioSlider->setEnabled(false);
}
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::updateSliderLimits(void)
@ -239,5 +385,10 @@ void TimingConfDialog_t::updateSliderLimits(void)
emuSchedPrioSlider->setMinimum( consoleWindow->emulatorThread->getMinSchedPriority() );
emuSchedPrioSlider->setMaximum( consoleWindow->emulatorThread->getMaxSchedPriority() );
guiSchedNiceSlider->setMinimum( -20 );
guiSchedNiceSlider->setMaximum( 20 );
guiSchedPrioSlider->setMinimum( consoleWindow->getMinSchedPriority() );
guiSchedPrioSlider->setMaximum( consoleWindow->getMaxSchedPriority() );
}
//----------------------------------------------------------------------------

View File

@ -35,6 +35,10 @@ class TimingConfDialog_t : public QDialog
QSlider *emuSchedPrioSlider;
QSlider *emuSchedNiceSlider;
QLabel *emuSchedPrioLabel;
QComboBox *guiSchedPolicyBox;
QSlider *guiSchedPrioSlider;
QSlider *guiSchedNiceSlider;
QLabel *guiSchedPrioLabel;
private:
void updatePolicyBox(void);
@ -47,5 +51,8 @@ class TimingConfDialog_t : public QDialog
void emuSchedNiceChange( int val );
void emuSchedPrioChange( int val );
void emuSchedPolicyChange( int index );
void guiSchedNiceChange( int val );
void guiSchedPrioChange( int val );
void guiSchedPolicyChange( int index );
};