forked from enlightenment/enlightenment
e nice/pri change - centralise to util code
also getrlimit to know if we can lower nice level, you will want something like: * - nice 0 in /etc/security/limits.conf to allow for users to both raise and lower nice level up until this limit (ie not negative nice levels). perhaps enlightenment_system needs to do this...
This commit is contained in:
parent
e0ccb08d0a
commit
5ad1680a7d
|
@ -534,59 +534,12 @@ _e_comp_wl_evas_cb_multi_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_comp_wl_client_priority_adjust(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_child, Eina_Bool do_child)
|
||||
{
|
||||
Eina_List *files;
|
||||
char *file, buff[PATH_MAX];
|
||||
FILE *f;
|
||||
int pid2, ppid;
|
||||
int num_read;
|
||||
int n;
|
||||
|
||||
if (use_adj)
|
||||
n = (getpriority(PRIO_PROCESS, pid) + adj);
|
||||
else
|
||||
n = set;
|
||||
|
||||
setpriority(PRIO_PROCESS, pid, n);
|
||||
|
||||
if (adj_child)
|
||||
use_adj = EINA_TRUE;
|
||||
|
||||
if (!do_child) return;
|
||||
|
||||
files = ecore_file_ls("/proc");
|
||||
EINA_LIST_FREE(files, file)
|
||||
{
|
||||
if (!isdigit(file[0]))
|
||||
continue;
|
||||
|
||||
snprintf(buff, sizeof(buff), "/proc/%s/stat", file);
|
||||
if ((f = fopen(buff, "r")))
|
||||
{
|
||||
pid2 = -1;
|
||||
ppid = -1;
|
||||
num_read = fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid);
|
||||
fclose(f);
|
||||
if (num_read == 2 && ppid == pid)
|
||||
_e_comp_wl_client_priority_adjust(pid2, set,
|
||||
adj, use_adj,
|
||||
adj_child, do_child);
|
||||
}
|
||||
|
||||
free(file);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_comp_wl_client_priority_raise(E_Client *ec)
|
||||
{
|
||||
if (ec->netwm.pid <= 0) return;
|
||||
if (ec->netwm.pid == getpid()) return;
|
||||
_e_comp_wl_client_priority_adjust(ec->netwm.pid,
|
||||
e_config->priority - 1, -1,
|
||||
EINA_FALSE, EINA_TRUE, EINA_FALSE);
|
||||
e_pid_nice_priority_fg(ec->netwm.pid);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -594,8 +547,7 @@ _e_comp_wl_client_priority_normal(E_Client *ec)
|
|||
{
|
||||
if (ec->netwm.pid <= 0) return;
|
||||
if (ec->netwm.pid == getpid()) return;
|
||||
_e_comp_wl_client_priority_adjust(ec->netwm.pid, e_config->priority, 1,
|
||||
EINA_FALSE, EINA_TRUE, EINA_FALSE);
|
||||
e_pid_nice_priority_bg(ec->netwm.pid);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
|
|
@ -657,58 +657,6 @@ _e_comp_x_add_fail_job(void *d EINA_UNUSED)
|
|||
"GPU to use OpenGL with compositing."));
|
||||
}
|
||||
|
||||
static void
|
||||
_pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
|
||||
{
|
||||
int newpri = set;
|
||||
|
||||
if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
|
||||
setpriority(PRIO_PROCESS, pid, newpri);
|
||||
// shouldn't need to do this as default ionice class is "none" (0), and
|
||||
// this inherits io priority FROM nice level
|
||||
// ioprio_set(IOPRIO_WHO_PROCESS, pid,
|
||||
// IOPRIO_PRIO_VALUE(2, 5));
|
||||
if (do_children)
|
||||
{
|
||||
Eina_List *files;
|
||||
char *file, buf[PATH_MAX];
|
||||
FILE *f;
|
||||
int pid2, ppid;
|
||||
|
||||
// yes - this is /proc specific... so this may not work on some
|
||||
// os's - works on linux. too bad for others.
|
||||
files = ecore_file_ls("/proc");
|
||||
EINA_LIST_FREE(files, file)
|
||||
{
|
||||
if (isdigit(file[0]))
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
|
||||
f = fopen(buf, "r");
|
||||
if (f)
|
||||
{
|
||||
pid2 = -1;
|
||||
ppid = -1;
|
||||
if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
|
||||
{
|
||||
fclose(f);
|
||||
if (ppid == pid)
|
||||
{
|
||||
if (adj_children)
|
||||
_pri_adj(pid2, set, adj, EINA_TRUE,
|
||||
adj_children, do_children);
|
||||
else
|
||||
_pri_adj(pid2, set, adj, use_adj,
|
||||
adj_children, do_children);
|
||||
}
|
||||
}
|
||||
else fclose(f);
|
||||
}
|
||||
}
|
||||
free(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static E_Client *
|
||||
_e_comp_x_client_find_by_alarm(Ecore_X_Sync_Alarm al)
|
||||
{
|
||||
|
@ -953,12 +901,7 @@ _e_comp_x_client_pri_raise(E_Client *ec)
|
|||
{
|
||||
if (ec->netwm.pid <= 0) return;
|
||||
if (ec->netwm.pid == getpid()) return;
|
||||
_pri_adj(ec->netwm.pid,
|
||||
e_config->priority - 1, -1, EINA_FALSE,
|
||||
// EINA_TRUE, EINA_TRUE);
|
||||
EINA_TRUE, EINA_FALSE);
|
||||
// printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
|
||||
// ec->netwm.pid, e_client_util_name_get(ec));
|
||||
e_pid_nice_priority_fg(ec->netwm.pid);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -966,12 +909,7 @@ _e_comp_x_client_pri_norm(E_Client *ec)
|
|||
{
|
||||
if (ec->netwm.pid <= 0) return;
|
||||
if (ec->netwm.pid == getpid()) return;
|
||||
_pri_adj(ec->netwm.pid,
|
||||
e_config->priority, 1, EINA_FALSE,
|
||||
// EINA_TRUE, EINA_TRUE);
|
||||
EINA_TRUE, EINA_FALSE);
|
||||
// printf("WIN: pid %i, title %s (NORMAL)\n",
|
||||
// ec->netwm.pid, e_client_util_name_get(ec));
|
||||
e_pid_nice_priority_bg(ec->netwm.pid);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1591,3 +1591,151 @@ e_username_get(void)
|
|||
if (pw) return pw->pw_name;
|
||||
return "";
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pid;
|
||||
int pri_set, pri_adj;
|
||||
int pri_only_filter;
|
||||
Eina_Bool do_adj : 1;
|
||||
Eina_Bool do_adj_children : 1;
|
||||
Eina_Bool do_children : 1;
|
||||
} E_Pri_Set_Adj_Data;
|
||||
|
||||
static void
|
||||
_pri_adj(int pid, int pri_set, int pri_adj, int pri_only_filter,
|
||||
Eina_Bool do_adj, Eina_Bool do_adj_children, Eina_Bool do_children)
|
||||
{
|
||||
Eina_List *files;
|
||||
char *file, buf[PATH_MAX];
|
||||
int pid2, ppid, newpri, ret;
|
||||
FILE *f;
|
||||
|
||||
newpri = getpriority(PRIO_PROCESS, pid) + pri_adj;
|
||||
if ((pri_only_filter == -99) || (pri_only_filter != newpri))
|
||||
{
|
||||
if (do_adj) newpri += pri_adj;
|
||||
else newpri = pri_set;
|
||||
if (newpri > 19) newpri = 19;
|
||||
// printf("PRI: %i -> %i (adj=%i, adj_ch=%i ch=%i)\n", pid, newpri, do_adj, do_adj_children, do_children);
|
||||
ret = setpriority(PRIO_PROCESS, pid, newpri);
|
||||
// if (ret < 0) printf("PRI: ret = %i | %s\n", ret, strerror(errno));
|
||||
}
|
||||
// shouldn't need to do this as default ionice class is "none" (0), and
|
||||
// this inherits io priority FROM nice level
|
||||
// ioprio_set(IOPRIO_WHO_PROCESS, pid,
|
||||
// IOPRIO_PRIO_VALUE(2, 5));
|
||||
if (do_children)
|
||||
{
|
||||
// yes - this is /proc specific... so this may not work on some
|
||||
// os's - works on linux. too bad for others.
|
||||
files = ecore_file_ls("/proc");
|
||||
EINA_LIST_FREE(files, file)
|
||||
{
|
||||
if (isdigit(file[0]))
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
|
||||
f = fopen(buf, "r");
|
||||
if (f)
|
||||
{
|
||||
pid2 = ppid = -1;
|
||||
ret = fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid);
|
||||
fclose(f);
|
||||
if (ret == 2)
|
||||
{
|
||||
if (ppid == pid)
|
||||
{
|
||||
if (do_adj_children)
|
||||
_pri_adj(pid2, pri_set, pri_adj,
|
||||
pri_only_filter,
|
||||
EINA_TRUE,
|
||||
do_adj_children,
|
||||
do_children);
|
||||
else
|
||||
_pri_adj(pid2, pri_set, pri_adj,
|
||||
pri_only_filter,
|
||||
do_adj,
|
||||
do_adj_children,
|
||||
do_children);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_pid_nice_priority_set_adjust_thread(void *data,
|
||||
Ecore_Thread *eth EINA_UNUSED)
|
||||
{
|
||||
E_Pri_Set_Adj_Data *dat = data;
|
||||
|
||||
// printf("PRI: --------\n");
|
||||
_pri_adj(dat->pid, dat->pri_set, dat->pri_adj, dat->pri_only_filter,
|
||||
dat->do_adj, dat->do_adj_children, dat->do_children);
|
||||
free(dat);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_pid_nice_priority_set_adjust(int pid, int pri_set, int pri_adj,
|
||||
int pri_only_filter,
|
||||
Eina_Bool do_adj, Eina_Bool do_adj_children,
|
||||
Eina_Bool do_children)
|
||||
{
|
||||
E_Pri_Set_Adj_Data *dat = calloc(1, sizeof(E_Pri_Set_Adj_Data));
|
||||
|
||||
if (!dat) return;
|
||||
dat->pid = pid;
|
||||
dat->pri_set = pri_set;
|
||||
dat->pri_adj = pri_adj;
|
||||
dat->pri_only_filter = pri_only_filter;
|
||||
dat->do_adj = do_adj;
|
||||
dat->do_adj_children = do_adj_children;
|
||||
dat->do_children = do_children;
|
||||
ecore_thread_run(_e_pid_nice_priority_set_adjust_thread, NULL, NULL, dat);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_pid_nice_priority_lower_can(void)
|
||||
{
|
||||
#ifdef RLIMIT_NICE
|
||||
static int checked = -1;
|
||||
struct rlimit rlim;
|
||||
|
||||
again:
|
||||
if (checked == 0) return EINA_FALSE;
|
||||
else if (checked == 1) return EINA_TRUE;
|
||||
|
||||
checked = 1;
|
||||
if (getrlimit(RLIMIT_NICE, &rlim) == 0)
|
||||
{
|
||||
// if we can't lower pri to at least 20 (nice 0 ...) then assume
|
||||
// we can only raise nice level never lower it
|
||||
if (rlim.rlim_cur < 20) checked = 0;
|
||||
}
|
||||
goto again; // set checked now - try again
|
||||
#endif
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_pid_nice_priority_fg(int pid)
|
||||
{
|
||||
int pri = e_config->priority - 1;
|
||||
|
||||
if (!_e_pid_nice_priority_lower_can()) pri = e_config->priority;
|
||||
_e_pid_nice_priority_set_adjust(pid, pri, -1, -99, // only these procs
|
||||
EINA_FALSE, EINA_FALSE, EINA_FALSE);
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_pid_nice_priority_bg(int pid)
|
||||
{
|
||||
int pri = e_config->priority;
|
||||
|
||||
if (!_e_pid_nice_priority_lower_can()) pri = e_config->priority;
|
||||
_e_pid_nice_priority_set_adjust(pid, pri, 1, -99, // only these procs
|
||||
EINA_FALSE, EINA_FALSE, EINA_FALSE);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,9 @@ E_API Ecore_Exe *e_util_exe_safe_run(const char *cmd, void *data);
|
|||
|
||||
E_API const char *e_username_get(void);
|
||||
|
||||
E_API void e_pid_nice_priority_fg(int pid);
|
||||
E_API void e_pid_nice_priority_bg(int pid);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
E_UTIL_ACTION_NONE,
|
||||
|
|
Loading…
Reference in New Issue