Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ client_wake1(2) — CX/UX 6.20

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

gettid(2)



client_block(2)               CX/UX               client_block(2)



NAME
     clientblock, clientwake1, clientwakechan - client-server
     thread coordination

SYNOPSIS
     #include <sys/types.h>
     #include <sys/time.h>
     #include <sys/threadsynch.h>

     int clientblock (server, chan, options, m, r, timeout)
     tidt server;
     int chan, options;
     struct spinmutex *m;
     struct reschedvar *r;
     struct timeval *timeout;

     int clientwake1 (server, client, r)
     tidt server, client;
     struct reschedvar *r;

     int clientwakechan (server, chan, r)
     tidt server;
     int chan;
     struct reschedvar *r;

DESCRIPTION
     When one thread requests service from another, the former
     thread is called a "client", and the latter thread is called
     a "server." To control priority inversion, a server should
     have a priority at least as high as any of its clients.  The
     routines described here provide a priority inheritance
     mechanism.

     clientblock blocks the calling thread (a client) and estab-
     lishes a formal client-server relationship with another
     thread (the server).  Clientwake1 and clientwakechan wake
     threads that are blocked in clientblock.

     clientblock releases spinlock m, decrements the number of
     rescheduling locks in r, and blocks the caller.  The unlock
     and block operations are atomic to guarantee that the caller
     does not miss a wakeup.  Server's priority will be at least
     as high as the caller's while the caller is blocked.  m and
     r are optional and may be specified as NULL.

     If the options flag is 1 the server will be woken as in
     serverwake1(2).

     The chan parameter groups related clients of a server.  It
     is used by clientwakechan.





Page 1                        CX/UX Programmer's Reference Manual





client_block(2)               CX/UX               client_block(2)



     If timeout is not NULL, it specifies the maximum length of
     time the caller will be blocked.  If timeout is NULL, the
     caller is blocked indefinitely.

     The real or effective user ID of the caller must match the
     real or effective user ID of server, unless the effective
     user ID of the caller is super-user.

     The caller should be prepared for premature returns; that
     is, it should re-test the condition that originally caused
     it to block.  Upon return there is no guarantee that the
     condition blocking the caller has changed.

     Clientwake1 wakes client, if it is blocked in clientblock
     requesting service from server, and decrements the number of
     rescheduling locks in r.  If client is not blocked under
     these conditions, clientwake1 has no effect on it.  A value
     of 0 for server refers to the calling thread.  (In this
     implementation, server must be 0.)

     The real or effective user ID of the caller must match the
     real or effective user ID of client, unless the effective
     user ID of the caller is super-user.

     Clientwakechan wakes all of the clients grouped under chan
     requesting service from server, and decrements the number of
     rescheduling locks in r.  A value of 0 for server refers to
     the calling thread.  (In this implementation, server must be
     0.)  A value of 0 for chan wakes ALL of the server's
     clients.

     The real or effective user ID of the caller must match the
     real or effective user ID of the clients, unless the effec-
     tive user ID of the caller is super-user.

EXAMPLES
     Priority inversion is a condition wherein one or more low
     priority threads prevent the progress of a high priority
     thread.  The most often cited example is that of a low
     priority thread L being preempted in a critical region.  A
     high priority thread H attempting to enter the critical
     region will block until L leaves the critical region.  How-
     ever, threads in the priority gap between H and L prevent L
     from running.  If L were to inherit H's priority, the gap
     would close and L would run until it was preempted by H upon
     exit from the critical region.

     The code fragments below implement priority inheritance in
     sleepy-wait mutual exclusion.  Let

     01 struct sleepmutex {
     02   struct spinmutex mx;



Page 2                        CX/UX Programmer's Reference Manual





client_block(2)               CX/UX               client_block(2)



     03   tidt owner;
     04   int waiters;
     05 };

     represent a sleepy-wait mutex.  The owner field identifies
     the thread that owns the mutex, the waiters field indicates
     whether threads are blocked on the mutex, and the mx field
     serializes access to the mutex.  Let rv represent the run-
     ning thread's rescheduling variable, and spin_acquire and
     spin_release represent primitives that lock and unlock spin-
     locks and rescheduling variables (see spintrylock(2)).

     A mutex may be locked as follows.

     11 void
     12 sleeplock (s)
     13   struct sleepmutex *s;
     14 {
     15   spinacquire (&s->mx, &rv);
     16   while (s->owner) {
     17        s->waiters = 1;
     18        clientblock (s->owner, s, 0, &s->mx, &rv, 0);
     19        spinacquire (&s->mx, &rv);
     20   }
     21   s->owner = rv.rvtid;
     22   spinrelease (&s->mx, &rv);
     23 }

     Although perhaps an unusual interpretation of the client-
     server relationship, the owner of the mutex is considered to
     be a server, and the waiting threads are considered to be
     its clients.  clientblock guarantees that the owner's
     priority is at least as high as any of the waiting threads.
     This example assumes that a mutex appears at the same loca-
     tion in every thread's address space, so the address of the
     mutex is used as the chan argument to clientblock to dis-
     tinguish one mutex's waiters from another's.

     A mutex may be unlocked as follows.

     31 void
     32 sleepunlock (s)
     33   struct sleepmutex *s;
     34 {
     35   int werewaiters;
     36
     37   spinacquire (&s->mx, &rv);
     38   if (s->owner != rv.rvtid) {
     39        Indicate error condition.
     40   }
     41   s->owner = 0;
     42   werewaiters = s->waiters;



Page 3                        CX/UX Programmer's Reference Manual





client_block(2)               CX/UX               client_block(2)



     43   s->waiters = 0;
     44   spinunlock (&s->mx);
     45
     46   if (werewaiters)
     47        clientwakechan (0, s, &rv);
     48   else
     49        reschedunlock (&rv);
     50 }

     When an owner releases a mutex all of the waiters are woken.
     The newly awakened waiters re-contend for the mutex when
     they execute.  One will become the new owner of the mutex,
     while the others block and establish new client-server rela-
     tionships.

RETURN VALUE
     Upon successful completion 0 is returned.  Otherwise, -1 is
     returned and errno is set to indicate the error.

ERRORS
     These routines will fail if any of the following are true:

     [EFAULT]       A bad address was specified for one of the
                    arguments.

     [EINVAL]       The spinlock specified in m was not in the
                    locked state.

     [EINVAL]       The timeout was invalid.

     [EINVAL]       The rescheduling variable specified in r was
                    not the caller's rescheduling variable.

     [EINVAL]       The number of rescheduling locks in r was <=
                    0.

     [ESRCH]        No thread could be found with the specified
                    ID.

     [EPERM]        The user ID of the calling thread was not
                    super-user, and its real or effective user ID
                    did not match the real or effective user ID
                    of the target thread.

     [EINTR]        The system call was interrupted by a signal.

     [ETIME]        The system call timed out.

SEE ALSO
     CX/UX Programmer's Guide.
     gettid(2), reschedcntl(2), spintrylock(2),
     serverblock(2).



Page 4                        CX/UX Programmer's Reference Manual



Typewritten Software • bear@typewritten.org • Edmonds, WA 98026