1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: System Services -- STREAMS
25 Desc: Implementation of STREAMS messaging functions.
29 *********************************************************************21*/
32 /* header include files (.h) */
34 #include "envopt.h" /* environment options */
35 #include "envdep.h" /* environment dependent */
36 #include "envind.h" /* environment independent */
38 #include "gen.h" /* general layer */
39 #include "ssi.h" /* system services */
41 #include "ss_err.h" /* errors */
42 #include "ss_dep.h" /* implementation-specific */
43 #include "ss_queue.h" /* queues */
44 #include "ss_strm.h" /* STREAMS */
45 #include "ss_msg.h" /* messaging */
46 #include "ss_mem.h" /* memory management interface */
47 #include "ss_gen.h" /* general */
48 #include "cm_mem.h" /* memory management */
52 /* header/extern include files (.x) */
54 #include "gen.x" /* general layer */
55 #include "ssi.x" /* system services */
58 #include "ss_dep.x" /* implementation-specific */
59 #include "ss_queue.x" /* queues */
60 #include "ss_task.x" /* tasking */
61 #include "ss_timer.x" /* timers */
62 #include "ss_strm.x" /* STREAMS */
63 #include "ss_msg.x" /* messaging */
64 #include "ss_mem.x" /* memory management interface */
65 #include "ss_drvr.x" /* driver tasks */
66 #ifdef SS_LOCKLESS_MEMORY
69 #include "cm_mem_wl.x" /* common memory manager */
71 #include "cm_mem.x" /* common memory manager */
72 #endif /* SS_LOCKLESS_MEMORY */
73 #include "ss_gen.x" /* general */
77 /* private variable declarations */
81 Region mdRegion; /* region for message and data blocks */
82 Region datRegion; /* region for data buffers */
89 * Interface functions (System Services--non-STREAMS interface)
97 * Desc: Configures the STREAMS system.
109 Region mdRegId, /* region for message and data blocks */
110 Region datRegId /* region for data buffers */
113 S16 ssStrmCfg(mdRegId, datRegId)
114 Region mdRegId; /* region for message and data blocks */
115 Region datRegId; /* region for data buffers */
119 strmCfg.mdRegion = mdRegId;
120 strmCfg.datRegion = datRegId;
128 * STREAMS interface functions
130 * All these assume that ssStrmCfg() has been called first, with
139 * Desc: Trim abs(len) bytes from a message. If len is less than
140 * 0, trim from the tail, otherwise from the head. Operates
141 * only on blocks of the same type. Does not remove emptied
156 SsMblk *mp, /* message */
157 S32 len /* bytes to remove */
160 S32 ssAdjMsg(mp, len)
161 SsMblk *mp; /* message */
162 S32 len; /* bytes to remove */
166 S32 size; /* size of mblks of same type as head/tail */
167 U8 type; /* message type */
168 SsMblk *bp; /* mblk for iteration */
169 SsMblk *first; /* first mblk to be adjusted */
171 #if (ERRCLASS & ERRCLS_INT_PAR)
174 SSLOGERROR(ERRCLS_INT_PAR, ESS325, ERRZERO, "Null pointer");
180 if (len == 0) /* nothing to do */
186 if (len > 0) /* trim from the head */
188 /* figure out the size of all blocks of the same type as the head */
191 type = bp->b_datap->db_type;
192 while (bp && bp->b_datap->db_type == type)
194 n = bp->b_wptr - bp->b_rptr;
204 /* if we can't trim len bytes, fail */
211 /* do the trimming */
215 n = bp->b_wptr - bp->b_rptr;
231 else /* trim from the tail */
233 /* figure out the size of all blocks of the same type as the tail */
237 type = bp->b_datap->db_type;
240 if (bp->b_datap->db_type == type)
242 n = bp->b_wptr - bp->b_rptr;
250 type = bp->b_datap->db_type;
259 /* if we can't trim len bytes, fail */
267 /* do the trimming */
270 n = first->b_wptr - first->b_rptr;
274 first->b_rptr = first->b_wptr;
280 first->b_wptr = first->b_rptr + size;
286 first = first->b_cont;
299 * Desc: Returns a pointer to a message block of type M_DATA
300 * in which the data buffer is of at least the specified
304 * Ret: non-NULL - success
307 * Notes: The parameter pri is unused.
315 S32 size, /* required size */
316 U32 pri /* message priority */
319 SsMblk *ssAllocB(size, pri)
320 S32 size; /* required size */
321 U32 pri; /* message priority */
324 SsMblk *bp; /* mblk for iteration */
325 Data *dat; /* pointer to data buffer */
326 Size m; /* temporary */
327 Size n; /* temporary */
328 S16 r; /* return value */
331 #ifdef T2K_MEM_LEAK_DBG
332 char* file = __FILE__;
339 /* allocate a single block for the mblock and the dblock */
340 m = (sizeof(SsMblk) + sizeof(SsDblk));
341 /* ss001.301: additions */
342 #ifdef SS_HISTOGRAM_SUPPORT
343 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp, __LINE__, (U8*)__FILE__, ENTNC);
345 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp);
346 #endif /* SS_HISTOGRAM_SUPPORT */
349 #if (ERRCLASS & ERRCLS_ADD_RES)
350 SSLOGERROR(ERRCLS_ADD_RES, ESS326, (ErrVal) r, "SAlloc() failed");
357 /* allocate space for the data block */
361 /* ss001.301: additions */
362 #ifdef SS_HISTOGRAM_SUPPORT
363 r = SAlloc(strmCfg.datRegion, &n, 0, &dat, __LINE__, (U8*)__FILE__, ENTNC);
365 r = SAlloc(strmCfg.datRegion, &n, 0, &dat);
366 #endif /* SS_HISTOGRAM_SUPPORT */
369 #if (ERRCLASS & ERRCLS_ADD_RES)
370 SSLOGERROR(ERRCLS_ADD_RES, ESS327, (ErrVal) r, "SAlloc() failed");
373 /* ss001.301: additions */
374 #ifdef SS_HISTOGRAM_SUPPORT
375 SFree(strmCfg.mdRegion, (Data *)bp, m, __LINE__, (U8*)__FILE__, ENTNC);
377 SFree(strmCfg.mdRegion, (Data *)bp, m);
378 #endif /* SS_HISTOGRAM_SUPPORT */
382 /* we _can_ allocate a message with an empty data block */
388 /* generic set-up-message function */
389 SS_STRM_INITB(bp, (SsDblk *)(((U8 *)bp) + sizeof(SsMblk)), dat, size, NULLP);
400 * Desc: Copies the contents of the specified message block
401 * into a newly-allocated message block of at least
402 * the same size. Calls ssAllocB().
415 SsMblk *mp /* message block */
419 SsMblk *mp; /* message block */
422 SsMblk *bp; /* mblk for iteration */
423 U8 *ptr; /* pointer to data */
424 U32 size; /* size of data content */
427 #if (ERRCLASS & ERRCLS_INT_PAR)
430 SSLOGERROR(ERRCLS_INT_PAR, ESS328, ERRZERO, "Null pointer");
436 /* allocate another message */
437 bp = ssAllocB((mp->b_datap->db_lim - mp->b_datap->db_base), 0);
440 #if (ERRCLASS & ERRCLS_ADD_RES)
441 SSLOGERROR(ERRCLS_ADD_RES, ESS329, ERRZERO, "ssAllocB() failed");
448 /* copy the contents, if any */
449 size = (mp->b_wptr - mp->b_rptr);
453 while (ptr != mp->b_wptr)
455 *bp->b_wptr++ = *ptr++;
468 * Desc: Uses ssCopyB to copy the message blocks contained in
469 * the specified message to newly allocated blocks and
470 * links those blocks into a new message.
483 SsMblk *mp /* message block */
486 SsMblk *ssCopyMsg(mp)
487 SsMblk *mp; /* message block */
490 SsMblk *first; /* first mblk in message */
491 SsMblk *bp; /* mblk for iteration */
493 #if (ERRCLASS & ERRCLS_INT_PAR)
496 SSLOGERROR(ERRCLS_INT_PAR, ESS330, ERRZERO, "Null pointer");
502 /* copy the first mblock */
503 first = bp = ssCopyB(mp);
506 #if (ERRCLASS & ERRCLS_ADD_RES)
507 SSLOGERROR(ERRCLS_ADD_RES, ESS331, ERRZERO, "ssCopyB() failed");
514 /* copy all the rest, linking the new ones at the same time */
519 bp->b_cont = ssCopyB(mp);
521 /* if any copy fails, free whatever exists of the new message */
522 if (bp->b_cont == NULLP)
524 #if (ERRCLASS & ERRCLS_ADD_RES)
525 SSLOGERROR(ERRCLS_ADD_RES, ESS332, ERRZERO, "ssCopyB() failed");
544 * Desc: Duplicates the specified message block, copying it
545 * into a newly-allocated message block. Increments
546 * the reference count of the data block that is pointed
547 * at by the original message block descriptor.
560 SsMblk *mp /* message block */
564 SsMblk *mp; /* message block */
567 SsMblk *bp; /* mblk for iteration */
568 /* ss028.103 - Addition of lock for mBuf reference count */
570 #if (ERRCLASS & ERRCLS_INT_PAR)
573 SSLOGERROR(ERRCLS_INT_PAR, ESS333, ERRZERO, "Null pointer");
579 /* allocate a message with no data buffer */
583 #if (ERRCLASS & ERRCLS_ADD_RES)
584 SSLOGERROR(ERRCLS_ADD_RES, ESS334, ERRZERO, "ssAllocB() failed");
591 /* make the new message block identical to the one to be dup'ed.
592 * notice that an mblk/dblk pair is allocated but only the mblk
593 * is used,, this is for optimum performance in the average case.
598 /* ss002.13: addition */
601 /* ss003.13: addition */
602 SMemCpy( (Void *)bp, (Void *)mp, (size_t)sizeof(SsMblk));
605 /* ss028.103 - Addition of lock for mBuf reference count */
606 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
607 #ifndef SS_DBUF_REFLOCK_DISABLE
608 if(SLock(&mp->b_datap->dBufLock) != ROK)
610 SSLOGERROR(ERRCLS_DEBUG, ESS335, ERRZERO,
611 "Could not lock the mBuf Ref Lock");
616 /* increment the reference count of the dblock */
617 mp->b_datap->db_ref++;
618 mp->b_datap->shared = TRUE;
620 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
621 #ifndef SS_DBUF_REFLOCK_DISABLE
622 if ( SUnlock(&mp->b_datap->dBufLock) != ROK)
624 #if (ERRCLASS & ERRCLS_DEBUG)
625 SSLOGERROR(ERRCLS_DEBUG, ESS336, ERRZERO,
626 "Could not give the Semaphore");
640 * Desc: Calls ssDupB to duplicate the specified message by
641 * copying all message block descriptors and then linking
642 * the new message blocks together to form a new message.
655 SsMblk *mp /* message block */
659 SsMblk *mp; /* message block */
662 SsMblk *first; /* first mblk in message */
663 SsMblk *bp; /* mblk for iteration */
665 /* dup the first mblock */
666 first = bp = ssDupB(mp);
669 #if (ERRCLASS & ERRCLS_ADD_RES)
670 SSLOGERROR(ERRCLS_ADD_RES, ESS337, ERRZERO, "ssDupB() failed");
677 /* dup all the rest, linking the new ones at the same time */
682 bp->b_cont = ssDupB(mp);
684 /* if any dup fails, free whatever exists of the new message */
685 if (bp->b_cont == NULLP)
687 #if (ERRCLASS & ERRCLS_ADD_RES)
688 SSLOGERROR(ERRCLS_ADD_RES, ESS338, ERRZERO, "ssDupB() failed");
707 * Desc: Allocates message and data blocks that point directly
708 * at a client-supplied buffer.
721 U8 *base, /* client supplied data buffer */
722 S32 size, /* size of data buffer */
723 S32 pri, /* message priority */
724 SsFrtn *fr_rtn /* free routine */
727 SsMblk *ssESBAlloc(base, size, pri, fr_rtn)
728 U8 *base; /* client supplied data buffer */
729 S32 size; /* size of data buffer */
730 S32 pri; /* message priority */
731 SsFrtn *fr_rtn; /* free routine */
734 SsMblk *bp; /* mblk for iteration */
735 Size m; /* mblk + dblk */
736 S16 r; /* return value */
741 #if (ERRCLASS & ERRCLS_INT_PAR)
742 if (base == NULLP || fr_rtn == NULLP)
744 SSLOGERROR(ERRCLS_INT_PAR, ESS339, ERRZERO, "Null pointer");
750 /* allocate space for an mblock and a dblock */
751 m = (sizeof(SsMblk) + sizeof(SsDblk));
752 /* ss001.301: additions */
753 #ifdef SS_HISTOGRAM_SUPPORT
754 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp, __LINE__, (U8*)__FILE__, ENTNC);
756 #ifdef T2K_MEM_LEAK_DBG
757 char* file = __FILE__;
760 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp);
761 #endif /* SS_HISTOGRAM_SUPPORT */
764 #if (ERRCLASS & ERRCLS_ADD_RES)
765 SSLOGERROR(ERRCLS_ADD_RES, ESS340, (ErrVal) r, "SAlloc() failed");
772 /* use the generic set-up-message function to initialize everything */
773 SS_STRM_INITB(bp, (SsDblk *)(((U8 *)bp) + sizeof(SsMblk)),
785 * Desc: Deallocates the specified message block descriptor
786 * and frees the corresponding data block if the
787 * reference count is equal to 1. If not, the reference
788 * count is decremented.
800 SsMblk *mp /* message block */
804 SsMblk *mp; /* message block */
807 SsMblk *bp; /* mblk for iteration */
808 Size size; /* mblk + dblk */
809 /* ss028.103 - Addition of lock for mBuf reference count */
811 #ifdef T2K_MEM_LEAK_DBG
812 char* file = __FILE__;
816 #if (ERRCLASS & ERRCLS_INT_PAR)
819 SSLOGERROR(ERRCLS_INT_PAR, ESS341, ERRZERO, "Null pointer");
825 size = sizeof(SsMblk) + sizeof(SsDblk);
828 /* this mblock has already been freed, and still exists only
829 * because there is a reference to its dblock. it will be
830 * freed when the referring mblock is freed.
833 if (mp->b_datap == NULLP)
839 /* ?? this should never happen ?? */
840 if (mp->b_datap->db_ref == 0)
842 #if (ERRCLASS & ERRCLS_DEBUG)
843 SSLOGERROR(ERRCLS_DEBUG, ESS342, ERRZERO,
844 "Zero reference count in ssFreeB; logic failure");
847 /* ss001.301: additions */
848 #ifdef SS_HISTOGRAM_SUPPORT
849 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (U8*)__FILE__, ENTNC);
851 #ifdef T2K_MEM_LEAK_DBG
852 SFree(strmCfg.mdRegion, (Data *)mp, size);
854 SFree(strmCfg.mdRegion, (Data *)mp, size);
856 #endif /* SS_HISTOGRAM_SUPPORT */
860 /* ss028.103 - Addition of lock for mBuf reference count */
861 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
862 #ifndef SS_DBUF_REFLOCK_DISABLE
863 if(SLock(&mp->b_datap->dBufLock) != ROK)
865 SSLOGERROR(ERRCLS_DEBUG, ESS343, ERRZERO,
866 "Could not lock the mBuf Ref Lock");
871 /* decrement reference count of the dblock */
872 mp->b_datap->db_ref--;
874 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
875 #ifndef SS_DBUF_REFLOCK_DISABLE
876 if ( SUnlock(&mp->b_datap->dBufLock) != ROK)
878 #if (ERRCLASS & ERRCLS_DEBUG)
879 SSLOGERROR(ERRCLS_DEBUG, ESS344, ERRZERO,
880 "Could not give the Semaphore");
886 /* if we have no more references to this dblock, we can free
887 * the data buffer and the header.
890 if (mp->b_datap->db_ref == 0)
892 /* if there is a free routine, we call it for the data buffer;
893 * otherwise, we've allocated the data buffer and so we free it.
895 #ifndef SS_DBUF_REFLOCK_DISABLE
896 SDestroyLock(&mp->b_datap->dBufLock);
899 #ifdef SS_DBLK_FREE_RTN
900 if (mp->b_datap->db_frtnp)
902 (*(mp->b_datap->db_frtnp->free_func))(mp->b_datap->db_frtnp->free_arg);
906 if (mp->b_datap->db_base != NULLP)
908 /* ss001.301: additions */
909 #ifdef SS_HISTOGRAM_SUPPORT
910 SFree(strmCfg.datRegion, mp->b_datap->db_base,
911 (Size)(mp->b_datap->db_lim - mp->b_datap->db_base),
912 __LINE__, (U8*)__FILE__, ENTNC);
914 SFree(strmCfg.datRegion, mp->b_datap->db_base,
915 (Size)(mp->b_datap->db_lim - mp->b_datap->db_base));
916 #endif /* SS_HISTOGRAM_SUPPORT */
920 /* if the dblock is in this header, we free this header
921 * and we're done. if the dblock is in another header,
922 * we have to free that header too.
925 if (mp->b_datap != ((SsDblk *)(mp + sizeof(SsMblk))))
927 bp = (SsMblk *)(mp->b_datap - sizeof (SsMblk));
928 /* ss001.301: additions */
929 #ifdef SS_HISTOGRAM_SUPPORT
930 SFree(strmCfg.mdRegion, (Data *)bp, size, __LINE__, (U8*)__FILE__, ENTNC);
932 SFree(strmCfg.mdRegion, (Data *)bp, size);
933 #endif /* SS_HISTOGRAM_SUPPORT */
936 /* ss001.301: additions */
937 #ifdef SS_HISTOGRAM_SUPPORT
938 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (U8*)__FILE__, ENTNC);
940 SFree(strmCfg.mdRegion, (Data *)mp, size);
941 #endif /* SS_HISTOGRAM_SUPPORT */
945 /* reference count is non-zero; if it is this header's
946 * dblock, we don't free the header, we just mark the
947 * dblock pointer empty so we know about it. if it is
948 * another header's dblock, we can free this header.
951 if (mp->b_datap == (SsDblk *)(mp + sizeof(SsMblk)))
957 /* ss001.301: additions */
958 #ifdef SS_HISTOGRAM_SUPPORT
959 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (U8*)__FILE__, ENTNC);
961 SFree(strmCfg.mdRegion, (Data *)mp, size);
962 #endif /* SS_HISTOGRAM_SUPPORT */
974 * Desc: Calls ssFreeB to free all message blocks and their
975 * corresponding data blocks for the specified
988 SsMblk *mp /* message block */
992 SsMblk *mp; /* message block */
995 SsMblk *bp; /* mblk for iteration */
997 /* free all the message blocks in the message */
1013 * Desc: Puts the second specified message at the tail of
1014 * the first specified message.
1026 SsMblk *mp, /* first message block */
1027 SsMblk *bp /* second message block */
1030 Void ssLinkB(mp, bp)
1031 SsMblk *mp; /* first message block */
1032 SsMblk *bp; /* second message block */
1036 #if (ERRCLASS & ERRCLS_INT_PAR)
1037 if (mp == NULLP || bp == NULLP)
1039 SSLOGERROR(ERRCLS_INT_PAR, ESS345, ERRZERO, "Null pointer");
1045 /* run down to the end of the message */
1052 /* link in the passed mblock */
1063 * Desc: Returns the number of bytes of data in the
1064 * specified message.
1066 * Ret: S32 - number of bytes
1076 SsMblk *mp /* message block */
1080 SsMblk *mp; /* message block */
1083 S32 n; /* temporary */
1084 S32 size; /* size of data */
1086 /* for all blocks that are of type data, count the bytes */
1090 if (mp->b_datap->db_type == SS_M_DATA)
1092 n = mp->b_wptr - mp->b_rptr;
1111 * Desc: Concatenates and aligns the first 'len' bytes
1112 * of the specified message into a single, contiguous
1126 SsMblk *mp, /* message block */
1127 S32 len /* number of bytes to align */
1130 S32 ssPullupMsg(mp, len)
1131 SsMblk *mp; /* message block */
1132 S32 len; /* number of bytes to align */
1135 SsMblk *bp; /* mblk for iteration */
1136 SsMblk *newbp; /* the new mblk */
1137 SsMblk *prev; /* mblk of same type */
1138 U8 *base; /* for swapping data buffers */
1139 U8 *lim; /* for swapping data buffers */
1140 U8 *rptr; /* for swapping data buffers */
1141 U8 *wptr; /* for swapping data buffers */
1143 #ifdef SS_DBLK_FREE_RTN
1144 SsFrtn *frtn; /* for swapping data buffers */
1146 S32 mLen; /* number of bytes in all blocks of same type */
1147 S32 m; /* temporary */
1148 S32 n; /* temporary */
1149 U8 type; /* message type */
1151 #if (ERRCLASS & ERRCLS_INT_PAR)
1154 SSLOGERROR(ERRCLS_INT_PAR, ESS346, ERRZERO, "Null pointer");
1160 SSLOGERROR(ERRCLS_INT_PAR, ESS347, len, "Invalid length");
1166 /* count the number of bytes in all blocks of the same type */
1169 type = bp->b_datap->db_type;
1170 while (bp && bp->b_datap->db_type == type)
1172 n = bp->b_wptr - bp->b_rptr;
1181 /* if -1 has been passed, we want to pull up all bytes */
1193 /* do we have enough bytes to pull up? */
1194 if (len < 0 || len > mLen)
1200 /* allocate a new message of the required size */
1201 newbp = ssAllocB(len, 0);
1207 newbp->b_datap->db_type = mp->b_datap->db_type;
1210 /* now we copy all the data in the blocks of the same type into
1218 /* if this buffer is of a different type, we just skip over it */
1219 if (bp->b_datap->db_type != newbp->b_datap->db_type)
1227 /* we have to copy this buffer */
1228 n = bp->b_wptr - bp->b_rptr;
1231 n = m = MIN(n, len);
1234 *newbp->b_wptr++ = *bp->b_rptr++;
1242 /* the buffer is copied, now--can we free it? if this the
1243 * first buffer, we don't free it. also, if this buffer has
1244 * something in it, we don't free it. otherwise, we link
1245 * around this buffer, from the previous one to the next,
1246 * and free this buffer.
1249 if (prev != NULLP && bp->b_rptr == bp->b_wptr)
1251 prev->b_cont = bp->b_cont;
1263 /* now we have to make the passed mblock point at the new data
1264 * buffer we've just filled. then, we have to free the new
1265 * mblock we created. also, we have to free the data buffer of
1266 * the old mblock, we left it in there. we do this by basically
1267 * swapping the data buffers of the passed mblock and the new
1268 * mblock, and then freeing the new mblock.
1273 base = mp->b_datap->db_base;
1274 lim = mp->b_datap->db_lim;
1276 #ifdef SS_DBLK_FREE_RTN
1277 frtn = mp->b_datap->db_frtnp;
1280 mp->b_rptr = newbp->b_rptr;
1281 mp->b_wptr = newbp->b_wptr;
1282 mp->b_datap->db_base = newbp->b_datap->db_base;
1283 mp->b_datap->db_lim = newbp->b_datap->db_lim;
1285 #ifdef SS_DBLK_FREE_RTN
1286 mp->b_datap->db_frtnp = NULLP;
1289 newbp->b_rptr = rptr;
1290 newbp->b_wptr = wptr;
1291 newbp->b_datap->db_base = base;
1292 newbp->b_datap->db_lim = lim;
1294 #ifdef SS_DBLK_FREE_RTN
1295 newbp->b_datap->db_frtnp = frtn;
1309 * Desc: Removes the specified message block from the
1310 * specified message and restores the linkage of
1311 * the remaining blocks in the message.
1313 * Ret: non-NULL - pointer to the head of the new message
1314 * -1 - specified message block not found in message
1317 * Notes: The block removed is not freed.
1325 SsMblk *mp, /* message */
1326 SsMblk *bp /* message block */
1329 SsMblk *ssRmvB(mp, bp)
1330 SsMblk *mp; /* message */
1331 SsMblk *bp; /* message block */
1334 SsMblk *rp; /* mblk that will be returned */
1336 #if (ERRCLASS & ERRCLS_INT_PAR)
1337 if (mp == NULLP || bp == NULLP)
1339 SSLOGERROR(ERRCLS_INT_PAR, ESS348, ERRZERO, "Null pointer");
1345 /* we will return rp */
1349 /* if the block to be removed is the first one, its easy */
1354 /* otherwise we run through the message, hunting */
1361 return ((SsMblk *)-1);
1363 else if (mp->b_cont == bp)
1365 mp->b_cont = bp->b_cont;
1376 /* we've removed bp from the message, clear its next pointer */
1388 * Desc: Checks for the availability of a message buffer
1389 * of the specified size without actually retrieving
1392 * Ret: 1 - buffer is available
1395 * Notes: Is currently a hack that allocates a message and
1404 S32 size, /* size required */
1405 U32 pri /* priority of the message buffer */
1408 S32 ssTestB(size, pri)
1409 S32 size; /* size required */
1410 U32 pri; /* priority of the message buffer */
1413 SsMblk *bp; /* mblk for iteration */
1415 bp = ssAllocB(size, pri);
1431 * Desc: Removes the first message block pointed at
1432 * by the specified message and returns a pointer
1433 * to the head of the resultant message.
1435 * Ret: non-NULL - head of the new message
1446 SsMblk *mp /* message */
1449 SsMblk *ssUnlinkB(mp)
1450 SsMblk *mp; /* message */
1453 SsMblk *bp; /* mblk for iteration */
1455 #if (ERRCLASS & ERRCLS_INT_PAR)
1458 SSLOGERROR(ERRCLS_INT_PAR, ESS349, ERRZERO, "Null pointer");
1464 /* does this need a comment? ;) */
1472 /**********************************************************************
1474 **********************************************************************/