Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

gettid(2)

resched_cntl(2)

spin_trylock(2)

client_block(2)



server_block(2)               CX/UX               server_block(2)



NAME
     server_block, server_wake1, server_wakevec - client/server
     thread coordination

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

     int server_block (options, r, timeout)
     int options;
     struct resched_var *r;
     struct timeval *timeout;

     int server_wake1 (server, r)
     tid_t server;
     struct resched_var *r;

     int server_wakevec (servers, nservers, r)
     tid_t *servers;
     int nservers;
     struct resched_var *r;

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

     Options must be zero.

     If r is not NULL, server_block 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.

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

     If r is not NULL, server_wake1 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)



     Server_wakevec serves the same purpose as server_wake1,
     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 spin_mutex mx;    /* serializes access to mailbox */
     03   queue_of consumers; /* waiting consumers */
     04   queue_of 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 spin_trylock(2)).  Consumers
     extract data from the mailbox as follows.

     11 void
     12 consume (box, data)
     13   struct mailbox *box;
     14   any_t *data;
     15 {
     16   spin_acquire (&box->mx, &rv);
     17   while (box->data == empty) {
     18        enqueue (box->consumers, rv.rv_tid);
     19        spin_unlock (&box->mx);
     20        server_block (0, &rv, 0);
     21        spin_acquire (&box->mx, &rv);
     22   }
     23   *data = dequeue (box->data);
     24   spin_release (&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   any_t data;
     35 {
     36   spin_acquire (&box->mx, &rv);
     37   enqueue (box->data, data);
     38   if (box->consumers == empty)
     39        spin_release (&box->mx, &rv);
     40   else {
     41        tid_t tid = dequeue (box->consumers);
     42        spin_unlock (&box->mx);
     43        server_wake1 (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 server_wake1 would lengthen its hold time tremen-
     dously.  Also note that rescheduling remains disabled until
     the call to server_wake1 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), resched_cntl(2), spin_trylock(2),
     client_block(2).











































Page 4                        CX/UX Programmer's Reference Manual



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