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 PUBLIC S16 ssStrmCfg(mdRegId, datRegId)
114 Region mdRegId; /* region for message and data blocks */
115 Region datRegId; /* region for data buffers */
121 strmCfg.mdRegion = mdRegId;
122 strmCfg.datRegion = datRegId;
130 * STREAMS interface functions
132 * All these assume that ssStrmCfg() has been called first, with
141 * Desc: Trim abs(len) bytes from a message. If len is less than
142 * 0, trim from the tail, otherwise from the head. Operates
143 * only on blocks of the same type. Does not remove emptied
158 SsMblk *mp, /* message */
159 S32 len /* bytes to remove */
162 PUBLIC S32 ssAdjMsg(mp, len)
163 SsMblk *mp; /* message */
164 S32 len; /* bytes to remove */
168 S32 size; /* size of mblks of same type as head/tail */
169 U8 type; /* message type */
170 SsMblk *bp; /* mblk for iteration */
171 SsMblk *first; /* first mblk to be adjusted */
177 #if (ERRCLASS & ERRCLS_INT_PAR)
180 SSLOGERROR(ERRCLS_INT_PAR, ESS325, ERRZERO, "Null pointer");
186 if (len == 0) /* nothing to do */
192 if (len > 0) /* trim from the head */
194 /* figure out the size of all blocks of the same type as the head */
197 type = bp->b_datap->db_type;
198 while (bp && bp->b_datap->db_type == type)
200 n = bp->b_wptr - bp->b_rptr;
210 /* if we can't trim len bytes, fail */
217 /* do the trimming */
221 n = bp->b_wptr - bp->b_rptr;
237 else /* trim from the tail */
239 /* figure out the size of all blocks of the same type as the tail */
243 type = bp->b_datap->db_type;
246 if (bp->b_datap->db_type == type)
248 n = bp->b_wptr - bp->b_rptr;
256 type = bp->b_datap->db_type;
265 /* if we can't trim len bytes, fail */
273 /* do the trimming */
276 n = first->b_wptr - first->b_rptr;
280 first->b_rptr = first->b_wptr;
286 first->b_wptr = first->b_rptr + size;
292 first = first->b_cont;
305 * Desc: Returns a pointer to a message block of type M_DATA
306 * in which the data buffer is of at least the specified
310 * Ret: non-NULL - success
313 * Notes: The parameter pri is unused.
319 PUBLIC SsMblk *ssAllocB
321 S32 size, /* required size */
322 U32 pri /* message priority */
325 PUBLIC SsMblk *ssAllocB(size, pri)
326 S32 size; /* required size */
327 U32 pri; /* message priority */
330 SsMblk *bp; /* mblk for iteration */
331 Data *dat; /* pointer to data buffer */
332 Size m; /* temporary */
333 Size n; /* temporary */
334 S16 r; /* return value */
337 #ifdef T2K_MEM_LEAK_DBG
338 char* file = __FILE__;
347 /* allocate a single block for the mblock and the dblock */
348 m = (sizeof(SsMblk) + sizeof(SsDblk));
349 /* ss001.301: additions */
350 #ifdef SS_HISTOGRAM_SUPPORT
351 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp, __LINE__, (U8*)__FILE__, ENTNC);
353 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp);
354 #endif /* SS_HISTOGRAM_SUPPORT */
357 #if (ERRCLASS & ERRCLS_ADD_RES)
358 SSLOGERROR(ERRCLS_ADD_RES, ESS326, (ErrVal) r, "SAlloc() failed");
365 /* allocate space for the data block */
369 /* ss001.301: additions */
370 #ifdef SS_HISTOGRAM_SUPPORT
371 r = SAlloc(strmCfg.datRegion, &n, 0, &dat, __LINE__, (U8*)__FILE__, ENTNC);
373 r = SAlloc(strmCfg.datRegion, &n, 0, &dat);
374 #endif /* SS_HISTOGRAM_SUPPORT */
377 #if (ERRCLASS & ERRCLS_ADD_RES)
378 SSLOGERROR(ERRCLS_ADD_RES, ESS327, (ErrVal) r, "SAlloc() failed");
381 /* ss001.301: additions */
382 #ifdef SS_HISTOGRAM_SUPPORT
383 SFree(strmCfg.mdRegion, (Data *)bp, m, __LINE__, (U8*)__FILE__, ENTNC);
385 SFree(strmCfg.mdRegion, (Data *)bp, m);
386 #endif /* SS_HISTOGRAM_SUPPORT */
390 /* we _can_ allocate a message with an empty data block */
396 /* generic set-up-message function */
397 SS_STRM_INITB(bp, (SsDblk *)(((U8 *)bp) + sizeof(SsMblk)), dat, size, NULLP);
408 * Desc: Copies the contents of the specified message block
409 * into a newly-allocated message block of at least
410 * the same size. Calls ssAllocB().
421 PUBLIC SsMblk *ssCopyB
423 SsMblk *mp /* message block */
426 PUBLIC SsMblk *ssCopyB(mp)
427 SsMblk *mp; /* message block */
430 SsMblk *bp; /* mblk for iteration */
431 U8 *ptr; /* pointer to data */
432 U32 size; /* size of data content */
438 #if (ERRCLASS & ERRCLS_INT_PAR)
441 SSLOGERROR(ERRCLS_INT_PAR, ESS328, ERRZERO, "Null pointer");
447 /* allocate another message */
448 bp = ssAllocB((mp->b_datap->db_lim - mp->b_datap->db_base), 0);
451 #if (ERRCLASS & ERRCLS_ADD_RES)
452 SSLOGERROR(ERRCLS_ADD_RES, ESS329, ERRZERO, "ssAllocB() failed");
459 /* copy the contents, if any */
460 size = (mp->b_wptr - mp->b_rptr);
464 while (ptr != mp->b_wptr)
466 *bp->b_wptr++ = *ptr++;
479 * Desc: Uses ssCopyB to copy the message blocks contained in
480 * the specified message to newly allocated blocks and
481 * links those blocks into a new message.
492 PUBLIC SsMblk *ssCopyMsg
494 SsMblk *mp /* message block */
497 PUBLIC SsMblk *ssCopyMsg(mp)
498 SsMblk *mp; /* message block */
501 SsMblk *first; /* first mblk in message */
502 SsMblk *bp; /* mblk for iteration */
508 #if (ERRCLASS & ERRCLS_INT_PAR)
511 SSLOGERROR(ERRCLS_INT_PAR, ESS330, ERRZERO, "Null pointer");
517 /* copy the first mblock */
518 first = bp = ssCopyB(mp);
521 #if (ERRCLASS & ERRCLS_ADD_RES)
522 SSLOGERROR(ERRCLS_ADD_RES, ESS331, ERRZERO, "ssCopyB() failed");
529 /* copy all the rest, linking the new ones at the same time */
534 bp->b_cont = ssCopyB(mp);
536 /* if any copy fails, free whatever exists of the new message */
537 if (bp->b_cont == NULLP)
539 #if (ERRCLASS & ERRCLS_ADD_RES)
540 SSLOGERROR(ERRCLS_ADD_RES, ESS332, ERRZERO, "ssCopyB() failed");
559 * Desc: Duplicates the specified message block, copying it
560 * into a newly-allocated message block. Increments
561 * the reference count of the data block that is pointed
562 * at by the original message block descriptor.
573 PUBLIC SsMblk *ssDupB
575 SsMblk *mp /* message block */
578 PUBLIC SsMblk *ssDupB(mp)
579 SsMblk *mp; /* message block */
582 SsMblk *bp; /* mblk for iteration */
583 /* ss028.103 - Addition of lock for mBuf reference count */
588 #if (ERRCLASS & ERRCLS_INT_PAR)
591 SSLOGERROR(ERRCLS_INT_PAR, ESS333, ERRZERO, "Null pointer");
597 /* allocate a message with no data buffer */
601 #if (ERRCLASS & ERRCLS_ADD_RES)
602 SSLOGERROR(ERRCLS_ADD_RES, ESS334, ERRZERO, "ssAllocB() failed");
609 /* make the new message block identical to the one to be dup'ed.
610 * notice that an mblk/dblk pair is allocated but only the mblk
611 * is used,, this is for optimum performance in the average case.
616 /* ss002.13: addition */
619 /* ss003.13: addition */
620 SMemCpy( (Void *)bp, (Void *)mp, (size_t)sizeof(SsMblk));
623 /* ss028.103 - Addition of lock for mBuf reference count */
624 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
625 #ifndef SS_DBUF_REFLOCK_DISABLE
626 if(SLock(&mp->b_datap->dBufLock) != ROK)
628 SSLOGERROR(ERRCLS_DEBUG, ESS335, ERRZERO,
629 "Could not lock the mBuf Ref Lock");
634 /* increment the reference count of the dblock */
635 mp->b_datap->db_ref++;
636 mp->b_datap->shared = TRUE;
638 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
639 #ifndef SS_DBUF_REFLOCK_DISABLE
640 if ( SUnlock(&mp->b_datap->dBufLock) != ROK)
642 #if (ERRCLASS & ERRCLS_DEBUG)
643 SSLOGERROR(ERRCLS_DEBUG, ESS336, ERRZERO,
644 "Could not give the Semaphore");
658 * Desc: Calls ssDupB to duplicate the specified message by
659 * copying all message block descriptors and then linking
660 * the new message blocks together to form a new message.
671 PUBLIC SsMblk *ssDupMsg
673 SsMblk *mp /* message block */
676 PUBLIC SsMblk *ssDupMsg(mp)
677 SsMblk *mp; /* message block */
680 SsMblk *first; /* first mblk in message */
681 SsMblk *bp; /* mblk for iteration */
687 /* dup the first mblock */
688 first = bp = ssDupB(mp);
691 #if (ERRCLASS & ERRCLS_ADD_RES)
692 SSLOGERROR(ERRCLS_ADD_RES, ESS337, ERRZERO, "ssDupB() failed");
699 /* dup all the rest, linking the new ones at the same time */
704 bp->b_cont = ssDupB(mp);
706 /* if any dup fails, free whatever exists of the new message */
707 if (bp->b_cont == NULLP)
709 #if (ERRCLASS & ERRCLS_ADD_RES)
710 SSLOGERROR(ERRCLS_ADD_RES, ESS338, ERRZERO, "ssDupB() failed");
729 * Desc: Allocates message and data blocks that point directly
730 * at a client-supplied buffer.
741 PUBLIC SsMblk *ssESBAlloc
743 U8 *base, /* client supplied data buffer */
744 S32 size, /* size of data buffer */
745 S32 pri, /* message priority */
746 SsFrtn *fr_rtn /* free routine */
749 PUBLIC SsMblk *ssESBAlloc(base, size, pri, fr_rtn)
750 U8 *base; /* client supplied data buffer */
751 S32 size; /* size of data buffer */
752 S32 pri; /* message priority */
753 SsFrtn *fr_rtn; /* free routine */
756 SsMblk *bp; /* mblk for iteration */
757 Size m; /* mblk + dblk */
758 S16 r; /* return value */
767 #if (ERRCLASS & ERRCLS_INT_PAR)
768 if (base == NULLP || fr_rtn == NULLP)
770 SSLOGERROR(ERRCLS_INT_PAR, ESS339, ERRZERO, "Null pointer");
776 /* allocate space for an mblock and a dblock */
777 m = (sizeof(SsMblk) + sizeof(SsDblk));
778 /* ss001.301: additions */
779 #ifdef SS_HISTOGRAM_SUPPORT
780 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp, __LINE__, (U8*)__FILE__, ENTNC);
782 #ifdef T2K_MEM_LEAK_DBG
783 char* file = __FILE__;
786 r = SAlloc(strmCfg.mdRegion, &m, 0, (Data **)&bp);
787 #endif /* SS_HISTOGRAM_SUPPORT */
790 #if (ERRCLASS & ERRCLS_ADD_RES)
791 SSLOGERROR(ERRCLS_ADD_RES, ESS340, (ErrVal) r, "SAlloc() failed");
798 /* use the generic set-up-message function to initialize everything */
799 SS_STRM_INITB(bp, (SsDblk *)(((U8 *)bp) + sizeof(SsMblk)),
811 * Desc: Deallocates the specified message block descriptor
812 * and frees the corresponding data block if the
813 * reference count is equal to 1. If not, the reference
814 * count is decremented.
826 SsMblk *mp /* message block */
829 PUBLIC Void ssFreeB(mp)
830 SsMblk *mp; /* message block */
833 SsMblk *bp; /* mblk for iteration */
834 Size size; /* mblk + dblk */
835 /* ss028.103 - Addition of lock for mBuf reference count */
837 #ifdef T2K_MEM_LEAK_DBG
838 char* file = __FILE__;
845 #if (ERRCLASS & ERRCLS_INT_PAR)
848 SSLOGERROR(ERRCLS_INT_PAR, ESS341, ERRZERO, "Null pointer");
854 size = sizeof(SsMblk) + sizeof(SsDblk);
857 /* this mblock has already been freed, and still exists only
858 * because there is a reference to its dblock. it will be
859 * freed when the referring mblock is freed.
862 if (mp->b_datap == NULLP)
868 /* ?? this should never happen ?? */
869 if (mp->b_datap->db_ref == 0)
871 #if (ERRCLASS & ERRCLS_DEBUG)
872 SSLOGERROR(ERRCLS_DEBUG, ESS342, ERRZERO,
873 "Zero reference count in ssFreeB; logic failure");
876 /* ss001.301: additions */
877 #ifdef SS_HISTOGRAM_SUPPORT
878 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (U8*)__FILE__, ENTNC);
880 #ifdef T2K_MEM_LEAK_DBG
881 SFree(strmCfg.mdRegion, (Data *)mp, size);
883 SFree(strmCfg.mdRegion, (Data *)mp, size);
885 #endif /* SS_HISTOGRAM_SUPPORT */
889 /* ss028.103 - Addition of lock for mBuf reference count */
890 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
891 #ifndef SS_DBUF_REFLOCK_DISABLE
892 if(SLock(&mp->b_datap->dBufLock) != ROK)
894 SSLOGERROR(ERRCLS_DEBUG, ESS343, ERRZERO,
895 "Could not lock the mBuf Ref Lock");
900 /* decrement reference count of the dblock */
901 mp->b_datap->db_ref--;
903 /* ss006.301 - use the mBufRefLock for the DFLT_REGION */
904 #ifndef SS_DBUF_REFLOCK_DISABLE
905 if ( SUnlock(&mp->b_datap->dBufLock) != ROK)
907 #if (ERRCLASS & ERRCLS_DEBUG)
908 SSLOGERROR(ERRCLS_DEBUG, ESS344, ERRZERO,
909 "Could not give the Semaphore");
915 /* if we have no more references to this dblock, we can free
916 * the data buffer and the header.
919 if (mp->b_datap->db_ref == 0)
921 /* if there is a free routine, we call it for the data buffer;
922 * otherwise, we've allocated the data buffer and so we free it.
924 #ifndef SS_DBUF_REFLOCK_DISABLE
925 SDestroyLock(&mp->b_datap->dBufLock);
928 #ifdef SS_DBLK_FREE_RTN
929 if (mp->b_datap->db_frtnp)
931 (*(mp->b_datap->db_frtnp->free_func))(mp->b_datap->db_frtnp->free_arg);
935 if (mp->b_datap->db_base != NULLP)
937 /* ss001.301: additions */
938 #ifdef SS_HISTOGRAM_SUPPORT
939 SFree(strmCfg.datRegion, mp->b_datap->db_base,
940 (Size)(mp->b_datap->db_lim - mp->b_datap->db_base),
941 __LINE__, (U8*)__FILE__, ENTNC);
943 SFree(strmCfg.datRegion, mp->b_datap->db_base,
944 (Size)(mp->b_datap->db_lim - mp->b_datap->db_base));
945 #endif /* SS_HISTOGRAM_SUPPORT */
949 /* if the dblock is in this header, we free this header
950 * and we're done. if the dblock is in another header,
951 * we have to free that header too.
954 if (mp->b_datap != ((SsDblk *)(mp + sizeof(SsMblk))))
956 bp = (SsMblk *)(mp->b_datap - sizeof (SsMblk));
957 /* ss001.301: additions */
958 #ifdef SS_HISTOGRAM_SUPPORT
959 SFree(strmCfg.mdRegion, (Data *)bp, size, __LINE__, (U8*)__FILE__, ENTNC);
961 SFree(strmCfg.mdRegion, (Data *)bp, size);
962 #endif /* SS_HISTOGRAM_SUPPORT */
965 /* ss001.301: additions */
966 #ifdef SS_HISTOGRAM_SUPPORT
967 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (U8*)__FILE__, ENTNC);
969 SFree(strmCfg.mdRegion, (Data *)mp, size);
970 #endif /* SS_HISTOGRAM_SUPPORT */
974 /* reference count is non-zero; if it is this header's
975 * dblock, we don't free the header, we just mark the
976 * dblock pointer empty so we know about it. if it is
977 * another header's dblock, we can free this header.
980 if (mp->b_datap == (SsDblk *)(mp + sizeof(SsMblk)))
986 /* ss001.301: additions */
987 #ifdef SS_HISTOGRAM_SUPPORT
988 SFree(strmCfg.mdRegion, (Data *)mp, size, __LINE__, (U8*)__FILE__, ENTNC);
990 SFree(strmCfg.mdRegion, (Data *)mp, size);
991 #endif /* SS_HISTOGRAM_SUPPORT */
1003 * Desc: Calls ssFreeB to free all message blocks and their
1004 * corresponding data blocks for the specified
1015 PUBLIC Void ssFreeMsg
1017 SsMblk *mp /* message block */
1020 PUBLIC Void ssFreeMsg(mp)
1021 SsMblk *mp; /* message block */
1024 SsMblk *bp; /* mblk for iteration */
1030 /* free all the message blocks in the message */
1046 * Desc: Puts the second specified message at the tail of
1047 * the first specified message.
1059 SsMblk *mp, /* first message block */
1060 SsMblk *bp /* second message block */
1063 PUBLIC Void ssLinkB(mp, bp)
1064 SsMblk *mp; /* first message block */
1065 SsMblk *bp; /* second message block */
1071 #if (ERRCLASS & ERRCLS_INT_PAR)
1072 if (mp == NULLP || bp == NULLP)
1074 SSLOGERROR(ERRCLS_INT_PAR, ESS345, ERRZERO, "Null pointer");
1080 /* run down to the end of the message */
1087 /* link in the passed mblock */
1098 * Desc: Returns the number of bytes of data in the
1099 * specified message.
1101 * Ret: S32 - number of bytes
1109 PUBLIC S32 ssMsgDSize
1111 SsMblk *mp /* message block */
1114 PUBLIC S32 ssMsgDSize(mp)
1115 SsMblk *mp; /* message block */
1118 S32 n; /* temporary */
1119 S32 size; /* size of data */
1125 /* for all blocks that are of type data, count the bytes */
1129 if (mp->b_datap->db_type == SS_M_DATA)
1131 n = mp->b_wptr - mp->b_rptr;
1150 * Desc: Concatenates and aligns the first 'len' bytes
1151 * of the specified message into a single, contiguous
1163 PUBLIC S32 ssPullupMsg
1165 SsMblk *mp, /* message block */
1166 S32 len /* number of bytes to align */
1169 PUBLIC S32 ssPullupMsg(mp, len)
1170 SsMblk *mp; /* message block */
1171 S32 len; /* number of bytes to align */
1174 SsMblk *bp; /* mblk for iteration */
1175 SsMblk *newbp; /* the new mblk */
1176 SsMblk *prev; /* mblk of same type */
1177 U8 *base; /* for swapping data buffers */
1178 U8 *lim; /* for swapping data buffers */
1179 U8 *rptr; /* for swapping data buffers */
1180 U8 *wptr; /* for swapping data buffers */
1182 #ifdef SS_DBLK_FREE_RTN
1183 SsFrtn *frtn; /* for swapping data buffers */
1185 S32 mLen; /* number of bytes in all blocks of same type */
1186 S32 m; /* temporary */
1187 S32 n; /* temporary */
1188 U8 type; /* message type */
1194 #if (ERRCLASS & ERRCLS_INT_PAR)
1197 SSLOGERROR(ERRCLS_INT_PAR, ESS346, ERRZERO, "Null pointer");
1203 SSLOGERROR(ERRCLS_INT_PAR, ESS347, len, "Invalid length");
1209 /* count the number of bytes in all blocks of the same type */
1212 type = bp->b_datap->db_type;
1213 while (bp && bp->b_datap->db_type == type)
1215 n = bp->b_wptr - bp->b_rptr;
1224 /* if -1 has been passed, we want to pull up all bytes */
1236 /* do we have enough bytes to pull up? */
1237 if (len < 0 || len > mLen)
1243 /* allocate a new message of the required size */
1244 newbp = ssAllocB(len, 0);
1250 newbp->b_datap->db_type = mp->b_datap->db_type;
1253 /* now we copy all the data in the blocks of the same type into
1261 /* if this buffer is of a different type, we just skip over it */
1262 if (bp->b_datap->db_type != newbp->b_datap->db_type)
1270 /* we have to copy this buffer */
1271 n = bp->b_wptr - bp->b_rptr;
1274 n = m = MIN(n, len);
1277 *newbp->b_wptr++ = *bp->b_rptr++;
1285 /* the buffer is copied, now--can we free it? if this the
1286 * first buffer, we don't free it. also, if this buffer has
1287 * something in it, we don't free it. otherwise, we link
1288 * around this buffer, from the previous one to the next,
1289 * and free this buffer.
1292 if (prev != NULLP && bp->b_rptr == bp->b_wptr)
1294 prev->b_cont = bp->b_cont;
1306 /* now we have to make the passed mblock point at the new data
1307 * buffer we've just filled. then, we have to free the new
1308 * mblock we created. also, we have to free the data buffer of
1309 * the old mblock, we left it in there. we do this by basically
1310 * swapping the data buffers of the passed mblock and the new
1311 * mblock, and then freeing the new mblock.
1316 base = mp->b_datap->db_base;
1317 lim = mp->b_datap->db_lim;
1319 #ifdef SS_DBLK_FREE_RTN
1320 frtn = mp->b_datap->db_frtnp;
1323 mp->b_rptr = newbp->b_rptr;
1324 mp->b_wptr = newbp->b_wptr;
1325 mp->b_datap->db_base = newbp->b_datap->db_base;
1326 mp->b_datap->db_lim = newbp->b_datap->db_lim;
1328 #ifdef SS_DBLK_FREE_RTN
1329 mp->b_datap->db_frtnp = NULLP;
1332 newbp->b_rptr = rptr;
1333 newbp->b_wptr = wptr;
1334 newbp->b_datap->db_base = base;
1335 newbp->b_datap->db_lim = lim;
1337 #ifdef SS_DBLK_FREE_RTN
1338 newbp->b_datap->db_frtnp = frtn;
1352 * Desc: Removes the specified message block from the
1353 * specified message and restores the linkage of
1354 * the remaining blocks in the message.
1356 * Ret: non-NULL - pointer to the head of the new message
1357 * -1 - specified message block not found in message
1360 * Notes: The block removed is not freed.
1366 PUBLIC SsMblk *ssRmvB
1368 SsMblk *mp, /* message */
1369 SsMblk *bp /* message block */
1372 PUBLIC SsMblk *ssRmvB(mp, bp)
1373 SsMblk *mp; /* message */
1374 SsMblk *bp; /* message block */
1377 SsMblk *rp; /* mblk that will be returned */
1383 #if (ERRCLASS & ERRCLS_INT_PAR)
1384 if (mp == NULLP || bp == NULLP)
1386 SSLOGERROR(ERRCLS_INT_PAR, ESS348, ERRZERO, "Null pointer");
1392 /* we will return rp */
1396 /* if the block to be removed is the first one, its easy */
1401 /* otherwise we run through the message, hunting */
1408 RETVALUE((SsMblk *)-1);
1410 else if (mp->b_cont == bp)
1412 mp->b_cont = bp->b_cont;
1423 /* we've removed bp from the message, clear its next pointer */
1435 * Desc: Checks for the availability of a message buffer
1436 * of the specified size without actually retrieving
1439 * Ret: 1 - buffer is available
1442 * Notes: Is currently a hack that allocates a message and
1451 S32 size, /* size required */
1452 U32 pri /* priority of the message buffer */
1455 PUBLIC S32 ssTestB(size, pri)
1456 S32 size; /* size required */
1457 U32 pri; /* priority of the message buffer */
1460 SsMblk *bp; /* mblk for iteration */
1466 bp = ssAllocB(size, pri);
1482 * Desc: Removes the first message block pointed at
1483 * by the specified message and returns a pointer
1484 * to the head of the resultant message.
1486 * Ret: non-NULL - head of the new message
1495 PUBLIC SsMblk *ssUnlinkB
1497 SsMblk *mp /* message */
1500 PUBLIC SsMblk *ssUnlinkB(mp)
1501 SsMblk *mp; /* message */
1504 SsMblk *bp; /* mblk for iteration */
1510 #if (ERRCLASS & ERRCLS_INT_PAR)
1513 SSLOGERROR(ERRCLS_INT_PAR, ESS349, ERRZERO, "Null pointer");
1519 /* does this need a comment? ;) */
1527 /**********************************************************************
1529 **********************************************************************/