1testb(9F) Kernel Functions for Drivers testb(9F)
2
3
4
6 testb - check for an available buffer
7
9 #include <sys/stream.h>
10
11
12
13 int testb(size_t size, uint_t pri);
14
15
17 Architecture independent level 1 (DDI/DKI).
18
20 size Size of the requested buffer.
21
22
23 pri Priority of the allocb request.
24
25
27 The testb() function checks to see if an allocb(9F) call is likely to
28 succeed if a buffer of size bytes at priority pri is requested. Even if
29 testb() returns successfully, the call to allocb(9F) can fail. The pri
30 argument is no longer used, but is retained for compatibility.
31
33 Returns 1 if a buffer of the requested size is available, and 0 if one
34 is not.
35
37 The testb() function can be called user, interrupt, or kernel context.
38
40 Example 1 testb() example
41
42
43 In a service routine, if copymsg(9F) fails (line 6), the message is put
44 back on the queue (line 7) and a routine, tryagain, is scheduled to be
45 run in one tenth of a second. Then the service routine returns.
46
47
48
49 When the timeout(9F) function runs, if there is no message on the front
50 of the queue, it just returns. Otherwise, for each message block in the
51 first message, check to see if an allocation would succeed. If the
52 number of message blocks equals the number we can allocate, then enable
53 the service procedure. Otherwise, reschedule tryagain to run again in
54 another tenth of a second. Note that tryagain is merely an approxima‐
55 tion. Its accounting may be faulty. Consider the case of a message com‐
56 prised of two 1024-byte message blocks. If there is only one free
57 1024-byte message block and no free 2048-byte message blocks, then
58 testb() will still succeed twice. If no message blocks are freed of
59 these sizes before the service procedure runs again, then the copy‐
60 msg(9F) will still fail. The reason testb() is used here is because it
61 is significantly faster than calling copymsg. We must minimize the
62 amount of time spent in a timeout() routine.
63
64
65 1 xxxsrv(q)
66 2 queue_t *q;
67 3 {
68 4 mblk_t *mp;
69 5 mblk_t *nmp;
70 . . .
71 6 if ((nmp = copymsg(mp)) == NULL) {
72 7 putbq(q, mp);
73 8 timeout(tryagain, (intptr_t)q, drv_usectohz(100000));
74 9 return;
75 10 }
76 . . .
77 11 }
78 12
79 13 tryagain(q)
80 14 queue_t *q;
81 15 {
82 16 register int can_alloc = 0;
83 17 register int num_blks = 0;
84 18 register mblk_t *mp;
85 19
86 20 if (!q->q_first)
87 21 return;
88 22 for (mp = q->q_first; mp; mp = mp->b_cont) {
89 23 num_blks++;
90 24 can_alloc += testb((mp->b_datap->db_lim -
91 25 mp->b_datap->db_base), BPRI_MED);
92 26 }
93 27 if (num_blks == can_alloc)
94 28 qenable(q);
95 29 else
96 30 timeout(tryagain, (intptr_t)q, drv_usectohz(100000));
97 31 }
98
99
101 allocb(9F), bufcall(9F), copymsg(9F), timeout(9F)
102
103
104 Writing Device Drivers
105
106
107 STREAMS Programming Guide
108
110 The pri argument is provided for compatibility only. Its value is
111 ignored.
112
113
114
115SunOS 5.11 16 Jan 2006 testb(9F)