generic: remove bogus I/O nice-ness support

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2021-07-10 18:30:57 +03:00
parent 905796f68d
commit 301eb95286
28 changed files with 119 additions and 885 deletions

View file

@ -29,9 +29,6 @@
#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
#include <asm/unistd.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include "../../gui/SignalIDs.h"
#include "Command.h"
@ -45,33 +42,6 @@
#define TAGSIZE 32
#define KDEINITLEN sizeof( "kdeinit: " )
// NOTE: keep in sync with kde-workspace/libs/ksysguard/processcore/processes_linux_p.cpp
/* Check if this system has ionice */
#if defined(SYS_ioprio_get) && defined(SYS_ioprio_set)
#define HAVE_IONICE
#else
#warning "This architecture does not support IONICE. Disabling ionice feature."
#endif
/* Set up ionice functions */
#ifdef HAVE_IONICE
#define IOPRIO_WHO_PROCESS 1
#define IOPRIO_CLASS_SHIFT 13
/* Expose the kernel calls to usespace via syscall
* See man ioprio_set and man ioprio_get for information on these functions */
static int ioprio_set(int which, int who, int ioprio)
{
return syscall(SYS_ioprio_set, which, who, ioprio);
}
static int ioprio_get(int which, int who)
{
return syscall(SYS_ioprio_get, which, who);
}
#endif
#ifndef bool
#define bool char
#define true 1
@ -107,10 +77,6 @@ typedef struct {
/** The scheduling priority. */
int priority;
/** The i/o scheduling class and priority. */
int ioPriorityClass; /**< 0 for none, 1 for realtime, 2 for best-effort, 3 for idle. -1 for error. */
int ioPriority; /**< Between 0 and 7. 0 is highest priority, 7 is lowest. -1 for error. */
/**
The total amount of virtual memory space that this process uses. This includes shared and
swapped memory, plus graphics memory and mmap'ed files and so on.
@ -162,9 +128,6 @@ typedef struct {
} ProcessInfo;
void getIOnice( int pid, ProcessInfo *ps );
void ioniceProcess( const char* cmd );
static unsigned ProcessCount;
static DIR* procDir;
static void validateStr( char* str )
@ -364,8 +327,6 @@ static bool getProcess( int pid, ProcessInfo *ps )
ps->userName[ sizeof( ps->userName ) - 1 ] = '\0';
validateStr( ps->userName );
getIOnice(pid, ps);
return true;
}
@ -382,13 +343,12 @@ void printProcessList( const char* cmd)
long pid;
pid = atol( entry->d_name );
if(getProcess( pid, &ps )) /* Print out the details of the process. Because of a stupid bug in kde3 ksysguard, make sure cmdline and tty are not empty */
output( "%s\t%ld\t%ld\t%lu\t%lu\t%s\t%lu\t%lu\t%d\t%lu\t%lu\t%lu\t%s\t%ld\t%s\t%s\t%d\t%d\n",
output( "%s\t%ld\t%ld\t%lu\t%lu\t%s\t%lu\t%lu\t%d\t%lu\t%lu\t%lu\t%s\t%ld\t%s\t%s\n",
ps.name, pid, (long)ps.ppid,
(long)ps.uid, (long)ps.gid, ps.status, ps.userTime,
ps.sysTime, ps.niceLevel, ps.vmSize, ps.vmRss, ps.vmURss,
(ps.userName[0]==0)?" ":ps.userName, (long)ps.tracerpid,
(ps.tty[0]==0)?" ":ps.tty, (ps.cmdline[0]==0)?" ":ps.cmdline,
ps.ioPriorityClass, ps.ioPriority
(ps.tty[0]==0)?" ":ps.tty, (ps.cmdline[0]==0)?" ":ps.cmdline
);
}
}
@ -396,22 +356,6 @@ void printProcessList( const char* cmd)
return;
}
void getIOnice( int pid, ProcessInfo *ps ) {
#ifdef HAVE_IONICE
int ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid); /* Returns from 0 to 7 for the iopriority, and -1 if there's an error */
if(ioprio == -1) {
ps->ioPriority = -1;
ps->ioPriorityClass = -1;
return; /* Error. Just give up. */
}
ps->ioPriority = ioprio & 0xff; /* Bottom few bits are the priority */
ps->ioPriorityClass = ioprio >> IOPRIO_CLASS_SHIFT; /* Top few bits are the class */
#else
return; /* Do nothing, if we do not support this architecture */
#endif
}
/*
================================ public part =================================
*/
@ -426,9 +370,6 @@ void initProcessList( struct SensorModul* sm )
if ( !RunAsDaemon ) {
registerCommand( "kill", killProcess );
registerCommand( "setpriority", setPriority );
#ifdef HAVE_IONICE
registerCommand( "ionice", ioniceProcess );
#endif
}
/*open /proc now in advance*/
@ -595,56 +536,3 @@ void setPriority( const char* cmd )
} else
output( "0\t%d\t%d\n",pid, prio );
}
void ioniceProcess( const char* cmd )
{
/* Re-ionice's a process. cmd is a string containing:
*
* ionice <pid> <class> <priority>
*
* where c = 1 for real time, 2 for best-effort, 3 for idle
* and priority is between 0 and 7, 0 being the highest priority, and ignored if c=3
*
* For more information, see: man ionice
*
*/
int pid = 0;
int class = 2;
int priority = 0;
if(sscanf( cmd, "%*s %d %d %d", &pid, &class, &priority ) < 2) {
output( "4\t%d\n", pid ); /* 4 means error in values */
return; /* Error with input. */
}
#ifdef HAVE_IONICE
if(pid < 1 || class < 0 || class > 3) {
output( "4\t%d\n", pid ); /* 4 means error in values */
return; /* Error with input. Just ignore. */
}
if (ioprio_set(IOPRIO_WHO_PROCESS, pid, priority | class << IOPRIO_CLASS_SHIFT) == -1) {
switch ( errno ) {
case EINVAL:
output( "4\t%d\n", pid );
break;
case ESRCH:
output( "3\t%d\n", pid );
break;
case EPERM:
output( "2\t%d\n", pid );
break;
default: /* unknown error */
output( "1\t%d\n", pid );
break;
}
} else {
/* Successful */
output( "0\t%d\n", pid );
}
return;
#else
/** should never reach here */
output( "1\t%d\n", pid );
return;
#endif
}

View file

@ -32,6 +32,5 @@ void printProcessCountInfo( const char* );
void killProcess( const char* );
void setPriority( const char* );
void ioniceProcess( const char* );
#endif

View file

@ -1,6 +1,3 @@
/* Define to 1 if you have the <sys/ptrace.h> header file. */
#cmakedefine HAVE_SYS_PTRACE_H 1
/* Define to 1 if you have the <sys/endian.h> header file. */
#cmakedefine HAVE_SYS_ENDIAN_H 1

View file

@ -84,25 +84,6 @@ KAuth::ActionReply KSysGuardProcessListHelper::renice(QVariantMap parameters) {
return KAuth::ActionReply::HelperErrorReply;
}
KAuth::ActionReply KSysGuardProcessListHelper::changeioscheduler(QVariantMap parameters) {
if(!parameters.contains("ioScheduler") || !parameters.contains("ioSchedulerPriority") || !parameters.contains("pidcount"))
return KAuth::ActionReply::HelperErrorReply;
KSysGuard::ProcessesLocal processes;
int ioScheduler = qvariant_cast<int>(parameters.value("ioScheduler"));
int ioSchedulerPriority = qvariant_cast<int>(parameters.value("ioSchedulerPriority"));
bool success = true;
int numProcesses = parameters.value("pidcount").toInt();
for (int i = 0; i < numProcesses; ++i) {
qlonglong pid = GET_PID(i);
success = processes.setIoNiceness(pid, ioScheduler, ioSchedulerPriority) && success;
}
if(success)
return KAuth::ActionReply::SuccessReply;
else
return KAuth::ActionReply::HelperErrorReply;
}
KAuth::ActionReply KSysGuardProcessListHelper::changecpuscheduler(QVariantMap parameters) {
if(!parameters.contains("cpuScheduler") || !parameters.contains("cpuSchedulerPriority") || !parameters.contains("pidcount"))
return KAuth::ActionReply::HelperErrorReply;

View file

@ -35,7 +35,6 @@ class KSysGuardProcessListHelper : public QObject {
public Q_SLOTS:
ActionReply sendsignal(QVariantMap parameters);
ActionReply renice(QVariantMap parameters);
ActionReply changeioscheduler(QVariantMap parameters);
ActionReply changecpuscheduler(QVariantMap parameters);
};

View file

@ -42,27 +42,6 @@ QString KSysGuard::Process::niceLevelAsString() const {
return QString(); //impossible;
}
QString KSysGuard::Process::ioniceLevelAsString() const {
// Just some rough heuristic to map a number to how nice it is
if( ioniceLevel == 4) return i18nc("Process Niceness", "Normal");
if( ioniceLevel >= 6) return i18nc("Process Niceness", "Very low priority");
if( ioniceLevel > 4) return i18nc("Process Niceness", "Low priority");
if( ioniceLevel <= 2) return i18nc("Process Niceness", "Very high priority");
if( ioniceLevel < 4) return i18nc("Process Niceness", "High priority");
return QString(); //impossible;
}
QString KSysGuard::Process::ioPriorityClassAsString() const {
switch( ioPriorityClass ) {
case None: return i18nc("Priority Class", "None");
case RealTime: return i18nc("Priority Class", "Real Time");
case BestEffort: return i18nc("Priority Class", "Best Effort");
case Idle: return i18nc("Priority Class", "Idle");
default: return i18nc("Priority Class", "Unknown");
}
}
QString KSysGuard::Process::translatedStatus() const {
switch( status ) {
case Running: return i18nc("process status", "running");
@ -115,8 +94,6 @@ void KSysGuard::Process::clear() {
hasManagedGuiWindow = false;
status=OtherStatus;
parent = NULL;
ioPriorityClass = None;
ioniceLevel = -1;
scheduler = Other;
ioCharactersRead = 0;
ioCharactersWritten = 0;
@ -226,16 +203,7 @@ void KSysGuard::Process::setscheduler(Scheduler _scheduler) {
scheduler = _scheduler;
changes |= Process::NiceLevels;
}
void KSysGuard::Process::setIoPriorityClass(IoPriorityClass _ioPriorityClass) {
if(ioPriorityClass == _ioPriorityClass) return;
ioPriorityClass = _ioPriorityClass;
changes |= Process::NiceLevels;
}
void KSysGuard::Process::setIoniceLevel(int _ioniceLevel) {
if(ioniceLevel == _ioniceLevel) return;
ioniceLevel = _ioniceLevel;
changes |= Process::NiceLevels;
}
void KSysGuard::Process::setVmSize(qlonglong _vmSize) {
if(vmSizeChange != 0 || vmSize != 0)
vmSizeChange = _vmSize - vmSize;

View file

@ -35,7 +35,6 @@ namespace KSysGuard
class KDE_EXPORT Process {
public:
enum ProcessStatus { Running, Sleeping, DiskSleep, Zombie, Stopped, Paging, Ended, OtherStatus=99 };
enum IoPriorityClass { None, RealTime, BestEffort, Idle };
enum Scheduler { Other = 0, Fifo, RoundRobin, Batch, SchedulerIdle, Interactive }; ///< Interactive is Solaris only
Process();
Process(qlonglong _pid, qlonglong _ppid, Process *_parent);
@ -73,8 +72,6 @@ namespace KSysGuard
void setTotalSysUsage(int totalSysUsage); ///< Percentage (0 to 100) from the sum of itself and all its children recursively. If there's no children, it's equal to sysUsage. It might be more than 100% on multiple cpu core systems
void setNiceLevel(int niceLevel); ///< If Scheduler = Other, niceLevel is the niceness (-20 to 20) of this process. A lower number means a higher priority. Otherwise sched priority (1 to 99)
void setscheduler(Scheduler scheduler); ///< The scheduler this process is running in. See man sched_getscheduler for more info
void setIoPriorityClass(IoPriorityClass ioPriorityClass); ///< The IO priority class. See man ionice for detailed information.
void setIoniceLevel(int ioniceLevel); ///< IO Niceness (0 to 7) of this process. A lower number means a higher io priority. -1 if not known or not applicable because ioPriorityClass is Idle or None
void setVmSize(qlonglong vmSize); ///< Virtual memory size in KiloBytes, including memory used, mmap'ed files, graphics memory etc,
void setVmRSS(qlonglong vmRSS); ///< Physical memory used by the process and its shared libraries. If the process and libraries are swapped to disk, this could be as low as 0
void setVmURSS(qlonglong vmURSS); ///< Physical memory used only by the process, and not counting the code for shared libraries. Set to -1 if unknown
@ -119,8 +116,6 @@ namespace KSysGuard
unsigned long numChildren;
int niceLevel;
Scheduler scheduler;
IoPriorityClass ioPriorityClass;
int ioniceLevel;
qlonglong vmSize;
qlonglong vmRSS;
@ -154,8 +149,6 @@ namespace KSysGuard
QString translatedStatus() const; ///< Returns a translated string of the status. e.g. "Running" etc
QString niceLevelAsString() const; ///< Returns a simple translated string of the nice priority. e.g. "Normal", "High", etc
QString ioniceLevelAsString() const; ///< Returns a simple translated string of the io nice priority. e.g. "Normal", "High", etc
QString ioPriorityClassAsString() const; ///< Returns a translated string of the io nice class. i.e. "None", "Real Time", "Best Effort", "Idle"
QString schedulerAsString() const; ///< Returns a translated string of the scheduler class. e.g. "FIFO", "Round Robin", "Batch"
int index; ///< Each process has a parent process. Each sibling has a unique number to identify it under that parent. This is that number.

View file

@ -440,21 +440,6 @@ bool Processes::setScheduler(long pid, KSysGuard::Process::Scheduler priorityCla
return d->mAbstractProcesses->setScheduler(pid, priorityClass, priority);
}
bool Processes::setIoNiceness(long pid, KSysGuard::Process::IoPriorityClass priorityClass, int priority) {
d->mAbstractProcesses->errorCode = Unknown;
if(d->mUsingHistoricalData) {
d->mAbstractProcesses->errorCode = NotSupported;
return false;
}
return d->mAbstractProcesses->setIoNiceness(pid, priorityClass, priority);
}
bool Processes::supportsIoNiceness() {
if(d->mUsingHistoricalData)
return false;
return d->mAbstractProcesses->supportsIoNiceness();
}
long long Processes::totalPhysicalMemory() {
return d->mAbstractProcesses->totalPhysicalMemory();
}

View file

@ -138,19 +138,6 @@ namespace KSysGuard
*/
bool setScheduler(long pid, KSysGuard::Process::Scheduler priorityClass, int priority);
/**
* Set the io priority for a process. This is from 7 (very nice, lowest io priority) to
* 0 (highest priority). The default value is determined as: io_nice = (cpu_nice + 20) / 5.
*
* @return false if you do not have permission to set the priority
*/
bool setIoNiceness(long pid, KSysGuard::Process::IoPriorityClass priorityClass, int priority);
/**
* Returns true if ionice is supported on this system
*/
bool supportsIoNiceness();
/**
* Return the internal pointer of all the processes. The order of the processes
* is guaranteed to never change. Call updateAllProcesses() first to actually

View file

@ -350,20 +350,6 @@ bool ProcessesATop::setScheduler(long pid, int priorityClass, int priority) {
return false;
}
bool ProcessesATop::setIoNiceness(long pid, int priorityClass, int priority) {
Q_UNUSED(pid);
Q_UNUSED(priorityClass);
Q_UNUSED(priority);
errorCode = Processes::NotSupported;
return false;
}
bool ProcessesATop::supportsIoNiceness() {
return false;
}
long long ProcessesATop::totalPhysicalMemory() {
return 0;
}

View file

@ -47,8 +47,6 @@ namespace KSysGuard
virtual bool setNiceness(long pid, int priority);
virtual bool setScheduler(long pid, int priorityClass, int priority);
virtual long long totalPhysicalMemory();
virtual bool setIoNiceness(long pid, int priorityClass, int priority);
virtual bool supportsIoNiceness();
virtual long numberProcessorCores()
#ifdef _SC_NPROCESSORS_ONLN
{ return sysconf(_SC_NPROCESSORS_ONLN); } // Should work on any recent posix system

View file

@ -114,19 +114,6 @@ namespace KSysGuard
*/
virtual long long totalPhysicalMemory() = 0;
/** \brief Set the i/o priority for a process.
*
* This is from 7 (very nice, lowest i/o priority) to
* 0 (highest priority). The default value is determined as: io_nice = (cpu_nice + 20) / 5.
*
* @return false if you do not have permission to set the priority
*/
virtual bool setIoNiceness(long pid, int priorityClass, int priority) = 0;
/** \brief Returns true if ionice is supported on this system
*/
virtual bool supportsIoNiceness() = 0;
/** \brief Return the number of processor cores enabled.
*
* (A system can disable processors. Disabled processors are not counted here).

View file

@ -245,14 +245,6 @@ bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
}
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
return false; //Not yet supported
}
bool ProcessesLocal::supportsIoNiceness() {
return false;
}
long long ProcessesLocal::totalPhysicalMemory() {
size_t Total;

View file

@ -239,14 +239,6 @@ bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
}
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
return false; //Not yet supported
}
bool ProcessesLocal::supportsIoNiceness() {
return false;
}
long long ProcessesLocal::totalPhysicalMemory() {
size_t Total;

View file

@ -77,16 +77,6 @@ bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
return false;
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority)
{
return false;
}
bool ProcessesLocal::supportsIoNiceness()
{
return false;
}
long long ProcessesLocal::totalPhysicalMemory()
{
long long memory = 0;

View file

@ -39,44 +39,11 @@
#include <sys/resource.h>
#include <dirent.h>
#include <stdlib.h>
//for ionice
#include <asm/unistd.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
//for getsched
#include <sched.h>
#define PROCESS_BUFFER_SIZE 1000
// NOTE: keep in sync with kde-workspace/ksysguard/ksysguardd/Linux/ProcessList.c
/* Check if this system has ionice */
#if defined(SYS_ioprio_get) && defined(SYS_ioprio_set)
#define HAVE_IONICE
#else
#warning "This architecture does not support IONICE. Disabling ionice feature."
#endif
/* Set up ionice functions */
#ifdef HAVE_IONICE
#define IOPRIO_WHO_PROCESS 1
#define IOPRIO_CLASS_SHIFT 13
/* Expose the kernel calls to userspace via syscall
* See man ioprio_set and man ioprio_get for information on these functions */
static int ioprio_set(int which, int who, int ioprio)
{
return syscall(SYS_ioprio_set, which, who, ioprio);
}
static int ioprio_get(int which, int who)
{
return syscall(SYS_ioprio_get, which, who);
}
#endif
namespace KSysGuard
{
@ -401,25 +368,14 @@ bool ProcessesLocal::Private::getNiceness(long pid, Process *process) {
}
if(sched == SCHED_FIFO || sched == SCHED_RR) {
struct sched_param param;
if(sched_getparam(pid, &param) == 0)
process->setNiceLevel(param.sched_priority);
else
process->setNiceLevel(0); //Error getting scheduler parameters.
if(sched_getparam(pid, &param) == 0) {
process->setNiceLevel(param.sched_priority);
} else {
process->setNiceLevel(0); //Error getting scheduler parameters.
return false;
}
}
#ifdef HAVE_IONICE
int ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid); /* Returns from 0 to 7 for the iopriority, and -1 if there's an error */
if(ioprio == -1) {
process->ioniceLevel = -1;
process->ioPriorityClass = KSysGuard::Process::None;
return false; /* Error. Just give up. */
}
process->ioniceLevel = ioprio & 0xff; /* Bottom few bits are the priority */
process->ioPriorityClass = (KSysGuard::Process::IoPriorityClass)(ioprio >> IOPRIO_CLASS_SHIFT); /* Top few bits are the class */
return true;
#else
return false; /* Do nothing, if we do not support this architecture */
#endif
}
bool ProcessesLocal::Private::getIOStatistics(const QString &dir, Process *process)
@ -601,46 +557,6 @@ bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority) {
return true;
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
errno = 0;
if (pid <= 0) {
errorCode = Processes::InvalidPid;
return false;
}
#ifdef HAVE_IONICE
if (ioprio_set(IOPRIO_WHO_PROCESS, pid, priority | priorityClass << IOPRIO_CLASS_SHIFT) == -1) {
//set io niceness failed
switch (errno) {
case ESRCH:
errorCode = Processes::ProcessDoesNotExistOrZombie;
break;
case EINVAL:
errorCode = Processes::InvalidParameter;
break;
case EPERM:
errorCode = Processes::InsufficientPermissions;
break;
default:
break;
}
return false;
}
return true;
#else
errorCode = Processes::NotSupported;
return false;
#endif
}
bool ProcessesLocal::supportsIoNiceness() {
#ifdef HAVE_IONICE
return true;
#else
return false;
#endif
}
long long ProcessesLocal::totalPhysicalMemory() {
//Try to get the memory via sysconf. Note the cast to long long to try to avoid a long overflow
//Should we use sysconf(_SC_PAGESIZE) or getpagesize() ?

View file

@ -46,8 +46,6 @@ namespace KSysGuard
virtual bool setNiceness(long pid, int priority);
virtual bool setScheduler(long pid, int priorityClass, int priority);
virtual long long totalPhysicalMemory();
virtual bool setIoNiceness(long pid, int priorityClass, int priority);
virtual bool supportsIoNiceness();
virtual long numberProcessorCores()
#ifdef _SC_NPROCESSORS_ONLN
{ return sysconf(_SC_NPROCESSORS_ONLN); } // Should work on any recent posix system

View file

@ -271,16 +271,6 @@ bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
}
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority)
{
return false; // Not yet supported
}
bool ProcessesLocal::supportsIoNiceness()
{
return false;
}
long long ProcessesLocal::totalPhysicalMemory()
{
size_t Total;

View file

@ -259,15 +259,6 @@ bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
#endif
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority)
{
return false; // Not yet supported
}
bool ProcessesLocal::supportsIoNiceness() {
return false;
}
long long ProcessesLocal::totalPhysicalMemory()
{
static int physmem_mib[] = { CTL_HW, HW_PHYSMEM };

View file

@ -38,13 +38,14 @@ namespace KSysGuard
class ProcessesRemote::Private
{
public:
Private() {havePsInfo = false; pidColumn = 1;
ppidColumn = nameColumn = uidColumn = gidColumn =
statusColumn = userColumn = systemColumn = niceColumn =
vmSizeColumn = vmRSSColumn = loginColumn = commandColumn =
tracerPidColumn = ttyColumn = ioprioClassColumn = ioprioColumn =
vmURSSColumn = -1;
usedMemory = freeMemory;}
Private() {
havePsInfo = false; pidColumn = 1;
ppidColumn = nameColumn = uidColumn = gidColumn =
statusColumn = userColumn = systemColumn = niceColumn =
vmSizeColumn = vmRSSColumn = loginColumn = commandColumn =
tracerPidColumn = ttyColumn = vmURSSColumn = -1;
usedMemory = freeMemory;
}
~Private() {;}
QString host;
QList<QByteArray> lastAnswer;
@ -67,8 +68,6 @@ namespace KSysGuard
int vmURSSColumn;
int loginColumn;
int commandColumn;
int ioprioClassColumn;
int ioprioColumn;
int ttyColumn;
int numColumns;
@ -136,8 +135,6 @@ bool ProcessesRemote::updateProcessInfo( long pid, Process *process)
if(d->tracerPidColumn!= -1) process->setTracerpid(p.at(d->tracerPidColumn).toLong());
if(d->vmURSSColumn!= -1) process->setVmURSS(p.at(d->vmURSSColumn).toLong());
if(d->ttyColumn!= -1) process->setTty(p.at(d->ttyColumn));
if(d->ioprioColumn!= -1) process->setIoniceLevel(p.at(d->ioprioColumn).toInt());
if(d->ioprioClassColumn!= -1) process->setIoPriorityClass((KSysGuard::Process::IoPriorityClass)(p.at(d->ioprioClassColumn).toInt()));
return true;
}
@ -166,7 +163,7 @@ QSet<long> ProcessesRemote::getAllPids( )
}
bool ProcessesRemote::sendSignal(long pid, int sig) {
//TODO run the proper command for all these functions below
//TODO run the proper command for all these functions below
emit runCommand("kill " + QString::number(pid) + " " + QString::number(sig), (int)Kill);
return true;
}
@ -175,11 +172,6 @@ bool ProcessesRemote::setNiceness(long pid, int priority) {
return true;
}
bool ProcessesRemote::setIoNiceness(long pid, int priorityClass, int priority) {
emit runCommand("ionice " + QString::number(pid) + " " + QString::number(priorityClass) + " " + QString::number(priority), (int)Ionice);
return true;
}
bool ProcessesRemote::setScheduler(long pid, int priorityClass, int priority) {
Q_UNUSED(pid);
Q_UNUSED(priorityClass);
@ -189,10 +181,6 @@ bool ProcessesRemote::setScheduler(long pid, int priorityClass, int priority) {
return false;
}
bool ProcessesRemote::supportsIoNiceness() {
return true;
}
long long ProcessesRemote::totalPhysicalMemory() {
return d->usedMemory + d->freeMemory;
}
@ -239,10 +227,6 @@ void ProcessesRemote::answerReceived( int id, const QList<QByteArray>& answer )
d->ttyColumn = i;
else if(info[i] == "Command")
d->commandColumn = i;
else if(info[i] == "IO Priority Class")
d->ioprioClassColumn = i;
else if(info[i] == "IO Priority")
d->ioprioColumn = i;
}
d->havePsInfo = true;
break;

View file

@ -41,8 +41,6 @@ namespace KSysGuard
virtual bool setNiceness(long pid, int priority);
virtual bool setScheduler(long pid, int priorityClass, int priority);
virtual long long totalPhysicalMemory();
virtual bool setIoNiceness(long pid, int priorityClass, int priority);
virtual bool supportsIoNiceness();
virtual long numberProcessorCores();
virtual void updateAllProcesses( Processes::UpdateFlags updateFlags );
@ -62,7 +60,7 @@ namespace KSysGuard
void setup();
protected:
enum { PsInfo, Ps, UsedMemory, FreeMemory, Kill, Renice, Ionice };
enum { PsInfo, Ps, UsedMemory, FreeMemory, Kill, Renice };
private:
/**

View file

@ -216,15 +216,7 @@ bool ProcessesLocal::setScheduler(long pid, int priorityClass, int priority)
{
return false;
}
bool ProcessesLocal::setIoNiceness(long pid, int priorityClass, int priority) {
return false; //Not yet supported
}
bool ProcessesLocal::supportsIoNiceness() {
return false;
}
s
long long ProcessesLocal::totalPhysicalMemory() {
long long memory = ((long long)sysconf(_SC_PHYS_PAGES)) * (sysconf(_SC_PAGESIZE)/1024);
if(memory > 0) return memory;

View file

@ -1430,12 +1430,7 @@ QVariant ProcessModel::data(const QModelIndex &index, int role) const
if(process->scheduler != KSysGuard::Process::Other)
tooltip += i18n("<br/>Scheduler: %1", process->schedulerAsString());
if(process->ioPriorityClass != KSysGuard::Process::None) {
if((process->ioPriorityClass == KSysGuard::Process::RealTime || process->ioPriorityClass == KSysGuard::Process::BestEffort) && process->ioniceLevel != -1)
tooltip += i18n("<br/>I/O Nice level: %1 (%2)", process->ioniceLevel, process->ioniceLevelAsString() );
tooltip += i18n("<br/>I/O Class: %1", process->ioPriorityClassAsString() );
}
if(tracer.isEmpty()) return tooltip;
if(tracer.isEmpty()) return tooltip;
return QString(tooltip + "<br />" + tracer);
}
case HeadingCPUUsage:
@ -1472,11 +1467,6 @@ QVariant ProcessModel::data(const QModelIndex &index, int role) const
.toString();
if(process->niceLevel != 0)
tooltip += i18n("<br />Nice level: %1 (%2)", process->niceLevel, process->niceLevelAsString() );
if(process->ioPriorityClass != KSysGuard::Process::None) {
if((process->ioPriorityClass == KSysGuard::Process::RealTime || process->ioPriorityClass == KSysGuard::Process::BestEffort) && process->ioniceLevel != -1)
tooltip += i18n("<br/>I/O Nice level: %1 (%2)", process->ioniceLevel, process->ioniceLevelAsString() );
tooltip += i18n("<br/>I/O Class: %1", process->ioPriorityClassAsString() );
}
if(!tracer.isEmpty())
return QString(tooltip + "<br />" + tracer);

View file

@ -31,162 +31,111 @@
#include "ui_ReniceDlgUi.h"
#include "processcore/process.h"
ReniceDlg::ReniceDlg(QWidget* parent, const QStringList& processes, int currentCpuPrio, int currentCpuSched, int currentIoPrio, int currentIoSched )
: KDialog( parent )
ReniceDlg::ReniceDlg(QWidget* parent, const QStringList& processes, int currentCpuPrio, int currentCpuSched)
: KDialog( parent )
{
setObjectName( "Renice Dialog" );
setModal( true );
setCaption( i18n("Set Priority") );
setButtons( Ok | Cancel );
previous_cpuscheduler = 0;
setObjectName( "Renice Dialog" );
setModal( true );
setCaption( i18n("Set Priority") );
setButtons( Ok | Cancel );
previous_cpuscheduler = 0;
connect( this, SIGNAL(okClicked()), SLOT(slotOk()) );
connect( this, SIGNAL(okClicked()), SLOT(slotOk()) );
if(currentIoSched == KSysGuard::Process::None) {
// CurrentIoSched == 0 means that the priority is set automatically.
// Using the formula given by the linux kernel Documentation/block/ioprio
currentIoPrio = (currentCpuPrio+20)/5;
}
if(currentIoSched == (int)KSysGuard::Process::BestEffort && currentIoPrio == (currentCpuPrio+20)/5) {
// Unfortunately, in linux you can't ever set a process back to being None. So we fake it :)
currentIoSched = KSysGuard::Process::None;
}
ioniceSupported = (currentIoPrio != -2);
QWidget *widget = new QWidget(this);
setMainWidget(widget);
ui = new Ui_ReniceDlgUi();
ui->setupUi(widget);
ui->listWidget->insertItems(0, processes);
QWidget *widget = new QWidget(this);
setMainWidget(widget);
ui = new Ui_ReniceDlgUi();
ui->setupUi(widget);
ui->listWidget->insertItems(0, processes);
cpuScheduler = new QButtonGroup(this);
cpuScheduler->addButton(ui->radioNormal, (int)KSysGuard::Process::Other);
cpuScheduler = new QButtonGroup(this);
cpuScheduler->addButton(ui->radioNormal, (int)KSysGuard::Process::Other);
#ifndef Q_OS_SOLARIS
cpuScheduler->addButton(ui->radioBatch, (int)KSysGuard::Process::Batch);
cpuScheduler->addButton(ui->radioBatch, (int)KSysGuard::Process::Batch);
#else
cpuScheduler->addButton(ui->radioBatch, (int)KSysGuard::Process::Interactive);
cpuScheduler->addButton(ui->radioBatch, (int)KSysGuard::Process::Interactive);
ui->radioBatch->setText( i18nc("Scheduler", "Interactive") );
#endif
cpuScheduler->addButton(ui->radioFIFO, (int)KSysGuard::Process::Fifo);
cpuScheduler->addButton(ui->radioRR, (int)KSysGuard::Process::RoundRobin);
if(currentCpuSched >= 0) { //negative means none of these
QAbstractButton *sched = cpuScheduler->button(currentCpuSched);
if(sched) {
sched->setChecked(true); //Check the current scheduler
previous_cpuscheduler = currentCpuSched;
}
}
cpuScheduler->setExclusive(true);
cpuScheduler->addButton(ui->radioFIFO, (int)KSysGuard::Process::Fifo);
cpuScheduler->addButton(ui->radioRR, (int)KSysGuard::Process::RoundRobin);
if(currentCpuSched >= 0) { //negative means none of these
QAbstractButton *sched = cpuScheduler->button(currentCpuSched);
if(sched) {
sched->setChecked(true); //Check the current scheduler
previous_cpuscheduler = currentCpuSched;
}
}
cpuScheduler->setExclusive(true);
ioScheduler = new QButtonGroup(this);
ioScheduler->addButton(ui->radioIONormal, (int)KSysGuard::Process::None);
ioScheduler->addButton(ui->radioIdle, (int)KSysGuard::Process::Idle);
ioScheduler->addButton(ui->radioRealTime, (int)KSysGuard::Process::RealTime);
ioScheduler->addButton(ui->radioBestEffort, (int)KSysGuard::Process::BestEffort);
if(currentIoSched >= 0) { //negative means none of these
QAbstractButton *iosched = ioScheduler->button(currentIoSched);
if(iosched)
iosched->setChecked(true); //Check the current io scheduler
}
setSliderRange(); //Update the slider ranges before trying to set their current values
ui->sliderCPU->setValue(currentCpuPrio);
ioScheduler->setExclusive(true);
ui->imgCPU->setPixmap( KIcon("cpu").pixmap(128, 128) );
setSliderRange(); //Update the slider ranges before trying to set their current values
if(ioniceSupported)
ui->sliderIO->setValue(currentIoPrio);
ui->sliderCPU->setValue(currentCpuPrio);
newCPUPriority = 40;
ui->imgCPU->setPixmap( KIcon("cpu").pixmap(128, 128) );
ui->imgIO->setPixmap( KIcon("drive-harddisk").pixmap(128, 128) );
connect(cpuScheduler, SIGNAL(buttonClicked(int)), this, SLOT(cpuSchedulerChanged(int)));
connect(ui->sliderCPU, SIGNAL(valueChanged(int)), this, SLOT(cpuSliderChanged(int)));
newCPUPriority = 40;
connect(cpuScheduler, SIGNAL(buttonClicked(int)), this, SLOT(cpuSchedulerChanged(int)));
connect(ioScheduler, SIGNAL(buttonClicked(int)), this, SLOT(updateUi()));
connect(ui->sliderCPU, SIGNAL(valueChanged(int)), this, SLOT(cpuSliderChanged(int)));
connect(ui->sliderIO, SIGNAL(valueChanged(int)), this, SLOT(ioSliderChanged(int)));
updateUi();
}
void ReniceDlg::ioSliderChanged(int value) {
ui->sliderIO->setToolTip(QString::number(value));
updateUi();
}
void ReniceDlg::cpuSchedulerChanged(int value) {
if(value != previous_cpuscheduler) {
if( (value == (int)KSysGuard::Process::Other || value == KSysGuard::Process::Batch) &&
(previous_cpuscheduler == (int)KSysGuard::Process::Fifo || previous_cpuscheduler == (int)KSysGuard::Process::RoundRobin)) {
int slider = -ui->sliderCPU->value() * 2 / 5 + 20;
setSliderRange();
ui->sliderCPU->setValue( slider );
} else if( (previous_cpuscheduler == (int)KSysGuard::Process::Other || previous_cpuscheduler == KSysGuard::Process::Batch) &&
(value == (int)KSysGuard::Process::Fifo || value == (int)KSysGuard::Process::RoundRobin)) {
int slider = (-ui->sliderCPU->value() + 20) * 5 / 2;
setSliderRange();
ui->sliderCPU->setValue( slider );
}
}
previous_cpuscheduler = value;
updateUi();
if(value != previous_cpuscheduler) {
if( (value == (int)KSysGuard::Process::Other || value == KSysGuard::Process::Batch) &&
(previous_cpuscheduler == (int)KSysGuard::Process::Fifo || previous_cpuscheduler == (int)KSysGuard::Process::RoundRobin)) {
int slider = -ui->sliderCPU->value() * 2 / 5 + 20;
setSliderRange();
ui->sliderCPU->setValue( slider );
} else if( (previous_cpuscheduler == (int)KSysGuard::Process::Other || previous_cpuscheduler == KSysGuard::Process::Batch) &&
(value == (int)KSysGuard::Process::Fifo || value == (int)KSysGuard::Process::RoundRobin)) {
int slider = (-ui->sliderCPU->value() + 20) * 5 / 2;
setSliderRange();
ui->sliderCPU->setValue( slider );
}
}
previous_cpuscheduler = value;
updateUi();
}
void ReniceDlg::cpuSliderChanged(int value) {
if(ioniceSupported) {
if(cpuScheduler->checkedId() == (int)KSysGuard::Process::Other || cpuScheduler->checkedId() == (int)KSysGuard::Process::Batch) {
if( ioScheduler->checkedId() == -1 || ioScheduler->checkedId() == (int)KSysGuard::Process::None) {
//ionice is 'Normal', thus automatically calculated based on cpunice
ui->sliderIO->setValue((value+20)/5);
}
}
}
ui->sliderCPU->setToolTip(QString::number(value));
ui->sliderCPU->setToolTip(QString::number(value));
}
void ReniceDlg::updateUi() {
bool cpuPrioEnabled = ( cpuScheduler->checkedId() != -1);
bool ioPrioEnabled = ( ioniceSupported && ioScheduler->checkedId() != -1 && ioScheduler->checkedId() != (int)KSysGuard::Process::Idle && ioScheduler->checkedId() != (int)KSysGuard::Process::None);
bool cpuPrioEnabled = ( cpuScheduler->checkedId() != -1);
ui->sliderCPU->setEnabled(cpuPrioEnabled);
ui->lblCpuLow->setEnabled(cpuPrioEnabled);
ui->lblCpuHigh->setEnabled(cpuPrioEnabled);
ui->sliderCPU->setEnabled(cpuPrioEnabled);
ui->lblCpuLow->setEnabled(cpuPrioEnabled);
ui->lblCpuHigh->setEnabled(cpuPrioEnabled);
ui->sliderIO->setEnabled(ioPrioEnabled);
ui->lblIOLow->setEnabled(ioPrioEnabled);
ui->lblIOHigh->setEnabled(ioPrioEnabled);
ui->radioIONormal->setEnabled(ioniceSupported);
ui->radioIdle->setEnabled(ioniceSupported);
ui->radioRealTime->setEnabled(ioniceSupported);
ui->radioBestEffort->setEnabled(ioniceSupported);
setSliderRange();
cpuSliderChanged(ui->sliderCPU->value());
ioSliderChanged(ui->sliderIO->value());
setSliderRange();
cpuSliderChanged(ui->sliderCPU->value());
}
void ReniceDlg::setSliderRange() {
if(cpuScheduler->checkedId() == (int)KSysGuard::Process::Other || cpuScheduler->checkedId() == (int)KSysGuard::Process::Batch || cpuScheduler->checkedId() == (int)KSysGuard::Process::Interactive) {
//The slider is setting the priority, so goes from 19 to -20. We cannot actually do this with a slider, so instead we go from -19 to 20, and negate later
if(ui->sliderCPU->value() > 20) ui->sliderCPU->setValue(20);
ui->sliderCPU->setInvertedAppearance(true);
ui->sliderCPU->setMinimum(-19);
ui->sliderCPU->setMaximum(20);
ui->sliderCPU->setTickInterval(5);
} else {
if(ui->sliderCPU->value() < 1) ui->sliderCPU->setValue(1);
ui->sliderCPU->setInvertedAppearance(false);
ui->sliderCPU->setMinimum(1);
ui->sliderCPU->setMaximum(99);
ui->sliderCPU->setTickInterval(12);
}
if(cpuScheduler->checkedId() == (int)KSysGuard::Process::Other || cpuScheduler->checkedId() == (int)KSysGuard::Process::Batch || cpuScheduler->checkedId() == (int)KSysGuard::Process::Interactive) {
//The slider is setting the priority, so goes from 19 to -20. We cannot actually do this with a slider, so instead we go from -19 to 20, and negate later
if(ui->sliderCPU->value() > 20) {
ui->sliderCPU->setValue(20);
}
ui->sliderCPU->setInvertedAppearance(true);
ui->sliderCPU->setMinimum(-19);
ui->sliderCPU->setMaximum(20);
ui->sliderCPU->setTickInterval(5);
} else {
if(ui->sliderCPU->value() < 1) {
ui->sliderCPU->setValue(1);
}
ui->sliderCPU->setInvertedAppearance(false);
ui->sliderCPU->setMinimum(1);
ui->sliderCPU->setMaximum(99);
ui->sliderCPU->setTickInterval(12);
}
}
void ReniceDlg::slotOk()
{
newCPUPriority = ui->sliderCPU->value();
newIOPriority = ui->sliderIO->value();
newCPUSched = cpuScheduler->checkedId();
newIOSched = ioScheduler->checkedId();
newCPUPriority = ui->sliderCPU->value();
newCPUSched = cpuScheduler->checkedId();
}

View file

@ -36,34 +36,26 @@ QT_END_NAMESPACE
*/
class ReniceDlg : public KDialog
{
Q_OBJECT
Q_OBJECT
public:
/** Let the user specify the new priorities of the @p processes given, using the given current values.
* @p currentCpuSched The current Cpu Scheduler of the processes. Set to -1 to they have different schedulers
* @p currentIoSched The current I/O Scheduler of the processes. Set to -1 to they have different schedulers. Leave as the default -2 if not supported
*/
ReniceDlg(QWidget* parent, const QStringList& processes, int currentCpuPrio, int currentCpuSched, int currentIoPrio=-2, int currentIoSched=-2);
int newCPUPriority;
int newIOPriority;
int newCPUSched;
int newIOSched;
bool ioniceSupported;
/** Let the user specify the new priorities of the @p processes given, using the given current values.
* @p currentCpuSched The current Cpu Scheduler of the processes. Set to -1 to they have different schedulers
*/
ReniceDlg(QWidget* parent, const QStringList& processes, int currentCpuPrio, int currentCpuSched);
int newCPUPriority;
int newCPUSched;
public Q_SLOTS:
void slotOk();
void updateUi();
void cpuSliderChanged(int value);
void ioSliderChanged(int value);
void cpuSchedulerChanged(int value);
void slotOk();
void updateUi();
void cpuSliderChanged(int value);
void cpuSchedulerChanged(int value);
private:
void setSliderRange();
Ui_ReniceDlgUi *ui;
QButtonGroup *cpuScheduler;
QButtonGroup *ioScheduler;
int previous_cpuscheduler;
void setSliderRange();
Ui_ReniceDlgUi *ui;
QButtonGroup *cpuScheduler;
int previous_cpuscheduler;
};
#endif

View file

@ -202,170 +202,6 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item row="0" column="2">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QLabel" name="imgIO">
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="4">
<layout class="QVBoxLayout">
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>I/O Scheduler</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>8</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="radioIONormal">
<property name="toolTip">
<string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Process's priority is based on the CPU priority.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Normal Scheduling&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This is the same as &lt;span style=&quot; font-weight:600;&quot;&gt;Best Effort&lt;/span&gt; scheduling, except that the priority is calculated automatically based on the CPU priority. Processes with a higher priority will take priority for access to the hard disk. Programs running at the same &lt;span style=&quot; font-weight:600;&quot;&gt;Best Effort/Normal&lt;/span&gt; priority are served in a &lt;span style=&quot; font-weight:600;&quot;&gt;Round Robin&lt;/span&gt; fashion.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Normal</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioIdle">
<property name="toolTip">
<string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Process can only use the hard disk when no other process has used it very recently.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Idle Scheduling&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A program running with &lt;span style=&quot; font-weight:600;&quot;&gt;Idle&lt;/span&gt; I/O priority will only get disk time when no other program has asked for disk I/O for a defined grace period. The impact of &lt;span style=&quot; font-weight:600;&quot;&gt;Idle&lt;/span&gt; I/O processes on normal system activity should be zero. Priority is not applicable to this scheduling class.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Idle</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioBestEffort">
<property name="toolTip">
<string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Process is given higher priority to access the hard disk than Normal.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Best Effort Scheduling&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Processes with a higher priority will take priority for access to the hard disk. Programs running at the same &lt;span style=&quot; font-weight:600;&quot;&gt;Best Effort/Normal&lt;/span&gt; priority are served in a &lt;span style=&quot; font-weight:600;&quot;&gt;Round Robin&lt;/span&gt; fashion.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Best effort</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioRealTime">
<property name="toolTip">
<string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Process gets immediate access to the hard disk whenever needed, regardless of what else is going on.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Real Time Scheduling&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The &lt;span style=&quot; font-weight:600;&quot;&gt;Real Time&lt;/span&gt; scheduling class is given first access to the disk, regardless of what else is going on in the system. Thus the &lt;span style=&quot; font-weight:600;&quot;&gt;Real Time&lt;/span&gt; class needs to be used with some care, as it can starve other processes. As with the &lt;span style=&quot; font-weight:600;&quot;&gt;Best Effort&lt;/span&gt; class, 8 priority levels are defined denoting how big a time slice a given process will receive on each scheduling window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Real time</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<layout class="QGridLayout">
<item row="0" column="0" colspan="2">
@ -412,71 +248,6 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item row="1" column="2">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="3" colspan="2">
<layout class="QGridLayout">
<item row="0" column="0" colspan="2">
<widget class="QSlider" name="sliderIO">
<property name="maximum">
<number>7</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>3</number>
</property>
<property name="sliderPosition">
<number>3</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblIOLow">
<property name="text">
<string>Low Priority</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lblIOHigh">
<property name="text">
<string>High Priority</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>

View file

@ -1057,22 +1057,19 @@ void KSysGuardProcessList::reniceSelectedProcesses()
}
int sched = -2;
int iosched = -2;
foreach(KSysGuard::Process *process, processes) {
pids << process->pid;
selectedAsStrings << d->mModel.getStringForProcess(process);
if(sched == -2) sched = (int)process->scheduler;
else if(sched != -1 && sched != (int)process->scheduler) sched = -1; //If two processes have different schedulers, disable the cpu scheduler stuff
if(iosched == -2) iosched = (int)process->ioPriorityClass;
else if(iosched != -1 && iosched != (int)process->ioPriorityClass) iosched = -1; //If two processes have different schedulers, disable the cpu scheduler stuff
if(sched == -2) {
sched = (int)process->scheduler;
} else if(sched != -1 && sched != (int)process->scheduler) {
// If two processes have different schedulers, disable the cpu scheduler stuff
sched = -1;
}
}
int firstPriority = processes.first()->niceLevel;
int firstIOPriority = processes.first()->ioniceLevel;
bool supportsIoNice = d->mModel.processController()->supportsIoNiceness();
if(!supportsIoNice) { iosched = -2; firstIOPriority = -2; }
reniceDlg = new ReniceDlg(d->mUi->treeView, selectedAsStrings, firstPriority, sched, firstIOPriority, iosched);
reniceDlg = new ReniceDlg(d->mUi->treeView, selectedAsStrings, firstPriority, sched);
if(reniceDlg->exec() == QDialog::Rejected) {
delete reniceDlg;
return;
@ -1084,7 +1081,6 @@ void KSysGuardProcessList::reniceSelectedProcesses()
QList<long long> renicePids;
QList<long long> changeCPUSchedulerPids;
QList<long long> changeIOSchedulerPids;
foreach (long long pid, pids) {
KSysGuard::Process *process = d->mModel.getProcess(pid);
if (!process)
@ -1110,32 +1106,6 @@ void KSysGuardProcessList::reniceSelectedProcesses()
}
break;
}
switch(reniceDlg->newIOSched) {
case -2:
case -1: //Invalid, not changed etc.
break; //So do nothing
case KSysGuard::Process::None:
if(reniceDlg->newIOSched != (int)process->ioPriorityClass) {
// Unfortunately linux doesn't actually let us set the ioniceness back to none after being set to something else
if(process->ioPriorityClass != KSysGuard::Process::BestEffort || reniceDlg->newIOPriority != process->ioniceLevel)
changeIOSchedulerPids << pid;
}
break;
case KSysGuard::Process::Idle:
if(reniceDlg->newIOSched != (int)process->ioPriorityClass) {
changeIOSchedulerPids << pid;
}
break;
case KSysGuard::Process::BestEffort:
if(process->ioPriorityClass == KSysGuard::Process::None && reniceDlg->newIOPriority == (process->niceLevel + 20)/5)
break; //Don't set to BestEffort if it's on None and the nicelevel wouldn't change
case KSysGuard::Process::RealTime:
if(reniceDlg->newIOSched != (int)process->ioPriorityClass || reniceDlg->newIOPriority != process->ioniceLevel) {
changeIOSchedulerPids << pid;
}
break;
}
}
if(!changeCPUSchedulerPids.isEmpty()) {
Q_ASSERT(reniceDlg->newCPUSched >= 0);
@ -1152,51 +1122,10 @@ void KSysGuardProcessList::reniceSelectedProcesses()
return;
}
}
if(!changeIOSchedulerPids.isEmpty()) {
if(!changeIoScheduler(changeIOSchedulerPids, (KSysGuard::Process::IoPriorityClass) reniceDlg->newIOSched, reniceDlg->newIOPriority)) {
delete reniceDlg;
return;
}
}
delete reniceDlg;
updateList();
}
bool KSysGuardProcessList::changeIoScheduler(const QList< long long> &pids, KSysGuard::Process::IoPriorityClass newIoSched, int newIoSchedPriority)
{
if(newIoSched == KSysGuard::Process::None) newIoSched = KSysGuard::Process::BestEffort;
if(newIoSched == KSysGuard::Process::Idle) newIoSchedPriority = 0;
QList< long long> unchanged_pids;
for (int i = 0; i < pids.size(); ++i) {
bool success = d->mModel.processController()->setIoNiceness(pids.at(i), newIoSched, newIoSchedPriority);
if(!success) {
unchanged_pids << pids.at(i);
}
}
if(unchanged_pids.isEmpty()) return true;
if(!d->mModel.isLocalhost()) return false; //We can't use kauth to affect non-localhost processes
KAuth::Action *action = new KAuth::Action("org.kde.ksysguard.processlisthelper.changeioscheduler");
action->setParentWidget(window());
d->setupKAuthAction( action, unchanged_pids);
action->addArgument("ioScheduler", (int)newIoSched);
action->addArgument("ioSchedulerPriority", newIoSchedPriority);
KAuth::ActionReply reply = action->execute();
if (reply == KAuth::ActionReply::SuccessReply) {
updateList();
delete action;
} else if (reply != KAuth::ActionReply::UserCancelled && reply != KAuth::ActionReply::AuthorizationDenied) {
KMessageBox::sorry(this, i18n("You do not have the permission to change the I/O priority of the process and there "
"was a problem trying to run as root. Error %1 %2", reply.errorCode(), reply.errorDescription()));
delete action;
return false;
}
return true;
}
bool KSysGuardProcessList::changeCpuScheduler(const QList< long long> &pids, KSysGuard::Process::Scheduler newCpuSched, int newCpuSchedPriority)
{
if(newCpuSched == KSysGuard::Process::Other || newCpuSched == KSysGuard::Process::Batch) newCpuSchedPriority = 0;

View file

@ -140,14 +140,6 @@ class KDE_EXPORT KSysGuardProcessList : public QWidget
*/
bool changeCpuScheduler(const QList< long long> &pids, KSysGuard::Process::Scheduler newCpuSched, int newCpuSchedPriority);
/** Change the I/O scheduler for the given of processes to the given scheduler, with the given scheduler priority.
* If the scheduler is Other or Batch, @p newCpuSchedPriority is ignored.
* @return Whether the cpu scheduler changing went ahead. True if successful or user cancelled. False if there was a problem
*/
bool changeIoScheduler(const QList< long long> &pids, KSysGuard::Process::IoPriorityClass newIoSched, int newIoSchedPriority);
/** Renice the processes given to the given niceValue.
* @return Whether the kill went ahead. True if successful or user cancelled. False if there was a problem
* */
bool reniceProcesses(const QList<long long> &pids, int niceValue);
/** Fetch new process information and redraw the display */