This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository enlightenment.

View the commit online.

commit 5ad1680a7d1f1cbed970c501abab7746921b6b05
Author: Carsten Haitzler <ras...@rasterman.com>
AuthorDate: Thu May 5 13:50:25 2022 +0100

    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...
---
 src/bin/e_comp_wl.c |  52 +-----------------
 src/bin/e_comp_x.c  |  66 +----------------------
 src/bin/e_utils.c   | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/bin/e_utils.h   |   3 ++
 4 files changed, 155 insertions(+), 114 deletions(-)

diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 0df8544fa..4e38d4820 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -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
diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c
index ed00d553b..5139bc5ad 100644
--- a/src/bin/e_comp_x.c
+++ b/src/bin/e_comp_x.c
@@ -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
diff --git a/src/bin/e_utils.c b/src/bin/e_utils.c
index f2c983dee..7f5c650ee 100644
--- a/src/bin/e_utils.c
+++ b/src/bin/e_utils.c
@@ -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);
+}
diff --git a/src/bin/e_utils.h b/src/bin/e_utils.h
index 8884ede03..3cca72159 100644
--- a/src/bin/e_utils.h
+++ b/src/bin/e_utils.h
@@ -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,

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to