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;
184 uint64_t nWlsMacMemorySize = 0;
185 uint64_t nWlsPhyMemorySize = 0;
188 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
190 struct sigcontext my_uc_mcontext = { 0 };
195 #include <ucontext.h>
199 #define SIGSEGV_STACK_GENERIC
200 #define REGFORMAT "%x\n"
202 #ifdef XEON_SPECIFIC_CHANGES
203 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
206 void dump_external(void);
208 static Void mtDelSigals(Void)
212 memset(&sa, 0, sizeof(struct sigaction));
213 sigemptyset(&sa.sa_mask);
214 sa.sa_handler = SIG_DFL;
215 sigaction(SIGSEGV, &sa, NULL);
217 memset(&sa, 0, sizeof(struct sigaction));
218 sigemptyset(&sa.sa_mask);
219 sa.sa_handler = SIG_DFL;
220 sigaction(SIGILL, &sa, NULL);
224 static void signal_segv(int signum, siginfo_t * info, void *ptr)
226 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
229 ucontext_t *ucontext = (ucontext_t *) ptr;
230 #ifdef XEON_SPECIFIC_CHANGES
232 int *p32 = (int *) 0x2fff0000;
237 printf("\nsegv ooops @ %p\n", info->si_addr);
240 printf("\nSegmentation Fault!\n");
241 printf("\ninfo.si_signo = %d\n", signum);
242 printf("\ninfo.si_errno = %d\n", info->si_errno);
243 printf("\ninfo.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
244 printf("\ninfo.si_addr = %p\n", info->si_addr);
246 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
249 #ifndef RGL_SPECIFIC_CHANGES
250 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
251 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
252 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
253 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
254 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
255 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
256 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
257 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
258 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
259 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
260 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
261 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
262 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
263 printf("\nreg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
264 printf("\nreg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
265 printf("\nreg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
266 printf("\nreg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
269 printf("\nStack trace (non-dedicated):\n");
271 sz = backtrace(buffer, 50);
272 strings = backtrace_symbols(buffer, sz);
273 for (i = 0; i < sz; ++i)
274 printf("%s\n", strings[i]);
276 printf("\nEnd of stack trace\n");
278 #ifdef XEON_SPECIFIC_CHANGES
283 /* Lets first print our debug information */
284 printf("\nBefore dumping our Debug info\n");
286 printf("\nAfter dumping our Debug info\n");
288 /* Disable the signal and make the enodeb to dump. This will make
289 * eNB to generate the core with dumping the ccpu log
296 /* End printing debug information */
301 /*** TBD: IMPORTANT ***
302 *** The following definition is temporary. This must be removed
303 *** when all products have been updated with latest ssi.h file OR
304 *** all ssi.h files have been updated to contain this definitions
306 /* New error class for FTHA added */
308 #define ERRCLS_FTHA 0x8
309 #endif /* ERRCLS_FTHA */
311 typedef struct _SPThreadCreateArg
313 void *argument; /* argument that is to be passed to the actual pthread */
314 void *(*start_routine) (void *); /* function from which pthread starts */
317 void *pthreadCreateHdlr(void* arg);
319 #ifdef SS_LOCKLESS_MEMORY
320 Buffer *mtTskBuffer1;
321 Buffer *mtTskBuffer2;
323 pthread_t tmpRegTidMap[20];
325 S16 SGlobMemInfoShow(void);
326 #endif /* SS_LOCKLESS_MEMORY */
329 APP_CONTEXT AppContext;
333 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
334 unsigned int tlPost(void *handle);
337 /* forward references */
338 /* mt003.301 Modifications - Moved to ss_gen.x */
339 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
340 Void *mtTskHdlrT2kL2 ARGS((Void*));
341 void mtSigSegvHndlr ARGS((void));
342 void mtSigUsr2Hndlr ARGS((void));
345 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
346 static Void *mtTskHdlr ARGS((void *));
347 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
349 static Void *mtTmrHdlr ARGS((void *));
350 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
352 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
353 static Void mtIntSigHndlr ARGS((int));
354 static Void mtExitClnup ARGS((void));
357 static Void *mtConHdlr ARGS((void *));
361 #ifdef SS_DRVR_SUPPORT
362 static Void *mtIsTskHdlr ARGS((void *));
366 /* mt020.201 - Addition for no command line available */
368 static Void mtGetOpts ARGS((void));
369 /* mt003.301 Additions - File Based task registration made
370 * common for both MULTICORE and NON-MULTICORE
372 static Bool fileBasedMemCfg = FALSE;
375 /* mt033.201 - addition of local function to print the statistics such as
376 * (size vs. numAttempts) and (allocations vs. deallocations)
378 #ifdef SSI_DEBUG_LEVEL1
379 static S16 SPrintRegMemStats ARGS((Region region));
380 #endif /* SSI_DEBUG_LEVEL1 */
382 #ifdef SS_MULTICORE_SUPPORT
383 static SsSTskEntry* ssdAddTmrSTsk(Void);
384 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
385 #ifndef SS_LOCKLESS_MEMORY
386 #ifndef RGL_SPECIFIC_CHANGES
387 static S16 ssdInitMemInfo ARGS((void));
392 /* mt005.301: Cavium changes */
393 #ifdef SS_SEUM_CAVIUM
394 static Void *workRcvTsk ARGS((void *));
395 #endif /* SS_SEUM_CAVIUM */
397 #ifdef SS_THR_REG_MAP
398 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
400 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
401 #endif /* SS_THR_REG_MAP */
403 /* type declarations */
405 #ifdef SS_DRVR_SUPPORT
406 typedef struct mtIsFlag
416 /* public variable declarations */
418 Cntr cfgNumRegs = SS_MAX_REGS;
419 /* Set memory configuration as false.
420 * Set to true if memory configuration through file is successfull.
422 Bool memConfigured = FALSE;
423 /* mt022.201 - Modification for shared memory relay region and memcal tool */
424 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
427 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
429 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
430 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
431 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
432 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
433 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
434 { SS_POOL_STATIC, 0 }
440 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
442 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
443 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
444 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
445 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
446 { SS_POOL_STATIC, 0 }
449 #endif /* INTEL_WLS */
451 #ifdef SS_LOCKLESS_MEMORY
454 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
456 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
457 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
458 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
459 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
460 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
461 { SS_POOL_STATIC, 0 }
465 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
467 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
468 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
469 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
470 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
471 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
472 { SS_POOL_STATIC, 0 }
476 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
478 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
479 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
480 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
481 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
482 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
483 { SS_POOL_STATIC, 0 }
487 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
489 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
490 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
491 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
492 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
493 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
494 { SS_POOL_STATIC, 0 }
498 SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
500 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
501 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
502 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
503 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
504 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
505 { SS_POOL_STATIC, 0 }
509 SS_DFLT_REGION + 6, SS_MAX_POOLS_PER_REG - 1,
511 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
512 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
513 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
514 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
515 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
516 { SS_POOL_STATIC, 0 }
519 #ifndef INTEL_WLS_MEM
522 SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1,
524 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
525 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
526 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
527 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
528 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
529 { SS_POOL_STATIC, 0 }
534 #endif /* SS_LOCKLESS_MEMORY */
536 /* mt003.301 Modifications - File Based task registration made
537 * common for both MULTICORE and NON-MULTICORE
540 #ifdef SS_LOCKLESS_MEMORY
541 MtDynMemCfg mtDynMemoCfg =
543 SS_MAX_REGS, /* number of regions */
546 SS_DFLT_REGION, /* region id */
547 MT_MAX_BKTS, /* number of buckets */
549 /* block size, no. of blocks, Upper threshold, lower 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},
553 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
554 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
558 SS_DFLT_REGION + 1, /* region id */
559 MT_MAX_BKTS, /* number of buckets */
561 /* block size, no. of blocks, Upper threshold, lower 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},
565 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
566 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
570 SS_DFLT_REGION + 2, /* region id */
571 MT_MAX_BKTS, /* number of buckets */
573 /* block size, no. of blocks, Upper threshold, lower 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},
577 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
578 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
582 SS_DFLT_REGION + 3, /* region id */
583 MT_MAX_BKTS, /* number of buckets */
585 /* block size, no. of blocks, Upper threshold, lower 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},
589 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
590 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
594 SS_DFLT_REGION + 4, /* region id */
595 MT_MAX_BKTS, /* number of buckets */
597 /* block size, no. of blocks, Upper threshold, lower 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},
601 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
602 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
606 SS_DFLT_REGION + 5, /* region id */
607 MT_MAX_BKTS, /* number of buckets */
609 /* block size, no. of blocks, Upper threshold, lower 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},
613 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
614 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
618 SS_DFLT_REGION + 6, /* region id */
619 MT_MAX_BKTS, /* number of buckets */
621 /* block size, no. of blocks, Upper threshold, lower 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},
625 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
626 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
629 #ifndef INTEL_WLS_MEM
632 SS_DFLT_REGION + 7, /* region id */
633 MT_MAX_BKTS, /* number of buckets */
635 /* block size, no. of blocks, Upper threshold, lower 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},
639 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
640 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
644 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
647 SS_DFLT_REGION + 7, /* region id */
648 MT_MAX_BKTS, /* number of buckets */
650 /* block size, no. of blocks, Upper threshold, lower threshold */
651 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
652 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
653 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
654 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
662 MtGlobMemCfg mtGlobMemoCfg =
664 MT_MAX_BKTS, /* number of buckets */
667 /* block size, no. of blocks, Upper threshold, lower threshold */
668 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
669 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
670 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
671 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
672 {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
674 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
675 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
676 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
677 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
681 #endif /* SS_LOCKLESS_MEMORY */
683 /* mt022.201 - Modification for memory calculator tool */
684 /* mt018.201 - added memory configuration matrix */
688 SS_MAX_REGS - 1, /* number of regions */
690 #ifndef XEON_SPECIFIC_CHANGES
691 SS_MAX_REGS, /* number of regions */
698 SS_DFLT_REGION, /* region id */
699 MT_MAX_BKTS, /* number of buckets */
700 MT_HEAP_SIZE, /* heap size */
702 #ifndef XEON_SPECIFIC_CHANGES
703 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
704 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
705 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
706 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
707 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
709 {256, 491520}, /* 60 pages of 2M*/
710 {512, 12288}, /* 3 pages of 2M */
711 {2048, 99328}, /* 97 Pages of 2M */
712 {8192, 75008}, /* 293 Pages of 2M */
713 {16384, 4096} /* 32 pages of 2M */
718 #ifndef SS_LOCKLESS_MEMORY
720 SS_DFLT_REGION + 1, /* region id */
721 MT_MAX_BKTS, /* number of buckets */
722 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
724 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
725 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
726 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
727 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
735 #endif /* SS_LOCKLESS_MEMORY */
736 #endif /* INTEL_WLS */
737 #ifdef SS_LOCKLESS_MEMORY
739 SS_DFLT_REGION + 1, /* region id */
740 MT_MAX_BKTS, /* number of buckets */
741 MT_HEAP_SIZE, /* heap size */
743 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
744 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
745 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
746 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
747 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
751 SS_DFLT_REGION + 2, /* region id */
752 MT_MAX_BKTS, /* number of buckets */
753 MT_HEAP_SIZE, /* heap size */
755 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
756 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
757 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
758 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
759 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
763 SS_DFLT_REGION + 3, /* region id */
764 MT_MAX_BKTS, /* number of buckets */
765 MT_HEAP_SIZE, /* heap size */
767 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
768 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
769 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
770 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
771 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
775 SS_DFLT_REGION + 4, /* region id */
776 MT_MAX_BKTS, /* number of buckets */
777 MT_HEAP_SIZE, /* heap size */
779 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
780 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
781 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
782 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
783 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
787 SS_DFLT_REGION + 5, /* region id */
788 MT_MAX_BKTS, /* number of buckets */
789 MT_HEAP_SIZE, /* heap size */
791 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
792 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
793 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
794 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
795 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
799 SS_DFLT_REGION + 6, /* region id */
800 MT_MAX_BKTS, /* number of buckets */
801 MT_HEAP_SIZE, /* heap size */
803 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
804 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
805 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
806 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
807 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
810 #ifndef INTEL_WLS_MEM
813 SS_DFLT_REGION + 7, /* region id */
814 MT_MAX_BKTS, /* number of buckets */
815 MT_HEAP_SIZE, /* heap size */
817 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
818 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
819 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
820 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
821 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
825 #endif /* SS_LOCKLESS_MEMORY */
829 /* mt003.301 Modifications - File Based task registration made
830 * common for both MULTICORE and NON-MULTICORE
831 * bucket info, as different regions may request for different no.
834 MtBktCfg mtBktInfo[MT_MAX_BKTS];
835 S16 msArgc; /* argc */
836 Txt **msArgv; /* argv */
837 S16 msOptInd; /* SGetOpt vars */
838 S8 *msOptArg; /* SGetOpt vars */
841 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
842 typedef struct _MtRegMemSz
848 #ifdef SS_USE_WLS_MEM
849 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
850 static S16 SPartitionWlsDynMem();
851 static S16 SAllocateWlsDynMem();
854 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
859 /* private variable declarations */
860 /* mt018.201 - change mtCMMRegCfg as array of pointers */
861 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
862 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
863 /* mt003.301 - Fixed compilation warnings */
864 /*mt004.301-addede new veriable for FAP*/
865 /*mt010.301 - removed veriable defined for FA*/
868 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
871 void mtSetNtlHdl(unsigned int hdl)
876 unsigned int mtGetNtlHdl()
878 return(osCp.ntl.hdl);
882 void mtGetWlsHdl(void **hdlr)
884 *hdlr = osCp.wls.intf;
887 #ifdef XEON_MULTIPLE_CELL_CHANGES
888 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
889 S16 smWrReadWlsConfigParams (Void);
892 static int SOpenWlsIntf()
896 #define WLS_DEVICE_NAME "wls0"
898 char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", WLS_DEVICE_NAME, "--iova-mode=pa"};
899 printf("\nCalling rte_eal_init: ");
900 for (i = 0; i < RTE_DIM(my_argv); i++)
902 printf("%s ", my_argv[i]);
906 if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
907 rte_panic("\nCannot init EAL\n");
910 #ifdef XEON_SPECIFIC_CHANGES
911 #ifdef XEON_MULTIPLE_CELL_CHANGES
912 hdl = WLS_Open(gWrWlsDeviceName, 1);
914 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
917 #ifdef INTEL_L1_V19_10
918 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
920 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, &nWlsMacMemorySize, &nWlsPhyMemorySize);
924 printf("\nERROR: WLS_Open > DEVICE_NAME mismatch. WLS Device Name should be same as 'wls_dev_name' parameter in 'phycfg_xran.xml' file");
933 printf("\nCould not open WLS Interface \n");
948 * Desc: This function is the entry point for the final binary. It
949 * calls SInit() in the common code. It can be replaced by a
950 * user function if required (SInit() must still be called).
952 * Ret: none on success
962 int argc, /* argument count */
963 char **argv /* argument vector */
967 #ifdef XEON_MULTIPLE_CELL_CHANGES
968 /* Read the WLS parameters from the file and copy into global control block */
969 if(smWrReadWlsConfigParams() != ROK)
971 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
973 } /* end of if statement */
976 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
979 #endif /* INTEL_WLS */
983 /* mt003.301 Modifications */
986 printf("\n SInit failed, SSI could not start \n");
987 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
991 /*mt010.301 cleanup part exposed to user*/
1002 * Desc: This function is the entry point for the final binary. It
1003 * calls SInit() in the common code. It can be replaced by a
1004 * user function if required (SInit() must still be called).
1006 * Ret: none on success
1016 int argc, /* argument count */
1017 char **argv /* argument vector */
1033 * initialization functions
1038 * Fun: Initialize OS control point
1040 * Desc: This function initializes MTSS-specific information
1041 * in the OS control point.
1050 S16 ssdInitGen(void)
1052 struct sigaction act;
1054 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1055 struct sigaction sa;
1059 /*mt014.301 : 4GMX release related changes*/
1060 #ifdef SS_4GMX_UCORE
1063 /* mt005.301 : Cavium changes */
1064 #ifdef SS_SEUM_CAVIUM
1065 /* set group mask for the core */
1066 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
1067 #endif /* SS_SEUM_CAVIUM */
1069 osCp.dep.sysTicks = 0;
1071 /* mt020.201 - Addition for no command line available */
1073 /* parse command line */
1075 /* mt003.301 Additions */
1076 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
1078 printf("\n File Based Memory configuration failed \n");
1083 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
1084 #ifndef SS_LOCKLESS_MEMORY
1085 #ifdef SS_MULTICORE_SUPPORT
1086 if(memConfigured == FALSE)
1092 /* initialize the started semaphore */
1093 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1098 /* mt028.201 added compile time flag to allow not to mask signals */
1100 /* mask all signals in the main thread */
1102 sigdelset(&set, SIGINT);
1103 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1104 sigdelset(&set, SIGSEGV);
1105 sigdelset(&set, SIGUSR2);
1106 sigdelset(&set, SIGILL);
1107 #ifdef XEON_SPECIFIC_CHANGES
1108 sigdelset(&set, SIGABRT);
1109 sigdelset(&set, SIGTERM);
1110 sigdelset(&set, SIGHUP);
1113 pthread_sigmask(SIG_SETMASK, &set, NULLP);
1114 #endif /* UNMASK_SIG */
1116 /* install a SIGINT handler to shutdown */
1117 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1119 /*Initialize SIGSEGV Signal */
1120 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1122 memset(&sa, 0, sizeof(struct sigaction));
1123 sigemptyset(&sa.sa_mask);
1124 sa.sa_sigaction = signal_segv;
1125 sa.sa_flags = SA_SIGINFO;
1126 #ifndef XEON_SPECIFIC_CHANGES
1127 sigaction(SIGSEGV, &sa, NULL);
1129 memset(&sa, 0, sizeof(struct sigaction));
1130 sigemptyset(&sa.sa_mask);
1131 sa.sa_sigaction = signal_segv;
1132 sa.sa_flags = SA_SIGINFO;
1134 sigaction(SIGILL, &sa, NULL);
1136 if(sigaction(SIGILL, &sa, NULL) != 0)
1138 printf("\nFailed to process sigaction for the SIGILL\n");
1141 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1143 printf("\nFailed to process sigaction for the SIGSEGV\n");
1146 if(sigaction(SIGABRT, &sa, NULL) != 0)
1148 printf("\nFailed to process sigaction for the SIGABRT\n");
1151 if(sigaction(SIGTERM, &sa, NULL) != 0)
1153 printf("\nFailed to process sigaction for the SIGTERM\n");
1156 if(sigaction(SIGHUP, &sa, NULL) != 0)
1158 printf("\nFailed to process sigaction for the SIGHUP\n");
1163 signal (SIGSEGV, mtSigSegvHndlr);
1164 signal (SIGKILL, mtSigSegvHndlr);
1165 signal (SIGUSR2, mtSigUsr2Hndlr);
1170 signal (SIGINT, mtStopHndlr);
1173 act.sa_handler = mtIntSigHndlr;
1174 sigfillset(&act.sa_mask);
1176 if (sigaction(SIGINT, &act, NULLP) != 0)
1182 /* mt040.201 initialise random seed */
1183 osCp.dep.randSeed = time(NULLP);
1191 * Fun: De-initialize OS control point
1193 * Desc: This function reverses the initialization in ssdInitGen().
1202 Void ssdDeinitGen(void)
1206 sem_destroy(&osCp.dep.ssStarted);
1211 #ifdef SS_LOCKLESS_MEMORY
1215 * Fun: ssPutDynMemBlkSet
1217 * Desc: Returns the set of dynamic Blocks into the global region
1220 * Ret: ROK - successful,
1221 * RFAILED - unsuccessful.
1228 S16 ssPutDynMemBlkSet
1230 uint8_t bktIdx, /* Index to bucket list */
1231 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1232 added to global region */
1235 CmMmGlobRegCb *globReg;
1236 CmMmGlobalBktCb *bktCb;
1240 globReg = osCp.globRegCb;
1242 #if (ERRCLASS & ERRCLS_INT_PAR)
1243 if(bktIdx >= globReg->numBkts)
1247 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1249 bktCb = &(globReg->bktTbl[bktIdx]);
1251 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1253 blkPtr = dynMemSetElem->nextBktPtr;
1254 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1255 free((Void *)blkPtr);
1258 dynMemSetElem->nextBktPtr = NULLP;
1259 dynMemSetElem->numFreeBlks = 0;
1266 * Fun: ssGetDynMemBlkSet
1268 * Desc: Gets the set of dynamic memory blocks from the global region
1271 * Ret: ROK - successful,
1272 * RFAILED - unsuccessful.
1279 S16 ssGetDynMemBlkSet
1281 uint8_t bktIdx, /* Index to bucket list */
1282 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1283 with new set values */
1287 CmMmGlobRegCb *globReg;
1288 CmMmGlobalBktCb *bktCb;
1293 globReg = osCp.globRegCb;
1295 #if (ERRCLASS & ERRCLS_INT_PAR)
1296 if(bktIdx >= globReg->numBkts)
1300 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1302 bktCb = &(globReg->bktTbl[bktIdx]);
1303 basePtr = &(dynMemSetElem->nextBktPtr);
1305 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1307 blkPtr = (Data *)malloc(bktCb->size);
1309 basePtr = (CmMmEntry **)blkPtr;
1312 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1316 } /* ssGetDynMemBlkSet */
1321 * Fun: ssPutDynMemBlkSet
1323 * Desc: Returns the set of dynamic Blocks into the global region
1326 * Ret: ROK - successful,
1327 * RFAILED - unsuccessful.
1334 S16 ssPutDynMemBlkSet
1336 uint8_t bktIdx, /* Index to bucket list */
1337 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1338 added to global region */
1339 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1342 CmMmGlobRegCb *globReg;
1343 CmMmGlobalBktCb *bktCb;
1345 CmMmBlkSetElement *globMemNode;
1349 globReg = osCp.globRegCb;
1351 #if (ERRCLASS & ERRCLS_INT_PAR)
1352 if(bktIdx >= globReg->numBkts)
1356 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1358 bktCb = &(globReg->bktTbl[bktIdx]);
1360 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1361 try lock is used as it is not required to block as it will be taken
1362 in the next go else it will be blocked for lock as we have to get the
1365 SLock(&(bktCb->bucketLock));
1371 /* Get a free node from the free node linked list */
1372 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1373 if(lstNode == NULLP)
1375 SUnlock(&(bktCb->bucketLock));
1379 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1381 /* Copy the content of the received element information on to free node
1382 * and add it to valid linked list */
1383 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1384 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1385 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1386 dynMemSetElem->numFreeBlks = 0;
1387 dynMemSetElem->nextBktPtr = NULLP;
1389 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1391 SUnlock(&(bktCb->bucketLock));
1399 * Fun: ssGetDynMemBlkSet
1401 * Desc: Gets the set of dynamic memory blocks from the global region
1404 * Ret: ROK - successful,
1405 * RFAILED - unsuccessful.
1407 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1413 S16 ssGetDynMemBlkSet
1415 uint8_t bktIdx, /* Index to bucket list */
1416 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1417 with new set values */
1418 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1421 CmMmGlobRegCb *globReg;
1422 CmMmGlobalBktCb *bktCb;
1424 CmMmBlkSetElement *globMemNode;
1428 globReg = osCp.globRegCb;
1430 #if (ERRCLASS & ERRCLS_INT_PAR)
1431 if(bktIdx >= globReg->numBkts)
1435 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1437 bktCb = &(globReg->bktTbl[bktIdx]);
1439 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1440 try lock is used as it is not required to block as it will be taken
1441 in the next go else it will be blocked for lock as we have to get the
1444 SLock(&(bktCb->bucketLock));
1449 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1451 if(lstNode == NULLP)
1453 SUnlock(&(bktCb->bucketLock));
1457 /* Delete the node from the valid linked list and copy the values of the
1458 * elements of structrues into pointer */
1459 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1460 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1461 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1462 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1464 /* Add this node to the free node linked list */
1465 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1467 SUnlock(&(bktCb->bucketLock));
1471 } /* ssGetDynMemBlkSet */
1474 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1475 uint32_t gDynMemAlrm[4];
1476 static uint32_t memoryCheckCounter;
1478 uint32_t isMemThreshReached(Region reg)
1480 CmMmGlobRegCb *globReg;
1481 CmMmGlobalBktCb *bktCb;
1482 uint8_t bktIdx= reg;
1484 globReg = osCp.globRegCb;
1486 #if (ERRCLASS & ERRCLS_INT_PAR)
1487 if(bktIdx >= globReg->numBkts)
1491 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1493 bktCb = &(globReg->bktTbl[bktIdx]);
1495 if(gDynMemAlrm[bktIdx])
1497 // printf ("\nunder memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1498 SLock(&(bktCb->bucketLock));
1499 if(bktCb->listValidBktSet.count > 25)
1501 gDynMemAlrm[bktIdx] = FALSE;
1502 // printf ("\nrecoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1504 SUnlock(&(bktCb->bucketLock));
1510 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1512 // printf ("\nCHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1513 SLock(&(bktCb->bucketLock));
1514 if(bktCb->listValidBktSet.count < 15 )
1515 gDynMemAlrm[bktIdx] = TRUE;
1516 memoryCheckCounter = 0;
1517 SUnlock(&(bktCb->bucketLock));
1523 #endif /* USE_MALLOC */
1524 #endif /* SS_LOCKLESS_MEMORY */
1526 #ifdef SS_USE_ICC_MEMORY
1529 * Fun: Initialize region/pool tables
1531 * Desc: This function initializes MTSS-specific information
1532 * in the region/pool tables and configures the common
1533 * memory manager for use.
1542 Void * ssGetIccHdl(Region region)
1544 CmMmDynRegCb *dynRegCb;
1546 /* Klock work fix ccpu00148484 */
1547 if(!(region < SS_MAX_REGS))
1552 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1554 return (dynRegCb->iccHdl);
1556 #endif /* SS_USE_ICC_MEMORY */
1558 #ifdef T2K_MEM_LEAK_DBG
1559 RegionMemLeakInfo regMemLeakInfo;
1560 #endif /* T2K_MEM_LEAK_DBG */
1562 #ifdef SS_USE_WLS_MEM
1563 static S16 SPartitionWlsDynMem()
1566 uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1568 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1570 mtDynMemSz[i].startAddr = bktMemStrtAddr;
1571 bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1574 printf("\nGlobal Memory Info: \n");
1575 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1577 printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1582 static S16 SAllocateWlsDynMem()
1587 memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1589 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1591 reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1592 mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1594 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1595 #ifdef INTEL_L1_V19_10
1598 nWlsMacMemorySize+nWlsPhyMemorySize);
1600 (reqdMemSz + (4 * 1024 * 1024)));
1602 printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1603 SPartitionWlsDynMem();
1611 S16 SPartitionWlsMemory()
1616 uint64_t pageSize[1], hugePageSize;
1619 long int pageSize[1], hugePageSize;
1622 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1624 uint8_t *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1626 gethugepagesizes(pageSize,1);
1627 hugePageSize = pageSize[0];
1628 for (i = 0; i < 1; i++)
1630 mtRegMemSz[i].startAddr = regMemStrtAddr;
1631 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1633 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1634 reqdSz = numHugePg * hugePageSize;
1635 regMemStrtAddr += reqdSz;
1636 #ifdef T2K_MEM_LEAK_DBG
1637 /* Since wls is region 0 */
1638 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1639 regMemLeakInfo.numActvRegions++;
1640 #endif /* T2K_MEM_LEAK_DBG */
1642 //Store last region addr for validation
1643 mtRegMemSz[i].startAddr = regMemStrtAddr;
1647 #ifdef SS_MEM_WL_DEBUG
1648 Void SChkAddrValid(int type, int region, PTR ptr)
1650 char *tryPtr = NULL;
1651 if(type == 0) //Global
1653 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1654 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1656 printf("\n****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1662 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1664 printf("\n****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1670 #endif /* SS_MEM_WL_DEBUG */
1672 S16 SPartitionStaticMemory(uint8_t *startAddr)
1677 uint8_t *regMemStrtAddr = (uint8_t *)startAddr;
1680 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1681 for (i = 1; i < mtMemoCfg.numRegions; i++)
1683 mtRegMemSz[i].startAddr = regMemStrtAddr;
1684 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1685 regMemStrtAddr += reqdSz;
1686 #ifdef T2K_MEM_LEAK_DBG
1687 { /* Since region 1 onwards are used for non wls */
1688 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1689 regMemLeakInfo.numActvRegions++;
1691 #endif /* T2K_MEM_LEAK_DBG */
1695 S16 SAllocateWlsMem()
1703 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1704 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1706 for (i = 0; i < 1; i++)
1708 /* allocate space for the region */
1709 region = &mtMemoCfg.region[i];
1710 reqdMemSz += region->heapsize;
1711 mtRegMemSz[i].reqdSz += region->heapsize;
1713 for (j = 0; j < region->numBkts; j++)
1715 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1716 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1719 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1720 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1722 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1724 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1726 SPartitionWlsMemory();
1729 S16 SAllocateStaticMem()
1738 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1740 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1741 for (i = 1; i < mtMemoCfg.numRegions; i++)
1743 /* allocate space for the region */
1744 region = &mtMemoCfg.region[i];
1745 reqdMemSz += region->heapsize;
1746 mtRegMemSz[i].reqdSz += region->heapsize;
1748 for (j = 0; j < region->numBkts; j++)
1750 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1751 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1755 startAddr = malloc(reqdMemSz + (1024 * 10));
1757 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1759 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1761 SPartitionStaticMemory(startAddr);
1764 #endif /* INTEL_WLS */
1770 * Fun: Initialize region/pool tables
1772 * Desc: This function initializes MTSS-specific information
1773 * in the region/pool tables and configures the common
1774 * memory manager for use.
1783 S16 ssdInitMem(void)
1785 /* mt018.201 - added local variable */
1789 MtRegCfg *region = NULLP;
1790 Txt errMsg[256] = {'\0'};
1791 #ifdef SS_LOCKLESS_MEMORY
1792 CmMmDynRegCb *dynRegCb =0;
1793 #ifdef SS_USE_ICC_MEMORY
1795 CmMmGlobRegCb *globReg = NULLP;
1798 #endif /* SS_LOCKLESS_MEMORY */
1801 /* Use the default SSI memory manager if the ICC memory manager is not
1802 * avilable. If ICC memory manager is avilable, it will be used for
1803 * all sharable memory allocation and de-allocation */
1804 #ifdef SS_LOCKLESS_MEMORY
1805 #ifdef SS_USE_ICC_MEMORY
1806 #ifndef YS_PHY_3_8_2
1808 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1810 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1811 if(dynRegCb == NULLP)
1815 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1817 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1819 dynRegCb->region = i;
1820 cmMmDynRegInit(dynRegCb);
1821 printf("\niccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1824 /* ysIccHdl = dynRegCb->iccHdl; */
1827 /* Initialize the global region first */
1828 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1830 if(osCp.globRegCb == NULLP)
1835 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1837 #ifdef SS_USE_WLS_MEM
1838 SAllocateWlsDynMem();
1841 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1843 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1844 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1845 globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1846 printf("\nStarting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1849 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1851 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1854 if(globReg->bktTbl[i].startAddr == NULLP)
1858 globReg->bktTbl[i].poolId = i;
1859 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1860 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1861 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1864 globReg->numBkts = mtGlobMemoCfg.numBkts;
1865 cmMmGlobRegInit(globReg);
1867 /* Initialize the dynamic task regions and sanity check for the theshold
1869 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1871 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1872 if(dynRegCb == NULLP)
1876 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1878 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1879 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1880 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1881 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1883 #ifdef XEON_SPECIFIC_CHANGES
1888 dynRegCb->bktTbl[k].poolId = k;
1889 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1890 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1891 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1892 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1893 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1895 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1898 dynRegCb->region = i;
1899 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1900 cmMmDynRegInit(dynRegCb);
1902 #endif /* SS_USE_ICC_MEMORY */
1903 #endif /* SS_LOCKLESS_MEMORY */
1905 #ifdef T2K_MEM_LEAK_DBG
1907 /* Initailize mem leak tool memorys for debguing */
1908 regMemLeakInfo.numActvRegions=0;
1909 for(reg=0; reg <SS_MAX_REGS; reg++)
1911 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1912 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1913 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1914 regMemLeakInfo.regStartAddr[reg] = 0;
1917 regMemLeakInfo.regStartAddr[reg] = 0;
1918 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1920 printf("\n mutex init failed\n");
1926 /* Now allocate WLS memory */
1928 SAllocateStaticMem();
1930 /* mt018.201 - CMM Initialization */
1931 for (i = 0; i < mtMemoCfg.numRegions; i++)
1933 /* allocate space for the region control block */
1934 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1935 #ifdef TENB_RTLIN_CHANGES
1936 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1938 if (mtCMMRegCb[i] == NULLP)
1940 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1941 for the Region:%d control block\n",i);
1943 for (k = 0; k < i; k++)
1945 cmMmRegDeInit(mtCMMRegCb[k]);
1946 free(mtCMMRegCfg[k]->vAddr);
1947 free(mtCMMRegCb[k]);
1948 free(mtCMMRegCfg[k]);
1953 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1954 #ifdef TENB_RTLIN_CHANGES
1955 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1957 if (mtCMMRegCfg[i] == NULLP)
1959 for (k = 0; k < i; k++)
1961 cmMmRegDeInit(mtCMMRegCb[k]);
1962 free(mtCMMRegCfg[k]->vAddr);
1963 free(mtCMMRegCb[k]);
1964 free(mtCMMRegCfg[k]);
1966 free(mtCMMRegCb[i]);
1971 /* allocate space for the region */
1972 region = &mtMemoCfg.region[i];
1973 mtCMMRegCfg[i]->size = region->heapsize;
1974 for (j = 0; j < region->numBkts; j++)
1976 /* mt033.201 - addition for including the header size while computing the total size */
1977 #ifdef SSI_DEBUG_LEVEL1
1978 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1979 (region->bkt[j].numBlks);
1981 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1982 #endif /* SSI_DEBUG_LEVEL1 */
1985 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1987 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1990 #ifdef XEON_SPECIFIC_CHANGES
1991 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1992 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1994 #ifdef TENB_RTLIN_CHANGES
1995 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1998 if (mtCMMRegCfg[i]->vAddr == NULLP)
2000 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
2001 for the Region:%d \n",i);
2003 for (k = 0; k < i; k++)
2005 cmMmRegDeInit(mtCMMRegCb[k]);
2006 free(mtCMMRegCfg[k]->vAddr);
2007 free(mtCMMRegCb[k]);
2008 free(mtCMMRegCfg[k]);
2010 free(mtCMMRegCb[i]);
2011 free(mtCMMRegCfg[i]);
2016 /* set up the CMM configuration structure */
2017 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
2018 mtCMMRegCfg[i]->chFlag = 0;
2019 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
2020 mtCMMRegCfg[i]->numBkts = region->numBkts;
2022 for (j = 0; j < region->numBkts; j++)
2024 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
2025 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
2028 /* initialize the CMM */
2029 #ifdef SS_LOCKLESS_MEMORY
2030 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2032 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2033 #endif /* SS_LOCKLESS_MEMORY */
2035 for (k = 0; k < i; k++)
2037 cmMmRegDeInit(mtCMMRegCb[k]);
2038 free(mtCMMRegCfg[k]->vAddr);
2039 free(mtCMMRegCb[k]);
2040 free(mtCMMRegCfg[k]);
2042 free(mtCMMRegCfg[i]->vAddr);
2043 free(mtCMMRegCb[i]);
2044 free(mtCMMRegCfg[i]);
2049 /* initialize the STREAMS module */
2050 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
2051 if (region->regionId == 0)
2053 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
2055 for (k = 0; k < i; k++)
2057 cmMmRegDeInit(mtCMMRegCb[k]);
2058 free(mtCMMRegCfg[k]->vAddr);
2059 free(mtCMMRegCb[k]);
2060 free(mtCMMRegCfg[k]);
2062 cmMmRegDeInit(mtCMMRegCb[i]);
2063 free(mtCMMRegCfg[i]->vAddr);
2064 free(mtCMMRegCb[i]);
2065 free(mtCMMRegCfg[i]);
2070 /* mt001.301 : Additions */
2071 #ifdef SS_MEM_LEAK_STS
2073 #endif /* SS_MEM_LEAK_STS */
2081 * Fun: De-initialize region/pool tables
2083 * Desc: This function reverses the initialization in ssdInitMem().
2092 Void ssdDeinitMem(void)
2094 /* mt018.201 - added local variables */
2097 /* mt008.301 Additions */
2098 #ifdef SS_MEM_LEAK_STS
2099 cmDeinitMemLeakMdl();
2100 #endif /* SS_MEM_LEAK_STS */
2102 for (i = 0; i < mtMemoCfg.numRegions; i++)
2104 cmMmRegDeInit(mtCMMRegCb[i]);
2105 free(mtCMMRegCfg[i]->vAddr);
2106 free(mtCMMRegCb[i]);
2107 free(mtCMMRegCfg[i]);
2116 * Fun: Initialize task table
2118 * Desc: This function initializes MTSS-specific information
2119 * in the task table.
2128 S16 ssdInitTsk(void)
2130 /* mt001.301 : Additions */
2131 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2132 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2133 uint32_t tskInd = 0;
2134 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2138 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2139 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2140 /* initialize system task information */
2141 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2143 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2145 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2152 * Fun: Deinitialize task table
2154 * Desc: This function reverses the initialization perfomed in
2164 Void ssdDeinitTsk(void)
2171 #ifdef SS_DRVR_SUPPORT
2174 * Fun: Initialize driver task table
2176 * Desc: This function initializes MTSS-specific information
2177 * in the driver task table.
2186 S16 ssdInitDrvr(void)
2190 pthread_attr_t attr;
2195 /* initialize the dependent portion of the driver task entries */
2196 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2198 osCp.drvrTskTbl[i].dep.flag = FALSE;
2202 /* create pipe for communication between SSetIntPend() and
2203 * the isTskHdlr thread.
2205 if (pipe(osCp.dep.isFildes) != 0)
2211 /* create the isTskHdlr thread */
2212 pthread_attr_init(&attr);
2213 /* mt021.201 - Addition to set stack size */
2214 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2215 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2216 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2217 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2219 /* mt020.201 - Addition for destroying thread attribute object attr */
2220 pthread_attr_destroy(&attr);
2226 /*mt014.301 : 4GMX release related changes*/
2227 #ifdef SS_4GMX_UCORE
2235 /* mt020.201 - Addition for destroying thread attribute object attr */
2236 pthread_attr_destroy(&attr);
2245 * Fun: Deinitialize driver information
2247 * Desc: This function reverses the initialization performed in
2257 Void ssdDeinitDrvr(void)
2259 /* mt008.301: Terminate the Driver Task on exit */
2260 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2263 TL_Close(AppContext.hUAII);
2264 if (clusterMode == RADIO_CLUSTER_MODE)
2266 TL_Close(AppContext.hUAII_second);
2272 #endif /* SS_DRVR_SUPPORT */
2277 * Fun: Initialize timer table
2279 * Desc: This function initializes MTSS-specific information
2280 * in the timer table.
2289 S16 ssdInitTmr(void)
2291 pthread_attr_t attr;
2292 struct sched_param param_sched;
2293 /* mt010.21: addition */
2295 #ifdef SS_MULTICORE_SUPPORT
2297 #endif /* SS_MULTICORE_SUPPORT */
2298 #ifdef SS_THR_REG_MAP
2299 uint32_t threadCreated = FALSE;
2300 #endif /* SS_THR_REG_MAP */
2304 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2305 /* mt010.21: addition */
2306 osCp.dep.tmrTqCp.nxtEnt = 0;
2307 for (i=0; i< SS_MAX_TMRS; i++)
2309 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2312 #ifdef SS_MULTICORE_SUPPORT
2313 sTsk = ssdAddTmrSTsk();
2318 #endif /* SS_MULTICORE_SUPPORT */
2319 /* create the timer handler thread */
2320 pthread_attr_init(&attr);
2321 /* mt021.201 - Addition to set stack size */
2322 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2323 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2324 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2325 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2326 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2327 pthread_attr_setschedparam(&attr, ¶m_sched);
2330 #ifdef SS_THR_REG_MAP
2331 /* When the thread is created, we check for the memory mapping table if
2332 * threadId can be placed in thread memory map table. If it is not able to place
2333 * threadId is stored in tmporary array. Once thread is created successful,
2334 * thread_cancel is sent for each thread which are created before. All the
2335 * threads are made to wait on sema which is cancel point for thread.
2337 while(threadCreated == FALSE)
2340 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2342 /* mt020.201 - Addition for destroying thread attribute object attr */
2343 pthread_attr_destroy(&attr);
2348 #ifdef SS_THR_REG_MAP
2349 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2352 #endif /* SS_THR_REG_MAP */
2353 #ifdef SS_MEM_WL_DEBUG
2354 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2357 /* mt020.201 - Addition for destroying thread attribute object attr */
2358 pthread_attr_destroy(&attr);
2367 * Fun: Deinitialize timer table
2369 * Desc: This function reverses the initialization performed in
2379 Void ssdDeinitTmr(void)
2381 #ifdef SS_MULTICORE_SUPPORT
2384 #endif /* SS_MULTICORE_SUPPORT */
2387 #ifdef SS_MULTICORE_SUPPORT
2388 ret = SLock(&osCp.sTskTblLock);
2392 #if (ERRCLASS & ERRCLS_DEBUG)
2393 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2394 "Could not lock system task table");
2398 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2399 /* clean up the system task entry */
2403 SDestroyLock(&sTsk->lock);
2404 ssDestroyDmndQ(&sTsk->dQ);
2407 /* make this entry available in the system task table */
2408 sTsk->nxt = osCp.nxtSTskEntry;
2409 osCp.nxtSTskEntry = 0;
2413 /* unlock the system task table */
2414 SUnlock(&osCp.sTskTblLock);
2416 #endif /* SS_MULTICORE_SUPPORT */
2417 /* mt008.301: Terminate the timer thread on exit */
2418 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2428 * Desc: Pre-tst() initialization.
2437 S16 ssdInitLog(void)
2439 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2443 pthread_attr_t attr;
2446 #endif /* CONSTDIO */
2451 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2456 osCp.dep.conInFp = (FILE *) stdin;
2457 osCp.dep.conOutFp = (FILE *) stdout;
2458 /* added compile time flag CONRD: mt017.21 */
2462 /* disable canonical input processing */
2463 fd = fileno(osCp.dep.conInFp);
2464 if ((tcgetattr(fd, &tio)) != 0)
2466 printf("\nError: disable canonical input processing\n");
2470 tio.c_lflag &= ~ICANON;
2471 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2472 tio.c_cc[VTIME] = 0;
2473 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2475 printf("\nError: while tcsetattr() processing\n");
2479 #endif /* CONSTDIO */
2482 /* set up the input fd to block when no data is available */
2483 fd = fileno(osCp.dep.conInFp);
2484 flags = fcntl(fd, F_GETFL, &flags);
2485 flags &= ~O_NONBLOCK;
2486 if (fcntl(fd, F_SETFL, flags) == -1)
2488 printf("\nError: while fcntl processing\n");
2493 /* create the console handler thread */
2494 pthread_attr_init(&attr);
2495 /* mt021.201 - Addition to set stack size */
2496 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2497 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2498 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2501 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2503 /* mt020.201 - Addition for destroying thread attribute object attr */
2504 pthread_attr_destroy(&attr);
2506 printf("\nError: Logging Thread creation failed \n");
2510 /* mt020.201 - Addition for destroying thread attribute object attr */
2511 pthread_attr_destroy(&attr);
2525 * Desc: This function reverses the initialization performed in
2535 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2536 Void ssdDeinitLog(void)
2538 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2541 /* mt008.301: Terminate the console reader on exit */
2542 while(pthread_cancel(osCp.dep.conHdlrTID));
2548 /* mt001.301 : Additions */
2552 S16 ssdInitWatchDog(uint16_t port)
2555 Txt prntBuf[PRNTSZE];
2558 #ifdef SS_WATCHDOG_IPV6
2559 struct sockaddr_in6 tmpaddr;
2561 struct sockaddr_in tmpaddr;
2562 #endif /* SS_WATCHDOG_IPV6 */
2563 #ifdef SS_MULTIPLE_PROCS
2564 ProcId procId = SS_WD_WDPROC;
2565 if (SAddProcIdLst(1, &procId) != ROK)
2569 #endif /* SS_MULTIPLE_PROCS */
2572 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2574 /* Create a watch dog system task */
2575 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2577 /* Create a watch dog reveiver system task */
2578 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2580 /* Register and attach watch dog TAPA task */
2581 #ifdef SS_MULTIPLE_PROCS
2582 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2583 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2585 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2586 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2587 #endif /* SS_MULTIPLE_PROCS */
2588 /* Register and attach watch dog receiver TAPA task */
2589 #ifdef SS_MULTIPLE_PROCS
2590 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2591 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2593 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2594 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2595 #endif /* SS_MULTIPLE_PROCS */
2597 #ifndef SS_MULTIPLE_PROCS
2598 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2599 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2601 osCp.wdCp.watchDgPst.srcProcId = procId;
2602 osCp.wdCp.watchDgPst.dstProcId = procId;
2603 #endif /* SS_MULTIPLE_PROCS */
2605 /* Initialise the pst structure */
2606 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2607 /* Initialize the watch dog timer resolution default is 1 sec */
2609 cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2610 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2611 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2612 for(idx = 0; idx < 1; idx++)
2614 osCp.wdCp.watchDgTs[idx].first = NULLP;
2615 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2617 #ifdef SS_MULTIPLE_PROCS
2618 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2620 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2621 #endif /* SS_MULTIPLE_PROCS */
2623 /* Create the watch dog receiver socket */
2624 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2625 if(osCp.wdCp.globWd.sock == -1)
2627 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2631 #ifdef SS_WATCHDOG_IPV6
2632 tmpaddr.sin6_len = sizeof(tmpadDr);
2633 tmpaddr.sin6_family = AF_INET6;
2634 tmpaddr.sin6_addr = in6addr_any;
2635 tmpaddr.sin6_port = htons(port);
2637 tmpaddr.sin_family = AF_INET;
2638 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2639 tmpaddr.sin_port = htons(port);
2640 #endif /* SS_WATCHDOG_IPV6 */
2642 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2645 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2649 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2653 #ifndef SS_MULTIPLE_PROCS
2654 pst.srcProcId = SFndProcId();
2655 pst.dstProcId = SFndProcId();
2657 pst.srcProcId = procId;
2658 pst.dstProcId = procId;
2659 #endif /* SS_MULTIPLE_PROCS */
2660 pst.event = EVTSSHRTBTREQ;
2661 ssdInitWatchDgPst(&pst);
2662 SPstTsk(&pst, mBuf);
2667 S16 ssdInitWatchDgPst(Pst *pst)
2670 pst->selector = SS_LOOSE_COUPLING;
2672 pst->region = DFLT_REGION; /* region */
2673 pst->pool = DFLT_POOL; /* pool */
2675 pst->prior = PRIOR0; /* priority */
2676 pst->route = RTESPEC; /* route */
2678 pst->dstEnt = ENTHB; /* destination entity */
2680 pst->srcEnt = ENTDW; /* source entity */
2686 #ifdef SS_MULTIPLE_PROCS
2687 S16 ssdWatchDgActvTmr
2694 S16 ssdWatchDgActvTmr(Void)
2695 #endif /* SS_MULTIPLE_PROCS */
2698 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2703 Void ssdWatchDgTmrEvt
2705 PTR cb, /* control block */
2706 S16 event /* timer number */
2709 /* mt003.301 Fixed warings */
2713 Txt prntBuf[PRNTSZE];
2722 SPrint("Timer Heartbeat Request Expired");
2724 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2729 SLock(&osCp.wdCp.wdLock);
2730 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2732 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2734 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2736 if(osCp.wdCp.globWd.callback != 0)
2738 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2742 SUnlock(&osCp.wdCp.wdLock);
2744 if(!osCp.wdCp.globWd.watchdogStop)
2746 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2747 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2757 Void ssdStartWatchDgTmr
2768 Txt prntBuf[PRNTSZE];
2772 /* mt003.301 Modifications */
2775 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2776 if(event == SS_TMR_HRTBT)
2778 SPrint("\nSTART SS_TMR_HRTBT");
2785 SLock(&osCp.wdCp.wdLock);
2786 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2788 osCp.wdCp.globWd.wdsta[i].status = 0;
2790 SUnlock(&osCp.wdCp.wdLock);
2792 arg.tq = osCp.wdCp.watchDgTs;
2793 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2794 arg.timers = osCp.wdCp.watchDgTmr;
2795 arg.cb = (PTR)NULLP;
2797 arg.wait = osCp.wdCp.globWd.timeout = wait;
2805 Void ssdStopWatchDgTmr
2814 Txt prntBuf[PRNTSZE];
2818 /* mt003.301 Modifications */
2821 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2822 if(event == SS_TMR_HRTBT)
2824 SPrint("STOP SS_TMR_HRTBT");
2828 SLock(&osCp.wdCp.wdLock);
2829 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2831 osCp.wdCp.globWd.wdsta[i].status = 0;
2833 SUnlock(&osCp.wdCp.wdLock);
2836 arg.tq = osCp.wdCp.watchDgTs;
2837 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2838 arg.timers = osCp.wdCp.watchDgTmr;
2839 arg.cb = (PTR)NULLP;
2858 Txt prntBuf[PRNTSZE];
2860 struct sockaddr_in tmpaddr;
2861 char hbMsg[SS_WD_HB_MSG_SIZE];
2868 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2872 /* Pack the message */
2873 strcpy(hbMsg, "<HB>REQ</HB>");
2875 /* Send the heartbeat messages to all the configured nodes */
2876 SLock(&osCp.wdCp.wdLock);
2877 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2879 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2884 /* Identify the destination node */
2885 #ifdef SS_WATCHDOG_IPV6
2886 tmpaddr.sin6_len = sizeof(tmpaddr);
2887 tmpaddr.sin6_family = AF_INET6;
2888 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2889 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2891 tmpaddr.sin_family = AF_INET;
2892 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2893 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2894 #endif /* SS_WATCHDOG_IPV6 */
2896 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2900 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2901 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2908 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2913 SUnlock(&osCp.wdCp.wdLock);
2918 #endif /* SS_WATCHDOG */
2922 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2928 * Desc: This function gets command line options.
2937 static Void mtGetOpts(void)
2944 FILE *memOpt; /* memory options file pointer */
2947 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2953 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2955 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2961 #ifdef SS_LOCKLESS_MEMORY
2976 osCp.dep.fileOutFp = (FILE *)NULLP;
2978 /* initialize memOpt */
2979 memOpt = (FILE *) NULLP;
2986 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2991 /* mt001.301 : Additions */
2992 #ifdef SS_MEM_LEAK_STS
2994 cmMemOpenMemLkFile(msOptArg);
2998 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3001 fileBasedMemCfg = TRUE;
3002 memOpt = fopen(msOptArg, "r");
3004 /* if file does not exist or could not be opened then use the
3005 * default memory configuration as defined in mt_ss.h
3007 if (memOpt == (FILE *) NULLP)
3009 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3010 be opened, using default mem configuration\n", msOptArg);
3015 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3017 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3023 case 0: /*** INPUT: Number of regions ***/
3024 sscanf(line, "%ld", (long *) &numReg);
3025 mtMemoCfg.numRegions = numReg;
3026 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3028 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3034 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3035 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3036 if(numBkts > MT_MAX_BKTS)
3038 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3042 if(numPools > SS_MAX_POOLS_PER_REG)
3044 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3049 * Delay updation from local variable to global
3050 * structure of number of regions and heap data to
3051 * counter error conditions present above.
3053 for(idx = 0; idx < cfgNumRegs; idx++)
3055 mtMemoCfg.region[idx].numBkts = numBkts;
3056 cfgRegInfo[idx].region = idx;
3057 cfgRegInfo[idx].numPools = numPools;
3059 * Initialize the pool info as static type with size zero
3061 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3063 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3064 cfgRegInfo[idx].pools[poolIdx].size = 0;
3069 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3070 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3072 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3074 if(bktIdx >= numBkts)
3076 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3081 mtBktInfo[bktIdx].blkSize = bktSz;
3083 if(bktUpdtCnt == numBkts)
3085 i++; /*done reading bkt info, start reading individual region info*/
3089 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3090 sscanf(line,"%ld",(long *) ®Id);
3091 if(regId >= mtMemoCfg.numRegions)
3093 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3094 #ifndef XEON_SPECIFIC_CHANGES
3099 mtMemoCfg.region[regId].regionId = regId;
3102 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3103 if(bktUpdtCnt < numBkts)
3105 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3106 if(bktIdx >= numBkts)
3108 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3113 if(bktIdx < MT_MAX_BKTS)
3115 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3116 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3117 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3118 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3121 if(bktUpdtCnt == numBkts)
3128 case 5: /* INPUT: Heapsize ***/
3129 sscanf(line, "%ld", (long *) &heapSz);
3130 mtMemoCfg.region[regId].heapsize = heapSz;
3132 if(regUpdtCnt != mtMemoCfg.numRegions)
3141 #ifdef SS_LOCKLESS_MEMORY
3143 sscanf(line, "%ld", (long *) &numBkts);
3144 mtGlobMemoCfg.numBkts = numBkts;
3145 #ifndef XEON_SPECIFIC_CHANGES
3146 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3149 #ifdef XEON_SPECIFIC_CHANGES
3150 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3151 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3152 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3154 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3157 mtDynMemoCfg.region[idx].regionId = idx;
3158 mtDynMemoCfg.region[idx].numBkts = numBkts;
3166 if(bktUpdtCnt < numBkts)
3168 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3169 (long *) &bktSz, (long *) &bktNum,
3170 (long *) &bktSetSize, (long *) &bktRelThr,
3171 (long *) &bktAqurThr);
3172 /* Klock work fix ccpu00148484 */
3173 if(bktIdx < SS_MAX_POOLS_PER_REG)
3175 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3176 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3177 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3178 #ifdef XEON_SPECIFIC_CHANGES
3179 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3180 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3181 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3183 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3185 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3191 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3193 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3194 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3195 #ifdef XEON_SPECIFIC_CHANGES
3196 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3197 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3198 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3204 #ifdef XEON_SPECIFIC_CHANGES
3205 if(bktUpdtCnt == numBkts)
3211 case 8: /* INPUT: Global Heapsize ***/
3212 sscanf(line, "%ld", (long *) &heapSz);
3213 mtGlobMemoCfg.heapSize = heapSz;
3214 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3222 memConfigured = FALSE;
3226 memConfigured = TRUE;
3234 /* mt028.201: modification: multiple procs support related changes */
3235 #ifndef SS_MULTIPLE_PROCS
3238 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3240 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3243 #else /* SS_MULTIPLE_PROCS */
3247 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3249 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3251 SAddProcIdLst(1, &procId);
3254 #endif /* SS_MULTIPLE_PROCS */
3258 osCp.configFilePath = msOptArg;
3282 * Desc: Get options from command line
3284 * Ret: option - success
3286 * EOF - end of options
3288 * Notes: Handles command lines like the following
3291 * then command line should look like this...
3292 * -a foo -b foo1 -c -d foo
3296 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3301 * nloops = atoi(msArgv[msOptInd]);
3304 * state1 = atoi(msArgv[msOptInd]);
3316 int argc, /* argument count */
3317 char **argv, /* argument value */
3318 char *opts /* options */
3321 /* mt020.201 - Removed for no command line */
3329 /* mt020.201 - Addition for no command line */
3341 /*mt013.301 : Changes as per coding standards*/
3342 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3348 if (!strcmp(argv[msOptInd], "--"))
3353 else if (argv[msOptInd][0] != '-')
3361 c = argv[msOptInd][sp];
3362 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3364 if (argv[msOptInd][++sp] == '\0')
3375 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3378 if (++msOptInd >= (S16) argc)
3383 else msOptArg = argv[msOptInd++];
3390 if (argv[msOptInd][++sp] == '\0')
3402 #endif /* NOCMDLINE */
3410 * Desc: This function starts system services execution; the
3411 * permanent tasks are started and the system enters a
3428 /* mt025.201 - Modification for adding lock to timer handler */
3429 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3431 sem_post(&osCp.dep.ssStarted);
3440 * indirect interface functions to system services service user
3446 * Fun: ssdAttachTTsk
3448 * Desc: This function sends the initial tick message to a TAPA
3449 * task if the task is a permanent task.
3460 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3467 if (tTsk->tskType == SS_TSK_PERMANENT)
3469 /* Send a permanent tick message to this task, to start
3472 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3475 #if (ERRCLASS & ERRCLS_DEBUG)
3476 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3481 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3482 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3484 /* set up post structure */
3485 /* mt028.201: modification: multiple procs support related changes */
3486 #ifndef SS_MULTIPLE_PROCS
3487 mInfo->pst.dstProcId = SFndProcId();
3488 mInfo->pst.srcProcId = SFndProcId();
3489 #else /* SS_MULTIPLE_PROCS */
3490 mInfo->pst.dstProcId = tTsk->proc;
3491 mInfo->pst.srcProcId = tTsk->proc;
3492 #endif /* SS_MULTIPLE_PROCS */
3493 mInfo->pst.selector = SEL_LC_NEW;
3494 mInfo->pst.region = DFLT_REGION;
3495 mInfo->pst.pool = DFLT_POOL;
3496 mInfo->pst.prior = PRIOR3;
3497 mInfo->pst.route = RTESPEC;
3498 mInfo->pst.event = 0;
3499 mInfo->pst.dstEnt = tTsk->ent;
3500 mInfo->pst.dstInst = tTsk->inst;
3501 mInfo->pst.srcEnt = tTsk->ent;
3502 mInfo->pst.srcInst = tTsk->inst;
3504 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3505 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3511 #if (ERRCLASS & ERRCLS_DEBUG)
3512 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3513 "Could not write to demand queue");
3526 * Fun: ssdDetachTTsk
3528 * Desc: Does nothing.
3539 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3549 * Fun: ssdCreateSTsk
3551 * Desc: This function creates a system task. A thread is started
3552 * on the system task handler function defined later.
3563 SsSTskEntry *sTsk /* pointer to system task entry */
3567 pthread_attr_t attr;
3568 /* struct sched_param param_sched;*/
3570 #ifdef SS_THR_REG_MAP
3571 uint32_t threadCreated = FALSE;
3576 #ifdef SS_SINGLE_THREADED
3577 /* mt001.301 : Additions */
3579 #ifdef SS_MULTICORE_SUPPORT
3580 if (osCp.numSTsks > 1)
3582 if (osCp.numSTsks > 0)
3583 #endif /* SS_MULTICORE_SUPPORT */
3585 #ifdef SS_MULTICORE_SUPPORT
3586 if (osCp.numSTsks > 3)
3588 if (osCp.numSTsks > 2)
3589 #endif /* SS_MULTICORE_SUPPORT */
3590 #endif /* SS_WATCHDOG */
3597 /* set the current executing entity and instance IDs to
3598 * 'not configured'. create the lock to access them.
3600 sTsk->dep.ent = ENTNC;
3601 sTsk->dep.inst = INSTNC;
3604 /* create the thread */
3605 pthread_attr_init(&attr);
3606 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3608 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3609 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3610 if (sTsk->tskPrior == 0)
3612 printf("\nCreating RT thread #######################\n");
3613 #ifdef SS_THR_REG_MAP
3614 /* When the thread is created, we check for the memory mapping table if
3615 * threadId can be placed in thread memory map table. If it is not able to place
3616 * threadId is stored in tmporary array. Once thread is created successful,
3617 * thread_cancel is sent for each thread which are created before. All the
3618 * threads are made to wait on sema which is cancel point for thread.
3620 while(threadCreated == FALSE)
3623 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3626 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3627 pthread_attr_destroy(&attr);
3629 #if (ERRCLASS & ERRCLS_DEBUG)
3630 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3635 #ifdef SS_THR_REG_MAP
3636 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3644 #ifdef SS_THR_REG_MAP
3645 /* When the thread is created, we check for the memory mapping table if
3646 * threadId can be placed in thread memory map table. If it is not able to place
3647 * threadId is stored in tmporary array. Once thread is created successful,
3648 * thread_cancel is sent for each thread which are created before. All the
3649 * threads are made to wait on sema which is cancel point for thread.
3651 while(threadCreated == FALSE)
3654 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3658 /* mt020.201 - Addition for destroying thread attribute object attr */
3659 pthread_attr_destroy(&attr);
3661 #if (ERRCLASS & ERRCLS_DEBUG)
3662 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3667 #ifdef SS_THR_REG_MAP
3668 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3675 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3676 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3678 static uint32_t stLwpId = 3;
3679 sTsk->dep.lwpId = ++stLwpId;
3681 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3683 /* mt020.201 - Addition for destroying thread attribute object attr */
3684 pthread_attr_destroy(&attr);
3693 pthread_attr_t* attr,
3694 void *(*start_routine) (void *),
3699 #ifdef SS_THR_REG_MAP
3700 uint32_t threadCreated = FALSE;
3703 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3704 /* Klock work fix ccpu00148484 */
3705 if(threadArg == NULLP)
3709 threadArg->argument = arg;
3710 threadArg->start_routine = start_routine;
3713 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3715 #ifdef SS_THR_REG_MAP
3716 /* When the thread is created, we check for the memory mapping table if
3717 * threadId can be placed in thread memory map table. If it is not able to place
3718 * threadId is stored in tmporary array. Once thread is created successful,
3719 * thread_cancel is sent for each thread which are created before. All the
3720 * threads are made to wait on sema which is cancel point for thread.
3722 while(threadCreated == FALSE)
3725 /*pthreadCreateHdlr */
3726 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3731 #ifdef SS_THR_REG_MAP
3732 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3743 * Fun: Set Pthread Attributes
3745 * Desc: This function is used to set various explicit
3746 * pthread attributes like, priority scheduling,etc
3756 static S16 ssdSetPthreadAttr
3759 pthread_attr_t *attr
3762 struct sched_param param;
3765 SMemSet(¶m, 0, sizeof(param));
3767 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3768 param.sched_priority = 100 - 1 - tskPrior;
3770 param.sched_priority = 100 - 10 - tskPrior;
3773 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3774 /* TODO:: This can be avoided by reducing the priority
3775 * of iccserv thread in l1_master.sh*/
3777 if (clusterMode == RADIO_CLUSTER_MODE)
3779 if(tskPrior == PRIOR1)
3781 param.sched_priority = 91;
3788 printf("\nSet priority %u\n", param.sched_priority);
3790 /* Set Scheduler to explicit, without this non of the below
3791 pthread attr works */
3792 #ifdef TENB_RTLIN_CHANGES
3793 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3796 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3797 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3798 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3799 #ifdef TENB_RTLIN_CHANGES
3800 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3802 pthread_attr_setschedparam(attr, ¶m);
3806 } /* ssdSetPthreadAttr */
3808 /************* multi-core support **************/
3809 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3810 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3814 * Fun: Get the current core/cpu affinity for a thread/lwp
3816 * Desc: This function is used to get the current processor/core
3817 * affinity for a a system task (thread/lwp). It sets the
3818 * affinity based on the mode supplied by the caller.
3821 * RFAILED - failed, general (optional)
3830 SSTskId *tskId, /* filled in with system task ID */
3831 uint32_t *coreId /* the core/processor id to which the affinity is set */
3841 uint32_t cpuInd = 0;
3842 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3845 uint32_t lwpId = *tskId;
3849 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3851 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3853 tId = osCp.sTskTbl[tskInd].dep.tId;
3858 /* if tskId is not found in the tskTbl */
3859 if (tskInd == SS_MAX_STSKS)
3861 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3866 /* initialize the cpu mask */
3869 /* set thread affinity for linux */
3870 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3872 #if (ERRCLASS & ERRCLS_DEBUG)
3873 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3876 } /* end if pthread_setaffinity fails */
3878 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3880 if (CPU_ISSET (cpuInd, & cpuSet))
3889 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3891 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3893 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3898 /* if tskId is not found in the tskTbl */
3899 if (tskInd == SS_MAX_STSKS)
3901 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3905 /* set thread affinity for Solaris */
3906 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3908 #if (ERRCLASS & ERRCLS_DEBUG)
3909 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3912 } /* end if processor_bind fails */
3915 #endif /* SS_LINUX */
3919 } /* ssdGetAffinity */
3924 * Fun: Set the core/cpu affinity for a thread/lwp
3926 * Desc: This function is used to set processor/core affinity for a
3927 * a system task (thread/lwp). It sets the affinity based on the
3928 * mode supplied by the caller.
3931 * RFAILED - failed, general (optional)
3940 SSTskId *tskId, /* filled in with system task ID */
3941 uint32_t coreId /* the core/processor id to which the affinity has to be set */
3945 uint32_t tskInd = 0;
3950 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3953 uint32_t lwpId = *tskId;
3959 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3961 /* Here tskId can not be used as index as the task may be terminated if
3962 there is a TERM even for that tsk, thus breaking the task Id numbering
3964 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3966 tId = osCp.sTskTbl[tskInd].dep.tId;
3971 /* if tskId is not found in the tskTbl */
3972 if (tskInd == SS_MAX_STSKS)
3974 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3978 /* initialize the cpu mask */
3981 /* set the cpu mask */
3982 CPU_SET(coreId, &cpuSet);
3984 /* set thread affinity for linux */
3985 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3987 #if (ERRCLASS & ERRCLS_DEBUG)
3988 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
3991 } /* end if pthread_setaffinity fails */
3995 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3997 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
3998 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4000 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4005 /* if tskId is not found in the tskTbl */
4006 if (tskInd == SS_MAX_STSKS)
4008 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4012 /* set thread affinity for Solaris */
4013 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4015 #if (ERRCLASS & ERRCLS_DEBUG)
4016 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4019 } /* end if processor_bind fails */
4022 #endif /* SS_LINUX */
4024 } /* ssdSetAffinity */
4026 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4027 /************ end multi-core support *************/
4032 * Fun: ssdDestroySTsk
4034 * Desc: This function destroys a system task. A terminate
4035 * event message is sent to the thread function.
4046 SsSTskEntry *sTsk /* pointer to system task entry */
4055 /* we send a message to this system task to tell it to die */
4056 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4059 #if (ERRCLASS & ERRCLASS_DEBUG)
4060 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4066 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4067 mInfo->eventInfo.event = SS_EVNT_TERM;
4069 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4073 #if (ERRCLASS & ERRCLASS_DEBUG)
4074 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4075 "Could not write to demand queue");
4085 /* mt023.201 - Added SThreadYield function to yield CPU
4089 * Desc: This function defers thread execution to any other ready
4100 S16 SThreadYield(void)
4104 /* mt024.201 - seperated Linux and other UNIX implementations
4110 /* Set sleep value to 0 to yield CPU */
4114 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4116 #else /* other UNICes */
4118 return (sleep(0) == 0 ? ROK : RFAILED);
4120 #endif /* SS_LINUX */
4127 * Fun: Register timer
4129 * Desc: This function is used to register a timer
4130 * function for the service user. System services
4131 * will invoke the timer activation function
4132 * passed to it at the specified intervals.
4136 * Notes: Timing is handled by the common timers. The
4137 * ticks are handled by a thread that uses
4138 * nanosleep() and thus timing precision will not
4146 SsTmrEntry *tmr /* pointer to timer entry */
4154 /* initialize common timers */
4155 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4158 /* start the timer */
4159 arg.tq = osCp.dep.tmrTq;
4160 arg.tqCp = &osCp.dep.tmrTqCp;
4161 arg.timers = tmr->dep.timers;
4166 arg.max = TMR_DEF_MAX;
4167 arg.wait = tmr->interval;
4177 * Fun: Deregister timer
4179 * Desc: This function is used to deregister a timer function.
4190 SsTmrEntry *tmr /* pointer to timer entry */
4198 /* stop the timer */
4199 arg.tq = osCp.dep.tmrTq;
4200 arg.tqCp = &osCp.dep.tmrTqCp;
4201 arg.timers = tmr->dep.timers;
4206 arg.max = TMR_DEF_MAX;
4207 arg.wait = tmr->interval;
4217 * Fun: Critical error
4219 * Desc: This function is called when a critical error occurs.
4230 Seq seq, /* sequence number */
4231 Reason reason /* reset reason */
4241 /* get calling task ID */
4242 tId = pthread_self();
4245 /* set up the message to display */
4246 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4247 "reason = %d\n\n", (uint8_t)tId, seq, reason);
4251 /* delete all system tasks */
4252 for (i = 0; i < SS_MAX_STSKS; i++)
4254 if (osCp.sTskTbl[i].used
4255 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4257 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4263 pthread_exit(NULLP);
4266 /* won't reach here */
4275 * Desc: This function is called to log an error.
4286 Ent ent, /* Calling layer's entity id */
4287 Inst inst, /* Calling layer's instance id */
4288 ProcId procId, /* Calling layer's processor id */
4289 Txt *file, /* file name where error occured */
4290 S32 line, /* line in file where error occured */
4291 ErrCls errCls, /* error class */
4292 ErrCode errCode, /* layer unique error code */
4293 ErrVal errVal, /* error value */
4294 Txt *errDesc /* description of error */
4307 /* get calling task ID */
4309 tId = pthread_self();
4315 case ERRCLS_ADD_RES:
4316 errClsMsg = "ERRCLS_ADD_RES";
4319 case ERRCLS_INT_PAR:
4320 errClsMsg = "ERRCLS_INT_PAR";
4324 errClsMsg = "ERRCLS_DEBUG";
4327 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4329 errClsMsg = "ERRCLS_FTHA";
4333 errClsMsg = "INVALID ERROR CLASS!";
4338 /*mt009.301 Fixed 64BIT compilation warnings*/
4341 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4342 "file: %s line: %03d errcode: %05d errcls: %s\n"
4343 "errval: %05d errdesc: %s\n",
4344 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4347 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4348 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4349 "errval: %05ld errdesc: %s\n",
4350 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4352 SDisplay(0, errBuf);
4353 /* mt001.301 : Additions */
4354 #ifdef SS_LOGGER_SUPPORT
4356 #endif /* SS_LOGGER_SUPPORT */
4360 /* debug errors halt the system */
4361 if (errCls == ERRCLS_DEBUG)
4363 /* mt001.301 : Additions */
4364 #ifdef SS_LOGGER_SUPPORT
4366 #endif /* SS_LOGGER_SUPPORT */
4367 /* delete all system tasks */
4368 for (i = 0; i < SS_MAX_STSKS; i++)
4370 if (osCp.sTskTbl[i].used
4371 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4373 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4379 pthread_exit(NULLP);
4391 * Fun: Register driver task
4393 * Desc: This function is called to register the handlers for a
4405 SsDrvrTskEntry *drvrTsk /* driver task entry */
4412 /* mt001.30 : Additions */
4415 * Fun: Deregister driver task
4417 * Desc: This function is called to deregister the handlers for a
4429 SsDrvrTskEntry *drvrTsk /* driver task entry */
4442 * mt003.301 Additions - SDeRegTTsk fix
4444 #ifdef SS_MULTIPLE_PROCS
4451 #else /*SS_MULTIPLE_PROCS*/
4457 #endif /*SS_MULTIPLE_PROCS*/
4459 #ifdef SS_MULTIPLE_PROCS
4472 /* We check the sTsk element; if it is not NULLP, the
4473 * task is attached. So we have to detach it before
4474 * deregistering the task.
4476 ret = SLock(&osCp.sTskTblLock);
4479 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4482 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4485 #if (ERRCLASS & ERRCLS_DEBUG)
4486 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4488 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4490 #if (ERRCLASS & ERRCLS_DEBUG)
4491 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4499 #ifdef SS_MULTIPLE_PROCS
4501 if (tTsk->initTsk != NULLP)
4504 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4507 &(osCp.tTskTbl[idx].xxCb));
4509 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4512 &(osCp.tTskTbl[idx].xxCb));
4513 #endif /* USE_MEMCAL */
4515 #endif /* SS_MULTIPLE_PROCS */
4517 if (tTsk->sTsk != NULLP)
4521 sTsk->dep.ent = ent;
4522 sTsk->dep.inst = inst;
4524 for (n = 0; n < SS_MAX_TTSKS; n++)
4526 if (sTsk->tTsks[n] == idx)
4528 sTsk->tTsks[n] = SS_INVALID_IDX;
4534 /* call the implementation to detach the task */
4535 ssdDetachTTsk(tTsk);
4537 sTsk->dep.ent = ENTNC;
4538 sTsk->dep.inst = INSTNC;
4541 /* Now we empty the entry for this task and update the table
4544 #ifdef SS_MULTIPLE_PROCS
4545 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4546 #else /* SS_MULTIPLE_PROCS */
4547 osCp.tTskIds[ent][inst] = SS_TSKNC;
4548 #endif /* SS_MULTIPLE_PROCS */
4551 #ifdef SS_MULTIPLE_PROCS
4552 tTsk->proc = PROCNC;
4553 #endif /* SS_MULTIPLE_PROCS */
4555 tTsk->inst = INSTNC;
4556 tTsk->tskType = TTUND;
4557 tTsk->initTsk = NULLP;
4558 tTsk->actvTsk = NULLP;
4561 tTsk->nxt = osCp.nxtTTskEntry;
4562 osCp.nxtTTskEntry = idx;
4565 #ifdef SS_MULTIPLE_PROCS
4566 /* mark the control block for this task as invalid */
4567 osCp.tTskTbl[idx].xxCb = NULLP;
4570 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4571 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4573 #if (ERRCLASS & ERRCLS_DEBUG)
4574 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4581 //#ifndef SPLIT_RLC_DL_TASK
4582 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4583 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4584 Void ysMtTskHdlr(Void);
4585 Void ysMtPollPhyMsg(uint8_t region);
4586 Void ysMtRcvPhyMsg(Void);
4587 Void *mtTskHdlrT2kL2
4589 Ptr tskPtr /* pointer to task entry */
4595 /* wait for SS to come up */
4596 /* It is required to block on this semaphore before starting actual processing of
4597 the thread becasue the creator of this thread might want to cance it without
4598 doing any processing. When this semaphore is released, means the creator gives
4599 the go ahead for actual processing and we should never come back to this point */
4600 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4609 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4610 * (processes L1 msgs) */
4616 Void ysMtTskHdlr(Void);
4617 Void YsPhyRecvMsg();
4618 Void *mtTskHdlrT2kL2
4620 Ptr tskPtr /* pointer to task entry */
4626 /* get out the system task entry from the parameter */
4627 sTsk = (SsSTskEntry *) tskPtr;
4629 /* wait for SS to come up */
4630 /* It is required to block on this semaphore before starting actual processing of
4631 the thread becasue the creator of this thread might want to cance it without
4632 doing any processing. When this semaphore is released, means the creator gives
4633 the go ahead for actual processing and we should never come back to this point */
4634 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4637 #ifndef RGL_SPECIFIC_CHANGES
4645 #ifdef V5GTF_SPECIFIC_CHANGES
4648 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4649 * (processes L1 msgs) */
4651 /* get a message from the demand queue */
4653 #ifdef RLC_MAC_DAT_REQ_RBUF
4654 rgDlDatReqBatchProc();
4657 ret = mtTskHdlMsg(sTsk);
4660 /* exit the for loop here */
4663 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4670 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4673 void *pthreadCreateHdlr(void * arg)
4676 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4677 /* mt038.201 changed how sem_wait is called */
4678 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4681 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4689 * Desc: This is the system task handler function. It blocks on
4690 * the system task's demand queue. On receiving a message,
4691 * it identifies the target TAPA task, verifies that the
4692 * TAPA task belongs to this system task and if so, calls
4693 * the activation function of that TAPA task with the
4694 * received message. The task activation function or the
4695 * timer activation function may be called.
4697 * Ret: (thread function)
4706 Ptr tskPtr /* pointer to task entry */
4712 /* get out the system task entry from the parameter */
4713 sTsk = (SsSTskEntry *) tskPtr;
4716 /* wait for SS to come up */
4718 /* mt038.201 changed how sem_wait is called */
4719 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4721 #ifdef XEON_SPECIFIC_CHANGES
4722 printf("\n**********MT Task Handler********\n");
4726 /* Wait for a message from the demand queue */
4727 #ifdef SS_CDMNDQ_SUPPORT
4728 ret = ssCDmndQWait(&sTsk->dQ);
4730 ret = ssDmndQWait(&sTsk->dQ);
4735 ret = mtTskHdlMsg(sTsk);
4750 * Desc: This is the system task handler function. It blocks on
4751 * the system task's demand queue. On receiving a message,
4752 * it identifies the target TAPA task, verifies that the
4753 * TAPA task belongs to this system task and if so, calls
4754 * the activation function of that TAPA task with the
4755 * received message. The task activation function or the
4756 * timer activation function may be called.
4758 * Ret: (thread function)
4773 SsTTskEntry *tTsk=NULLP;
4776 Buffer *mBuf2=NULLP;
4778 SsMsgInfo *mInfo=NULLP;
4780 /* mt028.201: modification: multiple procs support related changes */
4781 #ifndef SS_MULTIPLE_PROCS
4783 PAIFTMRS16 tmrActvFnMt = NULLP;
4785 /* mt015.301 Initialized the timer activation functions with NULLP */
4786 PFS16 tmrActvFn = NULLP;
4788 PAIFTMRS16 tmrActvFn =NULLP;
4789 uint16_t procIdIdx =0;
4790 #endif /* SS_MULTIPLE_PROCS */
4791 /* mt003.301 Modifications */
4792 #ifdef SS_THREAD_PROFILE
4794 #endif /* SS_THREAD_PROFILE */
4797 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4800 /* nothing to receive */
4804 /* if we can't lock this system task entry, return the message */
4805 ret = SLock(&sTsk->lock);
4809 #if (ERRCLASS & ERRCLS_DEBUG)
4810 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4811 "Could not lock system task entry");
4821 mBuf2 = mBuf->b_next;
4823 /* find out what kind of message this is */
4824 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4825 #ifdef SS_MEM_WL_DEBUG
4826 mtTskBuffer1 = mBuf2;
4828 mtTskBuffer2 = mBuf2->b_next;
4830 if(mInfo == 0x5050505)
4834 cmAnalyseBtInfo((PTR) mBuf,4);
4836 printf("\n In trouble .... \n");
4838 else if (mInfo == 0x2020202)
4841 cmAnalyseBtInfo((PTR) mBuf,1);
4842 printf("\n In trouble .... \n");
4844 #endif /* SS_MEM_WL_DEBUG */
4845 switch (mInfo->eventInfo.event)
4847 /* this is a termination event, we die */
4849 /* release the message */
4852 /* Unlock the system task entry and lock the system
4853 * task table to clean our entry up.
4855 SUnlock(&sTsk->lock);
4857 ret = SLock(&osCp.sTskTblLock);
4861 #if (ERRCLASS & ERRCLS_DEBUG)
4862 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
4863 "Could not lock system task table");
4865 /* what to do here? */
4869 /* clean up the system task entry */
4872 /* mt003.301 Modifications - SDeRegTTsk */
4873 /* sTsk->numTTsks = 0; */
4874 SDestroyLock(&sTsk->lock);
4875 ssDestroyDmndQ(&sTsk->dQ);
4877 /* lock for current executing TAPA task ID */
4879 /* make this entry available in the system task table */
4880 sTsk->nxt = osCp.nxtSTskEntry;
4881 for (i = 0; i < SS_MAX_STSKS; i++)
4883 if (sTsk == &osCp.sTskTbl[i])
4885 osCp.nxtSTskEntry = i;
4892 /* unlock the system task table */
4893 SUnlock(&osCp.sTskTblLock);
4898 /* this is a data message or a permanent task keep-alive message */
4900 case SS_EVNT_PERMTICK:
4901 /* message to a task. find the destination task */
4902 /* mt028.201: modification: multiple procs support related changes */
4903 #ifdef SS_MULTIPLE_PROCS
4904 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
4906 if (procIdIdx == SS_INV_PROCID_IDX)
4912 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
4913 #else /* SS_MULTIPLE_PROCS */
4914 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
4915 #endif /* SS_MULTIPLE_PROCS */
4917 /* verify that it hasn't been deregistered */
4918 if (idx == SS_TSKNC)
4924 /* verify that this system task is still running it */
4925 tTsk = &osCp.tTskTbl[idx];
4926 if (tTsk->sTsk != sTsk)
4932 /* set the current executing TAPA task ID */
4933 sTsk->dep.ent = mInfo->pst.dstEnt;
4934 sTsk->dep.inst = mInfo->pst.dstInst;
4936 /* copy the Pst structure into a local duplicate */
4937 for (i = 0; i < (S16) sizeof(Pst); i++)
4938 *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
4940 /* Give the message to the task activation function. If
4941 * its a normal data message, we pass it, if this is a
4942 * keep-alive message for a permanent task then we pass
4943 * NULLP in place of the message to the task activation
4946 if (mInfo->eventInfo.event == SS_EVNT_DATA)
4948 #ifndef RGL_SPECIFIC_CHANGES
4949 #ifdef SS_TSKLOG_ENABLE
4950 uint32_t t = MacGetTick();
4953 /* mt003.301 Modifications */
4954 #if SS_THREAD_PROFILE
4955 tTsk->curEvent = nPst.event;
4957 #endif /* SS_THREAD_PROFILE */
4958 tTsk->actvTsk(&nPst, mBuf);
4959 #ifndef RGL_SPECIFIC_CHANGES
4960 #ifdef SS_TSKLOG_ENABLE
4961 SStopTask(t,PID_SSI_TSK);
4964 #if SS_THREAD_PROFILE
4966 tTsk->curEvtTime = (uint32_t)(et2 - et1);
4967 tTsk->totTime += (uint64_t)tTsk->curEvtTime;
4968 #endif /* SS_THREAD_PROFILE */
4972 #if (ERRCLASS & ERRCLS_DEBUG)
4973 /* this message should only come to a permanent task */
4974 if (tTsk->tskType != SS_TSK_PERMANENT)
4976 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
4980 tTsk->actvTsk(&nPst, NULLP);
4982 /* We need to re-send this message back to ourselves so
4983 * the permanent task continues to run.
4985 /* Check if this task got deregistered or detached
4986 * by the activation function; if so, there's nothing
4987 * more to do here, otherwise go ahead.
4990 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
4992 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
4993 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
4997 /* failure here is a real problem */
5000 #if (ERRCLASS & ERRCLS_DEBUG)
5001 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5002 "Could not write to demand queue");
5008 /* unset the current executing TAPA task ID */
5009 sTsk->dep.ent = ENTNC;
5010 sTsk->dep.inst = INSTNC;
5015 /* timer event. find the timer entry */
5016 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5018 /* lock the timer table, coz we're going to peek in it */
5019 ret = SLock(&osCp.tmrTblLock);
5023 #if (ERRCLASS & ERRCLS_DEBUG)
5024 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5025 "Could not lock timer table");
5031 /* Verify that this timer entry is still around and that it
5032 * belongs to our task.
5034 if (osCp.tmrTbl[idx].used == FALSE
5035 /* mt028.201: modification: multiple procs support related changes */
5036 #ifdef SS_MULTIPLE_PROCS
5037 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5038 #endif /* SS_MULTIPLE_PROCS */
5039 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5040 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5042 SUnlock(&osCp.tmrTblLock);
5047 /* mt005.21: addition */
5048 /* set the current executing TAPA task ID */
5049 sTsk->dep.ent = mInfo->pst.dstEnt;
5050 sTsk->dep.inst = mInfo->pst.dstInst;
5052 #ifndef SS_MULTIPLE_PROCS
5054 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5055 tmrActvFnMt = NULLP;
5056 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5058 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5064 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5067 /* unlock the timer table */
5068 SUnlock(&osCp.tmrTblLock);
5070 /* activate the timer function */
5071 /* mt028.201: modification: multiple procs support related changes */
5072 #ifndef SS_MULTIPLE_PROCS
5076 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5077 osCp.tmrTbl[idx].ownerInst);
5085 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5086 osCp.tmrTbl[idx].ownerInst);
5087 #endif /* SS_MULTIPLE_PROCS */
5089 /*mt005.21: addition */
5090 /* unset the current executing TAPA task ID */
5091 sTsk->dep.ent = ENTNC;
5092 sTsk->dep.inst = INSTNC;
5095 /* return the message buffer */
5099 * mt003.301 - SDeRegTTsk fix
5101 case SS_EVNT_TTSK_TERM:
5102 #ifdef SS_MULTIPLE_PROCS
5103 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5105 if (procIdIdx == SS_INV_PROCID_IDX)
5111 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5112 #else /* SS_MULTIPLE_PROCS */
5113 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5114 #endif /* SS_MULTIPLE_PROCS */
5116 /* verify that it hasn't been deregistered */
5117 if (idx == SS_TSKNC)
5123 /* verify that this system task is still running it */
5124 tTsk = &osCp.tTskTbl[idx];
5125 if (tTsk->sTsk != sTsk)
5130 #ifdef SS_MULTIPLE_PROCS
5131 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5133 ssdProcTTskTerm(tTsk, idx);
5139 #if (ERRCLASS & ERRCLS_DEBUG)
5140 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5147 } while (mBuf != NULLP);
5150 /* unlock the system task entry */
5151 SUnlock(&sTsk->lock);
5154 /* yield for other threads */
5155 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5164 * Fun: mtTmrHdlrPublic
5166 Void mtTmrHdlrPublic()
5168 if (SLock(&osCp.tmrTblLock) != ROK)
5170 #if (ERRCLASS & ERRCLS_DEBUG)
5171 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5175 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5176 /* unlock the timer table */
5177 SUnlock(&osCp.tmrTblLock);
5185 * Desc: The timer handler thread function. Counts time
5186 * and invokes the common timer function on each
5189 * Ret: (thread function)
5196 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5197 static Void *mtTmrHdlr
5199 void *parm /* unused */
5202 /*mt004.301-addede new region*/
5203 /* mt010.301 Removed SS_FAP portion and
5204 * enabled oroginal code in function mtTmrHdlr */
5208 uint32_t i, cnt, oldTicks, newTicks;
5209 struct timeval tv1,tv2;
5210 /* mt038.201 added return */
5212 /* mt039.201 changes for nanosleep */
5213 struct timespec tsN;
5214 static uint32_t err_in_usec;
5216 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5221 /* mt027.201 - Modification for SRegCfgTmr support */
5222 /* check SS_TICKS_SEC */
5223 if (SS_1MS < SS_TICKS_SEC)
5225 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5228 /* mt025.201 - Addition to stop timer handler till task registration is done */
5229 /* wait for SS to come up */
5230 /* mt038.201 changed how sem_wait is called */
5231 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5234 /* mt027.201 - Modification for SRegCfgTmr support */
5235 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5237 ts.tv_nsec = (MT_TICK_CNT * 1000);
5238 /* mt039.201 changes for nanosleep */
5244 if (gettimeofday(&tv1, NULL) == -1)
5246 #if (ERRCLASS & ERRCLS_DEBUG)
5247 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5248 "Error in clock_gettime");
5258 #ifndef STUB_TTI_HANDLING_5GTF
5259 printf("\nReturning from mtTmrHdlr()\n");
5264 /* mt039.201 changes for nanosleep */
5265 /* sleep for MT_TICK_CNT milli seconds */
5266 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5267 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5269 ts.tv_nsec = tsN.tv_nsec;
5274 if (gettimeofday(&tv2,NULL) == -1)
5276 #if (ERRCLASS & ERRCLS_DEBUG)
5277 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5278 "Error in clock_gettime");
5282 /*mt013.301 : changed check while calculating timer to fix
5283 * diffrence between MTSS time and real unix time
5285 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5287 time_int = (tv2.tv_usec - tv1.tv_usec);
5289 else if (tv2.tv_sec > tv1.tv_sec)
5291 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5293 else /* ts2 < ts1, this will not happen in normal scenario */
5295 /* to make sure cnt = 1 */
5297 time_int = MT_TICK_CNT;
5300 oldTicks = osCp.dep.sysTicks;
5301 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5302 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5303 newTicks = osCp.dep.sysTicks;
5304 tv1.tv_usec = tv2.tv_usec;
5305 tv1.tv_sec = tv2.tv_sec;
5307 cnt = newTicks - oldTicks;
5309 while(err_in_usec >= MT_TICK_CNT)
5312 err_in_usec -= MT_TICK_CNT;
5314 if( cnt >= MT_MAX_TICK_CNT_VAL)
5315 cnt = MT_MIN_TICK_CNT_VAL;
5316 /* call the common timer tick handler */
5317 for (i = 0; i < cnt; i++)
5319 /* mt008.301: cmPrcTmr is guarded with a lock */
5320 /* lock the timer table */
5321 if (SLock(&osCp.tmrTblLock) != ROK)
5323 #if (ERRCLASS & ERRCLS_DEBUG)
5324 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5328 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5329 /* unlock the timer table */
5330 SUnlock(&osCp.tmrTblLock);
5334 /* mt009.21: addition */
5335 return ( (Void *) NULLP);
5336 /* will not reach here */
5344 * Desc: Process timer event. Called from the common timer
5345 * code when a timeout occurs.
5356 PTR tCb, /* control block */
5357 S16 evnt /* event */
5366 #ifndef TENB_RTLIN_CHANGES
5369 /* mt028.201: modification: multiple procs support related changes */
5370 #ifdef SS_MULTIPLE_PROCS
5372 #endif /* SS_MULTIPLE_PROCS */
5373 #ifdef RGL_SPECIFIC_CHANGES
5374 #ifdef MSPD_MLOG_NEW
5375 uint32_t t = GetTIMETICK();
5381 /* get the timer entry */
5382 tEnt = (SsTmrEntry *) tCb;
5385 /* if the timer was deleted, this will be NULL, so drop it */
5391 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5394 /* Hmmmm, the timer might have been deleted while we've been
5395 * working at getting here, so we just skip this.
5397 if (tEnt->used == FALSE)
5403 /* Set up and send a timer message to the destination tasks'
5406 #ifndef SS_MULTICORE_SUPPORT
5407 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5409 #ifdef RGL_SPECIFIC_CHANGES
5410 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5412 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5417 #if (ERRCLASS & ERRCLS_DEBUG)
5418 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5424 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5425 mInfo->eventInfo.event = SS_EVNT_TIMER;
5426 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5428 mInfo->pst.dstEnt = tEnt->ownerEnt;
5429 mInfo->pst.dstInst = tEnt->ownerInst;
5430 mInfo->pst.srcEnt = tEnt->ownerEnt;
5431 mInfo->pst.srcInst = tEnt->ownerInst;
5432 /* mt028.201: modification: multiple procs support related changes */
5433 #ifndef SS_MULTIPLE_PROCS
5434 mInfo->pst.dstProcId = SFndProcId();
5435 mInfo->pst.srcProcId = SFndProcId();
5436 #else /* SS_MULTIPLE_PROCS */
5437 mInfo->pst.dstProcId = tEnt->ownerProc;
5438 mInfo->pst.srcProcId = tEnt->ownerProc;
5439 #endif /* SS_MULTIPLE_PROCS */
5440 mInfo->pst.selector = SEL_LC_NEW;
5441 #ifndef SS_MULTICORE_SUPPORT
5442 mInfo->pst.region = DFLT_REGION;
5445 mInfo->pst.pool = DFLT_POOL;
5446 mInfo->pst.prior = PRIOR0;
5447 mInfo->pst.route = RTESPEC;
5448 mInfo->pst.event = 0;
5451 #ifndef TENB_RTLIN_CHANGES
5452 /* get a semaphore for the TAPA task table */
5453 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5458 #if (ERRCLASS & ERRCLS_DEBUG)
5459 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5467 /* find the owner TAPA task */
5468 /* mt028.201: modification: multiple procs support related changes */
5469 #ifdef SS_MULTIPLE_PROCS
5470 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5471 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5472 #else /* SS_MULTIPLE_PROCS */
5473 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5474 #endif /* SS_MULTIPLE_PROCS */
5475 if (idx == SS_TSKNC)
5477 #ifndef TENB_RTLIN_CHANGES
5478 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5485 /* ensure that the TAPA task is hale and hearty */
5486 tTsk = &osCp.tTskTbl[idx];
5489 #ifndef TENB_RTLIN_CHANGES
5490 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5495 /* Klock work fix ccpu00148484 */
5496 /* write the timer message to the queue of the destination task */
5497 /* mt008.301 : check sTsk before putting into it's DQ */
5498 if (tTsk->sTsk == NULLP)
5500 #ifndef TENB_RTLIN_CHANGES
5501 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5505 #if (ERRCLASS & ERRCLS_DEBUG)
5506 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5507 "Could not write to demand queue");
5512 #ifdef SS_LOCKLESS_MEMORY
5513 mInfo->pst.region = tTsk->sTsk->region;
5514 mInfo->region = tTsk->sTsk->region;
5515 #endif /* SS_LOCKLESS_MEMORY */
5516 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5517 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5519 #ifndef TENB_RTLIN_CHANGES
5520 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5524 #if (ERRCLASS & ERRCLS_DEBUG)
5525 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5526 "Could not write to demand queue");
5531 /* Fix for ccpu00130657 */
5532 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5533 if (tTsk->sTsk->tskPrior == PRIOR0)
5536 WLS_WakeUp(mtGetWlsHdl());
5543 /* release the semaphore for the TAPA task table */
5544 #ifndef TENB_RTLIN_CHANGES
5545 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5549 /* restart the timer */
5550 arg.tq = osCp.dep.tmrTq;
5551 arg.tqCp = &osCp.dep.tmrTqCp;
5552 arg.timers = tEnt->dep.timers;
5553 arg.cb = (PTR) tEnt;
5557 arg.max = TMR_DEF_MAX;
5558 arg.wait = tEnt->interval;
5560 #ifdef RGL_SPECIFIC_CHANGES
5561 #ifdef MSPD_MLOG_NEW
5562 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5574 * Desc: This thread reads the console and hands over any
5575 * data read to a user function.
5577 * Ret: (thread function)
5584 static Void *mtConHdlr
5586 Ptr parm /* unused */
5593 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5599 /* check if we have a console input file handle */
5600 if (osCp.dep.conInFp == NULLP)
5606 fd = fileno(osCp.dep.conInFp);
5611 if ((read(fd, &data, 1)) != 1)
5617 /* call rdConQ, defined by the system service user */
5627 #ifdef SS_DRVR_SUPPORT
5630 * Fun: Interrupt service task handler
5632 * Desc: This is the interrupt service task handler. It blocks
5633 * on a pipe from which it reads an isFlag structure. The
5634 * structure indicates which interrupt service task is to
5635 * be executed. The thread identifies the task, calls the
5636 * isTsk function and sends itself a message to repeat
5637 * this operation until it receives a message to cease.
5646 /* mt009.21: addition */
5647 static Void *mtIsTskHdlr
5649 Ptr tskPtr /* pointer to task entry */
5652 #if (ERRCLASS & ERRCLS_DEBUG)
5659 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5664 switch (isFlag.action)
5667 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5669 /* call the interrupt service task activation function */
5670 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5672 /* send self a message to keep doing this */
5673 isFlag.action = MT_IS_RESET;
5675 #if (ERRCLASS & ERRCLS_DEBUG)
5676 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5677 if (ret != sizeof(isFlag))
5679 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5680 "write() to pipe failed");
5683 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5690 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5695 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5697 /* call the interrupt service task activation function */
5698 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5700 #if (ERRCLASS & ERRCLS_DEBUG)
5701 /* send self a message to do this again */
5702 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5704 if (ret != sizeof(isFlag))
5706 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5707 "write() to pipe failed");
5710 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5718 /* where did THIS come from?? */
5722 /* mt009.21: addition */
5723 return ( (Void *) NULLP);
5727 #endif /* SS_DRVR_SUPPORT */
5728 #endif /* L2_L3_SPLIT */
5730 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5734 * Fun: mtIntSigHndlr
5736 * Desc: Exit function, shuts down.
5745 Void mtIntSigHndlr(int arg)
5748 osCp.dep.sigEvnt=TRUE;
5751 #ifdef TENB_RTLIN_CHANGES
5759 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5764 * Desc: function, shuts down.
5773 Void mtExitClnup(void)
5779 SGetSysTime(&ticks);
5781 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5783 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5785 #ifdef SS_HISTOGRAM_SUPPORT
5789 osCp.dep.sigEvnt=FALSE;
5791 if (osCp.dep.fileOutFp)
5793 fclose(osCp.dep.fileOutFp);
5801 Void SIncrementTtiCount(Void)
5806 Ticks SGetTtiCount(Void)
5815 * Desc: This function displays a string to a given output
5820 * Notes: Buffer should be null terminated.
5822 * channel 0 is reserved for backwards compatibility
5830 S16 chan, /* channel */
5831 Txt *buf /* buffer */
5835 /* mt020.201 - Fixed typo */
5836 #if (ERRCLASS & ERRCLS_INT_PAR)
5839 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
5844 #ifndef XEON_SPECIFIC_CHANGES
5845 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5846 ssMemlog(buf, strlen(buf));
5851 /* mt012.301 :FIX for LOG RELATED ISSUE */
5859 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
5865 if (osCp.dep.fileOutFp)
5866 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
5867 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
5870 fflush(osCp.dep.fileOutFp);
5883 * Desc: function, shuts down.
5895 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
5896 a loop to overcome the child processes being killed upon exiting the
5898 #ifdef SS_LINUX /* this should have already been defined */
5899 /* mt010.301 removed flag SLES9_PLUS */
5900 /* wait forever for children */
5904 if(osCp.dep.sigEvnt==TRUE)
5911 pthread_exit(NULLP);
5917 * Fun: Set date and time
5919 * Desc: This function is used to set the calendar
5924 * Notes: Unimplemented
5931 REG1 DateTime *dt /* date and time */
5944 * Fun: Get date and time
5946 * Desc: This function is used to determine the calendar
5947 * date and time. This information may be used for
5948 * some management functions.
5960 REG1 DateTime *dt /* date and time */
5963 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
5966 struct timespec ptime;
5968 struct timeval ptime;
5975 #if (ERRCLASS & ERRCLS_INT_PAR)
5978 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
5987 localtime_r(&tt, &tme);
5990 clock_gettime(CLOCK_REALTIME, &ptime);
5992 gettimeofday(&ptime, NULL);
5994 localtime_r(&ptime.tv_sec, &tme);
5996 dt->month = (uint8_t) tme.tm_mon + 1;
5997 dt->day = (uint8_t) tme.tm_mday;
5998 dt->year = (uint8_t) tme.tm_year;
5999 dt->hour = (uint8_t) tme.tm_hour;
6000 dt->min = (uint8_t) tme.tm_min;
6001 dt->sec = (uint8_t) tme.tm_sec;
6004 #ifdef SS_DATETIME_USEC
6006 dt->usec = ptime.tv_nsec / 1000;
6008 dt->usec = ptime.tv_usec;
6010 #endif /*-- SS_DATETIME_USEC --*/
6016 * Get time from epoch in milliseconds
6018 * Fun: Get time from epoch in milliseconds
6020 * Desc: This function is used to get the time from epoch in milli seconds.
6021 * This information may be used for calculating a layer's activation function
6022 * execution time used for thread profiling.
6031 /* mt003.301 Modifications */
6034 EpcTime *et /* date and time */
6037 /* mt003.301 Modifications */
6038 static uint64_t now;
6039 uint64_t to_sec = 1000000;
6040 uint64_t to_nsec = 1000;
6042 struct timespec ptime;
6044 struct timeval ptime;
6049 #if (ERRCLASS & ERRCLS_INT_PAR)
6058 clock_gettime(CLOCK_REALTIME, &ptime);
6060 gettimeofday(&ptime, NULL);
6061 #endif /* SS_LINUX */
6063 now = (ptime.tv_sec * to_sec);
6066 now += (ptime.tv_nsec / to_nsec);
6067 #else /* SS_LINUX */
6068 now += (ptime.tv_usec);
6070 #endif /* SS_LINUX */
6071 now = (now / to_nsec);
6082 * Fun: Get system time
6084 * Desc: This function is used to determine the system time.
6088 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6095 Ticks *sysTime /* system time */
6100 #if (ERRCLASS & ERRCLS_INT_PAR)
6101 if (sysTime == NULLP)
6103 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6109 *sysTime = osCp.dep.sysTicks;
6115 /* mt021.201 - Addition of SGetRefTime function */
6118 * Fun: Get referenced time
6120 * Desc: This function is used to determine the time in seconds
6121 * and microseconds from a reference time. The reference
6122 * time is expressed in seconds from UTC EPOC, January 1,
6128 * Notes: Macros are defined for reference times:
6129 * SS_REFTIME_01_01_1970
6130 * SS_REFTIME_01_01_2002
6137 uint32_t refTime, /* reference time */
6144 struct timespec ptime;
6146 struct timeval ptime;
6151 clock_gettime(CLOCK_REALTIME, &ptime);
6153 gettimeofday(&ptime, NULL);
6156 #if (ERRCLASS & ERRCLS_INT_PAR)
6157 if (sec == NULLP || usec == NULLP)
6159 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6162 /* mt022.201 - Modification to fix compile warning */
6163 if (refTime > (uint32_t)(ptime.tv_sec))
6165 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6170 *sec = ptime.tv_sec - refTime;
6172 *usec = ptime.tv_nsec / 1000;
6174 *usec = ptime.tv_usec;
6184 * Fun: Get Random Number
6186 * Desc: Invoked by layer when a pseudorandom number is required.
6190 * Notes: Suggested approach uses shuffled Linear Congruential
6191 * Operators as described in Byte magazine October
6192 * 1984; "Generating and Testing Pseudorandom Numbers"
6199 Random *value /* random number */
6204 #if (ERRCLASS & ERRCLS_INT_PAR)
6207 /* mt011.21: addition */
6208 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6214 *value = (Random) rand_r(&osCp.dep.randSeed);
6225 * Desc: This function exits from a task.
6229 * Notes: Currently does nothing.
6244 * Fun: Exit Interrupt
6246 * Desc: This function exits from an interrupt.
6250 * Notes: Currently does nothing.
6265 * Fun: Hold Interrupt
6267 * Desc: This function prohibits interrupts from being enabled until
6268 * release interrupt. This function should be called when
6269 * interrupts are disabled and prior to any call to system
6270 * services either by entry to an interrupt service routine or
6271 * by explicit call to disable interrupt.
6275 * Notes: Currently does nothing
6290 * Fun: Release Interrupt
6292 * Desc: This function allows interrupts to be enabled.
6296 * Notes: Currently does nothing.
6313 * Desc: Enable interrupts
6315 * Ret: ROK on success
6318 * Notes: Currently does nothing.
6323 inline S16 SEnbInt(void)
6335 * Desc: Disable interrupts
6337 * Ret: ROK on success
6340 * Notes: Currently does nothing.
6345 inline S16 SDisInt(void)
6357 * Desc: This function gets the function address stored at the
6358 * specified interrupt vector.
6362 * Notes: Currently does nothing.
6369 VectNmb vectNmb, /* vector number */
6370 PIF *vectFnct /* vector function */
6387 * Desc: This function installs the specified function at the
6388 * specified interrupt vector.
6392 * Notes: Currently does nothing.
6399 VectNmb vectNmb, /* vector number */
6400 PIF vectFnct /* vector function */
6412 /* mt028.201: modification: multiple procs support related changes */
6413 #ifndef SS_MULTIPLE_PROCS
6419 * Desc: This function gets the current entity and instance.
6422 * RFAILED - failed, general (optional)
6424 * Notes: This function may be called by the OS or Layer 1
6432 Ent *ent, /* entity */
6433 Inst *inst /* instance */
6444 #if (ERRCLASS & ERRCLS_INT_PAR)
6445 /* check pointers */
6446 if (ent == NULLP || inst == NULLP)
6448 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6454 /* get the thread id */
6455 tId = pthread_self();
6458 /* find the system task in whose context we're running */
6460 ret = SLock(&osCp.sTskTblLock);
6465 for (i = 0; i < SS_MAX_STSKS; i++)
6467 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6469 sTsk = &osCp.sTskTbl[i];
6475 *ent = sTsk->dep.ent;
6476 *inst = sTsk->dep.inst;
6478 SUnlock(&osCp.sTskTblLock);
6481 return (ret == ROK ? ROK : RFAILED);
6489 * Desc: This function sets the current entity and instance.
6500 Ent ent, /* entity */
6501 Inst inst /* instance */
6512 #if (ERRCLASS & ERRCLS_INT_PAR)
6513 /* check entity and instance IDs */
6514 if (ent >= ENTNC || inst >= INSTNC)
6516 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6522 /* get the thread id */
6523 tId = pthread_self();
6526 /* find the system task in whose context we're running */
6528 ret = SLock(&osCp.sTskTblLock);
6533 for (i = 0; i < SS_MAX_STSKS; i++)
6535 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6537 sTsk = &osCp.sTskTbl[i];
6543 sTsk->dep.ent = ent;
6544 sTsk->dep.inst = inst;
6546 SUnlock(&osCp.sTskTblLock);
6549 return (ret == ROK ? ROK : RFAILED);
6552 #endif /* SS_MULTIPLE_PROCS */
6554 #ifdef SS_DRVR_SUPPORT
6560 * Desc: Set interrupt pending flag
6562 * Ret: ROK on success
6570 inline S16 SSetIntPend
6572 uint16_t id, /* driver task identifier */
6573 Bool flag /* flag */
6581 #if (ERRCLASS & ERRCLS_INT_PAR)
6582 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6584 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6591 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6593 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6601 #endif /* SS_DRVR_SUPPORT */
6604 #ifdef SS_LOCKLESS_MEMORY
6607 * Fun: SGlobMemInfoShow
6609 * Desc: This function displays the memory usage information
6610 * for the destined region. It will show the usage of
6611 * each configured bucket and the heap for the specified region.
6614 * RFAILED Region not registered
6619 S16 SGlobMemInfoShow(Void)
6623 CmMmGlobRegCb *globReg;
6626 globReg = osCp.globRegCb;
6628 sprintf(prntBuf, "--------------------------------------------------------------\n");
6629 SDisplay(0, prntBuf);
6630 sprintf(prntBuf, "Global Region Bucket Information\n");
6631 SDisplay(0, prntBuf);
6632 sprintf(prntBuf, "====================================================\n");
6633 SDisplay(0, prntBuf);
6634 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
6635 SDisplay(0, prntBuf);
6636 sprintf(prntBuf, "====================================================\n");
6637 SDisplay(0, prntBuf);
6640 for (idx = 0; idx < globReg->numBkts; idx++)
6642 #ifdef XEON_SPECIFIC_CHANGES
6643 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
6644 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6647 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
6648 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6650 sprintf(prntBuf, "%2u %12u %8u %9u\n",
6651 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6654 SDisplay(0, prntBuf);
6656 sprintf(prntBuf, "--------------------------------------------------------------\n");
6657 SDisplay(0, prntBuf);
6662 #endif /* SS_LOCKLESS_MEMORY */
6665 Bool IsMemoryThresholdHit(Region reg, Pool pool)
6667 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6669 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6672 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6673 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6680 /* mt022.201 - Addition of SRegInfoShow function */
6685 * Desc: This function displays the memory usage information
6686 * for the destined region. It will show the usage of
6687 * each configured bucket and the heap for the specified region.
6690 * RFAILED Region not registered
6692 * Notes: A Sample Output from the function
6693 * Bucket Memory: region 1
6694 * ====================================================
6695 * Bucket Number of Blks configured Size Allocated
6696 * ====================================================
6704 * Heap Memory: region 1
6707 * Heap Segmented blocks: 0
6723 #if (ERRCLASS & ERRCLS_INT_PAR)
6724 if (region > (SS_MAX_REGS-1) )
6726 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
6733 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
6734 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
6735 SDisplay(0, prntBuf);
6736 sprintf(prntBuf, "====================================================\n");
6737 SDisplay(0, prntBuf);
6738 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
6739 SDisplay(0, prntBuf);
6740 sprintf(prntBuf, "====================================================\n");
6741 SDisplay(0, prntBuf);
6745 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6747 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6749 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
6750 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6751 mtCMMRegCb[region]->bktTbl[idx].size,
6752 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6753 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6755 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
6756 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6757 mtCMMRegCb[region]->bktTbl[idx].size,
6758 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6759 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6762 /*mt009.301 Fixed 64BIT compilation warnings*/
6764 sprintf(prntBuf, "%2u %8u %5u %8u\n",
6765 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6766 mtCMMRegCb[region]->bktTbl[idx].size,
6767 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6769 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
6770 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6771 mtCMMRegCb[region]->bktTbl[idx].size,
6772 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6774 #endif /* not TENB_RTLIN_CHANGES */
6775 SDisplay(0, prntBuf);
6776 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
6777 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6778 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6780 sprintf(prntBuf, "\n---------------\n");
6781 SDisplay(0, prntBuf);
6782 sprintf(prntBuf, "Heap Memory: region %d\n", region);
6783 SDisplay(0, prntBuf);
6784 /*mt009.301 Fixed 64BIT compilation warnings*/
6786 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
6788 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
6790 SDisplay(0, prntBuf);
6791 /*mt009.301 Fixed 64BIT compilation warnings*/
6793 sprintf(prntBuf, "Heap Allocated: %u\n",
6794 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6796 sprintf(prntBuf, "Heap Allocated: %lu\n",
6797 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6799 SDisplay(0, prntBuf);
6800 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
6801 #if (ERRCLASS & ERRCLS_DEBUG)
6802 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
6803 mtCMMRegCb[region]->heapCb.numFragBlk);
6804 SDisplay(0, prntBuf);
6809 #ifdef XEON_SPECIFIC_CHANGES
6810 #define SSI_MAX_BKT_THRESHOLD 6
6811 #define SSI_MAX_REG_THRESHOLD 2
6812 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6813 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6814 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6816 static Void SInitMemThreshold
6823 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6825 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
6826 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
6827 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
6828 printf("\nREGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
6832 S16 SRegReachedMemThreshold
6839 uint8_t memStatus = 3;
6840 static uint8_t initFlag = 1;
6844 SInitMemThreshold(region, maxBkt);
6847 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6849 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
6854 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
6858 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
6866 /* mt033.201 - addition of API to return the memory statistical data */
6871 * Desc: This function returns the memory usage information
6872 * for the destined region. It will return the usage of
6873 * each configured bucket and the heap for the specified region.
6876 * RFAILED Region not registered
6886 SsMemDbgInfo *dbgInfo
6892 #if (ERRCLASS & ERRCLS_INT_PAR)
6893 if (region >= mtMemoCfg.numRegions )
6895 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
6900 dbgInfo->availmem = 0;
6902 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
6903 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
6905 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
6907 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
6909 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
6910 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
6911 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
6913 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
6914 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6915 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6918 dbgInfo->region = region;
6920 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
6922 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
6923 mtCMMRegCb[region]->heapCb.avlSize);
6925 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
6927 #if (ERRCLASS & ERRCLS_DEBUG)
6928 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
6940 /* Send number of Region available */
6941 *numRegion = mtMemoCfg.numRegions;
6942 /* Send number of Pools available */
6943 *numPool = cfgRegInfo[0].numPools;
6948 /* mt033.201 - addition of APIs to print the memory statistical data
6949 * as defined by SSI enhancements
6951 #ifdef SSI_DEBUG_LEVEL1
6954 * Fun: SPrintRegMemStatusInfo
6956 * Desc: This function displays the memory usage information
6957 * for the destined region. It will show the total memory
6958 * used for static and dynamic memory if typeFlag is
6959 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
6960 * memory block allocated for a particular size if typeFlag
6961 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
6962 * calling SRegPrintMemStats.
6971 S16 SPrintRegMemStatusInfo
6979 uint32_t statMemSize;
6980 uint32_t dynMemSize;
6983 #if (ERRCLASS & ERRCLS_INT_PAR)
6984 if (region >= mtMemoCfg.numRegions )
6986 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
6991 /* initialize the counters*/
6995 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
6997 /* total static and dynamic memory allocated from all the buckets in region requested */
6998 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
6999 SDisplay(0, prntBuf);
7000 sprintf(prntBuf, "===========================================\n");
7001 SDisplay(0, prntBuf);
7002 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7003 SDisplay(0, prntBuf);
7004 sprintf(prntBuf, "===========================================\n");
7005 SDisplay(0, prntBuf);
7006 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7008 /*mt009.301 Fixed 64BIT compilation warnings*/
7010 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7011 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7012 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7014 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7015 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7016 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7018 SDisplay(0, prntBuf);
7019 /* update the total count */
7020 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7021 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7024 /*mt009.301 Fixed 64BIT compilation warnings*/
7026 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7027 SDisplay(0, prntBuf);
7028 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7030 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7031 SDisplay(0, prntBuf);
7032 /*mt010.301 fix for compilation error*/
7033 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7035 SDisplay(0, prntBuf);
7037 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7038 SDisplay(0, prntBuf);
7039 /*mt009.301 Fixed 64BIT compilation warnings*/
7041 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7042 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7044 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7045 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7047 SDisplay(0, prntBuf);
7049 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7051 /* Bucket Memory allocation Statistics */
7052 return (SPrintRegMemStats(region));
7057 sprintf(prntBuf, "\n Invalid choice \n");
7058 SDisplay(0, prntBuf);
7066 * Fun: SPrintRegMemStats
7068 * Desc: This function displays the memory usage information for
7069 * the destined region. It will show the number of memory
7070 * block allocated for a particular size from the hash list.
7079 static S16 SPrintRegMemStats(Region region)
7081 CmMmHashListCp *hashListCp;
7087 hashListCp = &mtCMMRegCb[region]->hashListCp;
7089 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7090 SDisplay(0, prntBuf);
7091 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7092 hashListCp->numOfbins, hashListCp->numOfEntries);
7093 SDisplay(0, prntBuf);
7094 sprintf(prntBuf, "===================================\n");
7095 SDisplay(0, prntBuf);
7096 sprintf(prntBuf, "Block Size Total number of requests\n");
7097 SDisplay(0, prntBuf);
7098 sprintf(prntBuf, "===================================\n");
7099 SDisplay(0, prntBuf);
7101 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7102 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7104 if (hashListCp->hashList[idx].numAttempts)
7107 /*mt009.301 Fixed 64BIT compilation warnings*/
7109 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7110 hashListCp->hashList[idx].numAttempts);
7112 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7113 hashListCp->hashList[idx].numAttempts);
7115 SDisplay(0, prntBuf);
7119 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7120 SDisplay(0, prntBuf);
7121 sprintf(prntBuf, "=================================================\n");
7122 SDisplay(0, prntBuf);
7123 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7124 SDisplay(0, prntBuf);
7125 sprintf(prntBuf, "=================================================\n");
7126 SDisplay(0, prntBuf);
7128 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7129 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7131 /*mt009.301 Fixed 64BIT compilation warnings*/
7133 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7134 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7135 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7137 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7138 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7139 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7141 SDisplay(0, prntBuf);
7143 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7144 SDisplay(0, prntBuf);
7145 /*mt009.301 Fixed 64BIT compilation warnings*/
7147 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7148 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7149 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7151 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7152 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7153 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7155 SDisplay(0, prntBuf);
7156 sprintf(prntBuf, "\n");
7157 SDisplay(0, prntBuf);
7164 * Fun: SRegMemErrHdlr
7166 * Desc: This function handles the errors returned from the memory
7167 * related functions. Customers are suggested to modify this
7168 * API according to their specific requirement.
7187 if (errCode == RDBLFREE)
7189 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7190 SDisplay(0, prntBuf);
7192 else if (errCode == RTRAMPLINGNOK)
7194 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7195 SDisplay(0, prntBuf);
7203 * Fun: SPrintRegMemProfile
7205 * Desc: This function displays the memory profile information
7206 * for the destined region. This function prints for:
7207 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7208 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7217 S16 SPrintRegMemProfile
7224 CmMmBlkHdr *curBktBlk;
7226 Size offsetToNxtBlk;
7234 #if (ERRCLASS & ERRCLS_INT_PAR)
7235 if (region >= mtMemoCfg.numRegions )
7237 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7242 regCb = mtCMMRegCb[region];
7244 /* memory profile */
7245 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7246 SDisplay(0, prntBuf);
7248 /* bucket profile */
7249 sprintf(prntBuf, "\nBucket Profile\n");
7250 SDisplay(0, prntBuf);
7252 for (idx = 0; idx < regCb->numBkts; idx++)
7255 /*mt009.301 Fixed 64BIT compilation warnings*/
7257 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7258 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7260 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7261 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7263 SDisplay(0, prntBuf);
7265 sprintf(prntBuf, "==========================================================================\n");
7266 SDisplay(0, prntBuf);
7267 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7268 SDisplay(0, prntBuf);
7269 sprintf(prntBuf, "==========================================================================\n");
7270 SDisplay(0, prntBuf);
7272 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7274 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7275 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7276 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7278 /*mt009.301 Fixed 64BIT compilation warnings*/
7280 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7282 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7284 SDisplay(0, prntBuf);
7285 /* check if it is a sane block, elxe jump to next block */
7286 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7288 sprintf(prntBuf, " Trampled \n");
7289 SDisplay(0, prntBuf);
7294 if (CMM_IS_STATIC(curBktBlk->memFlags))
7296 /*mt009.301 Fixed 64BIT compilation warnings*/
7298 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7300 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7302 SDisplay(0, prntBuf);
7304 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7306 /*mt009.301 Fixed 64BIT compilation warnings*/
7308 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7310 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7312 SDisplay(0, prntBuf);
7314 else if (CMM_IS_FREE(curBktBlk->memFlags))
7316 /*mt009.301 Fixed 64BIT compilation warnings*/
7318 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7320 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7322 SDisplay(0, prntBuf);
7326 sprintf(prntBuf, " Trampled \n");
7327 SDisplay(0, prntBuf);
7333 sprintf(prntBuf, "\nHeap Profile\n");
7334 SDisplay(0, prntBuf);
7336 /* point to heapCb */
7337 heapCb = &(regCb->heapCb);
7339 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7340 SDisplay(0, prntBuf);
7341 sprintf(prntBuf, "==========================================================================\n");
7342 SDisplay(0, prntBuf);
7343 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7344 SDisplay(0, prntBuf);
7345 sprintf(prntBuf, "==========================================================================\n");
7346 SDisplay(0, prntBuf);
7348 /* traverse the entire heap to output the heap profile */
7349 hdrSize = sizeof(CmHEntry);
7350 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7351 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7353 /*mt009.301 Fixed 64BIT compilation warnings*/
7355 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7357 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7359 SDisplay(0, prntBuf);
7361 /* check if it is a sane block, elxe jump to next block */
7362 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7364 sprintf(prntBuf, " Trampled \n");
7365 SDisplay(0, prntBuf);
7367 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7368 SDisplay(0, prntBuf);
7371 * To go to next block in the heap we do not have any offset value
7372 * other than curHBlk->size. As the block is already trampled
7373 * we cannot rely on this size. So it is better to stop here unless there
7374 * exists any other mechanism(?) to know the offset to next block.
7379 /*mt009.301 Fixed 64BIT compilation warnings*/
7381 sprintf(prntBuf, " %8u", curHBlk->size);
7383 sprintf(prntBuf, " %8lu", curHBlk->size);
7385 SDisplay(0, prntBuf);
7387 if (CMM_IS_STATIC(curHBlk->memFlags))
7389 /*mt009.301 Fixed 64BIT compilation warnings*/
7391 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7393 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7395 SDisplay(0, prntBuf);
7397 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7399 /*mt009.301 Fixed 64BIT compilation warnings*/
7401 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7403 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7405 SDisplay(0, prntBuf);
7407 else if (CMM_IS_FREE(curHBlk->memFlags))
7409 /*mt009.301 Fixed 64BIT compilation warnings*/
7411 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7413 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7415 SDisplay(0, prntBuf);
7419 sprintf(prntBuf, " Trampled \n");
7420 SDisplay(0, prntBuf);
7422 /* goto next block in the heap */
7423 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7429 #endif /* SSI_DEBUG_LEVEL1 */
7431 /*-- mt035.201 : Added new API for timestamp --*/
7434 * Fun: Get TimeStamp
7436 * Desc: This function is used to Get TimeStamp in micro seconds
7453 struct timespec ptime;
7455 struct timeval ptime;
7464 clock_gettime(CLOCK_REALTIME, &ptime);
7466 gettimeofday(&ptime, NULL);
7469 /* Obtain the time of day, and convert it to a tm struct. --*/
7470 ptm = localtime (&ptime.tv_sec);
7471 /* Klock work fix ccpu00148484 */
7474 /* Format the date and time, down to a single second. --*/
7475 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7478 /* Compute microseconds. --*/
7480 microseconds = ptime.tv_nsec / 1000;
7482 microseconds = ptime.tv_usec;
7485 /* Print the formatted time, in seconds, followed by a decimal point
7486 and the microseconds. --*/
7487 /*mt009.301 Fixed 64BIT compilation warnings*/
7489 sprintf(ts, "%s.%03d", time_string, microseconds);
7491 sprintf(ts, "%s.%03ld", time_string, microseconds);
7497 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7500 * Fun: Get SGetSystemTsk
7502 * Desc: This function is used to Get sytem task id
7511 uint32_t SGetSystemTsk(Void)
7514 return (pthread_self());
7516 } /* end of SGetSystemTsk */
7518 #ifdef SS_MULTICORE_SUPPORT
7521 * Fun: Add Timer thread into system task table
7523 * Desc: This function is used to add the system task
7524 * associated with Timer thread.
7533 static SsSTskEntry* ssdAddTmrSTsk(Void)
7539 /* lock the system task table */
7540 ret = SLock(&osCp.sTskTblLock);
7544 #if (ERRCLASS & ERRCLS_DEBUG)
7545 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7546 "Could not lock system task table");
7552 /* check count of system tasks */
7553 if (osCp.numSTsks == SS_MAX_STSKS)
7556 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7558 #if (ERRCLASS & ERRCLS_DEBUG)
7559 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7560 "Could not give the Semaphore");
7565 #if (ERRCLASS & ERRCLS_ADD_RES)
7566 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7573 /* initialize the system task entry with the information we have */
7574 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7576 /* store the system task priority */
7577 sTsk->tskPrior = SS_NORM_TSK_PRI;
7579 /* initialize the demand queue */
7580 if (ssInitDmndQ(&sTsk->dQ) != ROK)
7583 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7585 #if (ERRCLASS & ERRCLS_DEBUG)
7586 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7587 "Could not give the Semaphore");
7592 #if (ERRCLASS & ERRCLS_DEBUG)
7593 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7594 "Could not initialize demand queue");
7600 /* initialize the system task entry lock */
7601 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7603 ssDestroyDmndQ(&sTsk->dQ);
7605 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7607 #if (ERRCLASS & ERRCLS_DEBUG)
7608 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7609 "Could not give the Semaphore");
7614 #if (ERRCLASS & ERRCLS_DEBUG)
7615 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
7616 "Could not initialize system task entry lock");
7623 /* success, update the table */
7624 sTsk->tskId = osCp.nxtSTskEntry;
7626 sTsk->termPend = FALSE;
7627 osCp.nxtSTskEntry = sTsk->nxt;
7630 /* unlock the system task table */
7632 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7634 #if (ERRCLASS & ERRCLS_DEBUG)
7635 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
7636 "Could not give the Semaphore");
7643 #endif /* SS_MULTICORE_SUPPORT */
7644 /* mt003.301 Readwrite lock and recursive mutex additions */
7645 #ifdef SS_LOCK_SUPPORT
7648 * Fun: ssdInitLockNew
7650 * Desc: This function is used to initialise lock/mutex
7659 S16 ssdInitLockNew(SLockInfo *lockId,uint8_t lockType)
7662 #ifdef SS_REC_LOCK_SUPPORT
7663 pthread_mutexattr_t attr;
7664 #endif /* SS_REC_LOCK_SUPPORT */
7665 Txt prntBuf[PRNTSZE];
7671 #ifdef SS_RDWR_LOCK_SUPPORT
7674 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
7676 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
7677 SDisplay(0, prntBuf);
7682 #endif /* SS_RDWR_LOCK_SUPPORT */
7683 #ifdef SS_REC_LOCK_SUPPORT
7686 retVal = pthread_mutexattr_init(&attr);
7690 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
7695 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
7697 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
7701 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
7702 pthread_mutexattr_destroy(&attr);
7706 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
7709 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
7710 pthread_mutexattr_destroy(&attr);
7716 #endif /* SS_REC_LOCK_SUPPORT */
7719 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
7720 SDisplay(0, prntBuf);
7730 * Desc: This function is used to aquire the read write lock
7739 S16 ssdLockNew(SLockInfo *lockId,uint8_t lockType)
7742 Txt prntBuf[PRNTSZE];
7748 #ifdef SS_RDWR_LOCK_SUPPORT
7751 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
7753 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7754 SDisplay(0, prntBuf);
7761 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
7763 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
7764 SDisplay(0, prntBuf);
7771 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
7773 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7774 SDisplay(0, prntBuf);
7781 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
7783 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7784 SDisplay(0, prntBuf);
7789 #endif /* SS_RDWR_LOCK_SUPPORT */
7790 #ifdef SS_REC_LOCK_SUPPORT
7793 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
7795 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7796 SDisplay(0, prntBuf);
7801 #endif /* SS_REC_LOCK_SUPPORT */
7804 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
7805 SDisplay(0, prntBuf);
7818 * Desc: This function is used to Unlock the read write lock
7827 S16 ssdUnlockNew(SLockInfo *lockId,uint8_t lockType)
7830 Txt prntBuf[PRNTSZE];
7836 #ifdef SS_RDWR_LOCK_SUPPORT
7839 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
7841 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
7842 SDisplay(0, prntBuf);
7847 #endif /* SS_RDWR_LOCK_SUPPORT */
7848 #ifdef SS_REC_LOCK_SUPPORT
7851 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
7853 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7854 SDisplay(0, prntBuf);
7859 #endif /* SS_REC_LOCK_SUPPORT */
7862 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
7863 SDisplay(0, prntBuf);
7872 * Fun: ssdDestroyLockNew
7874 * Desc: This function is used to destroy the read write lock
7883 S16 ssdDestroyLockNew(SLockInfo *lockId,uint8_t lockType)
7885 Txt prntBuf[PRNTSZE];
7891 #ifdef SS_RDWR_LOCK_SUPPORT
7894 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
7896 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
7897 SDisplay(0, prntBuf);
7902 #endif /* SS_RDWR_LOCK_SUPPORT */
7903 #ifdef SS_REC_LOCK_SUPPORT
7906 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
7908 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
7909 SDisplay(0, prntBuf);
7914 #endif /* SS_REC_LOCK_SUPPORT */
7917 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
7918 SDisplay(0, prntBuf);
7924 #endif /* SS_LOCK_SUPPORT */
7926 /* mt005.301 : Cavium Changes */
7927 #ifdef SS_SEUM_CAVIUM
7931 * Fun: ssInitRcvWork
7933 * Desc: This is the initializtion function of receive
7937 * RFAILED - failed, general (optional)
7939 * Notes: Function to initialize the work queue packet
7940 * receiving thread. This creates the new thread to
7941 * receive the work and sets the affinity.
7946 S16 ssInitRcvWork(void)
7948 pthread_attr_t attr;
7952 /* set the required attributes */
7953 pthread_attr_init(&attr);
7954 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
7955 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
7956 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
7958 /* Create a new thread to receive the work queue messages */
7959 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
7961 pthread_attr_destroy(&attr);
7966 pthread_attr_destroy(&attr);
7970 }/* ssInitRcvWork */
7977 * Desc: This is the handler function of receive
7981 * RFAILED - failed, general (optional)
7983 * Notes:The handler function of the work queue receiver task.
7984 * This will be waiting for the work and after receiving
7985 * it, work will converted and posted to that entityt
7991 static void *workRcvTsk(Ptr ptr)
7994 cvmx_wqe_t *workPtr;
7995 Buffer *mBuf, *rcvdBuf;
7996 SsMsgInfo *minfoPtr;
8005 /* get the work if its avilable */
8006 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8008 if ( workPtr == NULLP )
8010 /* If there is no work then sleep for 10 usec */
8012 ts.tv_nsec = 500000;
8014 nanosleep(&ts, NULLP);
8018 switch(workPtr->tag)
8020 /* Switch over according to the tag value */
8021 case SS_CVMX_MBUF_TAG:
8023 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8025 /* Convert the physical address to Pointers */
8026 ret = SConvPhyPtr(&rcvdBuf);
8029 /* mt011.301: Cavium 32 bit changes */
8030 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8034 /* Copy the buffer to this region */
8035 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8038 /* mt011.301: Cavium 32 bit changes */
8039 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8043 /* mt011.301: Cavium 32 bit changes */
8044 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8046 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8048 /* Get the post strucutre and Post the message */
8049 if ( minfoPtr != NULLP)
8051 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8053 (Void)SPstTsk(&pst, mBuf);
8055 /* Free the buffer allocated if it cannot be sent */
8064 /* Invalid tag value, drop the work */
8065 /* mt011.301: Cavium 32 bit changes */
8066 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8075 #endif /* SS_SEUM_CAVIUM */
8077 #ifdef TENB_RTLIN_CHANGES
8078 S16 SInitLock(SLockId *l, uint8_t t)
8081 pthread_mutexattr_t prior;
8082 pthread_mutexattr_init(&prior);
8083 #ifndef RGL_SPECIFIC_CHANGES
8084 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8086 r = pthread_mutex_init(l, &prior);
8087 pthread_mutexattr_destroy(&prior);
8091 #ifdef SS_THR_REG_MAP
8094 * Fun: ssRegMainThread
8096 * Desc: This function is used to add the memory region
8097 * mapping for the main thread.
8099 * Ret: VOID (Always successful)
8107 Void ssRegMainThread(Void)
8110 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8112 printf("\nnot able to get different Id for main thread\n");
8115 /* Here the default region is added as we dont have any region associated with
8116 * Main thread. The thread should not perform any allocation except
8117 * the initial configuratin
8119 #ifdef XEON_SPECIFIC_CHANGES
8120 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8122 SS_GET_THREAD_MEM_REGION() =
8129 * Fun: ssCheckAndAddMemoryRegionMap
8131 * Desc: This function is used to add the memory region
8132 * mapping for the provided sTsk associated thread.
8133 * If the threadId can be placed in the thread memory
8134 * region mapping table and returns success if it is able
8135 * to place. If not, it keeps the thread ID in the static
8136 * local array and increments the count. Once thread Id
8137 * is successfully placed in the thread memory region mapping
8138 * table, pthread_cancel is sent for all the previous threads
8139 * which are failed to place in table.
8141 * Ret: TRUE - Thread ID successfully placed in thread memory region
8143 * FALSE - If thread Id is not placed in thread memory region
8146 * Notes:mapping tablemapping tablng tablee
8151 S32 ssCheckAndAddMemoryRegionMap
8153 pthread_t threadId, /* Thread Id of system task */
8154 Region region /* Region associated with thread */
8157 static uint32_t createdThreads;
8158 static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8162 /* Here 0xFF is considered as invalid region and if the mapping table
8163 * contains 0xFF, that mapping entry is free
8165 if(SS_INVALID_THREAD_REG_MAP !=
8166 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8168 /* Klock work fix ccpu00148484 */
8169 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8171 printf("\nfailed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8172 printf("\nNot able to get the different thread ID, exiting\n");
8175 createdThreadIds[createdThreads++] = threadId;
8178 /* If we found free mapping table entry, place the region and send pthread_cancel
8179 * for all the thread Ids which are created before this
8181 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8182 #ifdef XEON_SPECIFIC_CHANGES
8183 printf("\nThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8184 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8185 SS_MAX_THREAD_REGION_MAP), region);
8187 for(indx = 0; indx < createdThreads; indx++)
8189 #ifdef XEON_SPECIFIC_CHANGES
8190 printf("\nSending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8192 pthread_cancel(createdThreadIds[indx]);
8198 } /* ssCheckAndAddMemoryRegionMap */
8202 * Fun: ssCheckAndDelMemoryRegionMap
8204 * Desc: This function is used to add the memory region
8205 * mapping for the provided sTsk associated thread.
8206 * If the threadId can be placed in the thread memory
8207 * region mapping table and returns success if it is able
8208 * to place. If not, it keeps the thread ID in the static
8209 * local array and increments the count. Once thread Id
8210 * is successfully placed in the thread memory region mapping
8211 * table, pthread_cancel is sent for all the previous threads
8212 * which are failed to place in table.
8214 * Ret: TRUE - Thread ID successfully placed in thread memory region
8216 * FALSE - If thread Id is not placed in thread memory region
8219 * Notes:mapping tablemapping tablng tablee
8224 S32 ssCheckAndDelMemoryRegionMap
8226 pthread_t threadId /* Thread Id of system task */
8231 /* Raghu To-Do Check with team, is it necessary to acquire lock
8232 * as del and add may go parallel */
8233 /* Here 0xFF is considered as invalid region and if the mapping table
8234 * contains 0xFF, that mapping entry is free
8236 if(SS_INVALID_THREAD_REG_MAP ==
8237 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8240 printf("\nInvalid Thread ID (%ld)\n", (uint32_t)threadId);
8242 printf("\nInvalid Thread ID (%d)\n", (uint32_t)threadId);
8246 /* If we found free mapping table entry, place the region and send pthread_cancel
8247 * for all the thread Ids which are created before this
8249 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8253 } /* ssCheckAndAddMemoryRegionMap */
8257 #ifdef SS_TSKLOG_ENABLE
8262 * Desc: This function will return current time through input parameter.
8265 * RFAILED - failed, general (optional)
8273 volatile uint32_t *startTime,
8277 #ifdef MSPD_MLOG_NEW
8278 *startTime = GetTIMETICK();
8287 * Desc: This function will return current time through input parameter.
8288 * and take the difference of start time provided as input parameter
8292 * RFAILED - failed, general (optional)
8300 volatile uint32_t startTime,
8304 /*uint32_t stopTime;*/
8307 case PID_MAC_HARQ_IND:
8308 case PID_SCH_TTI_IND:
8310 case PID_MAC_DAT_IND:
8311 case PID_MAC_SF_ALLOC_REQ:
8312 case PID_MAC_STA_RSP:
8313 case PID_MAC_DL_SCHD:
8314 case PID_MAC_DL_CQI_IND:
8315 case PID_MAC_UL_CQI_IND:
8316 case PID_MAC_UL_SCHD:
8317 case PID_MAC_TTI_IND:
8318 case PID_CL_RCV_PHY_MSG:
8319 case PID_CL_HARQ_STA_IND:
8320 case PID_MAC_AM_HARQ_RLS:
8321 case PID_CL_DL_BATCH_PROC:
8322 case PID_CL_DLM_PRC_TTI_IND:
8323 case PID_CRC_IND_REAL:
8324 case PID_CRC_IND_DUMMY:
8325 case PID_TTI_LATENCY:
8326 case PID_RECPREQ_PROC:
8329 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8331 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8334 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8343 volatile uint32_t * startTime,
8353 volatile uint32_t startTime,
8360 #endif /*#ifdef SS_TSKLOG_ENABLE */
8361 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8363 * This primitive is used to calculate the CPU Utilization per Core
8368 * @return Void - function is always success
8370 Void UpdateSocCpuInfo
8372 CmCpuStatsInfo *cpuInfo,
8377 S8 mipsStr[MIPS_STRING_LEN];
8384 /* Open the file which holds the MIPS available value */
8385 mipsFd = fopen(MIPS_FILE, "r");
8392 /* Get the free mips available value from the file */
8393 if(NULLP == fgets(mipsStr, 24, mipsFd))
8395 printf("\nfgets to get the free mips available failed\n");
8400 strtok(mipsStr, " ");
8402 strPart = strtok(NULLP, " ");
8404 if(idx == CM_L2_CPU_UTIL)
8406 if(strPart != NULLP)
8408 l2FreeCpu = atoi(strPart);
8409 l2CpuUsed = 100 - l2FreeCpu;
8410 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8411 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
8412 cpuInfo->cpuUtil[0].numSamples++;
8415 if(idx == CM_L3_CPU_UTIL)
8417 strPart = strtok(NULLP, " ");
8418 if(strPart != NULLP)
8420 l3FreeCpu = atoi(strPart);
8421 l3CpuUsed = 100 - l3FreeCpu;
8422 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8423 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
8424 cpuInfo->cpuUtil[0].numSamples++;
8427 if(idx == CM_L2_CPU_UTIL)
8429 cpuInfo->numCores = CM_NUM_L2_CORES ;
8431 else if(idx == CM_L3_CPU_UTIL)
8433 cpuInfo->numCores = CM_NUM_L3_CORES ;
8439 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8440 #ifdef SS_MULTICORE_SUPPORT
8443 * Fun: Add Timer thread into system task table
8445 * Desc: This function is used to add the system task
8446 * associated with Timer thread.
8455 static SsSTskEntry* ssdReAddTmrSTsk(
8463 /* lock the system task table */
8464 ret = SLock(&osCp.sTskTblLock);
8468 #if (ERRCLASS & ERRCLS_DEBUG)
8469 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8470 "Could not lock system task table");
8476 /* initialize the system task entry with the information we have */
8477 sTsk = &osCp.sTskTbl[idx];
8482 SDestroyLock(&sTsk->lock);
8483 ssDestroyDmndQ(&sTsk->dQ);
8486 /* store the system task priority */
8487 sTsk->tskPrior = SS_NORM_TSK_PRI;
8489 /* initialize the demand queue */
8490 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8493 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8495 #if (ERRCLASS & ERRCLS_DEBUG)
8496 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8497 "Could not give the Semaphore");
8502 #if (ERRCLASS & ERRCLS_DEBUG)
8503 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8504 "Could not initialize demand queue");
8510 /* initialize the system task entry lock */
8511 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8513 ssDestroyDmndQ(&sTsk->dQ);
8515 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8517 #if (ERRCLASS & ERRCLS_DEBUG)
8518 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8519 "Could not give the Semaphore");
8524 #if (ERRCLASS & ERRCLS_DEBUG)
8525 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8526 "Could not initialize system task entry lock");
8533 /* success, update the table */
8534 sTsk->tskId = idx + 1;
8536 sTsk->termPend = FALSE;
8538 /* unlock the system task table */
8540 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8542 #if (ERRCLASS & ERRCLS_DEBUG)
8543 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8544 "Could not give the Semaphore");
8551 #endif /* SS_MULTICORE_SUPPORT */
8556 * Fun: Initialize timer table
8558 * Desc: This function initializes MTSS-specific information
8559 * in the timer table.
8568 S16 ssdReInitTmr(void)
8570 pthread_attr_t attr;
8571 struct sched_param param_sched;
8572 #ifndef XEON_SPECIFIC_CHANGES
8575 #ifdef SS_MULTICORE_SUPPORT
8577 #endif /* SS_MULTICORE_SUPPORT */
8578 #ifdef SS_THR_REG_MAP
8579 uint32_t threadCreated = FALSE;
8580 #endif /* SS_THR_REG_MAP */
8583 #ifndef XEON_SPECIFIC_CHANGES
8584 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
8587 #if (ERRCLASS & ERRCLS_DEBUG)
8588 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8589 "Could not give the Semaphore");
8595 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
8596 /* mt010.21: addition */
8598 #ifdef SS_MULTICORE_SUPPORT
8599 sTsk = ssdReAddTmrSTsk(0);
8604 #endif /* SS_MULTICORE_SUPPORT */
8605 /* create the timer handler thread */
8607 pthread_attr_init(&attr);
8608 /* mt021.201 - Addition to set stack size */
8609 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
8610 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8611 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8612 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
8613 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
8614 pthread_attr_setschedparam(&attr, ¶m_sched);
8617 #ifdef SS_THR_REG_MAP
8618 /* When the thread is created, we check for the memory mapping table if
8619 * threadId can be placed in thread memory map table. If it is not able to place
8620 * threadId is stored in tmporary array. Once thread is created successful,
8621 * thread_cancel is sent for each thread which are created before. All the
8622 * threads are made to wait on sema which is cancel point for thread.
8624 while(threadCreated == FALSE)
8627 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
8629 /* mt020.201 - Addition for destroying thread attribute object attr */
8630 pthread_attr_destroy(&attr);
8635 #ifdef SS_THR_REG_MAP
8636 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
8639 #endif /* SS_THR_REG_MAP */
8640 #ifdef SS_MEM_WL_DEBUG
8641 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
8644 /* mt020.201 - Addition for destroying thread attribute object attr */
8645 pthread_attr_destroy(&attr);
8646 sem_post(&osCp.dep.ssStarted);
8650 /**********************************************************************
8652 **********************************************************************/