Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ server_wake1(2) — CX/UX 6.20

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

gettid(2)



server_block(2)               CX/UX               server_block(2)



NAME
     serverblock, serverwake1, serverwakevec - client/server
     thread coordination

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

     int serverblock (options, r, timeout)
     int options;
     struct reschedvar *r;
     struct timeval *timeout;

     int serverwake1 (server, r)
     tidt server;
     struct reschedvar *r;

     int serverwakevec (servers, nservers, r)
     tidt *servers;
     int nservers;
     struct reschedvar *r;

DESCRIPTION
     serverblock blocks the calling thread if no wake-up has
     occurred since the last return from serverblock.  If a
     wake-up has occurred, serverblock returns immediately.

     Options must be zero.

     If r is not NULL, serverblock decrements the number of
     locks in the rescheduling variable.

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

     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.

     Serverwake1 wakes thread server if it is blocked in
     serverblock.  If server is not blocked in serverblock, the
     wake-up will be applied to the next call to serverblock.

     If r is not NULL, serverwake1 decrements the number of
     locks in the rescheduling variable.

     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.




Page 1                        CX/UX Programmer's Reference Manual





server_block(2)               CX/UX               server_block(2)



     Serverwakevec serves the same purpose as serverwake1,
     except that a vector of threads may be specified rather than
     one thread.

EXAMPLES
     Suppose that producer and consumer threads exchange data
     through a mailbox in shared memory.  When the mailbox is
     empty, consumers block until data arrives.  When producers
     deposit new data, they wake the waiting consumers.

     In the pseudo-code that follows, let

     01 struct mailbox {
     02   struct spinmutex mx;    /* serializes access to mailbox */
     03   queueof consumers; /* waiting consumers */
     04   queueof data;      /* the data, type varies */
     05 };

     represent a mailbox in shared memory, rv represent a
     rescheduling variable, and spin_acquire and spin_release
     represent primitives that lock and unlock spinlocks and
     rescheduling variables (see spintrylock(2)).  Consumers
     extract data from the mailbox as follows.

     11 void
     12 consume (box, data)
     13   struct mailbox *box;
     14   anyt *data;
     15 {
     16   spinacquire (&box->mx, &rv);
     17   while (box->data == empty) {
     18        enqueue (box->consumers, rv.rvtid);
     19        spinunlock (&box->mx);
     20        serverblock (0, &rv, 0);
     21        spinacquire (&box->mx, &rv);
     22   }
     23   *data = dequeue (box->data);
     24   spinrelease (&box->mx, &rv);
     25 }

     The mailbox is a shared data structure requiring serializa-
     tion.  Consumer threads lock the mailbox to test for the
     presence of and ultimately to extract the data.  When they
     wait, consumers unlock the mailbox to allow producers to
     deposit new data.  Consumers re-check the mailbox when they
     awaken because there is no guarantee that the mailbox will
     contain data.

     Producers store data into the mailbox as follows.  This
     example assumes that at most one consumer can benefit from
     the arrival of the new data, so producers wake one rather
     than all consumers.



Page 2                        CX/UX Programmer's Reference Manual





server_block(2)               CX/UX               server_block(2)



     31 void
     32 produce (box, data)
     33   struct mailbox *box;
     34   anyt data;
     35 {
     36   spinacquire (&box->mx, &rv);
     37   enqueue (box->data, data);
     38   if (box->consumers == empty)
     39        spinrelease (&box->mx, &rv);
     40   else {
     41        tidt tid = dequeue (box->consumers);
     42        spinunlock (&box->mx);
     43        serverwake1 (tid, &rv);
     44   }
     45 }

     Producers signal the arrival of new data only when there is
     a waiting consumer, and do so AFTER they unlock the mailbox.
     The first act of a newly awakened consumer is to lock the
     mailbox.  If a producer were to awaken a consumer before it
     unlocked the mailbox, the consumer may run only to find the
     mailbox locked.  Furthermore, spinlocks should only be held
     for short periods of time.  Unlocking the mailbox after the
     call to serverwake1 would lengthen its hold time tremen-
     dously.  Also note that rescheduling remains disabled until
     the call to serverwake1 in order to prevent unnecessary
     context switching.

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]       Options was non-zero.

     [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
                    less than or equal to 0.

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

     [EPERM]        The user ID of the calling thread was not



Page 3                        CX/UX Programmer's Reference Manual





server_block(2)               CX/UX               server_block(2)



                    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),
     clientblock(2).











































Page 4                        CX/UX Programmer's Reference Manual



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