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: Multi-threaded System Services - Solaris
25 Desc: C source code for the MTSS-Solaris implementation of
30 *********************************************************************21*/
35 #ifndef _POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE 199309L
38 /* mt003.301 moved env files to use the __USE_UNIX98 flag in sys includes */
45 #include <sys/types.h>
50 /* mt003.301: included sys/time.h
51 * for both solaris and linux
54 /* mt008.21: addition */
59 /* header include files (.h) */
62 #include "common_def.h"
63 #include "mt_ss.h" /* MTSS specific */
64 #include "mt_err.h" /* MTSS error defines */
66 #include "ss_queue.h" /* queues */
67 #include "ss_task.h" /* tasking */
68 #include "ss_msg.h" /* messaging */
69 #include "ss_mem.h" /* memory management interface */
70 #include "ss_gen.h" /* general */
71 /* mt003.301 Additions - Task deregistration */
72 #include "ss_err.h" /* error */
73 #include "cm_mem.h" /* common memory manager */
74 /* mt001.301 : Additions */
75 #ifdef SS_THREAD_PROFILE
78 #ifdef SS_LOCKLESS_MEMORY
83 /* multi-core support enhancement */
84 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
85 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
91 #include <sys/types.h>
92 #include <sys/processor.h>
93 #include <sys/procset.h>
96 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
97 /* mt001.301 : Additions */
99 #include <sys/types.h>
100 #include <sys/socket.h>
101 #include <netinet/in.h>
102 #include <arpa/inet.h>
103 #endif /* SS_WATCHDOG */
105 #ifdef SS_USE_WLS_MEM
106 #include <rte_common.h>
107 #include <rte_debug.h>
111 /* header/extern include files (.x) */
113 #include "gen.x" /* general layer */
114 #include "ssi.x" /* system services */
116 #include "cm5.x" /* common timers */
118 #include "mt_ss.x" /* MTSS specific */
119 #ifdef SS_LOCKLESS_MEMORY
120 #include "mt_ss_wl.x" /* MTSS specific */
121 #endif /* SS_LOCKLESS_MEMORY */
123 #include "ss_queue.x" /* queues */
124 #include "ss_task.x" /* tasking */
125 #include "ss_timer.x" /* timers */
126 #include "ss_strm.x" /* STREAMS */
127 #include "ss_msg.x" /* messaging */
128 #include "ss_mem.x" /* memory management interface */
129 #include "ss_drvr.x" /* driver tasks */
130 #include "ss_gen.x" /* general */
131 #ifdef SS_LOCKLESS_MEMORY
132 #include "cm_llist.x"
134 #include "cm_mem_wl.x" /* common memory manager */
136 #include "cm_mem.x" /* common memory manager */
137 #endif /* SS_LOCKLESS_MEMORY */
138 #include "cm_lte.x" /* common memory manager */
139 /* mt001.301 : Additions */
140 #ifdef SS_LOGGER_SUPPORT
142 #endif /* SS_LOGGER_SUPPORT */
144 /*mt005.301: Cavium Changes */
145 #ifdef SS_SEUM_CAVIUM
146 /* cvmx includes files */
147 #include "cvmx-config.h"
149 #include "cvmx-pow.h"
150 #include "cvmx-tim.h"
151 #include "cvmx-fpa.h"
152 #include "cvmx-helper-fpa.h"
153 #include "cvmx-malloc.h"
154 #endif /* SS_SEUM_CAVIUM */
157 #include "mt_plat_t33.h"
158 #include "mt_plat_t33.x"
159 #include "sys/syscall.h"
162 #if defined(RGL_SPECIFIC_CHANGES) || defined(INTEL_WLS) || defined(SS_USE_WLS_MEM)
164 #include <hugetlbfs.h>
167 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
168 S16 rgBatchProc (Void);
170 #ifdef RLC_MAC_DAT_REQ_RBUF
171 S16 rgDlDatReqBatchProc ARGS((
174 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
175 S16 rgBatchProc ARGS((
179 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
180 /* general purpose debug zone */
181 char my_buffer2[4096 * 4] = { 0 };
182 char my_buffer[4096] = { 0 };
183 int my_buffer_idx = 0;
186 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
188 struct sigcontext my_uc_mcontext = { 0 };
193 #include <ucontext.h>
197 #define SIGSEGV_STACK_GENERIC
198 #define REGFORMAT "%x\n"
200 #ifdef XEON_SPECIFIC_CHANGES
201 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
204 void dump_external(void);
206 static Void mtDelSigals(Void)
210 memset(&sa, 0, sizeof(struct sigaction));
211 sigemptyset(&sa.sa_mask);
212 sa.sa_handler = SIG_DFL;
213 sigaction(SIGSEGV, &sa, NULL);
215 memset(&sa, 0, sizeof(struct sigaction));
216 sigemptyset(&sa.sa_mask);
217 sa.sa_handler = SIG_DFL;
218 sigaction(SIGILL, &sa, NULL);
222 static void signal_segv(int signum, siginfo_t * info, void *ptr)
224 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
227 ucontext_t *ucontext = (ucontext_t *) ptr;
228 #ifdef XEON_SPECIFIC_CHANGES
230 int *p32 = (int *) 0x2fff0000;
235 printf("\nsegv ooops @ %p\n", info->si_addr);
238 printf("\nSegmentation Fault!\n");
239 printf("\ninfo.si_signo = %d\n", signum);
240 printf("\ninfo.si_errno = %d\n", info->si_errno);
241 printf("\ninfo.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
242 printf("\ninfo.si_addr = %p\n", info->si_addr);
244 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
247 #ifndef RGL_SPECIFIC_CHANGES
248 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
249 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
250 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
251 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
252 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
253 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
254 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
255 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
256 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
257 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
258 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
259 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
260 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
261 printf("\nreg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
262 printf("\nreg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
263 printf("\nreg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
264 printf("\nreg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
267 printf("\nStack trace (non-dedicated):\n");
269 sz = backtrace(buffer, 50);
270 strings = backtrace_symbols(buffer, sz);
271 for (i = 0; i < sz; ++i)
272 printf("%s\n", strings[i]);
274 printf("\nEnd of stack trace\n");
276 #ifdef XEON_SPECIFIC_CHANGES
281 /* Lets first print our debug information */
282 printf("\nBefore dumping our Debug info\n");
284 printf("\nAfter dumping our Debug info\n");
286 /* Disable the signal and make the enodeb to dump. This will make
287 * eNB to generate the core with dumping the ccpu log
294 /* End printing debug information */
299 /*** TBD: IMPORTANT ***
300 *** The following definition is temporary. This must be removed
301 *** when all products have been updated with latest ssi.h file OR
302 *** all ssi.h files have been updated to contain this definitions
304 /* New error class for FTHA added */
306 #define ERRCLS_FTHA 0x8
307 #endif /* ERRCLS_FTHA */
309 typedef struct _SPThreadCreateArg
311 void *argument; /* argument that is to be passed to the actual pthread */
312 void *(*start_routine) (void *); /* function from which pthread starts */
315 void *pthreadCreateHdlr(void* arg);
317 #ifdef SS_LOCKLESS_MEMORY
318 Buffer *mtTskBuffer1;
319 Buffer *mtTskBuffer2;
321 pthread_t tmpRegTidMap[20];
323 S16 SGlobMemInfoShow(void);
324 #endif /* SS_LOCKLESS_MEMORY */
327 APP_CONTEXT AppContext;
331 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
332 unsigned int tlPost(void *handle);
335 /* forward references */
336 /* mt003.301 Modifications - Moved to ss_gen.x */
337 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
338 Void *mtTskHdlrT2kL2 ARGS((Void*));
339 void mtSigSegvHndlr ARGS((void));
340 void mtSigUsr2Hndlr ARGS((void));
343 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
344 static Void *mtTskHdlr ARGS((void *));
345 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
347 static Void *mtTmrHdlr ARGS((void *));
348 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
350 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
351 static Void mtIntSigHndlr ARGS((int));
352 static Void mtExitClnup ARGS((void));
355 static Void *mtConHdlr ARGS((void *));
359 #ifdef SS_DRVR_SUPPORT
360 static Void *mtIsTskHdlr ARGS((void *));
364 /* mt020.201 - Addition for no command line available */
366 static Void mtGetOpts ARGS((void));
367 /* mt003.301 Additions - File Based task registration made
368 * common for both MULTICORE and NON-MULTICORE
370 static Bool fileBasedMemCfg = FALSE;
373 /* mt033.201 - addition of local function to print the statistics such as
374 * (size vs. numAttempts) and (allocations vs. deallocations)
376 #ifdef SSI_DEBUG_LEVEL1
377 static S16 SPrintRegMemStats ARGS((Region region));
378 #endif /* SSI_DEBUG_LEVEL1 */
380 #ifdef SS_MULTICORE_SUPPORT
381 static SsSTskEntry* ssdAddTmrSTsk(Void);
382 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
383 #ifndef SS_LOCKLESS_MEMORY
384 #ifndef RGL_SPECIFIC_CHANGES
385 static S16 ssdInitMemInfo ARGS((void));
390 /* mt005.301: Cavium changes */
391 #ifdef SS_SEUM_CAVIUM
392 static Void *workRcvTsk ARGS((void *));
393 #endif /* SS_SEUM_CAVIUM */
395 #ifdef SS_THR_REG_MAP
396 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
398 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
399 #endif /* SS_THR_REG_MAP */
401 /* type declarations */
403 #ifdef SS_DRVR_SUPPORT
404 typedef struct mtIsFlag
414 /* public variable declarations */
416 Cntr cfgNumRegs = SS_MAX_REGS;
417 /* Set memory configuration as false.
418 * Set to true if memory configuration through file is successfull.
420 Bool memConfigured = FALSE;
421 /* mt022.201 - Modification for shared memory relay region and memcal tool */
422 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
425 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
427 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
428 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
429 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
430 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
431 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
432 { SS_POOL_STATIC, 0 }
438 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
440 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
441 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
442 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
443 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
444 { SS_POOL_STATIC, 0 }
447 #endif /* INTEL_WLS */
449 #ifdef SS_LOCKLESS_MEMORY
452 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
454 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
455 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
456 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
457 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
458 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
459 { SS_POOL_STATIC, 0 }
463 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
465 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
466 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
467 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
468 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
469 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
470 { SS_POOL_STATIC, 0 }
474 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
476 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
477 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
478 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
479 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
480 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
481 { SS_POOL_STATIC, 0 }
485 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
487 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
488 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
489 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
490 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
491 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
492 { SS_POOL_STATIC, 0 }
496 SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
498 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
499 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
500 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
501 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
502 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
503 { SS_POOL_STATIC, 0 }
507 SS_DFLT_REGION + 6, SS_MAX_POOLS_PER_REG - 1,
509 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
510 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
511 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
512 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
513 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
514 { SS_POOL_STATIC, 0 }
517 #ifndef INTEL_WLS_MEM
520 SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1,
522 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
523 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
524 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
525 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
526 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
527 { SS_POOL_STATIC, 0 }
532 #endif /* SS_LOCKLESS_MEMORY */
534 /* mt003.301 Modifications - File Based task registration made
535 * common for both MULTICORE and NON-MULTICORE
538 #ifdef SS_LOCKLESS_MEMORY
539 MtDynMemCfg mtDynMemoCfg =
541 SS_MAX_REGS, /* number of regions */
544 SS_DFLT_REGION, /* region id */
545 MT_MAX_BKTS, /* number of buckets */
547 /* block size, no. of blocks, Upper threshold, lower threshold */
548 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
549 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
550 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
551 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
552 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
556 SS_DFLT_REGION + 1, /* region id */
557 MT_MAX_BKTS, /* number of buckets */
559 /* block size, no. of blocks, Upper threshold, lower threshold */
560 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
561 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
562 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
563 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
564 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
568 SS_DFLT_REGION + 2, /* region id */
569 MT_MAX_BKTS, /* number of buckets */
571 /* block size, no. of blocks, Upper threshold, lower threshold */
572 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
573 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
574 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
575 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
576 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
580 SS_DFLT_REGION + 3, /* region id */
581 MT_MAX_BKTS, /* number of buckets */
583 /* block size, no. of blocks, Upper threshold, lower threshold */
584 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
585 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
586 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
587 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
588 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
592 SS_DFLT_REGION + 4, /* region id */
593 MT_MAX_BKTS, /* number of buckets */
595 /* block size, no. of blocks, Upper threshold, lower threshold */
596 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
597 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
598 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
599 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
600 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
604 SS_DFLT_REGION + 5, /* region id */
605 MT_MAX_BKTS, /* number of buckets */
607 /* block size, no. of blocks, Upper threshold, lower threshold */
608 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
609 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
610 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
611 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
612 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
616 SS_DFLT_REGION + 6, /* region id */
617 MT_MAX_BKTS, /* number of buckets */
619 /* block size, no. of blocks, Upper threshold, lower threshold */
620 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
621 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
622 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
623 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
624 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
627 #ifndef INTEL_WLS_MEM
630 SS_DFLT_REGION + 7, /* region id */
631 MT_MAX_BKTS, /* number of buckets */
633 /* block size, no. of blocks, Upper threshold, lower threshold */
634 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
635 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
636 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
637 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
638 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
642 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
645 SS_DFLT_REGION + 7, /* region id */
646 MT_MAX_BKTS, /* number of buckets */
648 /* block size, no. of blocks, Upper threshold, lower threshold */
649 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
650 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
651 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
652 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
660 MtGlobMemCfg mtGlobMemoCfg =
662 MT_MAX_BKTS, /* number of buckets */
665 /* block size, no. of blocks, Upper threshold, lower threshold */
666 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
667 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
668 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
669 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
670 {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
672 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
673 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
674 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
675 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
679 #endif /* SS_LOCKLESS_MEMORY */
681 /* mt022.201 - Modification for memory calculator tool */
682 /* mt018.201 - added memory configuration matrix */
686 SS_MAX_REGS - 1, /* number of regions */
688 #ifndef XEON_SPECIFIC_CHANGES
689 SS_MAX_REGS, /* number of regions */
696 SS_DFLT_REGION, /* region id */
697 MT_MAX_BKTS, /* number of buckets */
698 MT_HEAP_SIZE, /* heap size */
700 #ifndef XEON_SPECIFIC_CHANGES
701 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
702 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
703 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
704 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
705 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
707 {256, 491520}, /* 60 pages of 2M*/
708 {512, 12288}, /* 3 pages of 2M */
709 {2048, 99328}, /* 97 Pages of 2M */
710 {8192, 75008}, /* 293 Pages of 2M */
711 {16384, 4096} /* 32 pages of 2M */
716 #ifndef SS_LOCKLESS_MEMORY
718 SS_DFLT_REGION + 1, /* region id */
719 MT_MAX_BKTS, /* number of buckets */
720 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
722 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
723 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
724 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
725 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
733 #endif /* SS_LOCKLESS_MEMORY */
734 #endif /* INTEL_WLS */
735 #ifdef SS_LOCKLESS_MEMORY
737 SS_DFLT_REGION + 1, /* region id */
738 MT_MAX_BKTS, /* number of buckets */
739 MT_HEAP_SIZE, /* heap size */
741 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
742 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
743 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
744 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
745 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
749 SS_DFLT_REGION + 2, /* region id */
750 MT_MAX_BKTS, /* number of buckets */
751 MT_HEAP_SIZE, /* heap size */
753 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
754 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
755 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
756 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
757 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
761 SS_DFLT_REGION + 3, /* region id */
762 MT_MAX_BKTS, /* number of buckets */
763 MT_HEAP_SIZE, /* heap size */
765 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
766 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
767 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
768 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
769 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
773 SS_DFLT_REGION + 4, /* region id */
774 MT_MAX_BKTS, /* number of buckets */
775 MT_HEAP_SIZE, /* heap size */
777 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
778 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
779 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
780 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
781 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
785 SS_DFLT_REGION + 5, /* region id */
786 MT_MAX_BKTS, /* number of buckets */
787 MT_HEAP_SIZE, /* heap size */
789 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
790 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
791 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
792 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
793 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
797 SS_DFLT_REGION + 6, /* region id */
798 MT_MAX_BKTS, /* number of buckets */
799 MT_HEAP_SIZE, /* heap size */
801 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
802 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
803 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
804 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
805 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
808 #ifndef INTEL_WLS_MEM
811 SS_DFLT_REGION + 7, /* region id */
812 MT_MAX_BKTS, /* number of buckets */
813 MT_HEAP_SIZE, /* heap size */
815 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
816 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
817 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
818 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
819 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
823 #endif /* SS_LOCKLESS_MEMORY */
827 /* mt003.301 Modifications - File Based task registration made
828 * common for both MULTICORE and NON-MULTICORE
829 * bucket info, as different regions may request for different no.
832 MtBktCfg mtBktInfo[MT_MAX_BKTS];
833 S16 msArgc; /* argc */
834 Txt **msArgv; /* argv */
835 S16 msOptInd; /* SGetOpt vars */
836 S8 *msOptArg; /* SGetOpt vars */
839 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
840 typedef struct _MtRegMemSz
846 #ifdef SS_USE_WLS_MEM
847 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
848 static S16 SPartitionWlsDynMem();
849 static S16 SAllocateWlsDynMem();
852 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
857 /* private variable declarations */
858 /* mt018.201 - change mtCMMRegCfg as array of pointers */
859 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
860 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
861 /* mt003.301 - Fixed compilation warnings */
862 /*mt004.301-addede new veriable for FAP*/
863 /*mt010.301 - removed veriable defined for FA*/
866 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
869 void mtSetNtlHdl(unsigned int hdl)
874 unsigned int mtGetNtlHdl()
876 return(osCp.ntl.hdl);
880 void mtGetWlsHdl(void **hdlr)
882 *hdlr = osCp.wls.intf;
885 #ifdef XEON_MULTIPLE_CELL_CHANGES
886 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
887 S16 smWrReadWlsConfigParams (Void);
890 /*WLS Memory Size variables*/
891 #ifdef INTEL_L1_V20_03_ONWARDS
892 uint64_t nWlsMacMemorySize = 0;
893 uint64_t nWlsPhyMemorySize = 0;
896 static int SOpenWlsIntf()
900 #define WLS_DEVICE_NAME "wls0"
902 char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", "gnb0", "--iova-mode=pa"};
903 printf("\nCalling rte_eal_init: ");
904 for (i = 0; i < RTE_DIM(my_argv); i++)
906 printf("%s ", my_argv[i]);
910 if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
911 rte_panic("\nCannot init EAL\n");
914 #ifdef XEON_SPECIFIC_CHANGES
915 #ifdef XEON_MULTIPLE_CELL_CHANGES
916 hdl = WLS_Open(gWrWlsDeviceName, 1);
918 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
922 #ifdef INTEL_L1_V20_03_ONWARDS
923 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, &nWlsMacMemorySize, &nWlsPhyMemorySize);
926 printf("\nERROR: WLS_Open > DEVICE_NAME mismatch. WLS Device Name should be same as 'wls_dev_name' parameter in 'phycfg_xran.xml' file");
929 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
930 #endif /*INTEL_L1_V20_03_ONWARDS*/
938 printf("\nCould not open WLS Interface \n");
953 * Desc: This function is the entry point for the final binary. It
954 * calls SInit() in the common code. It can be replaced by a
955 * user function if required (SInit() must still be called).
957 * Ret: none on success
967 int argc, /* argument count */
968 char **argv /* argument vector */
972 #ifdef XEON_MULTIPLE_CELL_CHANGES
973 /* Read the WLS parameters from the file and copy into global control block */
974 if(smWrReadWlsConfigParams() != ROK)
976 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
978 } /* end of if statement */
981 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
984 #endif /* INTEL_WLS */
988 /* mt003.301 Modifications */
991 printf("\n SInit failed, SSI could not start \n");
992 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
996 /*mt010.301 cleanup part exposed to user*/
1007 * Desc: This function is the entry point for the final binary. It
1008 * calls SInit() in the common code. It can be replaced by a
1009 * user function if required (SInit() must still be called).
1011 * Ret: none on success
1021 int argc, /* argument count */
1022 char **argv /* argument vector */
1038 * initialization functions
1043 * Fun: Initialize OS control point
1045 * Desc: This function initializes MTSS-specific information
1046 * in the OS control point.
1055 S16 ssdInitGen(void)
1057 struct sigaction act;
1059 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1060 struct sigaction sa;
1064 /*mt014.301 : 4GMX release related changes*/
1065 #ifdef SS_4GMX_UCORE
1068 /* mt005.301 : Cavium changes */
1069 #ifdef SS_SEUM_CAVIUM
1070 /* set group mask for the core */
1071 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
1072 #endif /* SS_SEUM_CAVIUM */
1074 osCp.dep.sysTicks = 0;
1076 /* mt020.201 - Addition for no command line available */
1078 /* parse command line */
1080 /* mt003.301 Additions */
1081 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
1083 printf("\n File Based Memory configuration failed \n");
1088 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
1089 #ifndef SS_LOCKLESS_MEMORY
1090 #ifdef SS_MULTICORE_SUPPORT
1091 if(memConfigured == FALSE)
1097 /* initialize the started semaphore */
1098 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1103 /* mt028.201 added compile time flag to allow not to mask signals */
1105 /* mask all signals in the main thread */
1107 sigdelset(&set, SIGINT);
1108 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1109 sigdelset(&set, SIGSEGV);
1110 sigdelset(&set, SIGUSR2);
1111 sigdelset(&set, SIGILL);
1112 #ifdef XEON_SPECIFIC_CHANGES
1113 sigdelset(&set, SIGABRT);
1114 sigdelset(&set, SIGTERM);
1115 sigdelset(&set, SIGHUP);
1118 pthread_sigmask(SIG_SETMASK, &set, NULLP);
1119 #endif /* UNMASK_SIG */
1121 /* install a SIGINT handler to shutdown */
1122 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1124 /*Initialize SIGSEGV Signal */
1125 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1127 memset(&sa, 0, sizeof(struct sigaction));
1128 sigemptyset(&sa.sa_mask);
1129 sa.sa_sigaction = signal_segv;
1130 sa.sa_flags = SA_SIGINFO;
1131 #ifndef XEON_SPECIFIC_CHANGES
1132 sigaction(SIGSEGV, &sa, NULL);
1134 memset(&sa, 0, sizeof(struct sigaction));
1135 sigemptyset(&sa.sa_mask);
1136 sa.sa_sigaction = signal_segv;
1137 sa.sa_flags = SA_SIGINFO;
1139 sigaction(SIGILL, &sa, NULL);
1141 if(sigaction(SIGILL, &sa, NULL) != 0)
1143 printf("\nFailed to process sigaction for the SIGILL\n");
1146 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1148 printf("\nFailed to process sigaction for the SIGSEGV\n");
1151 if(sigaction(SIGABRT, &sa, NULL) != 0)
1153 printf("\nFailed to process sigaction for the SIGABRT\n");
1156 if(sigaction(SIGTERM, &sa, NULL) != 0)
1158 printf("\nFailed to process sigaction for the SIGTERM\n");
1161 if(sigaction(SIGHUP, &sa, NULL) != 0)
1163 printf("\nFailed to process sigaction for the SIGHUP\n");
1168 signal (SIGSEGV, mtSigSegvHndlr);
1169 signal (SIGKILL, mtSigSegvHndlr);
1170 signal (SIGUSR2, mtSigUsr2Hndlr);
1175 signal (SIGINT, mtStopHndlr);
1178 act.sa_handler = mtIntSigHndlr;
1179 sigfillset(&act.sa_mask);
1181 if (sigaction(SIGINT, &act, NULLP) != 0)
1187 /* mt040.201 initialise random seed */
1188 osCp.dep.randSeed = time(NULLP);
1196 * Fun: De-initialize OS control point
1198 * Desc: This function reverses the initialization in ssdInitGen().
1207 Void ssdDeinitGen(void)
1211 sem_destroy(&osCp.dep.ssStarted);
1216 #ifdef SS_LOCKLESS_MEMORY
1220 * Fun: ssPutDynMemBlkSet
1222 * Desc: Returns the set of dynamic Blocks into the global region
1225 * Ret: ROK - successful,
1226 * RFAILED - unsuccessful.
1233 S16 ssPutDynMemBlkSet
1235 uint8_t bktIdx, /* Index to bucket list */
1236 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1237 added to global region */
1240 CmMmGlobRegCb *globReg;
1241 CmMmGlobalBktCb *bktCb;
1245 globReg = osCp.globRegCb;
1247 #if (ERRCLASS & ERRCLS_INT_PAR)
1248 if(bktIdx >= globReg->numBkts)
1252 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1254 bktCb = &(globReg->bktTbl[bktIdx]);
1256 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1258 blkPtr = dynMemSetElem->nextBktPtr;
1259 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1260 free((Void *)blkPtr);
1263 dynMemSetElem->nextBktPtr = NULLP;
1264 dynMemSetElem->numFreeBlks = 0;
1271 * Fun: ssGetDynMemBlkSet
1273 * Desc: Gets the set of dynamic memory blocks from the global region
1276 * Ret: ROK - successful,
1277 * RFAILED - unsuccessful.
1284 S16 ssGetDynMemBlkSet
1286 uint8_t bktIdx, /* Index to bucket list */
1287 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1288 with new set values */
1292 CmMmGlobRegCb *globReg;
1293 CmMmGlobalBktCb *bktCb;
1298 globReg = osCp.globRegCb;
1300 #if (ERRCLASS & ERRCLS_INT_PAR)
1301 if(bktIdx >= globReg->numBkts)
1305 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1307 bktCb = &(globReg->bktTbl[bktIdx]);
1308 basePtr = &(dynMemSetElem->nextBktPtr);
1310 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1312 blkPtr = (Data *)malloc(bktCb->size);
1314 basePtr = (CmMmEntry **)blkPtr;
1317 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1321 } /* ssGetDynMemBlkSet */
1326 * Fun: ssPutDynMemBlkSet
1328 * Desc: Returns the set of dynamic Blocks into the global region
1331 * Ret: ROK - successful,
1332 * RFAILED - unsuccessful.
1339 S16 ssPutDynMemBlkSet
1341 uint8_t bktIdx, /* Index to bucket list */
1342 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1343 added to global region */
1344 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1347 CmMmGlobRegCb *globReg;
1348 CmMmGlobalBktCb *bktCb;
1350 CmMmBlkSetElement *globMemNode;
1354 globReg = osCp.globRegCb;
1356 #if (ERRCLASS & ERRCLS_INT_PAR)
1357 if(bktIdx >= globReg->numBkts)
1361 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1363 bktCb = &(globReg->bktTbl[bktIdx]);
1365 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1366 try lock is used as it is not required to block as it will be taken
1367 in the next go else it will be blocked for lock as we have to get the
1370 SLock(&(bktCb->bucketLock));
1376 /* Get a free node from the free node linked list */
1377 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1378 if(lstNode == NULLP)
1380 SUnlock(&(bktCb->bucketLock));
1384 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1386 /* Copy the content of the received element information on to free node
1387 * and add it to valid linked list */
1388 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1389 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1390 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1391 dynMemSetElem->numFreeBlks = 0;
1392 dynMemSetElem->nextBktPtr = NULLP;
1394 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1396 SUnlock(&(bktCb->bucketLock));
1404 * Fun: ssGetDynMemBlkSet
1406 * Desc: Gets the set of dynamic memory blocks from the global region
1409 * Ret: ROK - successful,
1410 * RFAILED - unsuccessful.
1412 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1418 S16 ssGetDynMemBlkSet
1420 uint8_t bktIdx, /* Index to bucket list */
1421 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1422 with new set values */
1423 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1426 CmMmGlobRegCb *globReg;
1427 CmMmGlobalBktCb *bktCb;
1429 CmMmBlkSetElement *globMemNode;
1433 globReg = osCp.globRegCb;
1435 #if (ERRCLASS & ERRCLS_INT_PAR)
1436 if(bktIdx >= globReg->numBkts)
1440 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1442 bktCb = &(globReg->bktTbl[bktIdx]);
1444 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1445 try lock is used as it is not required to block as it will be taken
1446 in the next go else it will be blocked for lock as we have to get the
1449 SLock(&(bktCb->bucketLock));
1454 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1456 if(lstNode == NULLP)
1458 SUnlock(&(bktCb->bucketLock));
1462 /* Delete the node from the valid linked list and copy the values of the
1463 * elements of structrues into pointer */
1464 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1465 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1466 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1467 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1469 /* Add this node to the free node linked list */
1470 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1472 SUnlock(&(bktCb->bucketLock));
1476 } /* ssGetDynMemBlkSet */
1479 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1480 uint32_t gDynMemAlrm[4];
1481 static uint32_t memoryCheckCounter;
1483 uint32_t isMemThreshReached(Region reg)
1485 CmMmGlobRegCb *globReg;
1486 CmMmGlobalBktCb *bktCb;
1487 uint8_t bktIdx= reg;
1489 globReg = osCp.globRegCb;
1491 #if (ERRCLASS & ERRCLS_INT_PAR)
1492 if(bktIdx >= globReg->numBkts)
1496 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1498 bktCb = &(globReg->bktTbl[bktIdx]);
1500 if(gDynMemAlrm[bktIdx])
1502 // printf ("\nunder memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1503 SLock(&(bktCb->bucketLock));
1504 if(bktCb->listValidBktSet.count > 25)
1506 gDynMemAlrm[bktIdx] = FALSE;
1507 // printf ("\nrecoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1509 SUnlock(&(bktCb->bucketLock));
1515 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1517 // printf ("\nCHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1518 SLock(&(bktCb->bucketLock));
1519 if(bktCb->listValidBktSet.count < 15 )
1520 gDynMemAlrm[bktIdx] = TRUE;
1521 memoryCheckCounter = 0;
1522 SUnlock(&(bktCb->bucketLock));
1528 #endif /* USE_MALLOC */
1529 #endif /* SS_LOCKLESS_MEMORY */
1531 #ifdef SS_USE_ICC_MEMORY
1534 * Fun: Initialize region/pool tables
1536 * Desc: This function initializes MTSS-specific information
1537 * in the region/pool tables and configures the common
1538 * memory manager for use.
1547 Void * ssGetIccHdl(Region region)
1549 CmMmDynRegCb *dynRegCb;
1551 /* Klock work fix ccpu00148484 */
1552 if(!(region < SS_MAX_REGS))
1557 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1559 return (dynRegCb->iccHdl);
1561 #endif /* SS_USE_ICC_MEMORY */
1563 #ifdef T2K_MEM_LEAK_DBG
1564 RegionMemLeakInfo regMemLeakInfo;
1565 #endif /* T2K_MEM_LEAK_DBG */
1567 #ifdef SS_USE_WLS_MEM
1568 static S16 SPartitionWlsDynMem()
1571 uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1573 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1575 mtDynMemSz[i].startAddr = bktMemStrtAddr;
1576 bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1579 printf("\nGlobal Memory Info: \n");
1580 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1582 printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1587 static S16 SAllocateWlsDynMem()
1592 memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1594 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1596 reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1597 mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1599 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1600 #ifdef INTEL_L1_V20_03_ONWARDS
1601 nWlsMacMemorySize+nWlsPhyMemorySize);
1602 #elif INTEL_L1_V19_10
1605 (reqdMemSz + (4 * 1024 * 1024)));
1607 printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1608 SPartitionWlsDynMem();
1616 S16 SPartitionWlsMemory()
1621 uint64_t pageSize[1], hugePageSize;
1624 long int pageSize[1], hugePageSize;
1627 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1629 uint8_t *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1631 gethugepagesizes(pageSize,1);
1632 hugePageSize = pageSize[0];
1633 for (i = 0; i < 1; i++)
1635 mtRegMemSz[i].startAddr = regMemStrtAddr;
1636 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1638 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1639 reqdSz = numHugePg * hugePageSize;
1640 regMemStrtAddr += reqdSz;
1641 #ifdef T2K_MEM_LEAK_DBG
1642 /* Since wls is region 0 */
1643 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1644 regMemLeakInfo.numActvRegions++;
1645 #endif /* T2K_MEM_LEAK_DBG */
1647 //Store last region addr for validation
1648 mtRegMemSz[i].startAddr = regMemStrtAddr;
1652 #ifdef SS_MEM_WL_DEBUG
1653 Void SChkAddrValid(int type, int region, PTR ptr)
1655 char *tryPtr = NULL;
1656 if(type == 0) //Global
1658 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1659 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1661 printf("\n****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1667 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1669 printf("\n****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1675 #endif /* SS_MEM_WL_DEBUG */
1677 S16 SPartitionStaticMemory(uint8_t *startAddr)
1682 uint8_t *regMemStrtAddr = (uint8_t *)startAddr;
1685 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1686 for (i = 1; i < mtMemoCfg.numRegions; i++)
1688 mtRegMemSz[i].startAddr = regMemStrtAddr;
1689 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1690 regMemStrtAddr += reqdSz;
1691 #ifdef T2K_MEM_LEAK_DBG
1692 { /* Since region 1 onwards are used for non wls */
1693 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1694 regMemLeakInfo.numActvRegions++;
1696 #endif /* T2K_MEM_LEAK_DBG */
1700 S16 SAllocateWlsMem()
1708 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1709 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1711 for (i = 0; i < 1; i++)
1713 /* allocate space for the region */
1714 region = &mtMemoCfg.region[i];
1715 reqdMemSz += region->heapsize;
1716 mtRegMemSz[i].reqdSz += region->heapsize;
1718 for (j = 0; j < region->numBkts; j++)
1720 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1721 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1724 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1725 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1727 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1729 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1731 SPartitionWlsMemory();
1734 S16 SAllocateStaticMem()
1743 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1745 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1746 for (i = 1; i < mtMemoCfg.numRegions; i++)
1748 /* allocate space for the region */
1749 region = &mtMemoCfg.region[i];
1750 reqdMemSz += region->heapsize;
1751 mtRegMemSz[i].reqdSz += region->heapsize;
1753 for (j = 0; j < region->numBkts; j++)
1755 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1756 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1760 startAddr = malloc(reqdMemSz + (1024 * 10));
1762 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1764 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1766 SPartitionStaticMemory(startAddr);
1769 #endif /* INTEL_WLS */
1775 * Fun: Initialize region/pool tables
1777 * Desc: This function initializes MTSS-specific information
1778 * in the region/pool tables and configures the common
1779 * memory manager for use.
1788 S16 ssdInitMem(void)
1790 /* mt018.201 - added local variable */
1794 MtRegCfg *region = NULLP;
1795 Txt errMsg[256] = {'\0'};
1796 #ifdef SS_LOCKLESS_MEMORY
1797 CmMmDynRegCb *dynRegCb =0;
1798 #ifdef SS_USE_ICC_MEMORY
1800 CmMmGlobRegCb *globReg = NULLP;
1803 #endif /* SS_LOCKLESS_MEMORY */
1806 /* Use the default SSI memory manager if the ICC memory manager is not
1807 * avilable. If ICC memory manager is avilable, it will be used for
1808 * all sharable memory allocation and de-allocation */
1809 #ifdef SS_LOCKLESS_MEMORY
1810 #ifdef SS_USE_ICC_MEMORY
1811 #ifndef YS_PHY_3_8_2
1813 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1815 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1816 if(dynRegCb == NULLP)
1820 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1822 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1824 dynRegCb->region = i;
1825 cmMmDynRegInit(dynRegCb);
1826 printf("\niccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1829 /* ysIccHdl = dynRegCb->iccHdl; */
1832 /* Initialize the global region first */
1833 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1835 if(osCp.globRegCb == NULLP)
1840 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1842 #ifdef SS_USE_WLS_MEM
1843 SAllocateWlsDynMem();
1846 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1848 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1849 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1850 globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1851 printf("\nStarting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1854 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1856 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1859 if(globReg->bktTbl[i].startAddr == NULLP)
1863 globReg->bktTbl[i].poolId = i;
1864 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1865 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1866 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1869 globReg->numBkts = mtGlobMemoCfg.numBkts;
1870 cmMmGlobRegInit(globReg);
1872 /* Initialize the dynamic task regions and sanity check for the theshold
1874 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1876 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1877 if(dynRegCb == NULLP)
1881 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1883 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1884 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1885 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1886 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1888 #ifdef XEON_SPECIFIC_CHANGES
1893 dynRegCb->bktTbl[k].poolId = k;
1894 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1895 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1896 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1897 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1898 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1900 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1903 dynRegCb->region = i;
1904 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1905 cmMmDynRegInit(dynRegCb);
1907 #endif /* SS_USE_ICC_MEMORY */
1908 #endif /* SS_LOCKLESS_MEMORY */
1910 #ifdef T2K_MEM_LEAK_DBG
1912 /* Initailize mem leak tool memorys for debguing */
1913 regMemLeakInfo.numActvRegions=0;
1914 for(reg=0; reg <SS_MAX_REGS; reg++)
1916 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1917 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1918 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1919 regMemLeakInfo.regStartAddr[reg] = 0;
1922 regMemLeakInfo.regStartAddr[reg] = 0;
1923 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1925 printf("\n mutex init failed\n");
1931 /* Now allocate WLS memory */
1933 SAllocateStaticMem();
1935 /* mt018.201 - CMM Initialization */
1936 for (i = 0; i < mtMemoCfg.numRegions; i++)
1938 /* allocate space for the region control block */
1939 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1940 #ifdef TENB_RTLIN_CHANGES
1941 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1943 if (mtCMMRegCb[i] == NULLP)
1945 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1946 for the Region:%d control block\n",i);
1948 for (k = 0; k < i; k++)
1950 cmMmRegDeInit(mtCMMRegCb[k]);
1951 free(mtCMMRegCfg[k]->vAddr);
1952 free(mtCMMRegCb[k]);
1953 free(mtCMMRegCfg[k]);
1958 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1959 #ifdef TENB_RTLIN_CHANGES
1960 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1962 if (mtCMMRegCfg[i] == NULLP)
1964 for (k = 0; k < i; k++)
1966 cmMmRegDeInit(mtCMMRegCb[k]);
1967 free(mtCMMRegCfg[k]->vAddr);
1968 free(mtCMMRegCb[k]);
1969 free(mtCMMRegCfg[k]);
1971 free(mtCMMRegCb[i]);
1976 /* allocate space for the region */
1977 region = &mtMemoCfg.region[i];
1978 mtCMMRegCfg[i]->size = region->heapsize;
1979 for (j = 0; j < region->numBkts; j++)
1981 /* mt033.201 - addition for including the header size while computing the total size */
1982 #ifdef SSI_DEBUG_LEVEL1
1983 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1984 (region->bkt[j].numBlks);
1986 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1987 #endif /* SSI_DEBUG_LEVEL1 */
1990 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1992 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1995 #ifdef XEON_SPECIFIC_CHANGES
1996 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1997 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1999 #ifdef TENB_RTLIN_CHANGES
2000 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
2003 if (mtCMMRegCfg[i]->vAddr == NULLP)
2005 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
2006 for the Region:%d \n",i);
2008 for (k = 0; k < i; k++)
2010 cmMmRegDeInit(mtCMMRegCb[k]);
2011 free(mtCMMRegCfg[k]->vAddr);
2012 free(mtCMMRegCb[k]);
2013 free(mtCMMRegCfg[k]);
2015 free(mtCMMRegCb[i]);
2016 free(mtCMMRegCfg[i]);
2021 /* set up the CMM configuration structure */
2022 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
2023 mtCMMRegCfg[i]->chFlag = 0;
2024 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
2025 mtCMMRegCfg[i]->numBkts = region->numBkts;
2027 for (j = 0; j < region->numBkts; j++)
2029 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
2030 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
2033 /* initialize the CMM */
2034 #ifdef SS_LOCKLESS_MEMORY
2035 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2037 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2038 #endif /* SS_LOCKLESS_MEMORY */
2040 for (k = 0; k < i; k++)
2042 cmMmRegDeInit(mtCMMRegCb[k]);
2043 free(mtCMMRegCfg[k]->vAddr);
2044 free(mtCMMRegCb[k]);
2045 free(mtCMMRegCfg[k]);
2047 free(mtCMMRegCfg[i]->vAddr);
2048 free(mtCMMRegCb[i]);
2049 free(mtCMMRegCfg[i]);
2054 /* initialize the STREAMS module */
2055 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
2056 if (region->regionId == 0)
2058 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
2060 for (k = 0; k < i; k++)
2062 cmMmRegDeInit(mtCMMRegCb[k]);
2063 free(mtCMMRegCfg[k]->vAddr);
2064 free(mtCMMRegCb[k]);
2065 free(mtCMMRegCfg[k]);
2067 cmMmRegDeInit(mtCMMRegCb[i]);
2068 free(mtCMMRegCfg[i]->vAddr);
2069 free(mtCMMRegCb[i]);
2070 free(mtCMMRegCfg[i]);
2075 /* mt001.301 : Additions */
2076 #ifdef SS_MEM_LEAK_STS
2078 #endif /* SS_MEM_LEAK_STS */
2086 * Fun: De-initialize region/pool tables
2088 * Desc: This function reverses the initialization in ssdInitMem().
2097 Void ssdDeinitMem(void)
2099 /* mt018.201 - added local variables */
2102 /* mt008.301 Additions */
2103 #ifdef SS_MEM_LEAK_STS
2104 cmDeinitMemLeakMdl();
2105 #endif /* SS_MEM_LEAK_STS */
2107 for (i = 0; i < mtMemoCfg.numRegions; i++)
2109 cmMmRegDeInit(mtCMMRegCb[i]);
2110 free(mtCMMRegCfg[i]->vAddr);
2111 free(mtCMMRegCb[i]);
2112 free(mtCMMRegCfg[i]);
2121 * Fun: Initialize task table
2123 * Desc: This function initializes MTSS-specific information
2124 * in the task table.
2133 S16 ssdInitTsk(void)
2135 /* mt001.301 : Additions */
2136 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2137 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2138 uint32_t tskInd = 0;
2139 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2143 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2144 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2145 /* initialize system task information */
2146 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2148 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2150 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2157 * Fun: Deinitialize task table
2159 * Desc: This function reverses the initialization perfomed in
2169 Void ssdDeinitTsk(void)
2176 #ifdef SS_DRVR_SUPPORT
2179 * Fun: Initialize driver task table
2181 * Desc: This function initializes MTSS-specific information
2182 * in the driver task table.
2191 S16 ssdInitDrvr(void)
2195 pthread_attr_t attr;
2200 /* initialize the dependent portion of the driver task entries */
2201 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2203 osCp.drvrTskTbl[i].dep.flag = FALSE;
2207 /* create pipe for communication between SSetIntPend() and
2208 * the isTskHdlr thread.
2210 if (pipe(osCp.dep.isFildes) != 0)
2216 /* create the isTskHdlr thread */
2217 pthread_attr_init(&attr);
2218 /* mt021.201 - Addition to set stack size */
2219 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2220 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2221 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2222 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2224 /* mt020.201 - Addition for destroying thread attribute object attr */
2225 pthread_attr_destroy(&attr);
2231 /*mt014.301 : 4GMX release related changes*/
2232 #ifdef SS_4GMX_UCORE
2240 /* mt020.201 - Addition for destroying thread attribute object attr */
2241 pthread_attr_destroy(&attr);
2250 * Fun: Deinitialize driver information
2252 * Desc: This function reverses the initialization performed in
2262 Void ssdDeinitDrvr(void)
2264 /* mt008.301: Terminate the Driver Task on exit */
2265 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2268 TL_Close(AppContext.hUAII);
2269 if (clusterMode == RADIO_CLUSTER_MODE)
2271 TL_Close(AppContext.hUAII_second);
2277 #endif /* SS_DRVR_SUPPORT */
2282 * Fun: Initialize timer table
2284 * Desc: This function initializes MTSS-specific information
2285 * in the timer table.
2294 S16 ssdInitTmr(void)
2296 pthread_attr_t attr;
2297 struct sched_param param_sched;
2298 /* mt010.21: addition */
2300 #ifdef SS_MULTICORE_SUPPORT
2302 #endif /* SS_MULTICORE_SUPPORT */
2303 #ifdef SS_THR_REG_MAP
2304 uint32_t threadCreated = FALSE;
2305 #endif /* SS_THR_REG_MAP */
2309 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2310 /* mt010.21: addition */
2311 osCp.dep.tmrTqCp.nxtEnt = 0;
2312 for (i=0; i< SS_MAX_TMRS; i++)
2314 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2317 #ifdef SS_MULTICORE_SUPPORT
2318 sTsk = ssdAddTmrSTsk();
2323 #endif /* SS_MULTICORE_SUPPORT */
2324 /* create the timer handler thread */
2325 pthread_attr_init(&attr);
2326 /* mt021.201 - Addition to set stack size */
2327 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2328 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2329 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2330 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2331 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2332 pthread_attr_setschedparam(&attr, ¶m_sched);
2335 #ifdef SS_THR_REG_MAP
2336 /* When the thread is created, we check for the memory mapping table if
2337 * threadId can be placed in thread memory map table. If it is not able to place
2338 * threadId is stored in tmporary array. Once thread is created successful,
2339 * thread_cancel is sent for each thread which are created before. All the
2340 * threads are made to wait on sema which is cancel point for thread.
2342 while(threadCreated == FALSE)
2345 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2347 /* mt020.201 - Addition for destroying thread attribute object attr */
2348 pthread_attr_destroy(&attr);
2353 #ifdef SS_THR_REG_MAP
2354 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2357 #endif /* SS_THR_REG_MAP */
2358 #ifdef SS_MEM_WL_DEBUG
2359 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2362 /* mt020.201 - Addition for destroying thread attribute object attr */
2363 pthread_attr_destroy(&attr);
2372 * Fun: Deinitialize timer table
2374 * Desc: This function reverses the initialization performed in
2384 Void ssdDeinitTmr(void)
2386 #ifdef SS_MULTICORE_SUPPORT
2389 #endif /* SS_MULTICORE_SUPPORT */
2392 #ifdef SS_MULTICORE_SUPPORT
2393 ret = SLock(&osCp.sTskTblLock);
2397 #if (ERRCLASS & ERRCLS_DEBUG)
2398 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2399 "Could not lock system task table");
2403 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2404 /* clean up the system task entry */
2408 SDestroyLock(&sTsk->lock);
2409 ssDestroyDmndQ(&sTsk->dQ);
2412 /* make this entry available in the system task table */
2413 sTsk->nxt = osCp.nxtSTskEntry;
2414 osCp.nxtSTskEntry = 0;
2418 /* unlock the system task table */
2419 SUnlock(&osCp.sTskTblLock);
2421 #endif /* SS_MULTICORE_SUPPORT */
2422 /* mt008.301: Terminate the timer thread on exit */
2423 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2433 * Desc: Pre-tst() initialization.
2442 S16 ssdInitLog(void)
2444 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2448 pthread_attr_t attr;
2451 #endif /* CONSTDIO */
2456 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2461 osCp.dep.conInFp = (FILE *) stdin;
2462 osCp.dep.conOutFp = (FILE *) stdout;
2463 /* added compile time flag CONRD: mt017.21 */
2467 /* disable canonical input processing */
2468 fd = fileno(osCp.dep.conInFp);
2469 if ((tcgetattr(fd, &tio)) != 0)
2471 printf("\nError: disable canonical input processing\n");
2475 tio.c_lflag &= ~ICANON;
2476 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2477 tio.c_cc[VTIME] = 0;
2478 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2480 printf("\nError: while tcsetattr() processing\n");
2484 #endif /* CONSTDIO */
2487 /* set up the input fd to block when no data is available */
2488 fd = fileno(osCp.dep.conInFp);
2489 flags = fcntl(fd, F_GETFL, &flags);
2490 flags &= ~O_NONBLOCK;
2491 if (fcntl(fd, F_SETFL, flags) == -1)
2493 printf("\nError: while fcntl processing\n");
2498 /* create the console handler thread */
2499 pthread_attr_init(&attr);
2500 /* mt021.201 - Addition to set stack size */
2501 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2502 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2503 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2506 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2508 /* mt020.201 - Addition for destroying thread attribute object attr */
2509 pthread_attr_destroy(&attr);
2511 printf("\nError: Logging Thread creation failed \n");
2515 /* mt020.201 - Addition for destroying thread attribute object attr */
2516 pthread_attr_destroy(&attr);
2530 * Desc: This function reverses the initialization performed in
2540 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2541 Void ssdDeinitLog(void)
2543 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2546 /* mt008.301: Terminate the console reader on exit */
2547 while(pthread_cancel(osCp.dep.conHdlrTID));
2553 /* mt001.301 : Additions */
2557 S16 ssdInitWatchDog(uint16_t port)
2560 Txt prntBuf[PRNTSZE];
2563 #ifdef SS_WATCHDOG_IPV6
2564 struct sockaddr_in6 tmpaddr;
2566 struct sockaddr_in tmpaddr;
2567 #endif /* SS_WATCHDOG_IPV6 */
2568 #ifdef SS_MULTIPLE_PROCS
2569 ProcId procId = SS_WD_WDPROC;
2570 if (SAddProcIdLst(1, &procId) != ROK)
2574 #endif /* SS_MULTIPLE_PROCS */
2577 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2579 /* Create a watch dog system task */
2580 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2582 /* Create a watch dog reveiver system task */
2583 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2585 /* Register and attach watch dog TAPA task */
2586 #ifdef SS_MULTIPLE_PROCS
2587 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2588 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2590 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2591 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2592 #endif /* SS_MULTIPLE_PROCS */
2593 /* Register and attach watch dog receiver TAPA task */
2594 #ifdef SS_MULTIPLE_PROCS
2595 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2596 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2598 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2599 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2600 #endif /* SS_MULTIPLE_PROCS */
2602 #ifndef SS_MULTIPLE_PROCS
2603 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2604 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2606 osCp.wdCp.watchDgPst.srcProcId = procId;
2607 osCp.wdCp.watchDgPst.dstProcId = procId;
2608 #endif /* SS_MULTIPLE_PROCS */
2610 /* Initialise the pst structure */
2611 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2612 /* Initialize the watch dog timer resolution default is 1 sec */
2614 cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2615 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2616 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2617 for(idx = 0; idx < 1; idx++)
2619 osCp.wdCp.watchDgTs[idx].first = NULLP;
2620 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2622 #ifdef SS_MULTIPLE_PROCS
2623 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2625 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2626 #endif /* SS_MULTIPLE_PROCS */
2628 /* Create the watch dog receiver socket */
2629 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2630 if(osCp.wdCp.globWd.sock == -1)
2632 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2636 #ifdef SS_WATCHDOG_IPV6
2637 tmpaddr.sin6_len = sizeof(tmpadDr);
2638 tmpaddr.sin6_family = AF_INET6;
2639 tmpaddr.sin6_addr = in6addr_any;
2640 tmpaddr.sin6_port = htons(port);
2642 tmpaddr.sin_family = AF_INET;
2643 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2644 tmpaddr.sin_port = htons(port);
2645 #endif /* SS_WATCHDOG_IPV6 */
2647 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2650 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2654 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2658 #ifndef SS_MULTIPLE_PROCS
2659 pst.srcProcId = SFndProcId();
2660 pst.dstProcId = SFndProcId();
2662 pst.srcProcId = procId;
2663 pst.dstProcId = procId;
2664 #endif /* SS_MULTIPLE_PROCS */
2665 pst.event = EVTSSHRTBTREQ;
2666 ssdInitWatchDgPst(&pst);
2667 SPstTsk(&pst, mBuf);
2672 S16 ssdInitWatchDgPst(Pst *pst)
2675 pst->selector = SS_LOOSE_COUPLING;
2677 pst->region = DFLT_REGION; /* region */
2678 pst->pool = DFLT_POOL; /* pool */
2680 pst->prior = PRIOR0; /* priority */
2681 pst->route = RTESPEC; /* route */
2683 pst->dstEnt = ENTHB; /* destination entity */
2685 pst->srcEnt = ENTDW; /* source entity */
2691 #ifdef SS_MULTIPLE_PROCS
2692 S16 ssdWatchDgActvTmr
2699 S16 ssdWatchDgActvTmr(Void)
2700 #endif /* SS_MULTIPLE_PROCS */
2703 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2708 Void ssdWatchDgTmrEvt
2710 PTR cb, /* control block */
2711 S16 event /* timer number */
2714 /* mt003.301 Fixed warings */
2718 Txt prntBuf[PRNTSZE];
2727 SPrint("Timer Heartbeat Request Expired");
2729 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2734 SLock(&osCp.wdCp.wdLock);
2735 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2737 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2739 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2741 if(osCp.wdCp.globWd.callback != 0)
2743 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2747 SUnlock(&osCp.wdCp.wdLock);
2749 if(!osCp.wdCp.globWd.watchdogStop)
2751 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2752 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2762 Void ssdStartWatchDgTmr
2773 Txt prntBuf[PRNTSZE];
2777 /* mt003.301 Modifications */
2780 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2781 if(event == SS_TMR_HRTBT)
2783 SPrint("\nSTART SS_TMR_HRTBT");
2790 SLock(&osCp.wdCp.wdLock);
2791 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2793 osCp.wdCp.globWd.wdsta[i].status = 0;
2795 SUnlock(&osCp.wdCp.wdLock);
2797 arg.tq = osCp.wdCp.watchDgTs;
2798 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2799 arg.timers = osCp.wdCp.watchDgTmr;
2800 arg.cb = (PTR)NULLP;
2802 arg.wait = osCp.wdCp.globWd.timeout = wait;
2810 Void ssdStopWatchDgTmr
2819 Txt prntBuf[PRNTSZE];
2823 /* mt003.301 Modifications */
2826 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2827 if(event == SS_TMR_HRTBT)
2829 SPrint("STOP SS_TMR_HRTBT");
2833 SLock(&osCp.wdCp.wdLock);
2834 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2836 osCp.wdCp.globWd.wdsta[i].status = 0;
2838 SUnlock(&osCp.wdCp.wdLock);
2841 arg.tq = osCp.wdCp.watchDgTs;
2842 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2843 arg.timers = osCp.wdCp.watchDgTmr;
2844 arg.cb = (PTR)NULLP;
2863 Txt prntBuf[PRNTSZE];
2865 struct sockaddr_in tmpaddr;
2866 char hbMsg[SS_WD_HB_MSG_SIZE];
2873 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2877 /* Pack the message */
2878 strcpy(hbMsg, "<HB>REQ</HB>");
2880 /* Send the heartbeat messages to all the configured nodes */
2881 SLock(&osCp.wdCp.wdLock);
2882 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2884 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2889 /* Identify the destination node */
2890 #ifdef SS_WATCHDOG_IPV6
2891 tmpaddr.sin6_len = sizeof(tmpaddr);
2892 tmpaddr.sin6_family = AF_INET6;
2893 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2894 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2896 tmpaddr.sin_family = AF_INET;
2897 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2898 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2899 #endif /* SS_WATCHDOG_IPV6 */
2901 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2905 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2906 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2913 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2918 SUnlock(&osCp.wdCp.wdLock);
2923 #endif /* SS_WATCHDOG */
2927 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2933 * Desc: This function gets command line options.
2942 static Void mtGetOpts(void)
2949 FILE *memOpt; /* memory options file pointer */
2952 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2958 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2960 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2966 #ifdef SS_LOCKLESS_MEMORY
2981 osCp.dep.fileOutFp = (FILE *)NULLP;
2983 /* initialize memOpt */
2984 memOpt = (FILE *) NULLP;
2991 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2996 /* mt001.301 : Additions */
2997 #ifdef SS_MEM_LEAK_STS
2999 cmMemOpenMemLkFile(msOptArg);
3003 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3006 fileBasedMemCfg = TRUE;
3007 memOpt = fopen(msOptArg, "r");
3009 /* if file does not exist or could not be opened then use the
3010 * default memory configuration as defined in mt_ss.h
3012 if (memOpt == (FILE *) NULLP)
3014 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3015 be opened, using default mem configuration\n", msOptArg);
3020 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3022 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3028 case 0: /*** INPUT: Number of regions ***/
3029 sscanf(line, "%ld", (long *) &numReg);
3030 mtMemoCfg.numRegions = numReg;
3031 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3033 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3039 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3040 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3041 if(numBkts > MT_MAX_BKTS)
3043 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3047 if(numPools > SS_MAX_POOLS_PER_REG)
3049 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3054 * Delay updation from local variable to global
3055 * structure of number of regions and heap data to
3056 * counter error conditions present above.
3058 for(idx = 0; idx < cfgNumRegs; idx++)
3060 mtMemoCfg.region[idx].numBkts = numBkts;
3061 cfgRegInfo[idx].region = idx;
3062 cfgRegInfo[idx].numPools = numPools;
3064 * Initialize the pool info as static type with size zero
3066 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3068 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3069 cfgRegInfo[idx].pools[poolIdx].size = 0;
3074 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3075 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3077 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3079 if(bktIdx >= numBkts)
3081 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3086 mtBktInfo[bktIdx].blkSize = bktSz;
3088 if(bktUpdtCnt == numBkts)
3090 i++; /*done reading bkt info, start reading individual region info*/
3094 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3095 sscanf(line,"%ld",(long *) ®Id);
3096 if(regId >= mtMemoCfg.numRegions)
3098 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3099 #ifndef XEON_SPECIFIC_CHANGES
3104 mtMemoCfg.region[regId].regionId = regId;
3107 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3108 if(bktUpdtCnt < numBkts)
3110 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3111 if(bktIdx >= numBkts)
3113 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3118 if(bktIdx < MT_MAX_BKTS)
3120 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3121 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3122 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3123 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3126 if(bktUpdtCnt == numBkts)
3133 case 5: /* INPUT: Heapsize ***/
3134 sscanf(line, "%ld", (long *) &heapSz);
3135 mtMemoCfg.region[regId].heapsize = heapSz;
3137 if(regUpdtCnt != mtMemoCfg.numRegions)
3146 #ifdef SS_LOCKLESS_MEMORY
3148 sscanf(line, "%ld", (long *) &numBkts);
3149 mtGlobMemoCfg.numBkts = numBkts;
3150 #ifndef XEON_SPECIFIC_CHANGES
3151 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3154 #ifdef XEON_SPECIFIC_CHANGES
3155 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3156 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3157 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3159 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3162 mtDynMemoCfg.region[idx].regionId = idx;
3163 mtDynMemoCfg.region[idx].numBkts = numBkts;
3171 if(bktUpdtCnt < numBkts)
3173 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3174 (long *) &bktSz, (long *) &bktNum,
3175 (long *) &bktSetSize, (long *) &bktRelThr,
3176 (long *) &bktAqurThr);
3177 /* Klock work fix ccpu00148484 */
3178 if(bktIdx < SS_MAX_POOLS_PER_REG)
3180 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3181 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3182 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3183 #ifdef XEON_SPECIFIC_CHANGES
3184 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3185 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3186 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3188 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3190 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3196 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3198 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3199 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3200 #ifdef XEON_SPECIFIC_CHANGES
3201 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3202 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3203 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3209 #ifdef XEON_SPECIFIC_CHANGES
3210 if(bktUpdtCnt == numBkts)
3216 case 8: /* INPUT: Global Heapsize ***/
3217 sscanf(line, "%ld", (long *) &heapSz);
3218 mtGlobMemoCfg.heapSize = heapSz;
3219 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3227 memConfigured = FALSE;
3231 memConfigured = TRUE;
3239 /* mt028.201: modification: multiple procs support related changes */
3240 #ifndef SS_MULTIPLE_PROCS
3243 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3245 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3248 #else /* SS_MULTIPLE_PROCS */
3252 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3254 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3256 SAddProcIdLst(1, &procId);
3259 #endif /* SS_MULTIPLE_PROCS */
3263 osCp.configFilePath = msOptArg;
3287 * Desc: Get options from command line
3289 * Ret: option - success
3291 * EOF - end of options
3293 * Notes: Handles command lines like the following
3296 * then command line should look like this...
3297 * -a foo -b foo1 -c -d foo
3301 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3306 * nloops = atoi(msArgv[msOptInd]);
3309 * state1 = atoi(msArgv[msOptInd]);
3321 int argc, /* argument count */
3322 char **argv, /* argument value */
3323 char *opts /* options */
3326 /* mt020.201 - Removed for no command line */
3334 /* mt020.201 - Addition for no command line */
3346 /*mt013.301 : Changes as per coding standards*/
3347 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3353 if (!strcmp(argv[msOptInd], "--"))
3358 else if (argv[msOptInd][0] != '-')
3366 c = argv[msOptInd][sp];
3367 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3369 if (argv[msOptInd][++sp] == '\0')
3380 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3383 if (++msOptInd >= (S16) argc)
3388 else msOptArg = argv[msOptInd++];
3395 if (argv[msOptInd][++sp] == '\0')
3407 #endif /* NOCMDLINE */
3415 * Desc: This function starts system services execution; the
3416 * permanent tasks are started and the system enters a
3433 /* mt025.201 - Modification for adding lock to timer handler */
3434 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3436 sem_post(&osCp.dep.ssStarted);
3445 * indirect interface functions to system services service user
3451 * Fun: ssdAttachTTsk
3453 * Desc: This function sends the initial tick message to a TAPA
3454 * task if the task is a permanent task.
3465 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3472 if (tTsk->tskType == SS_TSK_PERMANENT)
3474 /* Send a permanent tick message to this task, to start
3477 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3480 #if (ERRCLASS & ERRCLS_DEBUG)
3481 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3486 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3487 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3489 /* set up post structure */
3490 /* mt028.201: modification: multiple procs support related changes */
3491 #ifndef SS_MULTIPLE_PROCS
3492 mInfo->pst.dstProcId = SFndProcId();
3493 mInfo->pst.srcProcId = SFndProcId();
3494 #else /* SS_MULTIPLE_PROCS */
3495 mInfo->pst.dstProcId = tTsk->proc;
3496 mInfo->pst.srcProcId = tTsk->proc;
3497 #endif /* SS_MULTIPLE_PROCS */
3498 mInfo->pst.selector = SEL_LC_NEW;
3499 mInfo->pst.region = DFLT_REGION;
3500 mInfo->pst.pool = DFLT_POOL;
3501 mInfo->pst.prior = PRIOR3;
3502 mInfo->pst.route = RTESPEC;
3503 mInfo->pst.event = 0;
3504 mInfo->pst.dstEnt = tTsk->ent;
3505 mInfo->pst.dstInst = tTsk->inst;
3506 mInfo->pst.srcEnt = tTsk->ent;
3507 mInfo->pst.srcInst = tTsk->inst;
3509 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3510 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3516 #if (ERRCLASS & ERRCLS_DEBUG)
3517 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3518 "Could not write to demand queue");
3531 * Fun: ssdDetachTTsk
3533 * Desc: Does nothing.
3544 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3554 * Fun: ssdCreateSTsk
3556 * Desc: This function creates a system task. A thread is started
3557 * on the system task handler function defined later.
3568 SsSTskEntry *sTsk /* pointer to system task entry */
3572 pthread_attr_t attr;
3573 /* struct sched_param param_sched;*/
3575 #ifdef SS_THR_REG_MAP
3576 uint32_t threadCreated = FALSE;
3581 #ifdef SS_SINGLE_THREADED
3582 /* mt001.301 : Additions */
3584 #ifdef SS_MULTICORE_SUPPORT
3585 if (osCp.numSTsks > 1)
3587 if (osCp.numSTsks > 0)
3588 #endif /* SS_MULTICORE_SUPPORT */
3590 #ifdef SS_MULTICORE_SUPPORT
3591 if (osCp.numSTsks > 3)
3593 if (osCp.numSTsks > 2)
3594 #endif /* SS_MULTICORE_SUPPORT */
3595 #endif /* SS_WATCHDOG */
3602 /* set the current executing entity and instance IDs to
3603 * 'not configured'. create the lock to access them.
3605 sTsk->dep.ent = ENTNC;
3606 sTsk->dep.inst = INSTNC;
3609 /* create the thread */
3610 pthread_attr_init(&attr);
3611 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3613 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3614 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3615 if (sTsk->tskPrior == 0)
3617 printf("\nCreating RT thread #######################\n");
3618 #ifdef SS_THR_REG_MAP
3619 /* When the thread is created, we check for the memory mapping table if
3620 * threadId can be placed in thread memory map table. If it is not able to place
3621 * threadId is stored in tmporary array. Once thread is created successful,
3622 * thread_cancel is sent for each thread which are created before. All the
3623 * threads are made to wait on sema which is cancel point for thread.
3625 while(threadCreated == FALSE)
3628 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3631 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3632 pthread_attr_destroy(&attr);
3634 #if (ERRCLASS & ERRCLS_DEBUG)
3635 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3640 #ifdef SS_THR_REG_MAP
3641 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3649 #ifdef SS_THR_REG_MAP
3650 /* When the thread is created, we check for the memory mapping table if
3651 * threadId can be placed in thread memory map table. If it is not able to place
3652 * threadId is stored in tmporary array. Once thread is created successful,
3653 * thread_cancel is sent for each thread which are created before. All the
3654 * threads are made to wait on sema which is cancel point for thread.
3656 while(threadCreated == FALSE)
3659 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3663 /* mt020.201 - Addition for destroying thread attribute object attr */
3664 pthread_attr_destroy(&attr);
3666 #if (ERRCLASS & ERRCLS_DEBUG)
3667 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3672 #ifdef SS_THR_REG_MAP
3673 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3680 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3681 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3683 static uint32_t stLwpId = 3;
3684 sTsk->dep.lwpId = ++stLwpId;
3686 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3688 /* mt020.201 - Addition for destroying thread attribute object attr */
3689 pthread_attr_destroy(&attr);
3698 pthread_attr_t* attr,
3699 void *(*start_routine) (void *),
3704 #ifdef SS_THR_REG_MAP
3705 uint32_t threadCreated = FALSE;
3708 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3709 /* Klock work fix ccpu00148484 */
3710 if(threadArg == NULLP)
3714 threadArg->argument = arg;
3715 threadArg->start_routine = start_routine;
3718 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3720 #ifdef SS_THR_REG_MAP
3721 /* When the thread is created, we check for the memory mapping table if
3722 * threadId can be placed in thread memory map table. If it is not able to place
3723 * threadId is stored in tmporary array. Once thread is created successful,
3724 * thread_cancel is sent for each thread which are created before. All the
3725 * threads are made to wait on sema which is cancel point for thread.
3727 while(threadCreated == FALSE)
3730 /*pthreadCreateHdlr */
3731 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3736 #ifdef SS_THR_REG_MAP
3737 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3748 * Fun: Set Pthread Attributes
3750 * Desc: This function is used to set various explicit
3751 * pthread attributes like, priority scheduling,etc
3761 static S16 ssdSetPthreadAttr
3764 pthread_attr_t *attr
3767 struct sched_param param;
3770 SMemSet(¶m, 0, sizeof(param));
3772 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3773 param.sched_priority = 100 - 1 - tskPrior;
3775 param.sched_priority = 100 - 10 - tskPrior;
3778 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3779 /* TODO:: This can be avoided by reducing the priority
3780 * of iccserv thread in l1_master.sh*/
3782 if (clusterMode == RADIO_CLUSTER_MODE)
3784 if(tskPrior == PRIOR1)
3786 param.sched_priority = 91;
3793 printf("\nSet priority %u\n", param.sched_priority);
3795 /* Set Scheduler to explicit, without this non of the below
3796 pthread attr works */
3797 #ifdef TENB_RTLIN_CHANGES
3798 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3801 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3802 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3803 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3804 #ifdef TENB_RTLIN_CHANGES
3805 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3807 pthread_attr_setschedparam(attr, ¶m);
3811 } /* ssdSetPthreadAttr */
3813 /************* multi-core support **************/
3814 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3815 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3819 * Fun: Get the current core/cpu affinity for a thread/lwp
3821 * Desc: This function is used to get the current processor/core
3822 * affinity for a a system task (thread/lwp). It sets the
3823 * affinity based on the mode supplied by the caller.
3826 * RFAILED - failed, general (optional)
3835 SSTskId *tskId, /* filled in with system task ID */
3836 uint32_t *coreId /* the core/processor id to which the affinity is set */
3846 uint32_t cpuInd = 0;
3847 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3850 uint32_t lwpId = *tskId;
3854 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3856 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3858 tId = osCp.sTskTbl[tskInd].dep.tId;
3863 /* if tskId is not found in the tskTbl */
3864 if (tskInd == SS_MAX_STSKS)
3866 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3871 /* initialize the cpu mask */
3874 /* set thread affinity for linux */
3875 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3877 #if (ERRCLASS & ERRCLS_DEBUG)
3878 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3881 } /* end if pthread_setaffinity fails */
3883 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3885 if (CPU_ISSET (cpuInd, & cpuSet))
3894 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3896 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3898 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3903 /* if tskId is not found in the tskTbl */
3904 if (tskInd == SS_MAX_STSKS)
3906 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3910 /* set thread affinity for Solaris */
3911 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3913 #if (ERRCLASS & ERRCLS_DEBUG)
3914 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3917 } /* end if processor_bind fails */
3920 #endif /* SS_LINUX */
3924 } /* ssdGetAffinity */
3929 * Fun: Set the core/cpu affinity for a thread/lwp
3931 * Desc: This function is used to set processor/core affinity for a
3932 * a system task (thread/lwp). It sets the affinity based on the
3933 * mode supplied by the caller.
3936 * RFAILED - failed, general (optional)
3945 SSTskId *tskId, /* filled in with system task ID */
3946 uint32_t coreId /* the core/processor id to which the affinity has to be set */
3950 uint32_t tskInd = 0;
3955 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3958 uint32_t lwpId = *tskId;
3964 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3966 /* Here tskId can not be used as index as the task may be terminated if
3967 there is a TERM even for that tsk, thus breaking the task Id numbering
3969 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3971 tId = osCp.sTskTbl[tskInd].dep.tId;
3976 /* if tskId is not found in the tskTbl */
3977 if (tskInd == SS_MAX_STSKS)
3979 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3983 /* initialize the cpu mask */
3986 /* set the cpu mask */
3987 CPU_SET(coreId, &cpuSet);
3989 /* set thread affinity for linux */
3990 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3992 #if (ERRCLASS & ERRCLS_DEBUG)
3993 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
3996 } /* end if pthread_setaffinity fails */
4000 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4002 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4003 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4005 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4010 /* if tskId is not found in the tskTbl */
4011 if (tskInd == SS_MAX_STSKS)
4013 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4017 /* set thread affinity for Solaris */
4018 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4020 #if (ERRCLASS & ERRCLS_DEBUG)
4021 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4024 } /* end if processor_bind fails */
4027 #endif /* SS_LINUX */
4029 } /* ssdSetAffinity */
4031 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4032 /************ end multi-core support *************/
4037 * Fun: ssdDestroySTsk
4039 * Desc: This function destroys a system task. A terminate
4040 * event message is sent to the thread function.
4051 SsSTskEntry *sTsk /* pointer to system task entry */
4060 /* we send a message to this system task to tell it to die */
4061 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4064 #if (ERRCLASS & ERRCLASS_DEBUG)
4065 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4071 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4072 mInfo->eventInfo.event = SS_EVNT_TERM;
4074 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4078 #if (ERRCLASS & ERRCLASS_DEBUG)
4079 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4080 "Could not write to demand queue");
4090 /* mt023.201 - Added SThreadYield function to yield CPU
4094 * Desc: This function defers thread execution to any other ready
4105 S16 SThreadYield(void)
4109 /* mt024.201 - seperated Linux and other UNIX implementations
4115 /* Set sleep value to 0 to yield CPU */
4119 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4121 #else /* other UNICes */
4123 return (sleep(0) == 0 ? ROK : RFAILED);
4125 #endif /* SS_LINUX */
4132 * Fun: Register timer
4134 * Desc: This function is used to register a timer
4135 * function for the service user. System services
4136 * will invoke the timer activation function
4137 * passed to it at the specified intervals.
4141 * Notes: Timing is handled by the common timers. The
4142 * ticks are handled by a thread that uses
4143 * nanosleep() and thus timing precision will not
4151 SsTmrEntry *tmr /* pointer to timer entry */
4159 /* initialize common timers */
4160 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4163 /* start the timer */
4164 arg.tq = osCp.dep.tmrTq;
4165 arg.tqCp = &osCp.dep.tmrTqCp;
4166 arg.timers = tmr->dep.timers;
4171 arg.max = TMR_DEF_MAX;
4172 arg.wait = tmr->interval;
4182 * Fun: Deregister timer
4184 * Desc: This function is used to deregister a timer function.
4195 SsTmrEntry *tmr /* pointer to timer entry */
4203 /* stop the timer */
4204 arg.tq = osCp.dep.tmrTq;
4205 arg.tqCp = &osCp.dep.tmrTqCp;
4206 arg.timers = tmr->dep.timers;
4211 arg.max = TMR_DEF_MAX;
4212 arg.wait = tmr->interval;
4222 * Fun: Critical error
4224 * Desc: This function is called when a critical error occurs.
4235 Seq seq, /* sequence number */
4236 Reason reason /* reset reason */
4246 /* get calling task ID */
4247 tId = pthread_self();
4250 /* set up the message to display */
4251 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4252 "reason = %d\n\n", (uint8_t)tId, seq, reason);
4256 /* delete all system tasks */
4257 for (i = 0; i < SS_MAX_STSKS; i++)
4259 if (osCp.sTskTbl[i].used
4260 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4262 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4268 pthread_exit(NULLP);
4271 /* won't reach here */
4280 * Desc: This function is called to log an error.
4291 Ent ent, /* Calling layer's entity id */
4292 Inst inst, /* Calling layer's instance id */
4293 ProcId procId, /* Calling layer's processor id */
4294 Txt *file, /* file name where error occured */
4295 S32 line, /* line in file where error occured */
4296 ErrCls errCls, /* error class */
4297 ErrCode errCode, /* layer unique error code */
4298 ErrVal errVal, /* error value */
4299 Txt *errDesc /* description of error */
4312 /* get calling task ID */
4314 tId = pthread_self();
4320 case ERRCLS_ADD_RES:
4321 errClsMsg = "ERRCLS_ADD_RES";
4324 case ERRCLS_INT_PAR:
4325 errClsMsg = "ERRCLS_INT_PAR";
4329 errClsMsg = "ERRCLS_DEBUG";
4332 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4334 errClsMsg = "ERRCLS_FTHA";
4338 errClsMsg = "INVALID ERROR CLASS!";
4343 /*mt009.301 Fixed 64BIT compilation warnings*/
4346 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4347 "file: %s line: %03d errcode: %05d errcls: %s\n"
4348 "errval: %05d errdesc: %s\n",
4349 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4352 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4353 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4354 "errval: %05ld errdesc: %s\n",
4355 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4357 SDisplay(0, errBuf);
4358 /* mt001.301 : Additions */
4359 #ifdef SS_LOGGER_SUPPORT
4361 #endif /* SS_LOGGER_SUPPORT */
4365 /* debug errors halt the system */
4366 if (errCls == ERRCLS_DEBUG)
4368 /* mt001.301 : Additions */
4369 #ifdef SS_LOGGER_SUPPORT
4371 #endif /* SS_LOGGER_SUPPORT */
4372 /* delete all system tasks */
4373 for (i = 0; i < SS_MAX_STSKS; i++)
4375 if (osCp.sTskTbl[i].used
4376 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4378 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4384 pthread_exit(NULLP);
4396 * Fun: Register driver task
4398 * Desc: This function is called to register the handlers for a
4410 SsDrvrTskEntry *drvrTsk /* driver task entry */
4417 /* mt001.30 : Additions */
4420 * Fun: Deregister driver task
4422 * Desc: This function is called to deregister the handlers for a
4434 SsDrvrTskEntry *drvrTsk /* driver task entry */
4447 * mt003.301 Additions - SDeRegTTsk fix
4449 #ifdef SS_MULTIPLE_PROCS
4456 #else /*SS_MULTIPLE_PROCS*/
4462 #endif /*SS_MULTIPLE_PROCS*/
4464 #ifdef SS_MULTIPLE_PROCS
4477 /* We check the sTsk element; if it is not NULLP, the
4478 * task is attached. So we have to detach it before
4479 * deregistering the task.
4481 ret = SLock(&osCp.sTskTblLock);
4484 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4487 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4490 #if (ERRCLASS & ERRCLS_DEBUG)
4491 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4493 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4495 #if (ERRCLASS & ERRCLS_DEBUG)
4496 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4504 #ifdef SS_MULTIPLE_PROCS
4506 if (tTsk->initTsk != NULLP)
4509 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4512 &(osCp.tTskTbl[idx].xxCb));
4514 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4517 &(osCp.tTskTbl[idx].xxCb));
4518 #endif /* USE_MEMCAL */
4520 #endif /* SS_MULTIPLE_PROCS */
4522 if (tTsk->sTsk != NULLP)
4526 sTsk->dep.ent = ent;
4527 sTsk->dep.inst = inst;
4529 for (n = 0; n < SS_MAX_TTSKS; n++)
4531 if (sTsk->tTsks[n] == idx)
4533 sTsk->tTsks[n] = SS_INVALID_IDX;
4539 /* call the implementation to detach the task */
4540 ssdDetachTTsk(tTsk);
4542 sTsk->dep.ent = ENTNC;
4543 sTsk->dep.inst = INSTNC;
4546 /* Now we empty the entry for this task and update the table
4549 #ifdef SS_MULTIPLE_PROCS
4550 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4551 #else /* SS_MULTIPLE_PROCS */
4552 osCp.tTskIds[ent][inst] = SS_TSKNC;
4553 #endif /* SS_MULTIPLE_PROCS */
4556 #ifdef SS_MULTIPLE_PROCS
4557 tTsk->proc = PROCNC;
4558 #endif /* SS_MULTIPLE_PROCS */
4560 tTsk->inst = INSTNC;
4561 tTsk->tskType = TTUND;
4562 tTsk->initTsk = NULLP;
4563 tTsk->actvTsk = NULLP;
4566 tTsk->nxt = osCp.nxtTTskEntry;
4567 osCp.nxtTTskEntry = idx;
4570 #ifdef SS_MULTIPLE_PROCS
4571 /* mark the control block for this task as invalid */
4572 osCp.tTskTbl[idx].xxCb = NULLP;
4575 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4576 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4578 #if (ERRCLASS & ERRCLS_DEBUG)
4579 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4586 //#ifndef SPLIT_RLC_DL_TASK
4587 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4588 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4589 Void ysMtTskHdlr(Void);
4590 Void ysMtPollPhyMsg(uint8_t region);
4591 Void ysMtRcvPhyMsg(Void);
4592 Void *mtTskHdlrT2kL2
4594 Ptr tskPtr /* pointer to task entry */
4600 /* wait for SS to come up */
4601 /* It is required to block on this semaphore before starting actual processing of
4602 the thread becasue the creator of this thread might want to cance it without
4603 doing any processing. When this semaphore is released, means the creator gives
4604 the go ahead for actual processing and we should never come back to this point */
4605 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4614 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4615 * (processes L1 msgs) */
4621 Void ysMtTskHdlr(Void);
4622 Void YsPhyRecvMsg();
4623 Void *mtTskHdlrT2kL2
4625 Ptr tskPtr /* pointer to task entry */
4631 /* get out the system task entry from the parameter */
4632 sTsk = (SsSTskEntry *) tskPtr;
4634 /* wait for SS to come up */
4635 /* It is required to block on this semaphore before starting actual processing of
4636 the thread becasue the creator of this thread might want to cance it without
4637 doing any processing. When this semaphore is released, means the creator gives
4638 the go ahead for actual processing and we should never come back to this point */
4639 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4642 #ifndef RGL_SPECIFIC_CHANGES
4650 #ifdef V5GTF_SPECIFIC_CHANGES
4653 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4654 * (processes L1 msgs) */
4656 /* get a message from the demand queue */
4658 #ifdef RLC_MAC_DAT_REQ_RBUF
4659 rgDlDatReqBatchProc();
4662 ret = mtTskHdlMsg(sTsk);
4665 /* exit the for loop here */
4668 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4675 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4678 void *pthreadCreateHdlr(void * arg)
4681 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4682 /* mt038.201 changed how sem_wait is called */
4683 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4686 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4694 * Desc: This is the system task handler function. It blocks on
4695 * the system task's demand queue. On receiving a message,
4696 * it identifies the target TAPA task, verifies that the
4697 * TAPA task belongs to this system task and if so, calls
4698 * the activation function of that TAPA task with the
4699 * received message. The task activation function or the
4700 * timer activation function may be called.
4702 * Ret: (thread function)
4711 Ptr tskPtr /* pointer to task entry */
4717 /* get out the system task entry from the parameter */
4718 sTsk = (SsSTskEntry *) tskPtr;
4721 /* wait for SS to come up */
4723 /* mt038.201 changed how sem_wait is called */
4724 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4726 #ifdef XEON_SPECIFIC_CHANGES
4727 printf("\n**********MT Task Handler********\n");
4731 /* Wait for a message from the demand queue */
4732 #ifdef SS_CDMNDQ_SUPPORT
4733 ret = ssCDmndQWait(&sTsk->dQ);
4735 ret = ssDmndQWait(&sTsk->dQ);
4740 ret = mtTskHdlMsg(sTsk);
4755 * Desc: This is the system task handler function. It blocks on
4756 * the system task's demand queue. On receiving a message,
4757 * it identifies the target TAPA task, verifies that the
4758 * TAPA task belongs to this system task and if so, calls
4759 * the activation function of that TAPA task with the
4760 * received message. The task activation function or the
4761 * timer activation function may be called.
4763 * Ret: (thread function)
4778 SsTTskEntry *tTsk=NULLP;
4781 Buffer *mBuf2=NULLP;
4783 SsMsgInfo *mInfo=NULLP;
4785 /* mt028.201: modification: multiple procs support related changes */
4786 #ifndef SS_MULTIPLE_PROCS
4788 PAIFTMRS16 tmrActvFnMt = NULLP;
4790 /* mt015.301 Initialized the timer activation functions with NULLP */
4791 PFS16 tmrActvFn = NULLP;
4793 PAIFTMRS16 tmrActvFn =NULLP;
4794 uint16_t procIdIdx =0;
4795 #endif /* SS_MULTIPLE_PROCS */
4796 /* mt003.301 Modifications */
4797 #ifdef SS_THREAD_PROFILE
4799 #endif /* SS_THREAD_PROFILE */
4802 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4805 /* nothing to receive */
4809 /* if we can't lock this system task entry, return the message */
4810 ret = SLock(&sTsk->lock);
4814 #if (ERRCLASS & ERRCLS_DEBUG)
4815 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4816 "Could not lock system task entry");
4826 mBuf2 = mBuf->b_next;
4828 /* find out what kind of message this is */
4829 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4830 #ifdef SS_MEM_WL_DEBUG
4831 mtTskBuffer1 = mBuf2;
4833 mtTskBuffer2 = mBuf2->b_next;
4835 if(mInfo == 0x5050505)
4839 cmAnalyseBtInfo((PTR) mBuf,4);
4841 printf("\n In trouble .... \n");
4843 else if (mInfo == 0x2020202)
4846 cmAnalyseBtInfo((PTR) mBuf,1);
4847 printf("\n In trouble .... \n");
4849 #endif /* SS_MEM_WL_DEBUG */
4850 switch (mInfo->eventInfo.event)
4852 /* this is a termination event, we die */
4854 /* release the message */
4857 /* Unlock the system task entry and lock the system
4858 * task table to clean our entry up.
4860 SUnlock(&sTsk->lock);
4862 ret = SLock(&osCp.sTskTblLock);
4866 #if (ERRCLASS & ERRCLS_DEBUG)
4867 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
4868 "Could not lock system task table");
4870 /* what to do here? */
4874 /* clean up the system task entry */
4877 /* mt003.301 Modifications - SDeRegTTsk */
4878 /* sTsk->numTTsks = 0; */
4879 SDestroyLock(&sTsk->lock);
4880 ssDestroyDmndQ(&sTsk->dQ);
4882 /* lock for current executing TAPA task ID */
4884 /* make this entry available in the system task table */
4885 sTsk->nxt = osCp.nxtSTskEntry;
4886 for (i = 0; i < SS_MAX_STSKS; i++)
4888 if (sTsk == &osCp.sTskTbl[i])
4890 osCp.nxtSTskEntry = i;
4897 /* unlock the system task table */
4898 SUnlock(&osCp.sTskTblLock);
4903 /* this is a data message or a permanent task keep-alive message */
4905 case SS_EVNT_PERMTICK:
4906 /* message to a task. find the destination task */
4907 /* mt028.201: modification: multiple procs support related changes */
4908 #ifdef SS_MULTIPLE_PROCS
4909 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
4911 if (procIdIdx == SS_INV_PROCID_IDX)
4917 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
4918 #else /* SS_MULTIPLE_PROCS */
4919 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
4920 #endif /* SS_MULTIPLE_PROCS */
4922 /* verify that it hasn't been deregistered */
4923 if (idx == SS_TSKNC)
4929 /* verify that this system task is still running it */
4930 tTsk = &osCp.tTskTbl[idx];
4931 if (tTsk->sTsk != sTsk)
4937 /* set the current executing TAPA task ID */
4938 sTsk->dep.ent = mInfo->pst.dstEnt;
4939 sTsk->dep.inst = mInfo->pst.dstInst;
4941 /* copy the Pst structure into a local duplicate */
4942 for (i = 0; i < (S16) sizeof(Pst); i++)
4943 *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
4945 /* Give the message to the task activation function. If
4946 * its a normal data message, we pass it, if this is a
4947 * keep-alive message for a permanent task then we pass
4948 * NULLP in place of the message to the task activation
4951 if (mInfo->eventInfo.event == SS_EVNT_DATA)
4953 #ifndef RGL_SPECIFIC_CHANGES
4954 #ifdef SS_TSKLOG_ENABLE
4955 uint32_t t = MacGetTick();
4958 /* mt003.301 Modifications */
4959 #if SS_THREAD_PROFILE
4960 tTsk->curEvent = nPst.event;
4962 #endif /* SS_THREAD_PROFILE */
4963 tTsk->actvTsk(&nPst, mBuf);
4964 #ifndef RGL_SPECIFIC_CHANGES
4965 #ifdef SS_TSKLOG_ENABLE
4966 SStopTask(t,PID_SSI_TSK);
4969 #if SS_THREAD_PROFILE
4971 tTsk->curEvtTime = (uint32_t)(et2 - et1);
4972 tTsk->totTime += (uint64_t)tTsk->curEvtTime;
4973 #endif /* SS_THREAD_PROFILE */
4977 #if (ERRCLASS & ERRCLS_DEBUG)
4978 /* this message should only come to a permanent task */
4979 if (tTsk->tskType != SS_TSK_PERMANENT)
4981 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
4985 tTsk->actvTsk(&nPst, NULLP);
4987 /* We need to re-send this message back to ourselves so
4988 * the permanent task continues to run.
4990 /* Check if this task got deregistered or detached
4991 * by the activation function; if so, there's nothing
4992 * more to do here, otherwise go ahead.
4995 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
4997 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
4998 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5002 /* failure here is a real problem */
5005 #if (ERRCLASS & ERRCLS_DEBUG)
5006 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5007 "Could not write to demand queue");
5013 /* unset the current executing TAPA task ID */
5014 sTsk->dep.ent = ENTNC;
5015 sTsk->dep.inst = INSTNC;
5020 /* timer event. find the timer entry */
5021 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5023 /* lock the timer table, coz we're going to peek in it */
5024 ret = SLock(&osCp.tmrTblLock);
5028 #if (ERRCLASS & ERRCLS_DEBUG)
5029 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5030 "Could not lock timer table");
5036 /* Verify that this timer entry is still around and that it
5037 * belongs to our task.
5039 if (osCp.tmrTbl[idx].used == FALSE
5040 /* mt028.201: modification: multiple procs support related changes */
5041 #ifdef SS_MULTIPLE_PROCS
5042 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5043 #endif /* SS_MULTIPLE_PROCS */
5044 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5045 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5047 SUnlock(&osCp.tmrTblLock);
5052 /* mt005.21: addition */
5053 /* set the current executing TAPA task ID */
5054 sTsk->dep.ent = mInfo->pst.dstEnt;
5055 sTsk->dep.inst = mInfo->pst.dstInst;
5057 #ifndef SS_MULTIPLE_PROCS
5059 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5060 tmrActvFnMt = NULLP;
5061 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5063 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5069 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5072 /* unlock the timer table */
5073 SUnlock(&osCp.tmrTblLock);
5075 /* activate the timer function */
5076 /* mt028.201: modification: multiple procs support related changes */
5077 #ifndef SS_MULTIPLE_PROCS
5081 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5082 osCp.tmrTbl[idx].ownerInst);
5090 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5091 osCp.tmrTbl[idx].ownerInst);
5092 #endif /* SS_MULTIPLE_PROCS */
5094 /*mt005.21: addition */
5095 /* unset the current executing TAPA task ID */
5096 sTsk->dep.ent = ENTNC;
5097 sTsk->dep.inst = INSTNC;
5100 /* return the message buffer */
5104 * mt003.301 - SDeRegTTsk fix
5106 case SS_EVNT_TTSK_TERM:
5107 #ifdef SS_MULTIPLE_PROCS
5108 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5110 if (procIdIdx == SS_INV_PROCID_IDX)
5116 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5117 #else /* SS_MULTIPLE_PROCS */
5118 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5119 #endif /* SS_MULTIPLE_PROCS */
5121 /* verify that it hasn't been deregistered */
5122 if (idx == SS_TSKNC)
5128 /* verify that this system task is still running it */
5129 tTsk = &osCp.tTskTbl[idx];
5130 if (tTsk->sTsk != sTsk)
5135 #ifdef SS_MULTIPLE_PROCS
5136 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5138 ssdProcTTskTerm(tTsk, idx);
5144 #if (ERRCLASS & ERRCLS_DEBUG)
5145 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5152 } while (mBuf != NULLP);
5155 /* unlock the system task entry */
5156 SUnlock(&sTsk->lock);
5159 /* yield for other threads */
5160 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5169 * Fun: mtTmrHdlrPublic
5171 Void mtTmrHdlrPublic()
5173 if (SLock(&osCp.tmrTblLock) != ROK)
5175 #if (ERRCLASS & ERRCLS_DEBUG)
5176 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5180 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5181 /* unlock the timer table */
5182 SUnlock(&osCp.tmrTblLock);
5190 * Desc: The timer handler thread function. Counts time
5191 * and invokes the common timer function on each
5194 * Ret: (thread function)
5201 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5202 static Void *mtTmrHdlr
5204 void *parm /* unused */
5207 /*mt004.301-addede new region*/
5208 /* mt010.301 Removed SS_FAP portion and
5209 * enabled oroginal code in function mtTmrHdlr */
5213 uint32_t i, cnt, oldTicks, newTicks;
5214 struct timeval tv1,tv2;
5215 /* mt038.201 added return */
5217 /* mt039.201 changes for nanosleep */
5218 struct timespec tsN;
5219 static uint32_t err_in_usec;
5221 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5226 /* mt027.201 - Modification for SRegCfgTmr support */
5227 /* check SS_TICKS_SEC */
5228 if (SS_1MS < SS_TICKS_SEC)
5230 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5233 /* mt025.201 - Addition to stop timer handler till task registration is done */
5234 /* wait for SS to come up */
5235 /* mt038.201 changed how sem_wait is called */
5236 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5239 /* mt027.201 - Modification for SRegCfgTmr support */
5240 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5242 ts.tv_nsec = (MT_TICK_CNT * 1000);
5243 /* mt039.201 changes for nanosleep */
5249 if (gettimeofday(&tv1, NULL) == -1)
5251 #if (ERRCLASS & ERRCLS_DEBUG)
5252 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5253 "Error in clock_gettime");
5263 #ifndef STUB_TTI_HANDLING_5GTF
5264 printf("\nReturning from mtTmrHdlr()\n");
5269 /* mt039.201 changes for nanosleep */
5270 /* sleep for MT_TICK_CNT milli seconds */
5271 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5272 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5274 ts.tv_nsec = tsN.tv_nsec;
5279 if (gettimeofday(&tv2,NULL) == -1)
5281 #if (ERRCLASS & ERRCLS_DEBUG)
5282 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5283 "Error in clock_gettime");
5287 /*mt013.301 : changed check while calculating timer to fix
5288 * diffrence between MTSS time and real unix time
5290 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5292 time_int = (tv2.tv_usec - tv1.tv_usec);
5294 else if (tv2.tv_sec > tv1.tv_sec)
5296 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5298 else /* ts2 < ts1, this will not happen in normal scenario */
5300 /* to make sure cnt = 1 */
5302 time_int = MT_TICK_CNT;
5305 oldTicks = osCp.dep.sysTicks;
5306 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5307 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5308 newTicks = osCp.dep.sysTicks;
5309 tv1.tv_usec = tv2.tv_usec;
5310 tv1.tv_sec = tv2.tv_sec;
5312 cnt = newTicks - oldTicks;
5314 while(err_in_usec >= MT_TICK_CNT)
5317 err_in_usec -= MT_TICK_CNT;
5319 if( cnt >= MT_MAX_TICK_CNT_VAL)
5320 cnt = MT_MIN_TICK_CNT_VAL;
5321 /* call the common timer tick handler */
5322 for (i = 0; i < cnt; i++)
5324 /* mt008.301: cmPrcTmr is guarded with a lock */
5325 /* lock the timer table */
5326 if (SLock(&osCp.tmrTblLock) != ROK)
5328 #if (ERRCLASS & ERRCLS_DEBUG)
5329 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5333 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5334 /* unlock the timer table */
5335 SUnlock(&osCp.tmrTblLock);
5339 /* mt009.21: addition */
5340 return ( (Void *) NULLP);
5341 /* will not reach here */
5349 * Desc: Process timer event. Called from the common timer
5350 * code when a timeout occurs.
5361 PTR tCb, /* control block */
5362 S16 evnt /* event */
5371 #ifndef TENB_RTLIN_CHANGES
5374 /* mt028.201: modification: multiple procs support related changes */
5375 #ifdef SS_MULTIPLE_PROCS
5377 #endif /* SS_MULTIPLE_PROCS */
5378 #ifdef RGL_SPECIFIC_CHANGES
5379 #ifdef MSPD_MLOG_NEW
5380 uint32_t t = GetTIMETICK();
5386 /* get the timer entry */
5387 tEnt = (SsTmrEntry *) tCb;
5390 /* if the timer was deleted, this will be NULL, so drop it */
5396 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5399 /* Hmmmm, the timer might have been deleted while we've been
5400 * working at getting here, so we just skip this.
5402 if (tEnt->used == FALSE)
5408 /* Set up and send a timer message to the destination tasks'
5411 #ifndef SS_MULTICORE_SUPPORT
5412 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5414 #ifdef RGL_SPECIFIC_CHANGES
5415 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5417 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5422 #if (ERRCLASS & ERRCLS_DEBUG)
5423 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5429 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5430 mInfo->eventInfo.event = SS_EVNT_TIMER;
5431 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5433 mInfo->pst.dstEnt = tEnt->ownerEnt;
5434 mInfo->pst.dstInst = tEnt->ownerInst;
5435 mInfo->pst.srcEnt = tEnt->ownerEnt;
5436 mInfo->pst.srcInst = tEnt->ownerInst;
5437 /* mt028.201: modification: multiple procs support related changes */
5438 #ifndef SS_MULTIPLE_PROCS
5439 mInfo->pst.dstProcId = SFndProcId();
5440 mInfo->pst.srcProcId = SFndProcId();
5441 #else /* SS_MULTIPLE_PROCS */
5442 mInfo->pst.dstProcId = tEnt->ownerProc;
5443 mInfo->pst.srcProcId = tEnt->ownerProc;
5444 #endif /* SS_MULTIPLE_PROCS */
5445 mInfo->pst.selector = SEL_LC_NEW;
5446 #ifndef SS_MULTICORE_SUPPORT
5447 mInfo->pst.region = DFLT_REGION;
5450 mInfo->pst.pool = DFLT_POOL;
5451 mInfo->pst.prior = PRIOR0;
5452 mInfo->pst.route = RTESPEC;
5453 mInfo->pst.event = 0;
5456 #ifndef TENB_RTLIN_CHANGES
5457 /* get a semaphore for the TAPA task table */
5458 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5463 #if (ERRCLASS & ERRCLS_DEBUG)
5464 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5472 /* find the owner TAPA task */
5473 /* mt028.201: modification: multiple procs support related changes */
5474 #ifdef SS_MULTIPLE_PROCS
5475 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5476 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5477 #else /* SS_MULTIPLE_PROCS */
5478 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5479 #endif /* SS_MULTIPLE_PROCS */
5480 if (idx == SS_TSKNC)
5482 #ifndef TENB_RTLIN_CHANGES
5483 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5490 /* ensure that the TAPA task is hale and hearty */
5491 tTsk = &osCp.tTskTbl[idx];
5494 #ifndef TENB_RTLIN_CHANGES
5495 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5500 /* Klock work fix ccpu00148484 */
5501 /* write the timer message to the queue of the destination task */
5502 /* mt008.301 : check sTsk before putting into it's DQ */
5503 if (tTsk->sTsk == NULLP)
5505 #ifndef TENB_RTLIN_CHANGES
5506 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5510 #if (ERRCLASS & ERRCLS_DEBUG)
5511 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5512 "Could not write to demand queue");
5517 #ifdef SS_LOCKLESS_MEMORY
5518 mInfo->pst.region = tTsk->sTsk->region;
5519 mInfo->region = tTsk->sTsk->region;
5520 #endif /* SS_LOCKLESS_MEMORY */
5521 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5522 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5524 #ifndef TENB_RTLIN_CHANGES
5525 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5529 #if (ERRCLASS & ERRCLS_DEBUG)
5530 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5531 "Could not write to demand queue");
5536 /* Fix for ccpu00130657 */
5537 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5538 if (tTsk->sTsk->tskPrior == PRIOR0)
5541 WLS_WakeUp(mtGetWlsHdl());
5548 /* release the semaphore for the TAPA task table */
5549 #ifndef TENB_RTLIN_CHANGES
5550 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5554 /* restart the timer */
5555 arg.tq = osCp.dep.tmrTq;
5556 arg.tqCp = &osCp.dep.tmrTqCp;
5557 arg.timers = tEnt->dep.timers;
5558 arg.cb = (PTR) tEnt;
5562 arg.max = TMR_DEF_MAX;
5563 arg.wait = tEnt->interval;
5565 #ifdef RGL_SPECIFIC_CHANGES
5566 #ifdef MSPD_MLOG_NEW
5567 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5579 * Desc: This thread reads the console and hands over any
5580 * data read to a user function.
5582 * Ret: (thread function)
5589 static Void *mtConHdlr
5591 Ptr parm /* unused */
5598 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5604 /* check if we have a console input file handle */
5605 if (osCp.dep.conInFp == NULLP)
5611 fd = fileno(osCp.dep.conInFp);
5616 if ((read(fd, &data, 1)) != 1)
5622 /* call rdConQ, defined by the system service user */
5632 #ifdef SS_DRVR_SUPPORT
5635 * Fun: Interrupt service task handler
5637 * Desc: This is the interrupt service task handler. It blocks
5638 * on a pipe from which it reads an isFlag structure. The
5639 * structure indicates which interrupt service task is to
5640 * be executed. The thread identifies the task, calls the
5641 * isTsk function and sends itself a message to repeat
5642 * this operation until it receives a message to cease.
5651 /* mt009.21: addition */
5652 static Void *mtIsTskHdlr
5654 Ptr tskPtr /* pointer to task entry */
5657 #if (ERRCLASS & ERRCLS_DEBUG)
5664 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5669 switch (isFlag.action)
5672 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5674 /* call the interrupt service task activation function */
5675 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5677 /* send self a message to keep doing this */
5678 isFlag.action = MT_IS_RESET;
5680 #if (ERRCLASS & ERRCLS_DEBUG)
5681 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5682 if (ret != sizeof(isFlag))
5684 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5685 "write() to pipe failed");
5688 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5695 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5700 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5702 /* call the interrupt service task activation function */
5703 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5705 #if (ERRCLASS & ERRCLS_DEBUG)
5706 /* send self a message to do this again */
5707 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5709 if (ret != sizeof(isFlag))
5711 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5712 "write() to pipe failed");
5715 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5723 /* where did THIS come from?? */
5727 /* mt009.21: addition */
5728 return ( (Void *) NULLP);
5732 #endif /* SS_DRVR_SUPPORT */
5733 #endif /* L2_L3_SPLIT */
5735 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5739 * Fun: mtIntSigHndlr
5741 * Desc: Exit function, shuts down.
5750 Void mtIntSigHndlr(int arg)
5753 osCp.dep.sigEvnt=TRUE;
5756 #ifdef TENB_RTLIN_CHANGES
5764 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5769 * Desc: function, shuts down.
5778 Void mtExitClnup(void)
5784 SGetSysTime(&ticks);
5786 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5788 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5790 #ifdef SS_HISTOGRAM_SUPPORT
5794 osCp.dep.sigEvnt=FALSE;
5796 if (osCp.dep.fileOutFp)
5798 fclose(osCp.dep.fileOutFp);
5806 Void SIncrementTtiCount(Void)
5811 Ticks SGetTtiCount(Void)
5820 * Desc: This function displays a string to a given output
5825 * Notes: Buffer should be null terminated.
5827 * channel 0 is reserved for backwards compatibility
5835 S16 chan, /* channel */
5836 Txt *buf /* buffer */
5840 /* mt020.201 - Fixed typo */
5841 #if (ERRCLASS & ERRCLS_INT_PAR)
5844 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
5849 #ifndef XEON_SPECIFIC_CHANGES
5850 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5851 ssMemlog(buf, strlen(buf));
5856 /* mt012.301 :FIX for LOG RELATED ISSUE */
5864 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
5870 if (osCp.dep.fileOutFp)
5871 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
5872 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
5875 fflush(osCp.dep.fileOutFp);
5888 * Desc: function, shuts down.
5900 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
5901 a loop to overcome the child processes being killed upon exiting the
5903 #ifdef SS_LINUX /* this should have already been defined */
5904 /* mt010.301 removed flag SLES9_PLUS */
5905 /* wait forever for children */
5909 if(osCp.dep.sigEvnt==TRUE)
5916 pthread_exit(NULLP);
5922 * Fun: Set date and time
5924 * Desc: This function is used to set the calendar
5929 * Notes: Unimplemented
5936 REG1 DateTime *dt /* date and time */
5949 * Fun: Get date and time
5951 * Desc: This function is used to determine the calendar
5952 * date and time. This information may be used for
5953 * some management functions.
5965 REG1 DateTime *dt /* date and time */
5968 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
5971 struct timespec ptime;
5973 struct timeval ptime;
5980 #if (ERRCLASS & ERRCLS_INT_PAR)
5983 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
5992 localtime_r(&tt, &tme);
5995 clock_gettime(CLOCK_REALTIME, &ptime);
5997 gettimeofday(&ptime, NULL);
5999 localtime_r(&ptime.tv_sec, &tme);
6001 dt->month = (uint8_t) tme.tm_mon + 1;
6002 dt->day = (uint8_t) tme.tm_mday;
6003 dt->year = (uint8_t) tme.tm_year;
6004 dt->hour = (uint8_t) tme.tm_hour;
6005 dt->min = (uint8_t) tme.tm_min;
6006 dt->sec = (uint8_t) tme.tm_sec;
6009 #ifdef SS_DATETIME_USEC
6011 dt->usec = ptime.tv_nsec / 1000;
6013 dt->usec = ptime.tv_usec;
6015 #endif /*-- SS_DATETIME_USEC --*/
6021 * Get time from epoch in milliseconds
6023 * Fun: Get time from epoch in milliseconds
6025 * Desc: This function is used to get the time from epoch in milli seconds.
6026 * This information may be used for calculating a layer's activation function
6027 * execution time used for thread profiling.
6036 /* mt003.301 Modifications */
6039 EpcTime *et /* date and time */
6042 /* mt003.301 Modifications */
6043 static uint64_t now;
6044 uint64_t to_sec = 1000000;
6045 uint64_t to_nsec = 1000;
6047 struct timespec ptime;
6049 struct timeval ptime;
6054 #if (ERRCLASS & ERRCLS_INT_PAR)
6063 clock_gettime(CLOCK_REALTIME, &ptime);
6065 gettimeofday(&ptime, NULL);
6066 #endif /* SS_LINUX */
6068 now = (ptime.tv_sec * to_sec);
6071 now += (ptime.tv_nsec / to_nsec);
6072 #else /* SS_LINUX */
6073 now += (ptime.tv_usec);
6075 #endif /* SS_LINUX */
6076 now = (now / to_nsec);
6087 * Fun: Get system time
6089 * Desc: This function is used to determine the system time.
6093 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6100 Ticks *sysTime /* system time */
6105 #if (ERRCLASS & ERRCLS_INT_PAR)
6106 if (sysTime == NULLP)
6108 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6114 *sysTime = osCp.dep.sysTicks;
6120 /* mt021.201 - Addition of SGetRefTime function */
6123 * Fun: Get referenced time
6125 * Desc: This function is used to determine the time in seconds
6126 * and microseconds from a reference time. The reference
6127 * time is expressed in seconds from UTC EPOC, January 1,
6133 * Notes: Macros are defined for reference times:
6134 * SS_REFTIME_01_01_1970
6135 * SS_REFTIME_01_01_2002
6142 uint32_t refTime, /* reference time */
6149 struct timespec ptime;
6151 struct timeval ptime;
6156 clock_gettime(CLOCK_REALTIME, &ptime);
6158 gettimeofday(&ptime, NULL);
6161 #if (ERRCLASS & ERRCLS_INT_PAR)
6162 if (sec == NULLP || usec == NULLP)
6164 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6167 /* mt022.201 - Modification to fix compile warning */
6168 if (refTime > (uint32_t)(ptime.tv_sec))
6170 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6175 *sec = ptime.tv_sec - refTime;
6177 *usec = ptime.tv_nsec / 1000;
6179 *usec = ptime.tv_usec;
6189 * Fun: Get Random Number
6191 * Desc: Invoked by layer when a pseudorandom number is required.
6195 * Notes: Suggested approach uses shuffled Linear Congruential
6196 * Operators as described in Byte magazine October
6197 * 1984; "Generating and Testing Pseudorandom Numbers"
6204 Random *value /* random number */
6209 #if (ERRCLASS & ERRCLS_INT_PAR)
6212 /* mt011.21: addition */
6213 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6219 *value = (Random) rand_r(&osCp.dep.randSeed);
6230 * Desc: This function exits from a task.
6234 * Notes: Currently does nothing.
6249 * Fun: Exit Interrupt
6251 * Desc: This function exits from an interrupt.
6255 * Notes: Currently does nothing.
6270 * Fun: Hold Interrupt
6272 * Desc: This function prohibits interrupts from being enabled until
6273 * release interrupt. This function should be called when
6274 * interrupts are disabled and prior to any call to system
6275 * services either by entry to an interrupt service routine or
6276 * by explicit call to disable interrupt.
6280 * Notes: Currently does nothing
6295 * Fun: Release Interrupt
6297 * Desc: This function allows interrupts to be enabled.
6301 * Notes: Currently does nothing.
6318 * Desc: Enable interrupts
6320 * Ret: ROK on success
6323 * Notes: Currently does nothing.
6328 inline S16 SEnbInt(void)
6340 * Desc: Disable interrupts
6342 * Ret: ROK on success
6345 * Notes: Currently does nothing.
6350 inline S16 SDisInt(void)
6362 * Desc: This function gets the function address stored at the
6363 * specified interrupt vector.
6367 * Notes: Currently does nothing.
6374 VectNmb vectNmb, /* vector number */
6375 PIF *vectFnct /* vector function */
6392 * Desc: This function installs the specified function at the
6393 * specified interrupt vector.
6397 * Notes: Currently does nothing.
6404 VectNmb vectNmb, /* vector number */
6405 PIF vectFnct /* vector function */
6417 /* mt028.201: modification: multiple procs support related changes */
6418 #ifndef SS_MULTIPLE_PROCS
6424 * Desc: This function gets the current entity and instance.
6427 * RFAILED - failed, general (optional)
6429 * Notes: This function may be called by the OS or Layer 1
6437 Ent *ent, /* entity */
6438 Inst *inst /* instance */
6449 #if (ERRCLASS & ERRCLS_INT_PAR)
6450 /* check pointers */
6451 if (ent == NULLP || inst == NULLP)
6453 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6459 /* get the thread id */
6460 tId = pthread_self();
6463 /* find the system task in whose context we're running */
6465 ret = SLock(&osCp.sTskTblLock);
6470 for (i = 0; i < SS_MAX_STSKS; i++)
6472 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6474 sTsk = &osCp.sTskTbl[i];
6480 *ent = sTsk->dep.ent;
6481 *inst = sTsk->dep.inst;
6483 SUnlock(&osCp.sTskTblLock);
6486 return (ret == ROK ? ROK : RFAILED);
6494 * Desc: This function sets the current entity and instance.
6505 Ent ent, /* entity */
6506 Inst inst /* instance */
6517 #if (ERRCLASS & ERRCLS_INT_PAR)
6518 /* check entity and instance IDs */
6519 if (ent >= ENTNC || inst >= INSTNC)
6521 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6527 /* get the thread id */
6528 tId = pthread_self();
6531 /* find the system task in whose context we're running */
6533 ret = SLock(&osCp.sTskTblLock);
6538 for (i = 0; i < SS_MAX_STSKS; i++)
6540 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6542 sTsk = &osCp.sTskTbl[i];
6548 sTsk->dep.ent = ent;
6549 sTsk->dep.inst = inst;
6551 SUnlock(&osCp.sTskTblLock);
6554 return (ret == ROK ? ROK : RFAILED);
6557 #endif /* SS_MULTIPLE_PROCS */
6559 #ifdef SS_DRVR_SUPPORT
6565 * Desc: Set interrupt pending flag
6567 * Ret: ROK on success
6575 inline S16 SSetIntPend
6577 uint16_t id, /* driver task identifier */
6578 Bool flag /* flag */
6586 #if (ERRCLASS & ERRCLS_INT_PAR)
6587 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6589 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6596 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6598 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6606 #endif /* SS_DRVR_SUPPORT */
6609 #ifdef SS_LOCKLESS_MEMORY
6612 * Fun: SGlobMemInfoShow
6614 * Desc: This function displays the memory usage information
6615 * for the destined region. It will show the usage of
6616 * each configured bucket and the heap for the specified region.
6619 * RFAILED Region not registered
6624 S16 SGlobMemInfoShow(Void)
6628 CmMmGlobRegCb *globReg;
6631 globReg = osCp.globRegCb;
6633 sprintf(prntBuf, "--------------------------------------------------------------\n");
6634 SDisplay(0, prntBuf);
6635 sprintf(prntBuf, "Global Region Bucket Information\n");
6636 SDisplay(0, prntBuf);
6637 sprintf(prntBuf, "====================================================\n");
6638 SDisplay(0, prntBuf);
6639 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
6640 SDisplay(0, prntBuf);
6641 sprintf(prntBuf, "====================================================\n");
6642 SDisplay(0, prntBuf);
6645 for (idx = 0; idx < globReg->numBkts; idx++)
6647 #ifdef XEON_SPECIFIC_CHANGES
6648 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
6649 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6652 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
6653 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6655 sprintf(prntBuf, "%2u %12u %8u %9u\n",
6656 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6659 SDisplay(0, prntBuf);
6661 sprintf(prntBuf, "--------------------------------------------------------------\n");
6662 SDisplay(0, prntBuf);
6667 #endif /* SS_LOCKLESS_MEMORY */
6670 Bool IsMemoryThresholdHit(Region reg, Pool pool)
6672 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6674 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6677 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6678 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6685 /* mt022.201 - Addition of SRegInfoShow function */
6690 * Desc: This function displays the memory usage information
6691 * for the destined region. It will show the usage of
6692 * each configured bucket and the heap for the specified region.
6695 * RFAILED Region not registered
6697 * Notes: A Sample Output from the function
6698 * Bucket Memory: region 1
6699 * ====================================================
6700 * Bucket Number of Blks configured Size Allocated
6701 * ====================================================
6709 * Heap Memory: region 1
6712 * Heap Segmented blocks: 0
6728 #if (ERRCLASS & ERRCLS_INT_PAR)
6729 if (region > (SS_MAX_REGS-1) )
6731 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
6738 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
6739 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
6740 SDisplay(0, prntBuf);
6741 sprintf(prntBuf, "====================================================\n");
6742 SDisplay(0, prntBuf);
6743 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
6744 SDisplay(0, prntBuf);
6745 sprintf(prntBuf, "====================================================\n");
6746 SDisplay(0, prntBuf);
6750 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6752 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6754 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
6755 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6756 mtCMMRegCb[region]->bktTbl[idx].size,
6757 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6758 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6760 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
6761 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6762 mtCMMRegCb[region]->bktTbl[idx].size,
6763 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6764 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6767 /*mt009.301 Fixed 64BIT compilation warnings*/
6769 sprintf(prntBuf, "%2u %8u %5u %8u\n",
6770 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6771 mtCMMRegCb[region]->bktTbl[idx].size,
6772 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6774 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
6775 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6776 mtCMMRegCb[region]->bktTbl[idx].size,
6777 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6779 #endif /* not TENB_RTLIN_CHANGES */
6780 SDisplay(0, prntBuf);
6781 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
6782 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6783 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6785 sprintf(prntBuf, "\n---------------\n");
6786 SDisplay(0, prntBuf);
6787 sprintf(prntBuf, "Heap Memory: region %d\n", region);
6788 SDisplay(0, prntBuf);
6789 /*mt009.301 Fixed 64BIT compilation warnings*/
6791 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
6793 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
6795 SDisplay(0, prntBuf);
6796 /*mt009.301 Fixed 64BIT compilation warnings*/
6798 sprintf(prntBuf, "Heap Allocated: %u\n",
6799 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6801 sprintf(prntBuf, "Heap Allocated: %lu\n",
6802 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6804 SDisplay(0, prntBuf);
6805 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
6806 #if (ERRCLASS & ERRCLS_DEBUG)
6807 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
6808 mtCMMRegCb[region]->heapCb.numFragBlk);
6809 SDisplay(0, prntBuf);
6814 #ifdef XEON_SPECIFIC_CHANGES
6815 #define SSI_MAX_BKT_THRESHOLD 6
6816 #define SSI_MAX_REG_THRESHOLD 2
6817 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6818 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6819 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6821 static Void SInitMemThreshold
6828 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6830 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
6831 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
6832 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
6833 printf("\nREGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
6837 S16 SRegReachedMemThreshold
6844 uint8_t memStatus = 3;
6845 static uint8_t initFlag = 1;
6849 SInitMemThreshold(region, maxBkt);
6852 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6854 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
6859 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
6863 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
6871 /* mt033.201 - addition of API to return the memory statistical data */
6876 * Desc: This function returns the memory usage information
6877 * for the destined region. It will return the usage of
6878 * each configured bucket and the heap for the specified region.
6881 * RFAILED Region not registered
6891 SsMemDbgInfo *dbgInfo
6897 #if (ERRCLASS & ERRCLS_INT_PAR)
6898 if (region >= mtMemoCfg.numRegions )
6900 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
6905 dbgInfo->availmem = 0;
6907 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
6908 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
6910 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
6912 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
6914 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
6915 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
6916 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
6918 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
6919 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6920 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6923 dbgInfo->region = region;
6925 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
6927 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
6928 mtCMMRegCb[region]->heapCb.avlSize);
6930 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
6932 #if (ERRCLASS & ERRCLS_DEBUG)
6933 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
6945 /* Send number of Region available */
6946 *numRegion = mtMemoCfg.numRegions;
6947 /* Send number of Pools available */
6948 *numPool = cfgRegInfo[0].numPools;
6953 /* mt033.201 - addition of APIs to print the memory statistical data
6954 * as defined by SSI enhancements
6956 #ifdef SSI_DEBUG_LEVEL1
6959 * Fun: SPrintRegMemStatusInfo
6961 * Desc: This function displays the memory usage information
6962 * for the destined region. It will show the total memory
6963 * used for static and dynamic memory if typeFlag is
6964 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
6965 * memory block allocated for a particular size if typeFlag
6966 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
6967 * calling SRegPrintMemStats.
6976 S16 SPrintRegMemStatusInfo
6984 uint32_t statMemSize;
6985 uint32_t dynMemSize;
6988 #if (ERRCLASS & ERRCLS_INT_PAR)
6989 if (region >= mtMemoCfg.numRegions )
6991 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
6996 /* initialize the counters*/
7000 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7002 /* total static and dynamic memory allocated from all the buckets in region requested */
7003 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7004 SDisplay(0, prntBuf);
7005 sprintf(prntBuf, "===========================================\n");
7006 SDisplay(0, prntBuf);
7007 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7008 SDisplay(0, prntBuf);
7009 sprintf(prntBuf, "===========================================\n");
7010 SDisplay(0, prntBuf);
7011 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7013 /*mt009.301 Fixed 64BIT compilation warnings*/
7015 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7016 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7017 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7019 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7020 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7021 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7023 SDisplay(0, prntBuf);
7024 /* update the total count */
7025 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7026 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7029 /*mt009.301 Fixed 64BIT compilation warnings*/
7031 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7032 SDisplay(0, prntBuf);
7033 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7035 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7036 SDisplay(0, prntBuf);
7037 /*mt010.301 fix for compilation error*/
7038 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7040 SDisplay(0, prntBuf);
7042 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7043 SDisplay(0, prntBuf);
7044 /*mt009.301 Fixed 64BIT compilation warnings*/
7046 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7047 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7049 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7050 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7052 SDisplay(0, prntBuf);
7054 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7056 /* Bucket Memory allocation Statistics */
7057 return (SPrintRegMemStats(region));
7062 sprintf(prntBuf, "\n Invalid choice \n");
7063 SDisplay(0, prntBuf);
7071 * Fun: SPrintRegMemStats
7073 * Desc: This function displays the memory usage information for
7074 * the destined region. It will show the number of memory
7075 * block allocated for a particular size from the hash list.
7084 static S16 SPrintRegMemStats(Region region)
7086 CmMmHashListCp *hashListCp;
7092 hashListCp = &mtCMMRegCb[region]->hashListCp;
7094 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7095 SDisplay(0, prntBuf);
7096 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7097 hashListCp->numOfbins, hashListCp->numOfEntries);
7098 SDisplay(0, prntBuf);
7099 sprintf(prntBuf, "===================================\n");
7100 SDisplay(0, prntBuf);
7101 sprintf(prntBuf, "Block Size Total number of requests\n");
7102 SDisplay(0, prntBuf);
7103 sprintf(prntBuf, "===================================\n");
7104 SDisplay(0, prntBuf);
7106 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7107 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7109 if (hashListCp->hashList[idx].numAttempts)
7112 /*mt009.301 Fixed 64BIT compilation warnings*/
7114 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7115 hashListCp->hashList[idx].numAttempts);
7117 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7118 hashListCp->hashList[idx].numAttempts);
7120 SDisplay(0, prntBuf);
7124 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7125 SDisplay(0, prntBuf);
7126 sprintf(prntBuf, "=================================================\n");
7127 SDisplay(0, prntBuf);
7128 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7129 SDisplay(0, prntBuf);
7130 sprintf(prntBuf, "=================================================\n");
7131 SDisplay(0, prntBuf);
7133 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7134 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7136 /*mt009.301 Fixed 64BIT compilation warnings*/
7138 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7139 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7140 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7142 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7143 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7144 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7146 SDisplay(0, prntBuf);
7148 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7149 SDisplay(0, prntBuf);
7150 /*mt009.301 Fixed 64BIT compilation warnings*/
7152 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7153 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7154 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7156 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7157 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7158 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7160 SDisplay(0, prntBuf);
7161 sprintf(prntBuf, "\n");
7162 SDisplay(0, prntBuf);
7169 * Fun: SRegMemErrHdlr
7171 * Desc: This function handles the errors returned from the memory
7172 * related functions. Customers are suggested to modify this
7173 * API according to their specific requirement.
7192 if (errCode == RDBLFREE)
7194 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7195 SDisplay(0, prntBuf);
7197 else if (errCode == RTRAMPLINGNOK)
7199 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7200 SDisplay(0, prntBuf);
7208 * Fun: SPrintRegMemProfile
7210 * Desc: This function displays the memory profile information
7211 * for the destined region. This function prints for:
7212 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7213 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7222 S16 SPrintRegMemProfile
7229 CmMmBlkHdr *curBktBlk;
7231 Size offsetToNxtBlk;
7239 #if (ERRCLASS & ERRCLS_INT_PAR)
7240 if (region >= mtMemoCfg.numRegions )
7242 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7247 regCb = mtCMMRegCb[region];
7249 /* memory profile */
7250 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7251 SDisplay(0, prntBuf);
7253 /* bucket profile */
7254 sprintf(prntBuf, "\nBucket Profile\n");
7255 SDisplay(0, prntBuf);
7257 for (idx = 0; idx < regCb->numBkts; idx++)
7260 /*mt009.301 Fixed 64BIT compilation warnings*/
7262 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7263 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7265 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7266 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7268 SDisplay(0, prntBuf);
7270 sprintf(prntBuf, "==========================================================================\n");
7271 SDisplay(0, prntBuf);
7272 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7273 SDisplay(0, prntBuf);
7274 sprintf(prntBuf, "==========================================================================\n");
7275 SDisplay(0, prntBuf);
7277 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7279 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7280 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7281 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7283 /*mt009.301 Fixed 64BIT compilation warnings*/
7285 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7287 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7289 SDisplay(0, prntBuf);
7290 /* check if it is a sane block, elxe jump to next block */
7291 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7293 sprintf(prntBuf, " Trampled \n");
7294 SDisplay(0, prntBuf);
7299 if (CMM_IS_STATIC(curBktBlk->memFlags))
7301 /*mt009.301 Fixed 64BIT compilation warnings*/
7303 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7305 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7307 SDisplay(0, prntBuf);
7309 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7311 /*mt009.301 Fixed 64BIT compilation warnings*/
7313 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7315 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7317 SDisplay(0, prntBuf);
7319 else if (CMM_IS_FREE(curBktBlk->memFlags))
7321 /*mt009.301 Fixed 64BIT compilation warnings*/
7323 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7325 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7327 SDisplay(0, prntBuf);
7331 sprintf(prntBuf, " Trampled \n");
7332 SDisplay(0, prntBuf);
7338 sprintf(prntBuf, "\nHeap Profile\n");
7339 SDisplay(0, prntBuf);
7341 /* point to heapCb */
7342 heapCb = &(regCb->heapCb);
7344 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7345 SDisplay(0, prntBuf);
7346 sprintf(prntBuf, "==========================================================================\n");
7347 SDisplay(0, prntBuf);
7348 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7349 SDisplay(0, prntBuf);
7350 sprintf(prntBuf, "==========================================================================\n");
7351 SDisplay(0, prntBuf);
7353 /* traverse the entire heap to output the heap profile */
7354 hdrSize = sizeof(CmHEntry);
7355 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7356 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7358 /*mt009.301 Fixed 64BIT compilation warnings*/
7360 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7362 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7364 SDisplay(0, prntBuf);
7366 /* check if it is a sane block, elxe jump to next block */
7367 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7369 sprintf(prntBuf, " Trampled \n");
7370 SDisplay(0, prntBuf);
7372 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7373 SDisplay(0, prntBuf);
7376 * To go to next block in the heap we do not have any offset value
7377 * other than curHBlk->size. As the block is already trampled
7378 * we cannot rely on this size. So it is better to stop here unless there
7379 * exists any other mechanism(?) to know the offset to next block.
7384 /*mt009.301 Fixed 64BIT compilation warnings*/
7386 sprintf(prntBuf, " %8u", curHBlk->size);
7388 sprintf(prntBuf, " %8lu", curHBlk->size);
7390 SDisplay(0, prntBuf);
7392 if (CMM_IS_STATIC(curHBlk->memFlags))
7394 /*mt009.301 Fixed 64BIT compilation warnings*/
7396 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7398 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7400 SDisplay(0, prntBuf);
7402 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7404 /*mt009.301 Fixed 64BIT compilation warnings*/
7406 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7408 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7410 SDisplay(0, prntBuf);
7412 else if (CMM_IS_FREE(curHBlk->memFlags))
7414 /*mt009.301 Fixed 64BIT compilation warnings*/
7416 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7418 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7420 SDisplay(0, prntBuf);
7424 sprintf(prntBuf, " Trampled \n");
7425 SDisplay(0, prntBuf);
7427 /* goto next block in the heap */
7428 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7434 #endif /* SSI_DEBUG_LEVEL1 */
7436 /*-- mt035.201 : Added new API for timestamp --*/
7439 * Fun: Get TimeStamp
7441 * Desc: This function is used to Get TimeStamp in micro seconds
7458 struct timespec ptime;
7460 struct timeval ptime;
7469 clock_gettime(CLOCK_REALTIME, &ptime);
7471 gettimeofday(&ptime, NULL);
7474 /* Obtain the time of day, and convert it to a tm struct. --*/
7475 ptm = localtime (&ptime.tv_sec);
7476 /* Klock work fix ccpu00148484 */
7479 /* Format the date and time, down to a single second. --*/
7480 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7483 /* Compute microseconds. --*/
7485 microseconds = ptime.tv_nsec / 1000;
7487 microseconds = ptime.tv_usec;
7490 /* Print the formatted time, in seconds, followed by a decimal point
7491 and the microseconds. --*/
7492 /*mt009.301 Fixed 64BIT compilation warnings*/
7494 sprintf(ts, "%s.%03d", time_string, microseconds);
7496 sprintf(ts, "%s.%03ld", time_string, microseconds);
7502 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7505 * Fun: Get SGetSystemTsk
7507 * Desc: This function is used to Get sytem task id
7516 uint32_t SGetSystemTsk(Void)
7519 return (pthread_self());
7521 } /* end of SGetSystemTsk */
7523 #ifdef SS_MULTICORE_SUPPORT
7526 * Fun: Add Timer thread into system task table
7528 * Desc: This function is used to add the system task
7529 * associated with Timer thread.
7538 static SsSTskEntry* ssdAddTmrSTsk(Void)
7544 /* lock the system task table */
7545 ret = SLock(&osCp.sTskTblLock);
7549 #if (ERRCLASS & ERRCLS_DEBUG)
7550 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7551 "Could not lock system task table");
7557 /* check count of system tasks */
7558 if (osCp.numSTsks == SS_MAX_STSKS)
7561 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7563 #if (ERRCLASS & ERRCLS_DEBUG)
7564 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7565 "Could not give the Semaphore");
7570 #if (ERRCLASS & ERRCLS_ADD_RES)
7571 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7578 /* initialize the system task entry with the information we have */
7579 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7581 /* store the system task priority */
7582 sTsk->tskPrior = SS_NORM_TSK_PRI;
7584 /* initialize the demand queue */
7585 if (ssInitDmndQ(&sTsk->dQ) != ROK)
7588 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7590 #if (ERRCLASS & ERRCLS_DEBUG)
7591 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7592 "Could not give the Semaphore");
7597 #if (ERRCLASS & ERRCLS_DEBUG)
7598 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7599 "Could not initialize demand queue");
7605 /* initialize the system task entry lock */
7606 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7608 ssDestroyDmndQ(&sTsk->dQ);
7610 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7612 #if (ERRCLASS & ERRCLS_DEBUG)
7613 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7614 "Could not give the Semaphore");
7619 #if (ERRCLASS & ERRCLS_DEBUG)
7620 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
7621 "Could not initialize system task entry lock");
7628 /* success, update the table */
7629 sTsk->tskId = osCp.nxtSTskEntry;
7631 sTsk->termPend = FALSE;
7632 osCp.nxtSTskEntry = sTsk->nxt;
7635 /* unlock the system task table */
7637 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7639 #if (ERRCLASS & ERRCLS_DEBUG)
7640 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
7641 "Could not give the Semaphore");
7648 #endif /* SS_MULTICORE_SUPPORT */
7649 /* mt003.301 Readwrite lock and recursive mutex additions */
7650 #ifdef SS_LOCK_SUPPORT
7653 * Fun: ssdInitLockNew
7655 * Desc: This function is used to initialise lock/mutex
7664 S16 ssdInitLockNew(SLockInfo *lockId,uint8_t lockType)
7667 #ifdef SS_REC_LOCK_SUPPORT
7668 pthread_mutexattr_t attr;
7669 #endif /* SS_REC_LOCK_SUPPORT */
7670 Txt prntBuf[PRNTSZE];
7676 #ifdef SS_RDWR_LOCK_SUPPORT
7679 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
7681 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
7682 SDisplay(0, prntBuf);
7687 #endif /* SS_RDWR_LOCK_SUPPORT */
7688 #ifdef SS_REC_LOCK_SUPPORT
7691 retVal = pthread_mutexattr_init(&attr);
7695 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
7700 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
7702 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
7706 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
7707 pthread_mutexattr_destroy(&attr);
7711 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
7714 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
7715 pthread_mutexattr_destroy(&attr);
7721 #endif /* SS_REC_LOCK_SUPPORT */
7724 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
7725 SDisplay(0, prntBuf);
7735 * Desc: This function is used to aquire the read write lock
7744 S16 ssdLockNew(SLockInfo *lockId,uint8_t lockType)
7747 Txt prntBuf[PRNTSZE];
7753 #ifdef SS_RDWR_LOCK_SUPPORT
7756 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
7758 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7759 SDisplay(0, prntBuf);
7766 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
7768 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
7769 SDisplay(0, prntBuf);
7776 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
7778 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7779 SDisplay(0, prntBuf);
7786 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
7788 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7789 SDisplay(0, prntBuf);
7794 #endif /* SS_RDWR_LOCK_SUPPORT */
7795 #ifdef SS_REC_LOCK_SUPPORT
7798 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
7800 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7801 SDisplay(0, prntBuf);
7806 #endif /* SS_REC_LOCK_SUPPORT */
7809 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
7810 SDisplay(0, prntBuf);
7823 * Desc: This function is used to Unlock the read write lock
7832 S16 ssdUnlockNew(SLockInfo *lockId,uint8_t lockType)
7835 Txt prntBuf[PRNTSZE];
7841 #ifdef SS_RDWR_LOCK_SUPPORT
7844 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
7846 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
7847 SDisplay(0, prntBuf);
7852 #endif /* SS_RDWR_LOCK_SUPPORT */
7853 #ifdef SS_REC_LOCK_SUPPORT
7856 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
7858 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7859 SDisplay(0, prntBuf);
7864 #endif /* SS_REC_LOCK_SUPPORT */
7867 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
7868 SDisplay(0, prntBuf);
7877 * Fun: ssdDestroyLockNew
7879 * Desc: This function is used to destroy the read write lock
7888 S16 ssdDestroyLockNew(SLockInfo *lockId,uint8_t lockType)
7890 Txt prntBuf[PRNTSZE];
7896 #ifdef SS_RDWR_LOCK_SUPPORT
7899 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
7901 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
7902 SDisplay(0, prntBuf);
7907 #endif /* SS_RDWR_LOCK_SUPPORT */
7908 #ifdef SS_REC_LOCK_SUPPORT
7911 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
7913 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
7914 SDisplay(0, prntBuf);
7919 #endif /* SS_REC_LOCK_SUPPORT */
7922 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
7923 SDisplay(0, prntBuf);
7929 #endif /* SS_LOCK_SUPPORT */
7931 /* mt005.301 : Cavium Changes */
7932 #ifdef SS_SEUM_CAVIUM
7936 * Fun: ssInitRcvWork
7938 * Desc: This is the initializtion function of receive
7942 * RFAILED - failed, general (optional)
7944 * Notes: Function to initialize the work queue packet
7945 * receiving thread. This creates the new thread to
7946 * receive the work and sets the affinity.
7951 S16 ssInitRcvWork(void)
7953 pthread_attr_t attr;
7957 /* set the required attributes */
7958 pthread_attr_init(&attr);
7959 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
7960 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
7961 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
7963 /* Create a new thread to receive the work queue messages */
7964 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
7966 pthread_attr_destroy(&attr);
7971 pthread_attr_destroy(&attr);
7975 }/* ssInitRcvWork */
7982 * Desc: This is the handler function of receive
7986 * RFAILED - failed, general (optional)
7988 * Notes:The handler function of the work queue receiver task.
7989 * This will be waiting for the work and after receiving
7990 * it, work will converted and posted to that entityt
7996 static void *workRcvTsk(Ptr ptr)
7999 cvmx_wqe_t *workPtr;
8000 Buffer *mBuf, *rcvdBuf;
8001 SsMsgInfo *minfoPtr;
8010 /* get the work if its avilable */
8011 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8013 if ( workPtr == NULLP )
8015 /* If there is no work then sleep for 10 usec */
8017 ts.tv_nsec = 500000;
8019 nanosleep(&ts, NULLP);
8023 switch(workPtr->tag)
8025 /* Switch over according to the tag value */
8026 case SS_CVMX_MBUF_TAG:
8028 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8030 /* Convert the physical address to Pointers */
8031 ret = SConvPhyPtr(&rcvdBuf);
8034 /* mt011.301: Cavium 32 bit changes */
8035 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8039 /* Copy the buffer to this region */
8040 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8043 /* mt011.301: Cavium 32 bit changes */
8044 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8048 /* mt011.301: Cavium 32 bit changes */
8049 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8051 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8053 /* Get the post strucutre and Post the message */
8054 if ( minfoPtr != NULLP)
8056 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8058 (Void)SPstTsk(&pst, mBuf);
8060 /* Free the buffer allocated if it cannot be sent */
8069 /* Invalid tag value, drop the work */
8070 /* mt011.301: Cavium 32 bit changes */
8071 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8080 #endif /* SS_SEUM_CAVIUM */
8082 #ifdef TENB_RTLIN_CHANGES
8083 S16 SInitLock(SLockId *l, uint8_t t)
8086 pthread_mutexattr_t prior;
8087 pthread_mutexattr_init(&prior);
8088 #ifndef RGL_SPECIFIC_CHANGES
8089 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8091 r = pthread_mutex_init(l, &prior);
8092 pthread_mutexattr_destroy(&prior);
8096 #ifdef SS_THR_REG_MAP
8099 * Fun: ssRegMainThread
8101 * Desc: This function is used to add the memory region
8102 * mapping for the main thread.
8104 * Ret: VOID (Always successful)
8112 Void ssRegMainThread(Void)
8115 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8117 printf("\nnot able to get different Id for main thread\n");
8120 /* Here the default region is added as we dont have any region associated with
8121 * Main thread. The thread should not perform any allocation except
8122 * the initial configuratin
8124 #ifdef XEON_SPECIFIC_CHANGES
8125 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8127 SS_GET_THREAD_MEM_REGION() =
8134 * Fun: ssCheckAndAddMemoryRegionMap
8136 * Desc: This function is used to add the memory region
8137 * mapping for the provided sTsk associated thread.
8138 * If the threadId can be placed in the thread memory
8139 * region mapping table and returns success if it is able
8140 * to place. If not, it keeps the thread ID in the static
8141 * local array and increments the count. Once thread Id
8142 * is successfully placed in the thread memory region mapping
8143 * table, pthread_cancel is sent for all the previous threads
8144 * which are failed to place in table.
8146 * Ret: TRUE - Thread ID successfully placed in thread memory region
8148 * FALSE - If thread Id is not placed in thread memory region
8151 * Notes:mapping tablemapping tablng tablee
8156 S32 ssCheckAndAddMemoryRegionMap
8158 pthread_t threadId, /* Thread Id of system task */
8159 Region region /* Region associated with thread */
8162 static uint32_t createdThreads;
8163 static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8167 /* Here 0xFF is considered as invalid region and if the mapping table
8168 * contains 0xFF, that mapping entry is free
8170 if(SS_INVALID_THREAD_REG_MAP !=
8171 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8173 /* Klock work fix ccpu00148484 */
8174 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8176 printf("\nfailed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8177 printf("\nNot able to get the different thread ID, exiting\n");
8180 createdThreadIds[createdThreads++] = threadId;
8183 /* If we found free mapping table entry, place the region and send pthread_cancel
8184 * for all the thread Ids which are created before this
8186 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8187 #ifdef XEON_SPECIFIC_CHANGES
8188 printf("\nThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8189 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8190 SS_MAX_THREAD_REGION_MAP), region);
8192 for(indx = 0; indx < createdThreads; indx++)
8194 #ifdef XEON_SPECIFIC_CHANGES
8195 printf("\nSending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8197 pthread_cancel(createdThreadIds[indx]);
8203 } /* ssCheckAndAddMemoryRegionMap */
8207 * Fun: ssCheckAndDelMemoryRegionMap
8209 * Desc: This function is used to add the memory region
8210 * mapping for the provided sTsk associated thread.
8211 * If the threadId can be placed in the thread memory
8212 * region mapping table and returns success if it is able
8213 * to place. If not, it keeps the thread ID in the static
8214 * local array and increments the count. Once thread Id
8215 * is successfully placed in the thread memory region mapping
8216 * table, pthread_cancel is sent for all the previous threads
8217 * which are failed to place in table.
8219 * Ret: TRUE - Thread ID successfully placed in thread memory region
8221 * FALSE - If thread Id is not placed in thread memory region
8224 * Notes:mapping tablemapping tablng tablee
8229 S32 ssCheckAndDelMemoryRegionMap
8231 pthread_t threadId /* Thread Id of system task */
8236 /* Raghu To-Do Check with team, is it necessary to acquire lock
8237 * as del and add may go parallel */
8238 /* Here 0xFF is considered as invalid region and if the mapping table
8239 * contains 0xFF, that mapping entry is free
8241 if(SS_INVALID_THREAD_REG_MAP ==
8242 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8245 printf("\nInvalid Thread ID (%ld)\n", (uint32_t)threadId);
8247 printf("\nInvalid Thread ID (%d)\n", (uint32_t)threadId);
8251 /* If we found free mapping table entry, place the region and send pthread_cancel
8252 * for all the thread Ids which are created before this
8254 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8258 } /* ssCheckAndAddMemoryRegionMap */
8262 #ifdef SS_TSKLOG_ENABLE
8267 * Desc: This function will return current time through input parameter.
8270 * RFAILED - failed, general (optional)
8278 volatile uint32_t *startTime,
8282 #ifdef MSPD_MLOG_NEW
8283 *startTime = GetTIMETICK();
8292 * Desc: This function will return current time through input parameter.
8293 * and take the difference of start time provided as input parameter
8297 * RFAILED - failed, general (optional)
8305 volatile uint32_t startTime,
8309 /*uint32_t stopTime;*/
8312 case PID_MAC_HARQ_IND:
8313 case PID_SCH_TTI_IND:
8315 case PID_MAC_DAT_IND:
8316 case PID_MAC_SF_ALLOC_REQ:
8317 case PID_MAC_STA_RSP:
8318 case PID_MAC_DL_SCHD:
8319 case PID_MAC_DL_CQI_IND:
8320 case PID_MAC_UL_CQI_IND:
8321 case PID_MAC_UL_SCHD:
8322 case PID_MAC_TTI_IND:
8323 case PID_CL_RCV_PHY_MSG:
8324 case PID_CL_HARQ_STA_IND:
8325 case PID_MAC_AM_HARQ_RLS:
8326 case PID_CL_DL_BATCH_PROC:
8327 case PID_CL_DLM_PRC_TTI_IND:
8328 case PID_CRC_IND_REAL:
8329 case PID_CRC_IND_DUMMY:
8330 case PID_TTI_LATENCY:
8331 case PID_RECPREQ_PROC:
8334 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8336 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8339 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8348 volatile uint32_t * startTime,
8358 volatile uint32_t startTime,
8365 #endif /*#ifdef SS_TSKLOG_ENABLE */
8366 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8368 * This primitive is used to calculate the CPU Utilization per Core
8373 * @return Void - function is always success
8375 Void UpdateSocCpuInfo
8377 CmCpuStatsInfo *cpuInfo,
8382 S8 mipsStr[MIPS_STRING_LEN];
8389 /* Open the file which holds the MIPS available value */
8390 mipsFd = fopen(MIPS_FILE, "r");
8397 /* Get the free mips available value from the file */
8398 if(NULLP == fgets(mipsStr, 24, mipsFd))
8400 printf("\nfgets to get the free mips available failed\n");
8405 strtok(mipsStr, " ");
8407 strPart = strtok(NULLP, " ");
8409 if(idx == CM_L2_CPU_UTIL)
8411 if(strPart != NULLP)
8413 l2FreeCpu = atoi(strPart);
8414 l2CpuUsed = 100 - l2FreeCpu;
8415 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8416 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
8417 cpuInfo->cpuUtil[0].numSamples++;
8420 if(idx == CM_L3_CPU_UTIL)
8422 strPart = strtok(NULLP, " ");
8423 if(strPart != NULLP)
8425 l3FreeCpu = atoi(strPart);
8426 l3CpuUsed = 100 - l3FreeCpu;
8427 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8428 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
8429 cpuInfo->cpuUtil[0].numSamples++;
8432 if(idx == CM_L2_CPU_UTIL)
8434 cpuInfo->numCores = CM_NUM_L2_CORES ;
8436 else if(idx == CM_L3_CPU_UTIL)
8438 cpuInfo->numCores = CM_NUM_L3_CORES ;
8444 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8445 #ifdef SS_MULTICORE_SUPPORT
8448 * Fun: Add Timer thread into system task table
8450 * Desc: This function is used to add the system task
8451 * associated with Timer thread.
8460 static SsSTskEntry* ssdReAddTmrSTsk(
8468 /* lock the system task table */
8469 ret = SLock(&osCp.sTskTblLock);
8473 #if (ERRCLASS & ERRCLS_DEBUG)
8474 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8475 "Could not lock system task table");
8481 /* initialize the system task entry with the information we have */
8482 sTsk = &osCp.sTskTbl[idx];
8487 SDestroyLock(&sTsk->lock);
8488 ssDestroyDmndQ(&sTsk->dQ);
8491 /* store the system task priority */
8492 sTsk->tskPrior = SS_NORM_TSK_PRI;
8494 /* initialize the demand queue */
8495 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8498 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8500 #if (ERRCLASS & ERRCLS_DEBUG)
8501 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8502 "Could not give the Semaphore");
8507 #if (ERRCLASS & ERRCLS_DEBUG)
8508 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8509 "Could not initialize demand queue");
8515 /* initialize the system task entry lock */
8516 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8518 ssDestroyDmndQ(&sTsk->dQ);
8520 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8522 #if (ERRCLASS & ERRCLS_DEBUG)
8523 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8524 "Could not give the Semaphore");
8529 #if (ERRCLASS & ERRCLS_DEBUG)
8530 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8531 "Could not initialize system task entry lock");
8538 /* success, update the table */
8539 sTsk->tskId = idx + 1;
8541 sTsk->termPend = FALSE;
8543 /* unlock the system task table */
8545 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8547 #if (ERRCLASS & ERRCLS_DEBUG)
8548 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8549 "Could not give the Semaphore");
8556 #endif /* SS_MULTICORE_SUPPORT */
8561 * Fun: Initialize timer table
8563 * Desc: This function initializes MTSS-specific information
8564 * in the timer table.
8573 S16 ssdReInitTmr(void)
8575 pthread_attr_t attr;
8576 struct sched_param param_sched;
8577 #ifndef XEON_SPECIFIC_CHANGES
8580 #ifdef SS_MULTICORE_SUPPORT
8582 #endif /* SS_MULTICORE_SUPPORT */
8583 #ifdef SS_THR_REG_MAP
8584 uint32_t threadCreated = FALSE;
8585 #endif /* SS_THR_REG_MAP */
8588 #ifndef XEON_SPECIFIC_CHANGES
8589 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
8592 #if (ERRCLASS & ERRCLS_DEBUG)
8593 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8594 "Could not give the Semaphore");
8600 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
8601 /* mt010.21: addition */
8603 #ifdef SS_MULTICORE_SUPPORT
8604 sTsk = ssdReAddTmrSTsk(0);
8609 #endif /* SS_MULTICORE_SUPPORT */
8610 /* create the timer handler thread */
8612 pthread_attr_init(&attr);
8613 /* mt021.201 - Addition to set stack size */
8614 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
8615 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8616 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8617 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
8618 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
8619 pthread_attr_setschedparam(&attr, ¶m_sched);
8622 #ifdef SS_THR_REG_MAP
8623 /* When the thread is created, we check for the memory mapping table if
8624 * threadId can be placed in thread memory map table. If it is not able to place
8625 * threadId is stored in tmporary array. Once thread is created successful,
8626 * thread_cancel is sent for each thread which are created before. All the
8627 * threads are made to wait on sema which is cancel point for thread.
8629 while(threadCreated == FALSE)
8632 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
8634 /* mt020.201 - Addition for destroying thread attribute object attr */
8635 pthread_attr_destroy(&attr);
8640 #ifdef SS_THR_REG_MAP
8641 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
8644 #endif /* SS_THR_REG_MAP */
8645 #ifdef SS_MEM_WL_DEBUG
8646 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
8649 /* mt020.201 - Addition for destroying thread attribute object attr */
8650 pthread_attr_destroy(&attr);
8651 sem_post(&osCp.dep.ssStarted);
8655 /**********************************************************************
8657 **********************************************************************/