Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ copyb(D3DK) — Motorola System V 88k Release 4 Version 4.3

Media Vault

Software Library

Restoration Projects

Artifacts Sought

copyb(D3DK)  —  

.IX \f4copyb\fP(D3DK)

NAME

copyb − copy a message block

SYNOPSIS

#include <sys/stream.h>
mblk_t ∗copyb(mblk_t ∗bp);

ARGUMENTS

bpPointer to the message block from which data are copied. 

DESCRIPTION

copyb allocates a new message block, and copies into it the data from the block pointed to by bp.  The new block will be at least as large as the block being copied.  The b_rptr and b_wptr members of the message block pointed to by bp are used to determine how many bytes to copy. 

RETURN VALUE

If successful, copyb returns a pointer to the newly allocated message block containing the copied data.  Otherwise, it returns a NULL pointer. 

LEVEL

Base or Interrupt. 

NOTES

Does not sleep. 

Driver-defined basic locks, read/write locks, and sleep locks may be held across calls to this function. 

SEE ALSO

allocb(D3DK), copymsg(D3DK), msgb(D4DK)

EXAMPLE

This example illustrates how copyb can be used during message retransmission.  If there are no messages to retransmit, we return (line 21).  Otherwise, we lock the retransmission list (line 23).  For each retransmission record in the list, we test to see if either the message has already been retransmitted, or if the downstream queue is full (by calling canputnext(D3DK) on line 26).  If either is true, we skip the current retransmission record and continue searching the list.  Otherwise, we use copyb(D3DK) to copy a header message block (line 30), and dupmsg(D3DK) to duplicate the data to be retransmitted (line 32). 

If either operation fails, we clean up and break out of the loop.  Otherwise, we update the new header block with the correct destination address (line 37), link the message to be retransmitted to it (line 38), mark the retransmission record as having sent the message (line 39), unlock the retransmission list (line 40), and send the message downstream (line 41).  Then we go back and lock the list again and start searching for more messages to retransmit. 

This continues until we are either at the end of the retransmission list, or unable to send a message because of allocation failure.  With the list still locked, we clear all the flags for sent messages (lines 44 and 45).  Finally, we unlock the list lock and reschedule a timeout at the next valid interval (line 47) and return.  Since we are using itimeout(D3DK), retransmit will run at the specified processor level, plstr. 

 1  struct retrns {
 2mblk_t∗r_mp;/∗ message to retransmit ∗/
 3longr_address;/∗ destination address ∗/
 4queue_t∗r_outq;/∗ output queue ∗/
 5struct retrns∗r_next;/∗ next retransmission ∗/
 6uchar_tr_sent;/∗ message sent ∗/
 7  };
 8  struct protoheader {
 9longh_address;/∗ destination address ∗/
...
10  };
11  mblk_t ∗header;
12  lock_t ∗retranslck;
13  struct retrns ∗rlist;
    ...
14  retransmit()
15  {
16register mblk_t ∗bp, ∗mp;
17register struct retrns ∗rp;
18struct protoheader ∗php;
19pl_t pl;
 20if (!rlist)
21return;
22  loop:
23pl = LOCK(retranslck, plstr);
24rp = rlist;
25while (rp) {
26if (rp->r_sent || !canputnext(rp->r_outq)) {
27rp = rp->r_next;
28continue;
29}
30if ((bp = copyb(header)) == NULL)
31break;
32if ((mp = dupmsg(rp->r_mp)) == NULL) {
33freeb(bp);
34break;
35}
36php = (struct protoheader ∗)bp->b_rptr;
37php->h_address = rp->r_address;
38bp->bp_cont = mp;
39rp->r_sent = 1;
40UNLOCK(retranslck, pl);
41putnext(rp->r_outq, bp);
42goto loop;
43}
44for (rp = rlist; rp; rp = rp->r_next)
45rp->r_sent = 0;
46UNLOCK(retranslck, pl);
47(void) itimeout(retransmit, 0, RETRNS_TIME, plstr);
48  }

.IX \f4copyb\fP(D3DK), example
.IX \f4canputnext\fP(D3DK), example
.IX \f4dupmsg\fP(D3DK), example
.IX \f4putnext\fP(D3DK), example
.IX \f4freeb\fP(D3DK), example
.IX \f4itimeout\fP(D3DK), example

DDI/DKI  —  STREAMS

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