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.
108 Region mdRegId, /* region for message and data blocks */
109 Region datRegId /* region for data buffers */
113 strmCfg.mdRegion = mdRegId;
114 strmCfg.datRegion = datRegId;
122 * STREAMS interface functions
124 * All these assume that ssStrmCfg() has been called first, with
133 * Desc: Trim abs(len) bytes from a message. If len is less than
134 * 0, trim from the tail, otherwise from the head. Operates
135 * only on blocks of the same type. Does not remove emptied
149 SsMblk *mp, /* message */
150 S32 len /* bytes to remove */
154 S32 size; /* size of mblks of same type as head/tail */
155 uint8_t type; /* message type */
156 SsMblk *bp; /* mblk for iteration */
157 SsMblk *first; /* first mblk to be adjusted */
159 #if (ERRCLASS & ERRCLS_INT_PAR)
162 SSLOGERROR(ERRCLS_INT_PAR, ESS325, ERRZERO, "Null pointer");
168 if (len == 0) /* nothing to do */
174 if (len > 0) /* trim from the head */
176 /* figure out the size of all blocks of the same type as the head */
179 type = bp->b_datap->db_type;
180 while (bp && bp->b_datap->db_type == type)
182 n = bp->b_wptr - bp->b_rptr;
192 /* if we can't trim len bytes, fail */
199 /* do the trimming */
203 n = bp->b_wptr - bp->b_rptr;
219 else /* trim from the tail */
221 /* figure out the size of all blocks of the same type as the tail */
225 type = bp->b_datap->db_type;
228 if (bp->b_datap->db_type == type)
230 n = bp->b_wptr - bp->b_rptr;
238 type = bp->b_datap->db_type;
247 /* if we can't trim len bytes, fail */
255 /* do the trimming */
258 n = first->b_wptr - first->b_rptr;
262 first->b_rptr = first->b_wptr;
268 first->b_wptr = first->b_rptr + size;
274 first = first->b_cont;
287 * Desc: Returns a pointer to a message block of type M_DATA
288 * in which the data buffer is of at least the specified
292 * Ret: non-NULL - success
295 * Notes: The parameter pri is unused.
302 S32 size, /* required size */
303 uint32_t pri /* message priority */
306 SsMblk *bp; /* mblk for iteration */
307 Data *dat; /* pointer to data buffer */
308 Size m; /* temporary */
309 Size n; /* temporary */
310 S16 r; /* return value */
313 #ifdef T2K_MEM_LEAK_DBG
314 char* file = __FILE__;
315 uint32_t line = __LINE__;
321 /* allocate a single block for the mblock and the dblock */
322 m = (sizeof(SsMblk) + sizeof(SsDblk));
323 /* ss001.301: additions */
324 #ifdef SS_HISTOGRAM_SUPPORT
325 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp, __LINE__, (uint8_t*)__FILE__, ENTNC);
327 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp);
328 #endif /* SS_HISTOGRAM_SUPPORT */
331 #if (ERRCLASS & ERRCLS_ADD_RES)
332 SSLOGERROR(ERRCLS_ADD_RES, ESS326, (ErrVal) r, "SAlloc() failed");
339 /* allocate space for the data block */
343 /* ss001.301: additions */
344 #ifdef SS_HISTOGRAM_SUPPORT
345 r = SAlloc(strmCfg.datRegion, &n, 0, &dat, __LINE__, (uint8_t*)__FILE__, ENTNC);
347 r = SAlloc(strmCfg.datRegion, &n, 0, &dat);
348 #endif /* SS_HISTOGRAM_SUPPORT */
351 #if (ERRCLASS & ERRCLS_ADD_RES)
352 SSLOGERROR(ERRCLS_ADD_RES, ESS327, (ErrVal) r, "SAlloc() failed");
355 /* ss001.301: additions */
356 #ifdef SS_HISTOGRAM_SUPPORT
357 SFree(strmCfg.mdRegion, (Data *)bp, m, __LINE__, (uint8_t*)__FILE__, ENTNC);
359 SFree(strmCfg.mdRegion, (Data *)bp, m);
360 #endif /* SS_HISTOGRAM_SUPPORT */
364 /* we _can_ allocate a message with an empty data block */
370 /* generic set-up-message function */
371 SS_STRM_INITB(bp, (SsDblk *)(((uint8_t *)bp) + sizeof(SsMblk)), dat, size, NULLP);
382 * Desc: Copies the contents of the specified message block
383 * into a newly-allocated message block of at least
384 * the same size. Calls ssAllocB().
396 SsMblk *mp /* message block */
399 SsMblk *bp; /* mblk for iteration */
400 uint8_t *ptr; /* pointer to data */
401 uint32_t size; /* size of data content */
404 #if (ERRCLASS & ERRCLS_INT_PAR)
407 SSLOGERROR(ERRCLS_INT_PAR, ESS328, ERRZERO, "Null pointer");
413 /* allocate another message */
414 bp = ssAllocB((mp->b_datap->db_lim - mp->b_datap->db_base), 0);
417 #if (ERRCLASS & ERRCLS_ADD_RES)
418 SSLOGERROR(ERRCLS_ADD_RES, ESS329, ERRZERO, "ssAllocB() failed");
425 /* copy the contents, if any */
426 size = (mp->b_wptr - mp->b_rptr);
430 while (ptr != mp->b_wptr)
432 *bp->b_wptr++ = *ptr++;
445 * Desc: Uses ssCopyB to copy the message blocks contained in
446 * the specified message to newly allocated blocks and
447 * links those blocks into a new message.
459 SsMblk *mp /* message block */
462 SsMblk *first; /* first mblk in message */
463 SsMblk *bp; /* mblk for iteration */
465 #if (ERRCLASS & ERRCLS_INT_PAR)
468 SSLOGERROR(ERRCLS_INT_PAR, ESS330, ERRZERO, "Null pointer");
474 /* copy the first mblock */
475 first = bp = ssCopyB(mp);
478 #if (ERRCLASS & ERRCLS_ADD_RES)
479 SSLOGERROR(ERRCLS_ADD_RES, ESS331, ERRZERO, "ssCopyB() failed");
486 /* copy all the rest, linking the new ones at the same time */
491 bp->b_cont = ssCopyB(mp);
493 /* if any copy fails, free whatever exists of the new message */
494 if (bp->b_cont == NULLP)
496 #if (ERRCLASS & ERRCLS_ADD_RES)
497 SSLOGERROR(ERRCLS_ADD_RES, ESS332, ERRZERO, "ssCopyB() failed");
516 * Desc: Duplicates the specified message block, copying it
517 * into a newly-allocated message block. Increments
518 * the reference count of the data block that is pointed
519 * at by the original message block descriptor.
531 SsMblk *mp /* message block */
534 SsMblk *bp; /* mblk for iteration */
535 /* ss028.103 - Addition of lock for mBuf reference count */
537 #if (ERRCLASS & ERRCLS_INT_PAR)
540 SSLOGERROR(ERRCLS_INT_PAR, ESS333, ERRZERO, "Null pointer");
546 /* allocate a message with no data buffer */
550 #if (ERRCLASS & ERRCLS_ADD_RES)
551 SSLOGERROR(ERRCLS_ADD_RES, ESS334, ERRZERO, "ssAllocB() failed");
558 /* make the new message block identical to the one to be dup'ed.
559 * notice that an mblk/dblk pair is allocated but only the mblk
560 * is used,, this is for optimum performance in the average case.
565 /* ss002.13: addition */
568 /* ss003.13: addition */
569 SMemCpy( (Void *)bp, (Void *)mp, (size_t)sizeof(SsMblk));
572 /* ss028.103 - Addition of lock for mBuf reference count */
573 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
574 #ifndef SS_DBUF_REFLOCK_DISABLE
575 if(SLock(&mp->b_datap->dBufLock) != ROK)
577 SSLOGERROR(ERRCLS_DEBUG, ESS335, ERRZERO,
578 "Could not lock the mBuf Ref Lock");
583 /* increment the reference count of the dblock */
584 mp->b_datap->db_ref++;
585 mp->b_datap->shared = TRUE;
587 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
588 #ifndef SS_DBUF_REFLOCK_DISABLE
589 if ( SUnlock(&mp->b_datap->dBufLock) != ROK)
591 #if (ERRCLASS & ERRCLS_DEBUG)
592 SSLOGERROR(ERRCLS_DEBUG, ESS336, ERRZERO,
593 "Could not give the Semaphore");
607 * Desc: Calls ssDupB to duplicate the specified message by
608 * copying all message block descriptors and then linking
609 * the new message blocks together to form a new message.
621 SsMblk *mp /* message block */
624 SsMblk *first; /* first mblk in message */
625 SsMblk *bp; /* mblk for iteration */
627 /* dup the first mblock */
628 first = bp = ssDupB(mp);
631 #if (ERRCLASS & ERRCLS_ADD_RES)
632 SSLOGERROR(ERRCLS_ADD_RES, ESS337, ERRZERO, "ssDupB() failed");
639 /* dup all the rest, linking the new ones at the same time */
644 bp->b_cont = ssDupB(mp);
646 /* if any dup fails, free whatever exists of the new message */
647 if (bp->b_cont == NULLP)
649 #if (ERRCLASS & ERRCLS_ADD_RES)
650 SSLOGERROR(ERRCLS_ADD_RES, ESS338, ERRZERO, "ssDupB() failed");
669 * Desc: Allocates message and data blocks that point directly
670 * at a client-supplied buffer.
682 uint8_t *base, /* client supplied data buffer */
683 S32 size, /* size of data buffer */
684 S32 pri, /* message priority */
685 SsFrtn *fr_rtn /* free routine */
688 SsMblk *bp; /* mblk for iteration */
689 Size m; /* mblk + dblk */
690 S16 r; /* return value */
695 #if (ERRCLASS & ERRCLS_INT_PAR)
696 if (base == NULLP || fr_rtn == NULLP)
698 SSLOGERROR(ERRCLS_INT_PAR, ESS339, ERRZERO, "Null pointer");
704 /* allocate space for an mblock and a dblock */
705 m = (sizeof(SsMblk) + sizeof(SsDblk));
706 /* ss001.301: additions */
707 #ifdef SS_HISTOGRAM_SUPPORT
708 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp, __LINE__, (uint8_t*)__FILE__, ENTNC);
710 #ifdef T2K_MEM_LEAK_DBG
711 char* file = __FILE__;
712 uint32_t line = __LINE__;
714 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp);
715 #endif /* SS_HISTOGRAM_SUPPORT */
718 #if (ERRCLASS & ERRCLS_ADD_RES)
719 SSLOGERROR(ERRCLS_ADD_RES, ESS340, (ErrVal) r, "SAlloc() failed");
726 /* use the generic set-up-message function to initialize everything */
727 SS_STRM_INITB(bp, (SsDblk *)(((uint8_t *)bp) + sizeof(SsMblk)),
739 * Desc: Deallocates the specified message block descriptor
740 * and frees the corresponding data block if the
741 * reference count is equal to 1. If not, the reference
742 * count is decremented.
753 SsMblk *mp /* message block */
756 SsMblk *bp; /* mblk for iteration */
757 Size size; /* mblk + dblk */
758 /* ss028.103 - Addition of lock for mBuf reference count */
760 #ifdef T2K_MEM_LEAK_DBG
761 char* file = __FILE__;
762 uint32_t line = __LINE__;
765 #if (ERRCLASS & ERRCLS_INT_PAR)
768 SSLOGERROR(ERRCLS_INT_PAR, ESS341, ERRZERO, "Null pointer");
774 size = sizeof(SsMblk) + sizeof(SsDblk);
777 /* this mblock has already been freed, and still exists only
778 * because there is a reference to its dblock. it will be
779 * freed when the referring mblock is freed.
782 if (mp->b_datap == NULLP)
788 /* ?? this should never happen ?? */
789 if (mp->b_datap->db_ref == 0)
791 #if (ERRCLASS & ERRCLS_DEBUG)
792 SSLOGERROR(ERRCLS_DEBUG, ESS342, ERRZERO,
793 "Zero reference count in ssFreeB; logic failure");
796 /* ss001.301: additions */
797 #ifdef SS_HISTOGRAM_SUPPORT
798 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (uint8_t*)__FILE__, ENTNC);
800 #ifdef T2K_MEM_LEAK_DBG
801 SFree(strmCfg.mdRegion, (Data *)mp, size);
803 SFree(strmCfg.mdRegion, (Data *)mp, size);
805 #endif /* SS_HISTOGRAM_SUPPORT */
809 /* ss028.103 - Addition of lock for mBuf reference count */
810 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
811 #ifndef SS_DBUF_REFLOCK_DISABLE
812 if(SLock(&mp->b_datap->dBufLock) != ROK)
814 SSLOGERROR(ERRCLS_DEBUG, ESS343, ERRZERO,
815 "Could not lock the mBuf Ref Lock");
820 /* decrement reference count of the dblock */
821 mp->b_datap->db_ref--;
823 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
824 #ifndef SS_DBUF_REFLOCK_DISABLE
825 if ( SUnlock(&mp->b_datap->dBufLock) != ROK)
827 #if (ERRCLASS & ERRCLS_DEBUG)
828 SSLOGERROR(ERRCLS_DEBUG, ESS344, ERRZERO,
829 "Could not give the Semaphore");
835 /* if we have no more references to this dblock, we can free
836 * the data buffer and the header.
839 if (mp->b_datap->db_ref == 0)
841 /* if there is a free routine, we call it for the data buffer;
842 * otherwise, we've allocated the data buffer and so we free it.
844 #ifndef SS_DBUF_REFLOCK_DISABLE
845 SDestroyLock(&mp->b_datap->dBufLock);
848 #ifdef SS_DBLK_FREE_RTN
849 if (mp->b_datap->db_frtnp)
851 (*(mp->b_datap->db_frtnp->free_func))(mp->b_datap->db_frtnp->free_arg);
855 if (mp->b_datap->db_base != NULLP)
857 /* ss001.301: additions */
858 #ifdef SS_HISTOGRAM_SUPPORT
859 SFree(strmCfg.datRegion, mp->b_datap->db_base,
860 (Size)(mp->b_datap->db_lim - mp->b_datap->db_base),
861 __LINE__, (uint8_t*)__FILE__, ENTNC);
863 SFree(strmCfg.datRegion, mp->b_datap->db_base,
864 (Size)(mp->b_datap->db_lim - mp->b_datap->db_base));
865 #endif /* SS_HISTOGRAM_SUPPORT */
869 /* if the dblock is in this header, we free this header
870 * and we're done. if the dblock is in another header,
871 * we have to free that header too.
874 if (mp->b_datap != ((SsDblk *)(mp + sizeof(SsMblk))))
876 bp = (SsMblk *)(mp->b_datap - sizeof (SsMblk));
877 /* ss001.301: additions */
878 #ifdef SS_HISTOGRAM_SUPPORT
879 SFree(strmCfg.mdRegion, (Data *)bp, size, __LINE__, (uint8_t*)__FILE__, ENTNC);
881 SFree(strmCfg.mdRegion, (Data *)bp, size);
882 #endif /* SS_HISTOGRAM_SUPPORT */
885 /* ss001.301: additions */
886 #ifdef SS_HISTOGRAM_SUPPORT
887 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (uint8_t*)__FILE__, ENTNC);
889 SFree(strmCfg.mdRegion, (Data *)mp, size);
890 #endif /* SS_HISTOGRAM_SUPPORT */
894 /* reference count is non-zero; if it is this header's
895 * dblock, we don't free the header, we just mark the
896 * dblock pointer empty so we know about it. if it is
897 * another header's dblock, we can free this header.
900 if (mp->b_datap == (SsDblk *)(mp + sizeof(SsMblk)))
906 /* ss001.301: additions */
907 #ifdef SS_HISTOGRAM_SUPPORT
908 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (uint8_t*)__FILE__, ENTNC);
910 SFree(strmCfg.mdRegion, (Data *)mp, size);
911 #endif /* SS_HISTOGRAM_SUPPORT */
923 * Desc: Calls ssFreeB to free all message blocks and their
924 * corresponding data blocks for the specified
936 SsMblk *mp /* message block */
939 SsMblk *bp; /* mblk for iteration */
941 /* free all the message blocks in the message */
957 * Desc: Puts the second specified message at the tail of
958 * the first specified message.
969 SsMblk *mp, /* first message block */
970 SsMblk *bp /* second message block */
974 #if (ERRCLASS & ERRCLS_INT_PAR)
975 if (mp == NULLP || bp == NULLP)
977 SSLOGERROR(ERRCLS_INT_PAR, ESS345, ERRZERO, "Null pointer");
983 /* run down to the end of the message */
990 /* link in the passed mblock */
1001 * Desc: Returns the number of bytes of data in the
1002 * specified message.
1004 * Ret: S32 - number of bytes
1013 SsMblk *mp /* message block */
1016 S32 n; /* temporary */
1017 S32 size; /* size of data */
1019 /* for all blocks that are of type data, count the bytes */
1023 if (mp->b_datap->db_type == SS_M_DATA)
1025 n = mp->b_wptr - mp->b_rptr;
1044 * Desc: Concatenates and aligns the first 'len' bytes
1045 * of the specified message into a single, contiguous
1058 SsMblk *mp, /* message block */
1059 S32 len /* number of bytes to align */
1062 SsMblk *bp; /* mblk for iteration */
1063 SsMblk *newbp; /* the new mblk */
1064 SsMblk *prev; /* mblk of same type */
1065 uint8_t *base; /* for swapping data buffers */
1066 uint8_t *lim; /* for swapping data buffers */
1067 uint8_t *rptr; /* for swapping data buffers */
1068 uint8_t *wptr; /* for swapping data buffers */
1070 #ifdef SS_DBLK_FREE_RTN
1071 SsFrtn *frtn; /* for swapping data buffers */
1073 S32 mLen; /* number of bytes in all blocks of same type */
1074 S32 m; /* temporary */
1075 S32 n; /* temporary */
1076 uint8_t type; /* message type */
1078 #if (ERRCLASS & ERRCLS_INT_PAR)
1081 SSLOGERROR(ERRCLS_INT_PAR, ESS346, ERRZERO, "Null pointer");
1087 SSLOGERROR(ERRCLS_INT_PAR, ESS347, len, "Invalid length");
1093 /* count the number of bytes in all blocks of the same type */
1096 type = bp->b_datap->db_type;
1097 while (bp && bp->b_datap->db_type == type)
1099 n = bp->b_wptr - bp->b_rptr;
1108 /* if -1 has been passed, we want to pull up all bytes */
1120 /* do we have enough bytes to pull up? */
1121 if (len < 0 || len > mLen)
1127 /* allocate a new message of the required size */
1128 newbp = ssAllocB(len, 0);
1134 newbp->b_datap->db_type = mp->b_datap->db_type;
1137 /* now we copy all the data in the blocks of the same type into
1145 /* if this buffer is of a different type, we just skip over it */
1146 if (bp->b_datap->db_type != newbp->b_datap->db_type)
1154 /* we have to copy this buffer */
1155 n = bp->b_wptr - bp->b_rptr;
1158 n = m = MIN(n, len);
1161 *newbp->b_wptr++ = *bp->b_rptr++;
1169 /* the buffer is copied, now--can we free it? if this the
1170 * first buffer, we don't free it. also, if this buffer has
1171 * something in it, we don't free it. otherwise, we link
1172 * around this buffer, from the previous one to the next,
1173 * and free this buffer.
1176 if (prev != NULLP && bp->b_rptr == bp->b_wptr)
1178 prev->b_cont = bp->b_cont;
1190 /* now we have to make the passed mblock point at the new data
1191 * buffer we've just filled. then, we have to free the new
1192 * mblock we created. also, we have to free the data buffer of
1193 * the old mblock, we left it in there. we do this by basically
1194 * swapping the data buffers of the passed mblock and the new
1195 * mblock, and then freeing the new mblock.
1200 base = mp->b_datap->db_base;
1201 lim = mp->b_datap->db_lim;
1203 #ifdef SS_DBLK_FREE_RTN
1204 frtn = mp->b_datap->db_frtnp;
1207 mp->b_rptr = newbp->b_rptr;
1208 mp->b_wptr = newbp->b_wptr;
1209 mp->b_datap->db_base = newbp->b_datap->db_base;
1210 mp->b_datap->db_lim = newbp->b_datap->db_lim;
1212 #ifdef SS_DBLK_FREE_RTN
1213 mp->b_datap->db_frtnp = NULLP;
1216 newbp->b_rptr = rptr;
1217 newbp->b_wptr = wptr;
1218 newbp->b_datap->db_base = base;
1219 newbp->b_datap->db_lim = lim;
1221 #ifdef SS_DBLK_FREE_RTN
1222 newbp->b_datap->db_frtnp = frtn;
1236 * Desc: Removes the specified message block from the
1237 * specified message and restores the linkage of
1238 * the remaining blocks in the message.
1240 * Ret: non-NULL - pointer to the head of the new message
1241 * -1 - specified message block not found in message
1244 * Notes: The block removed is not freed.
1251 SsMblk *mp, /* message */
1252 SsMblk *bp /* message block */
1255 SsMblk *rp; /* mblk that will be returned */
1257 #if (ERRCLASS & ERRCLS_INT_PAR)
1258 if (mp == NULLP || bp == NULLP)
1260 SSLOGERROR(ERRCLS_INT_PAR, ESS348, ERRZERO, "Null pointer");
1266 /* we will return rp */
1270 /* if the block to be removed is the first one, its easy */
1275 /* otherwise we run through the message, hunting */
1282 return ((SsMblk *)-1);
1284 else if (mp->b_cont == bp)
1286 mp->b_cont = bp->b_cont;
1297 /* we've removed bp from the message, clear its next pointer */
1309 * Desc: Checks for the availability of a message buffer
1310 * of the specified size without actually retrieving
1313 * Ret: 1 - buffer is available
1316 * Notes: Is currently a hack that allocates a message and
1324 S32 size, /* size required */
1325 uint32_t pri /* priority of the message buffer */
1328 SsMblk *bp; /* mblk for iteration */
1330 bp = ssAllocB(size, pri);
1346 * Desc: Removes the first message block pointed at
1347 * by the specified message and returns a pointer
1348 * to the head of the resultant message.
1350 * Ret: non-NULL - head of the new message
1360 SsMblk *mp /* message */
1363 SsMblk *bp; /* mblk for iteration */
1365 #if (ERRCLASS & ERRCLS_INT_PAR)
1368 SSLOGERROR(ERRCLS_INT_PAR, ESS349, ERRZERO, "Null pointer");
1374 /* does this need a comment? ;) */
1382 /**********************************************************************
1384 **********************************************************************/