setpriority() again

hi sebastian,

I'm currently coding a suid wrapper for beast to increase
nicety of the sound threads. basically, things work as
1) suidwrapper starts, does setpriority (PRIO_PROCESS, getpid(), PRIO_MIN); (i.e. nice=-20)
2) drops suid-ness to euid
3) suidwrapper executes beast
4) beast starts BSE thread
5) beast drops priority (via setpriority (PRIO_PROCESS, getpid(), 0); since
   i have no idea how to use g_thread_set_priority() to get exactly nice=0)
6) BSE thread starts SoundSequencer thread (with G_THREAD_PRIORITY_NORMAL)
7) upon user action: BSE thread starts SoundEngine thread (with G_THREAD_PRIORITY_NORMAL)

now, upon execution of (7) i'm getting:

(BEAST:21727): GLib-WARNING **: Priorities can only be increased by root.

the system setup i'm using is linux-2.6.1, glibc-2.3.2, gcc-3.3, glib-2.2.3.

the code for PID priorities in gthread.c does:
  priority_map[G_THREAD_PRIORITY_NORMAL] = getpriority (PRIO_PROCESS, (getpid ()));
  priority_map[G_THREAD_PRIORITY_LOW] = MIN (20, priority_map[G_THREAD_PRIORITY_NORMAL] + 10);
  priority_map[G_THREAD_PRIORITY_HIGH] = MAX (-20, priority_map[G_THREAD_PRIORITY_NORMAL] - 10);
  priority_map[G_THREAD_PRIORITY_URGENT] = MAX (-20, priority_map[G_THREAD_PRIORITY_NORMAL] - 15);
and i'm creating my threads with G_THREAD_PRIORITY_NORMAL.

note that under NPTL, getpid() returns the same value for all the threads
created under 4, 5, 6 and 7. so basically what happens is:
- when beast starts and does g_thread_init(),
  priority_map[G_THREAD_PRIORITY_NORMAL] is set to -20.
- the BSE thread and SoundSequencer threads are started *before* (5) is
  being executed.
- the newly started threads do
  setpriority(getpid(),priority_map[G_THREAD_PRIORITY_NORMAL]) and succeed.
  i.e. they try to set the priority of *beast* to a priority they and beast
  already have,
- beast drops priority to 0, i.e. (5) is being executed
- the SoundEngine thread started tries to
  setpriority(getpid(),priority_map[G_THREAD_PRIORITY_NORMAL]), i.e. tries
  to set its own priority to a priority it already has (namely -20), but
  fails to set the *beast* priority (now 0) to -20.

i think we should really disable the PID surrogate stuff, there's not much
point in renicing the same pid over and over with newer linuxes. and even
with older ones where this approach still works, it's pretty pointless to
reset priorities upon thread creation to a priority the main thread once had.

we should face it: thread priorities as provided by posix are a different
beast from pid niceties and thus need to be handled differently. in particular,
pid nicety handling has to be left up to the user, to not hinder:
- nice-level settings via a config dialog/file or command line option (here,
  users will want to specify exact nice levels)
- nice-level preparation via sudo wrappers, glib shouldn't interfere with that
  process by forcing nice-level resets
- ordinary idle cruncher nicing.

especially for the third scenario, it's more than a nuisance that
g_thread_set_priority() throws a programming warning if it fails for whatever
reason. e.g. trying to nice an idle cruncher to +5 via g_thread_set_priority()
throws a programming warning if the user started the program with nice levels >=6.
in a different scenario, the idle cruncher might renice itself by means of invoking
nice(+5) directly (since g_thread_set_priority() can't be used to accurately set
nice levels). in this case, it can't start anymore threads, since every new thread
will try to either renice itself or the main thread (NPTL) to the better original
nice level (-5 from the current, only allowed by root).

side note: stefan, due to getpid() returning the same pid for all threads,
   i'm not able to slightly lower the priority of the BSE thread compared to
   the SoundSequencer/SoundEngine threads.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]