Priority in QNX4 and QNX6?

Hi all!,

I’m big problem here, my task was to poart applications from QNX4 to QNX6 . In QNX4, the priority of each process will fixed from beginning of it creation. Then I notice the priority of each process in
QNX 6 keep changing and not fix from what we set before.
I create each process by calling spawn() and setprio(). Is there a way to make fix the priority of each process?

arms

Hello.

I use to change the priority by thread changing the sched_priority parameter of the thread in QNX 6.2.1 (I havent used QNX4).

If you use setprio, it only changes the priority of thread 1.

By default threads are created with priority 10. What happens is, if you change the priority of a thread to 15 but another thread is created with priority 10 and there are communication between them (message passing), the thread that acts as a server inherits the priority of the client. After that, the server changes the priority again (this is called priority inversion). This is a normal behaviour. It can be changed using the NTO_CHF_FIXED_PRIORITY flag but it is not recommended.

You can write a generic function that changes the priority of a thread and that can be called by any thread.
Then, you can call this function at the beginning of each thread.
I have something like that (this function changes the priority of the thread which call it).

void F_New_Thread_Priority(int new_prio)
{
sched_param_t param_prio;
int status;
int policy_thread;

status=pthread_getschedparam(0, &policy_thread, &param_prio);
param_prio.sched_priority=new_prio;	

status=pthread_setschedparam(0, policy_thread, &param_prio);

}

I hope it helps, it is just an example. It works for me, but may be there are better solutions. Sorry for my english.

In QNX6 “objects” hold priority inheritance information (i.e. it is not an attribute of an execution context). As far as Posix goes, QNX supports priority aware mutexes, and these can alter the priority of threads that are using them.

You are most likely interested in the channel object (which is QNX specific). When you create a channel object (using ChannelCreate) you can specify whether it alters the priority of threads using it (based on priority inheritance) or does not affect the priority of threads using it. The default is (rightly so) that the channel object will alter priority of the calling thread based on the priority inheritance protocol; in order to disable this feature, you must create the channel with the _NTO_CHF_FIXED_PRIORITY flag set.

See CreateChannel() in the docs…

Rennie

what if my server process uses name_attach() instead of CreateChannel()? in name_attach() I don’t think I can pass _NTO_CHF_FIXED_PRIORITY flag. Then how can I stop priority inversion of my server ?

Your in luck, as name_attach does not set _NTO_CHF_FIXED_PRIORITY; thus, priority inheritance is enabled

Rennie

that sucks… I thought name_attach calls CreateChannel() internally… hmmm
then how can we make resource manager to not to inherite priority?

Sadly,my application use name_attach() for InterProcessCommunication,
and can’t set _NTO_CHF_FIXED_PRIORITY. What should I do?

arms

name_attach does call ChannelCreate(); it just doesn’t call it with _NTO_CHF_FIXED_PRIORITY. If you want to disable the priority inheritance protocol then you’ll need to hand tweak the dispatch struct, and pass this into name_attach().

Here is some sample code:

  struct _dispatch *dpp=dispatch_create();
   
   if(dpp) {
     dpp->chid=ChannelCreate(_NTO_CHF_UNBLOCK|
                             _NTO_CHF_DISCONNECT|
                             _NTO_CHF_COID_DISCONNECT|
                             _NTO_CHF_FIXED_PRIORITY);
     if(dpp->chid != -1) {
       attach =name_attach(dpp, "Foo", 0);
     }
   }

If you pass a non-null pointer as the first argument to name_attach it will not call ChannelCreate, and you can therefore manually call ChannelCreate however you like. Of course struct _dispatch is supposed to be opaque so this might bite you in the future (you have been warned).

Hi rgallen and all!,

I use your sample code but did’nt work. Its says "invalid use of undefined type `struct _dispatch’ " when I compile it. Seem chid is not part of struct _dispatch. Any sollution?

You’ll have to include the header that defines “struct _dispatch”, finding out which header that is, is an exercise for the reader (since I am not on a QNX machine at the moment)…

Hi,
I already include that header file and the result still same. Error in compilation?
Any suggestion? help me!
#include <sys/iofunc.h>
#include <sys/dispatch.h>

Well the compilation error you show is "invalid use of undefined type `struct _dispatch’ ", which means that the compiler is not finding a definition for “struct _dispatch”. Try defining struct _dispatch as follows in your program…

struct _dispatch {
    //enum dispatch_type        type;
    int                     (*other_func)(resmgr_context_t *ctp, void *msg);
    unsigned                nparts_max;
    unsigned                msg_max_size;
    int                     block_type;
    struct timespec         timeout;
    unsigned int            flags;
    int                     chid;
    unsigned int            context_size;
};

struct _dispatch is a private libc header.

I’m assuming you got it from cvs.qnx.com? :v)

Can’t remember now. Just know I had one occasion where I needed fixed priority, and getting the definition of this struct is how I ended up achieving it. There may be better ways, and I am not endorsing fixed priority in any way (my requirement for fixed priority was due to a design defect).

Rennie

Hi rgallen and all of you,
It’s work very well. Thanks :smiley:

One other solution might be:

chid = ChannelCreate( _NTO_CHF_FIXED_PRIORITY);
dpp = _dispatch_create(chid, NULL);
name_attach(dpp, path, 0);

note: _dispatch_create is undocumented

Yeah, I new I had heard of this, but I can’t remember where. This is a better solution.

but said that _dispatch_create is not documented. Anyone know why?

Probably to discourage fixed priority channels :slight_smile:

Actually, I have no idea…

Rennie