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 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
168 /* general purpose debug zone */
169 char my_buffer2[4096 * 4] = { 0 };
170 char my_buffer[4096] = { 0 };
171 int my_buffer_idx = 0;
174 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
176 struct sigcontext my_uc_mcontext = { 0 };
181 #include <ucontext.h>
185 #define SIGSEGV_STACK_GENERIC
186 #define REGFORMAT "%x\n"
188 #ifdef XEON_SPECIFIC_CHANGES
189 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
192 void dump_external(void);
194 static Void mtDelSigals(Void)
198 memset(&sa, 0, sizeof(struct sigaction));
199 sigemptyset(&sa.sa_mask);
200 sa.sa_handler = SIG_DFL;
201 sigaction(SIGSEGV, &sa, NULL);
203 memset(&sa, 0, sizeof(struct sigaction));
204 sigemptyset(&sa.sa_mask);
205 sa.sa_handler = SIG_DFL;
206 sigaction(SIGILL, &sa, NULL);
210 static void signal_segv(int signum, siginfo_t * info, void *ptr)
212 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
215 ucontext_t *ucontext = (ucontext_t *) ptr;
216 #ifdef XEON_SPECIFIC_CHANGES
218 int *p32 = (int *) 0x2fff0000;
223 printf("\nsegv ooops @ %p\n", info->si_addr);
226 printf("\nSegmentation Fault!\n");
227 printf("\ninfo.si_signo = %d\n", signum);
228 printf("\ninfo.si_errno = %d\n", info->si_errno);
229 printf("\ninfo.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
230 printf("\ninfo.si_addr = %p\n", info->si_addr);
232 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
235 #ifndef RGL_SPECIFIC_CHANGES
236 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
237 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
238 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
239 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
240 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
241 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
242 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
243 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
244 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
245 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
246 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
247 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
248 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
249 printf("\nreg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
250 printf("\nreg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
251 printf("\nreg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
252 printf("\nreg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
255 printf("\nStack trace (non-dedicated):\n");
257 sz = backtrace(buffer, 50);
258 strings = backtrace_symbols(buffer, sz);
259 for (i = 0; i < sz; ++i)
260 printf("%s\n", strings[i]);
262 printf("\nEnd of stack trace\n");
264 #ifdef XEON_SPECIFIC_CHANGES
269 /* Lets first print our debug information */
270 printf("\nBefore dumping our Debug info\n");
272 printf("\nAfter dumping our Debug info\n");
274 /* Disable the signal and make the enodeb to dump. This will make
275 * eNB to generate the core with dumping the ccpu log
282 /* End printing debug information */
287 /*** TBD: IMPORTANT ***
288 *** The following definition is temporary. This must be removed
289 *** when all products have been updated with latest ssi.h file OR
290 *** all ssi.h files have been updated to contain this definitions
292 /* New error class for FTHA added */
294 #define ERRCLS_FTHA 0x8
295 #endif /* ERRCLS_FTHA */
297 typedef struct _SPThreadCreateArg
299 void *argument; /* argument that is to be passed to the actual pthread */
300 void *(*start_routine) (void *); /* function from which pthread starts */
303 void *pthreadCreateHdlr(void* arg);
305 #ifdef SS_LOCKLESS_MEMORY
306 Buffer *mtTskBuffer1;
307 Buffer *mtTskBuffer2;
309 pthread_t tmpRegTidMap[20];
311 S16 SGlobMemInfoShow(void);
312 #endif /* SS_LOCKLESS_MEMORY */
315 APP_CONTEXT AppContext;
319 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
320 unsigned int tlPost(void *handle);
323 /* forward references */
324 /* mt003.301 Modifications - Moved to ss_gen.x */
325 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
326 Void *mtTskHdlrT2kL2 ARGS((Void*));
327 void mtSigSegvHndlr ARGS((void));
328 void mtSigUsr2Hndlr ARGS((void));
331 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
332 static Void *mtTskHdlr ARGS((void *));
333 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
335 static Void *mtTmrHdlr ARGS((void *));
336 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
338 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
339 static Void mtIntSigHndlr ARGS((int));
340 static Void mtExitClnup ARGS((void));
343 static Void *mtConHdlr ARGS((void *));
347 #ifdef SS_DRVR_SUPPORT
348 static Void *mtIsTskHdlr ARGS((void *));
352 /* mt020.201 - Addition for no command line available */
354 static Void mtGetOpts ARGS((void));
355 /* mt003.301 Additions - File Based task registration made
356 * common for both MULTICORE and NON-MULTICORE
358 static Bool fileBasedMemCfg = FALSE;
361 /* mt033.201 - addition of local function to print the statistics such as
362 * (size vs. numAttempts) and (allocations vs. deallocations)
364 #ifdef SSI_DEBUG_LEVEL1
365 static S16 SPrintRegMemStats ARGS((Region region));
366 #endif /* SSI_DEBUG_LEVEL1 */
368 #ifdef SS_MULTICORE_SUPPORT
369 static SsSTskEntry* ssdAddTmrSTsk(Void);
370 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
371 #ifndef SS_LOCKLESS_MEMORY
372 #ifndef RGL_SPECIFIC_CHANGES
373 static S16 ssdInitMemInfo ARGS((void));
378 /* mt005.301: Cavium changes */
379 #ifdef SS_SEUM_CAVIUM
380 static Void *workRcvTsk ARGS((void *));
381 #endif /* SS_SEUM_CAVIUM */
383 #ifdef SS_THR_REG_MAP
384 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
386 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
387 #endif /* SS_THR_REG_MAP */
389 /* type declarations */
391 #ifdef SS_DRVR_SUPPORT
392 typedef struct mtIsFlag
402 /* public variable declarations */
404 Cntr cfgNumRegs = SS_MAX_REGS;
405 /* Set memory configuration as false.
406 * Set to true if memory configuration through file is successfull.
408 Bool memConfigured = FALSE;
409 /* mt022.201 - Modification for shared memory relay region and memcal tool */
410 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
413 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
415 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
416 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
417 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
418 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
419 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
420 { SS_POOL_STATIC, 0 }
426 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
428 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
429 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
430 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
431 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
432 { SS_POOL_STATIC, 0 }
435 #endif /* INTEL_WLS */
437 #ifdef SS_LOCKLESS_MEMORY
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_DYNAMIC, MT_POOL_4_DSIZE },
447 { SS_POOL_STATIC, 0 }
451 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
453 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
454 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
455 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
456 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
457 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
458 { SS_POOL_STATIC, 0 }
462 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
464 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
465 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
466 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
467 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
468 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
469 { SS_POOL_STATIC, 0 }
473 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
475 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
476 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
477 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
478 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
479 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
480 { SS_POOL_STATIC, 0 }
484 SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
486 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
487 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
488 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
489 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
490 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
491 { SS_POOL_STATIC, 0 }
495 SS_DFLT_REGION + 6, SS_MAX_POOLS_PER_REG - 1,
497 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
498 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
499 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
500 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
501 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
502 { SS_POOL_STATIC, 0 }
506 SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1,
508 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
509 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
510 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
511 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
512 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
513 { SS_POOL_STATIC, 0 }
517 #ifndef INTEL_WLS_MEM
520 SS_DFLT_REGION + 8, SS_MAX_POOLS_PER_REG - 1,
522 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
523 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
524 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
525 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
526 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
527 { SS_POOL_STATIC, 0 }
532 #endif /* SS_LOCKLESS_MEMORY */
534 /* mt003.301 Modifications - File Based task registration made
535 * common for both MULTICORE and NON-MULTICORE
538 #ifdef SS_LOCKLESS_MEMORY
539 MtDynMemCfg mtDynMemoCfg =
541 SS_MAX_REGS, /* number of regions */
544 SS_DFLT_REGION, /* region id */
545 MT_MAX_BKTS, /* number of buckets */
547 /* block size, no. of blocks, Upper threshold, lower threshold */
548 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
549 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
550 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
551 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
552 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
556 SS_DFLT_REGION + 1, /* region id */
557 MT_MAX_BKTS, /* number of buckets */
559 /* block size, no. of blocks, Upper threshold, lower threshold */
560 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
561 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
562 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
563 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
564 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
568 SS_DFLT_REGION + 2, /* region id */
569 MT_MAX_BKTS, /* number of buckets */
571 /* block size, no. of blocks, Upper threshold, lower threshold */
572 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
573 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
574 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
575 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
576 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
580 SS_DFLT_REGION + 3, /* region id */
581 MT_MAX_BKTS, /* number of buckets */
583 /* block size, no. of blocks, Upper threshold, lower threshold */
584 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
585 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
586 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
587 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
588 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
592 SS_DFLT_REGION + 4, /* region id */
593 MT_MAX_BKTS, /* number of buckets */
595 /* block size, no. of blocks, Upper threshold, lower threshold */
596 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
597 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
598 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
599 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
600 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
604 SS_DFLT_REGION + 5, /* region id */
605 MT_MAX_BKTS, /* number of buckets */
607 /* block size, no. of blocks, Upper threshold, lower threshold */
608 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
609 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
610 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
611 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
612 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
616 SS_DFLT_REGION + 6, /* region id */
617 MT_MAX_BKTS, /* number of buckets */
619 /* block size, no. of blocks, Upper threshold, lower threshold */
620 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
621 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
622 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
623 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
624 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
628 SS_DFLT_REGION + 7, /* region id */
629 MT_MAX_BKTS, /* number of buckets */
631 /* block size, no. of blocks, Upper threshold, lower threshold */
632 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
633 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
634 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
635 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
636 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
639 #ifndef INTEL_WLS_MEM
642 SS_DFLT_REGION + 8, /* region id */
643 MT_MAX_BKTS, /* number of buckets */
645 /* block size, no. of blocks, Upper threshold, lower threshold */
646 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
647 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
648 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
649 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
650 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
654 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
657 SS_DFLT_REGION + 7, /* region id */
658 MT_MAX_BKTS, /* number of buckets */
660 /* block size, no. of blocks, Upper threshold, lower threshold */
661 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
662 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
663 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
664 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
672 MtGlobMemCfg mtGlobMemoCfg =
674 MT_MAX_BKTS, /* number of buckets */
677 /* block size, no. of blocks, Upper threshold, lower threshold */
678 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
679 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
680 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
681 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
682 {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
684 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
685 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
686 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
687 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
691 #endif /* SS_LOCKLESS_MEMORY */
693 /* mt022.201 - Modification for memory calculator tool */
694 /* mt018.201 - added memory configuration matrix */
698 SS_MAX_REGS - 1, /* number of regions */
700 #ifndef XEON_SPECIFIC_CHANGES
701 SS_MAX_REGS, /* number of regions */
708 SS_DFLT_REGION, /* region id */
709 MT_MAX_BKTS, /* number of buckets */
710 MT_HEAP_SIZE, /* heap size */
712 #ifndef XEON_SPECIFIC_CHANGES
713 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
714 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
715 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
716 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
717 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
719 {256, 491520}, /* 60 pages of 2M*/
720 {512, 12288}, /* 3 pages of 2M */
721 {2048, 99328}, /* 97 Pages of 2M */
722 {8192, 75008}, /* 293 Pages of 2M */
723 {16384, 4096} /* 32 pages of 2M */
728 #ifndef SS_LOCKLESS_MEMORY
730 SS_DFLT_REGION + 1, /* region id */
731 MT_MAX_BKTS, /* number of buckets */
732 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
734 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
735 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
736 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
737 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
745 #endif /* SS_LOCKLESS_MEMORY */
746 #endif /* INTEL_WLS */
747 #ifdef SS_LOCKLESS_MEMORY
749 SS_DFLT_REGION + 1, /* region id */
750 MT_MAX_BKTS, /* number of buckets */
751 MT_HEAP_SIZE, /* heap size */
753 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
754 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
755 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
756 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
757 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
761 SS_DFLT_REGION + 2, /* region id */
762 MT_MAX_BKTS, /* number of buckets */
763 MT_HEAP_SIZE, /* heap size */
765 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
766 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
767 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
768 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
769 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
773 SS_DFLT_REGION + 3, /* region id */
774 MT_MAX_BKTS, /* number of buckets */
775 MT_HEAP_SIZE, /* heap size */
777 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
778 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
779 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
780 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
781 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
785 SS_DFLT_REGION + 4, /* region id */
786 MT_MAX_BKTS, /* number of buckets */
787 MT_HEAP_SIZE, /* heap size */
789 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
790 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
791 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
792 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
793 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
797 SS_DFLT_REGION + 5, /* region id */
798 MT_MAX_BKTS, /* number of buckets */
799 MT_HEAP_SIZE, /* heap size */
801 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
802 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
803 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
804 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
805 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
809 SS_DFLT_REGION + 6, /* region id */
810 MT_MAX_BKTS, /* number of buckets */
811 MT_HEAP_SIZE, /* heap size */
813 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
814 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
815 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
816 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
817 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
821 SS_DFLT_REGION + 7, /* region id */
822 MT_MAX_BKTS, /* number of buckets */
823 MT_HEAP_SIZE, /* heap size */
825 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
826 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
827 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
828 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
829 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
833 #ifndef INTEL_WLS_MEM
836 SS_DFLT_REGION + 8, /* region id */
837 MT_MAX_BKTS, /* number of buckets */
838 MT_HEAP_SIZE, /* heap size */
840 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
841 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
842 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
843 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
844 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
848 #endif /* SS_LOCKLESS_MEMORY */
852 /* mt003.301 Modifications - File Based task registration made
853 * common for both MULTICORE and NON-MULTICORE
854 * bucket info, as different regions may request for different no.
857 MtBktCfg mtBktInfo[MT_MAX_BKTS];
858 S16 msArgc; /* argc */
859 Txt **msArgv; /* argv */
860 S16 msOptInd; /* SGetOpt vars */
861 S8 *msOptArg; /* SGetOpt vars */
864 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
865 typedef struct _MtRegMemSz
871 #ifdef SS_USE_WLS_MEM
872 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
873 static S16 SPartitionWlsDynMem();
874 static S16 SAllocateWlsDynMem();
877 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
882 /* private variable declarations */
883 /* mt018.201 - change mtCMMRegCfg as array of pointers */
884 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
885 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
886 /* mt003.301 - Fixed compilation warnings */
887 /*mt004.301-addede new veriable for FAP*/
888 /*mt010.301 - removed veriable defined for FA*/
891 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
894 void mtSetNtlHdl(unsigned int hdl)
899 unsigned int mtGetNtlHdl()
901 return(osCp.ntl.hdl);
905 void mtGetWlsHdl(void **hdlr)
907 *hdlr = osCp.wls.intf;
910 #ifdef XEON_MULTIPLE_CELL_CHANGES
911 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
912 S16 smWrReadWlsConfigParams (Void);
915 /*WLS Memory Size variables*/
916 #ifdef INTEL_L1_V20_03_ONWARDS
917 uint64_t nWlsMacMemorySize = 0;
918 uint64_t nWlsPhyMemorySize = 0;
921 static int SOpenWlsIntf()
925 #define WLS_DEVICE_NAME "wls0"
927 char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", "gnb0", "--iova-mode=pa"};
928 printf("\nCalling rte_eal_init: ");
929 for (i = 0; i < RTE_DIM(my_argv); i++)
931 printf("%s ", my_argv[i]);
935 if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
936 rte_panic("\nCannot init EAL\n");
939 #ifdef XEON_SPECIFIC_CHANGES
940 #ifdef XEON_MULTIPLE_CELL_CHANGES
941 hdl = WLS_Open(gWrWlsDeviceName, 1);
943 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
947 #ifdef INTEL_L1_V20_03_ONWARDS
948 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, &nWlsMacMemorySize, &nWlsPhyMemorySize);
951 printf("\nERROR: WLS_Open > DEVICE_NAME mismatch. WLS Device Name should be same as 'wls_dev_name' parameter in 'phycfg_xran.xml' file");
954 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
955 #endif /*INTEL_L1_V20_03_ONWARDS*/
963 printf("\nCould not open WLS Interface \n");
978 * Desc: This function is the entry point for the final binary. It
979 * calls SInit() in the common code. It can be replaced by a
980 * user function if required (SInit() must still be called).
982 * Ret: none on success
992 int argc, /* argument count */
993 char **argv /* argument vector */
997 #ifdef XEON_MULTIPLE_CELL_CHANGES
998 /* Read the WLS parameters from the file and copy into global control block */
999 if(smWrReadWlsConfigParams() != ROK)
1001 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
1003 } /* end of if statement */
1006 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
1009 #endif /* INTEL_WLS */
1013 /* mt003.301 Modifications */
1016 printf("\n SInit failed, SSI could not start \n");
1017 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
1021 /*mt010.301 cleanup part exposed to user*/
1032 * Desc: This function is the entry point for the final binary. It
1033 * calls SInit() in the common code. It can be replaced by a
1034 * user function if required (SInit() must still be called).
1036 * Ret: none on success
1046 int argc, /* argument count */
1047 char **argv /* argument vector */
1063 * initialization functions
1068 * Fun: Initialize OS control point
1070 * Desc: This function initializes MTSS-specific information
1071 * in the OS control point.
1080 S16 ssdInitGen(void)
1082 struct sigaction act;
1084 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1085 struct sigaction sa;
1089 /*mt014.301 : 4GMX release related changes*/
1090 #ifdef SS_4GMX_UCORE
1093 /* mt005.301 : Cavium changes */
1094 #ifdef SS_SEUM_CAVIUM
1095 /* set group mask for the core */
1096 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
1097 #endif /* SS_SEUM_CAVIUM */
1099 osCp.dep.sysTicks = 0;
1101 /* mt020.201 - Addition for no command line available */
1103 /* parse command line */
1105 /* mt003.301 Additions */
1106 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
1108 printf("\n File Based Memory configuration failed \n");
1113 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
1114 #ifndef SS_LOCKLESS_MEMORY
1115 #ifdef SS_MULTICORE_SUPPORT
1116 if(memConfigured == FALSE)
1122 /* initialize the started semaphore */
1123 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1128 /* mt028.201 added compile time flag to allow not to mask signals */
1130 /* mask all signals in the main thread */
1132 sigdelset(&set, SIGINT);
1133 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1134 sigdelset(&set, SIGSEGV);
1135 sigdelset(&set, SIGUSR2);
1136 sigdelset(&set, SIGILL);
1137 #ifdef XEON_SPECIFIC_CHANGES
1138 sigdelset(&set, SIGABRT);
1139 sigdelset(&set, SIGTERM);
1140 sigdelset(&set, SIGHUP);
1143 pthread_sigmask(SIG_SETMASK, &set, NULLP);
1144 #endif /* UNMASK_SIG */
1146 /* install a SIGINT handler to shutdown */
1147 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1149 /*Initialize SIGSEGV Signal */
1150 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1152 memset(&sa, 0, sizeof(struct sigaction));
1153 sigemptyset(&sa.sa_mask);
1154 sa.sa_sigaction = signal_segv;
1155 sa.sa_flags = SA_SIGINFO;
1156 #ifndef XEON_SPECIFIC_CHANGES
1157 sigaction(SIGSEGV, &sa, NULL);
1159 memset(&sa, 0, sizeof(struct sigaction));
1160 sigemptyset(&sa.sa_mask);
1161 sa.sa_sigaction = signal_segv;
1162 sa.sa_flags = SA_SIGINFO;
1164 sigaction(SIGILL, &sa, NULL);
1166 if(sigaction(SIGILL, &sa, NULL) != 0)
1168 printf("\nFailed to process sigaction for the SIGILL\n");
1171 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1173 printf("\nFailed to process sigaction for the SIGSEGV\n");
1176 if(sigaction(SIGABRT, &sa, NULL) != 0)
1178 printf("\nFailed to process sigaction for the SIGABRT\n");
1181 if(sigaction(SIGTERM, &sa, NULL) != 0)
1183 printf("\nFailed to process sigaction for the SIGTERM\n");
1186 if(sigaction(SIGHUP, &sa, NULL) != 0)
1188 printf("\nFailed to process sigaction for the SIGHUP\n");
1193 signal (SIGSEGV, mtSigSegvHndlr);
1194 signal (SIGKILL, mtSigSegvHndlr);
1195 signal (SIGUSR2, mtSigUsr2Hndlr);
1200 signal (SIGINT, mtStopHndlr);
1203 act.sa_handler = mtIntSigHndlr;
1204 sigfillset(&act.sa_mask);
1206 if (sigaction(SIGINT, &act, NULLP) != 0)
1212 /* mt040.201 initialise random seed */
1213 osCp.dep.randSeed = time(NULLP);
1221 * Fun: De-initialize OS control point
1223 * Desc: This function reverses the initialization in ssdInitGen().
1232 Void ssdDeinitGen(void)
1236 sem_destroy(&osCp.dep.ssStarted);
1241 #ifdef SS_LOCKLESS_MEMORY
1245 * Fun: ssPutDynMemBlkSet
1247 * Desc: Returns the set of dynamic Blocks into the global region
1250 * Ret: ROK - successful,
1251 * RFAILED - unsuccessful.
1258 S16 ssPutDynMemBlkSet
1260 uint8_t bktIdx, /* Index to bucket list */
1261 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1262 added to global region */
1265 CmMmGlobRegCb *globReg;
1266 CmMmGlobalBktCb *bktCb;
1270 globReg = osCp.globRegCb;
1272 #if (ERRCLASS & ERRCLS_INT_PAR)
1273 if(bktIdx >= globReg->numBkts)
1277 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1279 bktCb = &(globReg->bktTbl[bktIdx]);
1281 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1283 blkPtr = dynMemSetElem->nextBktPtr;
1284 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1285 free((Void *)blkPtr);
1288 dynMemSetElem->nextBktPtr = NULLP;
1289 dynMemSetElem->numFreeBlks = 0;
1296 * Fun: ssGetDynMemBlkSet
1298 * Desc: Gets the set of dynamic memory blocks from the global region
1301 * Ret: ROK - successful,
1302 * RFAILED - unsuccessful.
1309 S16 ssGetDynMemBlkSet
1311 uint8_t bktIdx, /* Index to bucket list */
1312 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1313 with new set values */
1317 CmMmGlobRegCb *globReg;
1318 CmMmGlobalBktCb *bktCb;
1323 globReg = osCp.globRegCb;
1325 #if (ERRCLASS & ERRCLS_INT_PAR)
1326 if(bktIdx >= globReg->numBkts)
1330 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1332 bktCb = &(globReg->bktTbl[bktIdx]);
1333 basePtr = &(dynMemSetElem->nextBktPtr);
1335 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1337 blkPtr = (Data *)malloc(bktCb->size);
1339 basePtr = (CmMmEntry **)blkPtr;
1342 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1346 } /* ssGetDynMemBlkSet */
1351 * Fun: ssPutDynMemBlkSet
1353 * Desc: Returns the set of dynamic Blocks into the global region
1356 * Ret: ROK - successful,
1357 * RFAILED - unsuccessful.
1364 S16 ssPutDynMemBlkSet
1366 uint8_t bktIdx, /* Index to bucket list */
1367 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1368 added to global region */
1369 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1372 CmMmGlobRegCb *globReg;
1373 CmMmGlobalBktCb *bktCb;
1375 CmMmBlkSetElement *globMemNode;
1379 globReg = osCp.globRegCb;
1381 #if (ERRCLASS & ERRCLS_INT_PAR)
1382 if(bktIdx >= globReg->numBkts)
1386 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1388 bktCb = &(globReg->bktTbl[bktIdx]);
1390 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1391 try lock is used as it is not required to block as it will be taken
1392 in the next go else it will be blocked for lock as we have to get the
1395 SLock(&(bktCb->bucketLock));
1401 /* Get a free node from the free node linked list */
1402 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1403 if(lstNode == NULLP)
1405 SUnlock(&(bktCb->bucketLock));
1409 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1411 /* Copy the content of the received element information on to free node
1412 * and add it to valid linked list */
1413 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1414 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1415 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1416 dynMemSetElem->numFreeBlks = 0;
1417 dynMemSetElem->nextBktPtr = NULLP;
1419 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1421 SUnlock(&(bktCb->bucketLock));
1429 * Fun: ssGetDynMemBlkSet
1431 * Desc: Gets the set of dynamic memory blocks from the global region
1434 * Ret: ROK - successful,
1435 * RFAILED - unsuccessful.
1437 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1443 S16 ssGetDynMemBlkSet
1445 uint8_t bktIdx, /* Index to bucket list */
1446 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1447 with new set values */
1448 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1451 CmMmGlobRegCb *globReg;
1452 CmMmGlobalBktCb *bktCb;
1454 CmMmBlkSetElement *globMemNode;
1458 globReg = osCp.globRegCb;
1460 #if (ERRCLASS & ERRCLS_INT_PAR)
1461 if(bktIdx >= globReg->numBkts)
1465 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1467 bktCb = &(globReg->bktTbl[bktIdx]);
1469 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1470 try lock is used as it is not required to block as it will be taken
1471 in the next go else it will be blocked for lock as we have to get the
1474 SLock(&(bktCb->bucketLock));
1479 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1481 if(lstNode == NULLP)
1483 SUnlock(&(bktCb->bucketLock));
1487 /* Delete the node from the valid linked list and copy the values of the
1488 * elements of structrues into pointer */
1489 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1490 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1491 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1492 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1494 /* Add this node to the free node linked list */
1495 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1497 SUnlock(&(bktCb->bucketLock));
1501 } /* ssGetDynMemBlkSet */
1504 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1505 uint32_t gDynMemAlrm[4];
1506 static uint32_t memoryCheckCounter;
1508 uint32_t isMemThreshReached(Region reg)
1510 CmMmGlobRegCb *globReg;
1511 CmMmGlobalBktCb *bktCb;
1512 uint8_t bktIdx= reg;
1514 globReg = osCp.globRegCb;
1516 #if (ERRCLASS & ERRCLS_INT_PAR)
1517 if(bktIdx >= globReg->numBkts)
1521 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1523 bktCb = &(globReg->bktTbl[bktIdx]);
1525 if(gDynMemAlrm[bktIdx])
1527 // printf ("\nunder memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1528 SLock(&(bktCb->bucketLock));
1529 if(bktCb->listValidBktSet.count > 25)
1531 gDynMemAlrm[bktIdx] = FALSE;
1532 // printf ("\nrecoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1534 SUnlock(&(bktCb->bucketLock));
1540 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1542 // printf ("\nCHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1543 SLock(&(bktCb->bucketLock));
1544 if(bktCb->listValidBktSet.count < 15 )
1545 gDynMemAlrm[bktIdx] = TRUE;
1546 memoryCheckCounter = 0;
1547 SUnlock(&(bktCb->bucketLock));
1553 #endif /* USE_MALLOC */
1554 #endif /* SS_LOCKLESS_MEMORY */
1556 #ifdef SS_USE_ICC_MEMORY
1559 * Fun: Initialize region/pool tables
1561 * Desc: This function initializes MTSS-specific information
1562 * in the region/pool tables and configures the common
1563 * memory manager for use.
1572 Void * ssGetIccHdl(Region region)
1574 CmMmDynRegCb *dynRegCb;
1576 /* Klock work fix ccpu00148484 */
1577 if(!(region < SS_MAX_REGS))
1582 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1584 return (dynRegCb->iccHdl);
1586 #endif /* SS_USE_ICC_MEMORY */
1588 #ifdef T2K_MEM_LEAK_DBG
1589 RegionMemLeakInfo regMemLeakInfo;
1590 #endif /* T2K_MEM_LEAK_DBG */
1592 #ifdef SS_USE_WLS_MEM
1593 static S16 SPartitionWlsDynMem()
1596 uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1598 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1600 mtDynMemSz[i].startAddr = bktMemStrtAddr;
1601 bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1604 printf("\nGlobal Memory Info: \n");
1605 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1607 printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1612 static S16 SAllocateWlsDynMem()
1617 memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1619 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1621 reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1622 mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1624 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1625 #ifdef INTEL_L1_V20_03_ONWARDS
1626 nWlsMacMemorySize+nWlsPhyMemorySize);
1627 #elif INTEL_L1_V19_10
1630 (reqdMemSz + (4 * 1024 * 1024)));
1632 printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1633 SPartitionWlsDynMem();
1641 S16 SPartitionWlsMemory()
1646 uint64_t pageSize[1], hugePageSize;
1649 long int pageSize[1], hugePageSize;
1652 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1654 uint8_t *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1656 gethugepagesizes(pageSize,1);
1657 hugePageSize = pageSize[0];
1658 for (i = 0; i < 1; i++)
1660 mtRegMemSz[i].startAddr = regMemStrtAddr;
1661 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1663 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1664 reqdSz = numHugePg * hugePageSize;
1665 regMemStrtAddr += reqdSz;
1666 #ifdef T2K_MEM_LEAK_DBG
1667 /* Since wls is region 0 */
1668 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1669 regMemLeakInfo.numActvRegions++;
1670 #endif /* T2K_MEM_LEAK_DBG */
1672 //Store last region addr for validation
1673 mtRegMemSz[i].startAddr = regMemStrtAddr;
1677 #ifdef SS_MEM_WL_DEBUG
1678 Void SChkAddrValid(int type, int region, PTR ptr)
1680 char *tryPtr = NULL;
1681 if(type == 0) //Global
1683 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1684 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1686 printf("\n****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1692 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1694 printf("\n****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1700 #endif /* SS_MEM_WL_DEBUG */
1702 S16 SPartitionStaticMemory(uint8_t *startAddr)
1707 uint8_t *regMemStrtAddr = (uint8_t *)startAddr;
1710 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1711 for (i = 1; i < mtMemoCfg.numRegions; i++)
1713 mtRegMemSz[i].startAddr = regMemStrtAddr;
1714 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1715 regMemStrtAddr += reqdSz;
1716 #ifdef T2K_MEM_LEAK_DBG
1717 { /* Since region 1 onwards are used for non wls */
1718 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1719 regMemLeakInfo.numActvRegions++;
1721 #endif /* T2K_MEM_LEAK_DBG */
1725 S16 SAllocateWlsMem()
1733 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1734 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1736 for (i = 0; i < 1; i++)
1738 /* allocate space for the region */
1739 region = &mtMemoCfg.region[i];
1740 reqdMemSz += region->heapsize;
1741 mtRegMemSz[i].reqdSz += region->heapsize;
1743 for (j = 0; j < region->numBkts; j++)
1745 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1746 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1749 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1750 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1752 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1754 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1756 SPartitionWlsMemory();
1759 S16 SAllocateStaticMem()
1768 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1770 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1771 for (i = 1; i < mtMemoCfg.numRegions; i++)
1773 /* allocate space for the region */
1774 region = &mtMemoCfg.region[i];
1775 reqdMemSz += region->heapsize;
1776 mtRegMemSz[i].reqdSz += region->heapsize;
1778 for (j = 0; j < region->numBkts; j++)
1780 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1781 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1785 startAddr = malloc(reqdMemSz + (1024 * 10));
1787 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1789 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1791 SPartitionStaticMemory(startAddr);
1794 #endif /* INTEL_WLS */
1800 * Fun: Initialize region/pool tables
1802 * Desc: This function initializes MTSS-specific information
1803 * in the region/pool tables and configures the common
1804 * memory manager for use.
1813 S16 ssdInitMem(void)
1815 /* mt018.201 - added local variable */
1819 MtRegCfg *region = NULLP;
1820 Txt errMsg[256] = {'\0'};
1821 #ifdef SS_LOCKLESS_MEMORY
1822 CmMmDynRegCb *dynRegCb =0;
1823 #ifdef SS_USE_ICC_MEMORY
1825 CmMmGlobRegCb *globReg = NULLP;
1828 #endif /* SS_LOCKLESS_MEMORY */
1831 /* Use the default SSI memory manager if the ICC memory manager is not
1832 * avilable. If ICC memory manager is avilable, it will be used for
1833 * all sharable memory allocation and de-allocation */
1834 #ifdef SS_LOCKLESS_MEMORY
1835 #ifdef SS_USE_ICC_MEMORY
1836 #ifndef YS_PHY_3_8_2
1838 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1840 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1841 if(dynRegCb == NULLP)
1845 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1847 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1849 dynRegCb->region = i;
1850 cmMmDynRegInit(dynRegCb);
1851 printf("\niccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1854 /* ysIccHdl = dynRegCb->iccHdl; */
1857 /* Initialize the global region first */
1858 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1860 if(osCp.globRegCb == NULLP)
1865 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1867 #ifdef SS_USE_WLS_MEM
1868 SAllocateWlsDynMem();
1871 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1873 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1874 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1875 globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1876 printf("\nStarting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1879 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1881 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1884 if(globReg->bktTbl[i].startAddr == NULLP)
1888 globReg->bktTbl[i].poolId = i;
1889 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1890 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1891 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1894 globReg->numBkts = mtGlobMemoCfg.numBkts;
1895 cmMmGlobRegInit(globReg);
1897 /* Initialize the dynamic task regions and sanity check for the theshold
1899 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1901 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1902 if(dynRegCb == NULLP)
1906 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1908 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1909 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1910 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1911 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1913 #ifdef XEON_SPECIFIC_CHANGES
1918 dynRegCb->bktTbl[k].poolId = k;
1919 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1920 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1921 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1922 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1923 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1925 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1928 dynRegCb->region = i;
1929 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1930 cmMmDynRegInit(dynRegCb);
1932 #endif /* SS_USE_ICC_MEMORY */
1933 #endif /* SS_LOCKLESS_MEMORY */
1935 #ifdef T2K_MEM_LEAK_DBG
1937 /* Initailize mem leak tool memorys for debguing */
1938 regMemLeakInfo.numActvRegions=0;
1939 for(reg=0; reg <SS_MAX_REGS; reg++)
1941 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1942 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1943 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1944 regMemLeakInfo.regStartAddr[reg] = 0;
1947 regMemLeakInfo.regStartAddr[reg] = 0;
1948 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1950 printf("\n mutex init failed\n");
1956 /* Now allocate WLS memory */
1958 SAllocateStaticMem();
1960 /* mt018.201 - CMM Initialization */
1961 for (i = 0; i < mtMemoCfg.numRegions; i++)
1963 /* allocate space for the region control block */
1964 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1965 #ifdef TENB_RTLIN_CHANGES
1966 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1968 if (mtCMMRegCb[i] == NULLP)
1970 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1971 for the Region:%d control block\n",i);
1973 for (k = 0; k < i; k++)
1975 cmMmRegDeInit(mtCMMRegCb[k]);
1976 free(mtCMMRegCfg[k]->vAddr);
1977 free(mtCMMRegCb[k]);
1978 free(mtCMMRegCfg[k]);
1983 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1984 #ifdef TENB_RTLIN_CHANGES
1985 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1987 if (mtCMMRegCfg[i] == NULLP)
1989 for (k = 0; k < i; k++)
1991 cmMmRegDeInit(mtCMMRegCb[k]);
1992 free(mtCMMRegCfg[k]->vAddr);
1993 free(mtCMMRegCb[k]);
1994 free(mtCMMRegCfg[k]);
1996 free(mtCMMRegCb[i]);
2001 /* allocate space for the region */
2002 region = &mtMemoCfg.region[i];
2003 mtCMMRegCfg[i]->size = region->heapsize;
2004 for (j = 0; j < region->numBkts; j++)
2006 /* mt033.201 - addition for including the header size while computing the total size */
2007 #ifdef SSI_DEBUG_LEVEL1
2008 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
2009 (region->bkt[j].numBlks);
2011 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
2012 #endif /* SSI_DEBUG_LEVEL1 */
2015 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
2017 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
2020 #ifdef XEON_SPECIFIC_CHANGES
2021 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
2022 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
2024 #ifdef TENB_RTLIN_CHANGES
2025 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
2028 if (mtCMMRegCfg[i]->vAddr == NULLP)
2030 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
2031 for the Region:%d \n",i);
2033 for (k = 0; k < i; k++)
2035 cmMmRegDeInit(mtCMMRegCb[k]);
2036 free(mtCMMRegCfg[k]->vAddr);
2037 free(mtCMMRegCb[k]);
2038 free(mtCMMRegCfg[k]);
2040 free(mtCMMRegCb[i]);
2041 free(mtCMMRegCfg[i]);
2046 /* set up the CMM configuration structure */
2047 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
2048 mtCMMRegCfg[i]->chFlag = 0;
2049 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
2050 mtCMMRegCfg[i]->numBkts = region->numBkts;
2052 for (j = 0; j < region->numBkts; j++)
2054 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
2055 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
2058 /* initialize the CMM */
2059 #ifdef SS_LOCKLESS_MEMORY
2060 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2062 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2063 #endif /* SS_LOCKLESS_MEMORY */
2065 for (k = 0; k < i; k++)
2067 cmMmRegDeInit(mtCMMRegCb[k]);
2068 free(mtCMMRegCfg[k]->vAddr);
2069 free(mtCMMRegCb[k]);
2070 free(mtCMMRegCfg[k]);
2072 free(mtCMMRegCfg[i]->vAddr);
2073 free(mtCMMRegCb[i]);
2074 free(mtCMMRegCfg[i]);
2079 /* initialize the STREAMS module */
2080 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
2081 if (region->regionId == 0)
2083 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
2085 for (k = 0; k < i; k++)
2087 cmMmRegDeInit(mtCMMRegCb[k]);
2088 free(mtCMMRegCfg[k]->vAddr);
2089 free(mtCMMRegCb[k]);
2090 free(mtCMMRegCfg[k]);
2092 cmMmRegDeInit(mtCMMRegCb[i]);
2093 free(mtCMMRegCfg[i]->vAddr);
2094 free(mtCMMRegCb[i]);
2095 free(mtCMMRegCfg[i]);
2100 /* mt001.301 : Additions */
2101 #ifdef SS_MEM_LEAK_STS
2103 #endif /* SS_MEM_LEAK_STS */
2111 * Fun: De-initialize region/pool tables
2113 * Desc: This function reverses the initialization in ssdInitMem().
2122 Void ssdDeinitMem(void)
2124 /* mt018.201 - added local variables */
2127 /* mt008.301 Additions */
2128 #ifdef SS_MEM_LEAK_STS
2129 cmDeinitMemLeakMdl();
2130 #endif /* SS_MEM_LEAK_STS */
2132 for (i = 0; i < mtMemoCfg.numRegions; i++)
2134 cmMmRegDeInit(mtCMMRegCb[i]);
2135 free(mtCMMRegCfg[i]->vAddr);
2136 free(mtCMMRegCb[i]);
2137 free(mtCMMRegCfg[i]);
2146 * Fun: Initialize task table
2148 * Desc: This function initializes MTSS-specific information
2149 * in the task table.
2158 S16 ssdInitTsk(void)
2160 /* mt001.301 : Additions */
2161 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2162 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2163 uint32_t tskInd = 0;
2164 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2168 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2169 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2170 /* initialize system task information */
2171 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2173 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2175 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2182 * Fun: Deinitialize task table
2184 * Desc: This function reverses the initialization perfomed in
2194 Void ssdDeinitTsk(void)
2201 #ifdef SS_DRVR_SUPPORT
2204 * Fun: Initialize driver task table
2206 * Desc: This function initializes MTSS-specific information
2207 * in the driver task table.
2216 S16 ssdInitDrvr(void)
2220 pthread_attr_t attr;
2225 /* initialize the dependent portion of the driver task entries */
2226 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2228 osCp.drvrTskTbl[i].dep.flag = FALSE;
2232 /* create pipe for communication between SSetIntPend() and
2233 * the isTskHdlr thread.
2235 if (pipe(osCp.dep.isFildes) != 0)
2241 /* create the isTskHdlr thread */
2242 pthread_attr_init(&attr);
2243 /* mt021.201 - Addition to set stack size */
2244 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2245 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2246 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2247 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2249 /* mt020.201 - Addition for destroying thread attribute object attr */
2250 pthread_attr_destroy(&attr);
2256 /*mt014.301 : 4GMX release related changes*/
2257 #ifdef SS_4GMX_UCORE
2265 /* mt020.201 - Addition for destroying thread attribute object attr */
2266 pthread_attr_destroy(&attr);
2275 * Fun: Deinitialize driver information
2277 * Desc: This function reverses the initialization performed in
2287 Void ssdDeinitDrvr(void)
2289 /* mt008.301: Terminate the Driver Task on exit */
2290 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2293 TL_Close(AppContext.hUAII);
2294 if (clusterMode == RADIO_CLUSTER_MODE)
2296 TL_Close(AppContext.hUAII_second);
2302 #endif /* SS_DRVR_SUPPORT */
2307 * Fun: Initialize timer table
2309 * Desc: This function initializes MTSS-specific information
2310 * in the timer table.
2319 S16 ssdInitTmr(void)
2321 pthread_attr_t attr;
2322 struct sched_param param_sched;
2323 /* mt010.21: addition */
2325 #ifdef SS_MULTICORE_SUPPORT
2327 #endif /* SS_MULTICORE_SUPPORT */
2328 #ifdef SS_THR_REG_MAP
2329 uint32_t threadCreated = FALSE;
2330 #endif /* SS_THR_REG_MAP */
2334 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2335 /* mt010.21: addition */
2336 osCp.dep.tmrTqCp.nxtEnt = 0;
2337 for (i=0; i< SS_MAX_TMRS; i++)
2339 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2342 #ifdef SS_MULTICORE_SUPPORT
2343 sTsk = ssdAddTmrSTsk();
2348 #endif /* SS_MULTICORE_SUPPORT */
2349 /* create the timer handler thread */
2350 pthread_attr_init(&attr);
2351 /* mt021.201 - Addition to set stack size */
2352 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2353 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2354 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2355 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2356 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2357 pthread_attr_setschedparam(&attr, ¶m_sched);
2360 #ifdef SS_THR_REG_MAP
2361 /* When the thread is created, we check for the memory mapping table if
2362 * threadId can be placed in thread memory map table. If it is not able to place
2363 * threadId is stored in tmporary array. Once thread is created successful,
2364 * thread_cancel is sent for each thread which are created before. All the
2365 * threads are made to wait on sema which is cancel point for thread.
2367 while(threadCreated == FALSE)
2370 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2372 /* mt020.201 - Addition for destroying thread attribute object attr */
2373 pthread_attr_destroy(&attr);
2378 #ifdef SS_THR_REG_MAP
2379 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2382 #endif /* SS_THR_REG_MAP */
2383 #ifdef SS_MEM_WL_DEBUG
2384 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2387 /* mt020.201 - Addition for destroying thread attribute object attr */
2388 pthread_attr_destroy(&attr);
2397 * Fun: Deinitialize timer table
2399 * Desc: This function reverses the initialization performed in
2409 Void ssdDeinitTmr(void)
2411 #ifdef SS_MULTICORE_SUPPORT
2414 #endif /* SS_MULTICORE_SUPPORT */
2417 #ifdef SS_MULTICORE_SUPPORT
2418 ret = SLock(&osCp.sTskTblLock);
2422 #if (ERRCLASS & ERRCLS_DEBUG)
2423 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2424 "Could not lock system task table");
2428 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2429 /* clean up the system task entry */
2433 SDestroyLock(&sTsk->lock);
2434 ssDestroyDmndQ(&sTsk->dQ);
2437 /* make this entry available in the system task table */
2438 sTsk->nxt = osCp.nxtSTskEntry;
2439 osCp.nxtSTskEntry = 0;
2443 /* unlock the system task table */
2444 SUnlock(&osCp.sTskTblLock);
2446 #endif /* SS_MULTICORE_SUPPORT */
2447 /* mt008.301: Terminate the timer thread on exit */
2448 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2458 * Desc: Pre-tst() initialization.
2467 S16 ssdInitLog(void)
2469 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2473 pthread_attr_t attr;
2476 #endif /* CONSTDIO */
2481 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2486 osCp.dep.conInFp = (FILE *) stdin;
2487 osCp.dep.conOutFp = (FILE *) stdout;
2488 /* added compile time flag CONRD: mt017.21 */
2492 /* disable canonical input processing */
2493 fd = fileno(osCp.dep.conInFp);
2494 if ((tcgetattr(fd, &tio)) != 0)
2496 printf("\nError: disable canonical input processing\n");
2500 tio.c_lflag &= ~ICANON;
2501 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2502 tio.c_cc[VTIME] = 0;
2503 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2505 printf("\nError: while tcsetattr() processing\n");
2509 #endif /* CONSTDIO */
2512 /* set up the input fd to block when no data is available */
2513 fd = fileno(osCp.dep.conInFp);
2514 flags = fcntl(fd, F_GETFL, &flags);
2515 flags &= ~O_NONBLOCK;
2516 if (fcntl(fd, F_SETFL, flags) == -1)
2518 printf("\nError: while fcntl processing\n");
2523 /* create the console handler thread */
2524 pthread_attr_init(&attr);
2525 /* mt021.201 - Addition to set stack size */
2526 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2527 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2528 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2531 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2533 /* mt020.201 - Addition for destroying thread attribute object attr */
2534 pthread_attr_destroy(&attr);
2536 printf("\nError: Logging Thread creation failed \n");
2540 /* mt020.201 - Addition for destroying thread attribute object attr */
2541 pthread_attr_destroy(&attr);
2555 * Desc: This function reverses the initialization performed in
2565 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2566 Void ssdDeinitLog(void)
2568 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2571 /* mt008.301: Terminate the console reader on exit */
2572 while(pthread_cancel(osCp.dep.conHdlrTID));
2578 /* mt001.301 : Additions */
2582 S16 ssdInitWatchDog(uint16_t port)
2585 Txt prntBuf[PRNTSZE];
2588 #ifdef SS_WATCHDOG_IPV6
2589 struct sockaddr_in6 tmpaddr;
2591 struct sockaddr_in tmpaddr;
2592 #endif /* SS_WATCHDOG_IPV6 */
2593 #ifdef SS_MULTIPLE_PROCS
2594 ProcId procId = SS_WD_WDPROC;
2595 if (SAddProcIdLst(1, &procId) != ROK)
2599 #endif /* SS_MULTIPLE_PROCS */
2602 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2604 /* Create a watch dog system task */
2605 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2607 /* Create a watch dog reveiver system task */
2608 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2610 /* Register and attach watch dog TAPA task */
2611 #ifdef SS_MULTIPLE_PROCS
2612 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2613 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2615 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2616 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2617 #endif /* SS_MULTIPLE_PROCS */
2618 /* Register and attach watch dog receiver TAPA task */
2619 #ifdef SS_MULTIPLE_PROCS
2620 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2621 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2623 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2624 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2625 #endif /* SS_MULTIPLE_PROCS */
2627 #ifndef SS_MULTIPLE_PROCS
2628 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2629 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2631 osCp.wdCp.watchDgPst.srcProcId = procId;
2632 osCp.wdCp.watchDgPst.dstProcId = procId;
2633 #endif /* SS_MULTIPLE_PROCS */
2635 /* Initialise the pst structure */
2636 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2637 /* Initialize the watch dog timer resolution default is 1 sec */
2639 cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2640 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2641 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2642 for(idx = 0; idx < 1; idx++)
2644 osCp.wdCp.watchDgTs[idx].first = NULLP;
2645 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2647 #ifdef SS_MULTIPLE_PROCS
2648 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2650 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2651 #endif /* SS_MULTIPLE_PROCS */
2653 /* Create the watch dog receiver socket */
2654 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2655 if(osCp.wdCp.globWd.sock == -1)
2657 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2661 #ifdef SS_WATCHDOG_IPV6
2662 tmpaddr.sin6_len = sizeof(tmpadDr);
2663 tmpaddr.sin6_family = AF_INET6;
2664 tmpaddr.sin6_addr = in6addr_any;
2665 tmpaddr.sin6_port = htons(port);
2667 tmpaddr.sin_family = AF_INET;
2668 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2669 tmpaddr.sin_port = htons(port);
2670 #endif /* SS_WATCHDOG_IPV6 */
2672 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2675 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2679 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2683 #ifndef SS_MULTIPLE_PROCS
2684 pst.srcProcId = SFndProcId();
2685 pst.dstProcId = SFndProcId();
2687 pst.srcProcId = procId;
2688 pst.dstProcId = procId;
2689 #endif /* SS_MULTIPLE_PROCS */
2690 pst.event = EVTSSHRTBTREQ;
2691 ssdInitWatchDgPst(&pst);
2692 SPstTsk(&pst, mBuf);
2697 S16 ssdInitWatchDgPst(Pst *pst)
2700 pst->selector = SS_LOOSE_COUPLING;
2702 pst->region = DFLT_REGION; /* region */
2703 pst->pool = DFLT_POOL; /* pool */
2705 pst->prior = PRIOR0; /* priority */
2706 pst->route = RTESPEC; /* route */
2708 pst->dstEnt = ENTHB; /* destination entity */
2710 pst->srcEnt = ENTDW; /* source entity */
2716 #ifdef SS_MULTIPLE_PROCS
2717 S16 ssdWatchDgActvTmr
2724 S16 ssdWatchDgActvTmr(Void)
2725 #endif /* SS_MULTIPLE_PROCS */
2728 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2733 Void ssdWatchDgTmrEvt
2735 PTR cb, /* control block */
2736 S16 event /* timer number */
2739 /* mt003.301 Fixed warings */
2743 Txt prntBuf[PRNTSZE];
2752 SPrint("Timer Heartbeat Request Expired");
2754 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2759 SLock(&osCp.wdCp.wdLock);
2760 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2762 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2764 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2766 if(osCp.wdCp.globWd.callback != 0)
2768 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2772 SUnlock(&osCp.wdCp.wdLock);
2774 if(!osCp.wdCp.globWd.watchdogStop)
2776 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2777 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2787 Void ssdStartWatchDgTmr
2798 Txt prntBuf[PRNTSZE];
2802 /* mt003.301 Modifications */
2805 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2806 if(event == SS_TMR_HRTBT)
2808 SPrint("\nSTART SS_TMR_HRTBT");
2815 SLock(&osCp.wdCp.wdLock);
2816 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2818 osCp.wdCp.globWd.wdsta[i].status = 0;
2820 SUnlock(&osCp.wdCp.wdLock);
2822 arg.tq = osCp.wdCp.watchDgTs;
2823 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2824 arg.timers = osCp.wdCp.watchDgTmr;
2825 arg.cb = (PTR)NULLP;
2827 arg.wait = osCp.wdCp.globWd.timeout = wait;
2835 Void ssdStopWatchDgTmr
2844 Txt prntBuf[PRNTSZE];
2848 /* mt003.301 Modifications */
2851 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2852 if(event == SS_TMR_HRTBT)
2854 SPrint("STOP SS_TMR_HRTBT");
2858 SLock(&osCp.wdCp.wdLock);
2859 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2861 osCp.wdCp.globWd.wdsta[i].status = 0;
2863 SUnlock(&osCp.wdCp.wdLock);
2866 arg.tq = osCp.wdCp.watchDgTs;
2867 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2868 arg.timers = osCp.wdCp.watchDgTmr;
2869 arg.cb = (PTR)NULLP;
2888 Txt prntBuf[PRNTSZE];
2890 struct sockaddr_in tmpaddr;
2891 char hbMsg[SS_WD_HB_MSG_SIZE];
2898 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2902 /* Pack the message */
2903 strcpy(hbMsg, "<HB>REQ</HB>");
2905 /* Send the heartbeat messages to all the configured nodes */
2906 SLock(&osCp.wdCp.wdLock);
2907 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2909 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2914 /* Identify the destination node */
2915 #ifdef SS_WATCHDOG_IPV6
2916 tmpaddr.sin6_len = sizeof(tmpaddr);
2917 tmpaddr.sin6_family = AF_INET6;
2918 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2919 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2921 tmpaddr.sin_family = AF_INET;
2922 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2923 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2924 #endif /* SS_WATCHDOG_IPV6 */
2926 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2930 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2931 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2938 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2943 SUnlock(&osCp.wdCp.wdLock);
2948 #endif /* SS_WATCHDOG */
2952 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2958 * Desc: This function gets command line options.
2967 static Void mtGetOpts(void)
2974 FILE *memOpt; /* memory options file pointer */
2977 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2983 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2985 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2991 #ifdef SS_LOCKLESS_MEMORY
3006 osCp.dep.fileOutFp = (FILE *)NULLP;
3008 /* initialize memOpt */
3009 memOpt = (FILE *) NULLP;
3016 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
3021 /* mt001.301 : Additions */
3022 #ifdef SS_MEM_LEAK_STS
3024 cmMemOpenMemLkFile(msOptArg);
3028 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3031 fileBasedMemCfg = TRUE;
3032 memOpt = fopen(msOptArg, "r");
3034 /* if file does not exist or could not be opened then use the
3035 * default memory configuration as defined in mt_ss.h
3037 if (memOpt == (FILE *) NULLP)
3039 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3040 be opened, using default mem configuration\n", msOptArg);
3045 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3047 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3053 case 0: /*** INPUT: Number of regions ***/
3054 sscanf(line, "%ld", (long *) &numReg);
3055 mtMemoCfg.numRegions = numReg;
3056 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3058 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3064 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3065 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3066 if(numBkts > MT_MAX_BKTS)
3068 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3072 if(numPools > SS_MAX_POOLS_PER_REG)
3074 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3079 * Delay updation from local variable to global
3080 * structure of number of regions and heap data to
3081 * counter error conditions present above.
3083 for(idx = 0; idx < cfgNumRegs; idx++)
3085 mtMemoCfg.region[idx].numBkts = numBkts;
3086 cfgRegInfo[idx].region = idx;
3087 cfgRegInfo[idx].numPools = numPools;
3089 * Initialize the pool info as static type with size zero
3091 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3093 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3094 cfgRegInfo[idx].pools[poolIdx].size = 0;
3099 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3100 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3102 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3104 if(bktIdx >= numBkts)
3106 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3111 mtBktInfo[bktIdx].blkSize = bktSz;
3113 if(bktUpdtCnt == numBkts)
3115 i++; /*done reading bkt info, start reading individual region info*/
3119 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3120 sscanf(line,"%ld",(long *) ®Id);
3121 if(regId >= mtMemoCfg.numRegions)
3123 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3124 #ifndef XEON_SPECIFIC_CHANGES
3129 mtMemoCfg.region[regId].regionId = regId;
3132 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3133 if(bktUpdtCnt < numBkts)
3135 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3136 if(bktIdx >= numBkts)
3138 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3143 if(bktIdx < MT_MAX_BKTS)
3145 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3146 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3147 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3148 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3151 if(bktUpdtCnt == numBkts)
3158 case 5: /* INPUT: Heapsize ***/
3159 sscanf(line, "%ld", (long *) &heapSz);
3160 mtMemoCfg.region[regId].heapsize = heapSz;
3162 if(regUpdtCnt != mtMemoCfg.numRegions)
3171 #ifdef SS_LOCKLESS_MEMORY
3173 sscanf(line, "%ld", (long *) &numBkts);
3174 mtGlobMemoCfg.numBkts = numBkts;
3175 #ifndef XEON_SPECIFIC_CHANGES
3176 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3179 #ifdef XEON_SPECIFIC_CHANGES
3180 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3181 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3182 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3184 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3187 mtDynMemoCfg.region[idx].regionId = idx;
3188 mtDynMemoCfg.region[idx].numBkts = numBkts;
3196 if(bktUpdtCnt < numBkts)
3198 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3199 (long *) &bktSz, (long *) &bktNum,
3200 (long *) &bktSetSize, (long *) &bktRelThr,
3201 (long *) &bktAqurThr);
3202 /* Klock work fix ccpu00148484 */
3203 if(bktIdx < SS_MAX_POOLS_PER_REG)
3205 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3206 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3207 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3208 #ifdef XEON_SPECIFIC_CHANGES
3209 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3210 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3211 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3213 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3215 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3221 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3223 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3224 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3225 #ifdef XEON_SPECIFIC_CHANGES
3226 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3227 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3228 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3234 #ifdef XEON_SPECIFIC_CHANGES
3235 if(bktUpdtCnt == numBkts)
3241 case 8: /* INPUT: Global Heapsize ***/
3242 sscanf(line, "%ld", (long *) &heapSz);
3243 mtGlobMemoCfg.heapSize = heapSz;
3244 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3252 memConfigured = FALSE;
3256 memConfigured = TRUE;
3264 /* mt028.201: modification: multiple procs support related changes */
3265 #ifndef SS_MULTIPLE_PROCS
3268 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3270 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3273 #else /* SS_MULTIPLE_PROCS */
3277 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3279 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3281 SAddProcIdLst(1, &procId);
3284 #endif /* SS_MULTIPLE_PROCS */
3288 osCp.configFilePath = msOptArg;
3312 * Desc: Get options from command line
3314 * Ret: option - success
3316 * EOF - end of options
3318 * Notes: Handles command lines like the following
3321 * then command line should look like this...
3322 * -a foo -b foo1 -c -d foo
3326 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3331 * nloops = atoi(msArgv[msOptInd]);
3334 * state1 = atoi(msArgv[msOptInd]);
3346 int argc, /* argument count */
3347 char **argv, /* argument value */
3348 char *opts /* options */
3351 /* mt020.201 - Removed for no command line */
3359 /* mt020.201 - Addition for no command line */
3371 /*mt013.301 : Changes as per coding standards*/
3372 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3378 if (!strcmp(argv[msOptInd], "--"))
3383 else if (argv[msOptInd][0] != '-')
3391 c = argv[msOptInd][sp];
3392 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3394 if (argv[msOptInd][++sp] == '\0')
3405 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3408 if (++msOptInd >= (S16) argc)
3413 else msOptArg = argv[msOptInd++];
3420 if (argv[msOptInd][++sp] == '\0')
3432 #endif /* NOCMDLINE */
3440 * Desc: This function starts system services execution; the
3441 * permanent tasks are started and the system enters a
3458 /* mt025.201 - Modification for adding lock to timer handler */
3459 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3461 sem_post(&osCp.dep.ssStarted);
3470 * indirect interface functions to system services service user
3476 * Fun: ssdAttachTTsk
3478 * Desc: This function sends the initial tick message to a TAPA
3479 * task if the task is a permanent task.
3490 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3497 if (tTsk->tskType == SS_TSK_PERMANENT)
3499 /* Send a permanent tick message to this task, to start
3502 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3505 #if (ERRCLASS & ERRCLS_DEBUG)
3506 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3511 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3512 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3514 /* set up post structure */
3515 /* mt028.201: modification: multiple procs support related changes */
3516 #ifndef SS_MULTIPLE_PROCS
3517 mInfo->pst.dstProcId = SFndProcId();
3518 mInfo->pst.srcProcId = SFndProcId();
3519 #else /* SS_MULTIPLE_PROCS */
3520 mInfo->pst.dstProcId = tTsk->proc;
3521 mInfo->pst.srcProcId = tTsk->proc;
3522 #endif /* SS_MULTIPLE_PROCS */
3523 mInfo->pst.selector = SEL_LC_NEW;
3524 mInfo->pst.region = DFLT_REGION;
3525 mInfo->pst.pool = DFLT_POOL;
3526 mInfo->pst.prior = PRIOR3;
3527 mInfo->pst.route = RTESPEC;
3528 mInfo->pst.event = 0;
3529 mInfo->pst.dstEnt = tTsk->ent;
3530 mInfo->pst.dstInst = tTsk->inst;
3531 mInfo->pst.srcEnt = tTsk->ent;
3532 mInfo->pst.srcInst = tTsk->inst;
3534 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3535 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3541 #if (ERRCLASS & ERRCLS_DEBUG)
3542 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3543 "Could not write to demand queue");
3556 * Fun: ssdDetachTTsk
3558 * Desc: Does nothing.
3569 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3579 * Fun: ssdCreateSTsk
3581 * Desc: This function creates a system task. A thread is started
3582 * on the system task handler function defined later.
3593 SsSTskEntry *sTsk /* pointer to system task entry */
3597 pthread_attr_t attr;
3598 /* struct sched_param param_sched;*/
3600 #ifdef SS_THR_REG_MAP
3601 uint32_t threadCreated = FALSE;
3606 #ifdef SS_SINGLE_THREADED
3607 /* mt001.301 : Additions */
3609 #ifdef SS_MULTICORE_SUPPORT
3610 if (osCp.numSTsks > 1)
3612 if (osCp.numSTsks > 0)
3613 #endif /* SS_MULTICORE_SUPPORT */
3615 #ifdef SS_MULTICORE_SUPPORT
3616 if (osCp.numSTsks > 3)
3618 if (osCp.numSTsks > 2)
3619 #endif /* SS_MULTICORE_SUPPORT */
3620 #endif /* SS_WATCHDOG */
3627 /* set the current executing entity and instance IDs to
3628 * 'not configured'. create the lock to access them.
3630 sTsk->dep.ent = ENTNC;
3631 sTsk->dep.inst = INSTNC;
3634 /* create the thread */
3635 pthread_attr_init(&attr);
3636 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3638 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3639 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3640 if (sTsk->tskPrior == 0)
3642 printf("\nCreating RT thread #######################\n");
3643 #ifdef SS_THR_REG_MAP
3644 /* When the thread is created, we check for the memory mapping table if
3645 * threadId can be placed in thread memory map table. If it is not able to place
3646 * threadId is stored in tmporary array. Once thread is created successful,
3647 * thread_cancel is sent for each thread which are created before. All the
3648 * threads are made to wait on sema which is cancel point for thread.
3650 while(threadCreated == FALSE)
3653 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3656 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3657 pthread_attr_destroy(&attr);
3659 #if (ERRCLASS & ERRCLS_DEBUG)
3660 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3665 #ifdef SS_THR_REG_MAP
3666 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3674 #ifdef SS_THR_REG_MAP
3675 /* When the thread is created, we check for the memory mapping table if
3676 * threadId can be placed in thread memory map table. If it is not able to place
3677 * threadId is stored in tmporary array. Once thread is created successful,
3678 * thread_cancel is sent for each thread which are created before. All the
3679 * threads are made to wait on sema which is cancel point for thread.
3681 while(threadCreated == FALSE)
3684 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3688 /* mt020.201 - Addition for destroying thread attribute object attr */
3689 pthread_attr_destroy(&attr);
3691 #if (ERRCLASS & ERRCLS_DEBUG)
3692 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3697 #ifdef SS_THR_REG_MAP
3698 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3705 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3706 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3708 static uint32_t stLwpId = 3;
3709 sTsk->dep.lwpId = ++stLwpId;
3711 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3713 /* mt020.201 - Addition for destroying thread attribute object attr */
3714 pthread_attr_destroy(&attr);
3723 pthread_attr_t* attr,
3724 void *(*start_routine) (void *),
3729 #ifdef SS_THR_REG_MAP
3730 uint32_t threadCreated = FALSE;
3733 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3734 /* Klock work fix ccpu00148484 */
3735 if(threadArg == NULLP)
3739 threadArg->argument = arg;
3740 threadArg->start_routine = start_routine;
3743 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3745 #ifdef SS_THR_REG_MAP
3746 /* When the thread is created, we check for the memory mapping table if
3747 * threadId can be placed in thread memory map table. If it is not able to place
3748 * threadId is stored in tmporary array. Once thread is created successful,
3749 * thread_cancel is sent for each thread which are created before. All the
3750 * threads are made to wait on sema which is cancel point for thread.
3752 while(threadCreated == FALSE)
3755 /*pthreadCreateHdlr */
3756 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3761 #ifdef SS_THR_REG_MAP
3762 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3773 * Fun: Set Pthread Attributes
3775 * Desc: This function is used to set various explicit
3776 * pthread attributes like, priority scheduling,etc
3786 static S16 ssdSetPthreadAttr
3789 pthread_attr_t *attr
3792 struct sched_param param;
3795 SMemSet(¶m, 0, sizeof(param));
3797 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3798 param.sched_priority = 100 - 1 - tskPrior;
3800 param.sched_priority = 100 - 10 - tskPrior;
3803 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3804 /* TODO:: This can be avoided by reducing the priority
3805 * of iccserv thread in l1_master.sh*/
3807 if (clusterMode == RADIO_CLUSTER_MODE)
3809 if(tskPrior == PRIOR1)
3811 param.sched_priority = 91;
3818 printf("\nSet priority %u\n", param.sched_priority);
3820 /* Set Scheduler to explicit, without this non of the below
3821 pthread attr works */
3822 #ifdef TENB_RTLIN_CHANGES
3823 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3826 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3827 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3828 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3829 #ifdef TENB_RTLIN_CHANGES
3830 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3832 pthread_attr_setschedparam(attr, ¶m);
3836 } /* ssdSetPthreadAttr */
3838 /************* multi-core support **************/
3839 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3840 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3844 * Fun: Get the current core/cpu affinity for a thread/lwp
3846 * Desc: This function is used to get the current processor/core
3847 * affinity for a a system task (thread/lwp). It sets the
3848 * affinity based on the mode supplied by the caller.
3851 * RFAILED - failed, general (optional)
3860 SSTskId *tskId, /* filled in with system task ID */
3861 uint32_t *coreId /* the core/processor id to which the affinity is set */
3871 uint32_t cpuInd = 0;
3872 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3875 uint32_t lwpId = *tskId;
3879 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3881 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3883 tId = osCp.sTskTbl[tskInd].dep.tId;
3888 /* if tskId is not found in the tskTbl */
3889 if (tskInd == SS_MAX_STSKS)
3891 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3896 /* initialize the cpu mask */
3899 /* set thread affinity for linux */
3900 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3902 #if (ERRCLASS & ERRCLS_DEBUG)
3903 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3906 } /* end if pthread_setaffinity fails */
3908 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3910 if (CPU_ISSET (cpuInd, & cpuSet))
3919 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3921 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3923 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3928 /* if tskId is not found in the tskTbl */
3929 if (tskInd == SS_MAX_STSKS)
3931 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3935 /* set thread affinity for Solaris */
3936 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3938 #if (ERRCLASS & ERRCLS_DEBUG)
3939 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3942 } /* end if processor_bind fails */
3945 #endif /* SS_LINUX */
3949 } /* ssdGetAffinity */
3954 * Fun: Set the core/cpu affinity for a thread/lwp
3956 * Desc: This function is used to set processor/core affinity for a
3957 * a system task (thread/lwp). It sets the affinity based on the
3958 * mode supplied by the caller.
3961 * RFAILED - failed, general (optional)
3970 SSTskId *tskId, /* filled in with system task ID */
3971 uint32_t coreId /* the core/processor id to which the affinity has to be set */
3975 uint32_t tskInd = 0;
3980 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3983 uint32_t lwpId = *tskId;
3989 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3991 /* Here tskId can not be used as index as the task may be terminated if
3992 there is a TERM even for that tsk, thus breaking the task Id numbering
3994 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3996 tId = osCp.sTskTbl[tskInd].dep.tId;
4001 /* if tskId is not found in the tskTbl */
4002 if (tskInd == SS_MAX_STSKS)
4004 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4008 /* initialize the cpu mask */
4011 /* set the cpu mask */
4012 CPU_SET(coreId, &cpuSet);
4014 /* set thread affinity for linux */
4015 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4017 #if (ERRCLASS & ERRCLS_DEBUG)
4018 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4021 } /* end if pthread_setaffinity fails */
4025 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4027 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4028 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4030 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4035 /* if tskId is not found in the tskTbl */
4036 if (tskInd == SS_MAX_STSKS)
4038 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4042 /* set thread affinity for Solaris */
4043 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4045 #if (ERRCLASS & ERRCLS_DEBUG)
4046 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4049 } /* end if processor_bind fails */
4052 #endif /* SS_LINUX */
4054 } /* ssdSetAffinity */
4056 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4057 /************ end multi-core support *************/
4062 * Fun: ssdDestroySTsk
4064 * Desc: This function destroys a system task. A terminate
4065 * event message is sent to the thread function.
4076 SsSTskEntry *sTsk /* pointer to system task entry */
4085 /* we send a message to this system task to tell it to die */
4086 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4089 #if (ERRCLASS & ERRCLASS_DEBUG)
4090 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4096 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4097 mInfo->eventInfo.event = SS_EVNT_TERM;
4099 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4103 #if (ERRCLASS & ERRCLASS_DEBUG)
4104 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4105 "Could not write to demand queue");
4115 /* mt023.201 - Added SThreadYield function to yield CPU
4119 * Desc: This function defers thread execution to any other ready
4130 S16 SThreadYield(void)
4134 /* mt024.201 - seperated Linux and other UNIX implementations
4140 /* Set sleep value to 0 to yield CPU */
4144 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4146 #else /* other UNICes */
4148 return (sleep(0) == 0 ? ROK : RFAILED);
4150 #endif /* SS_LINUX */
4157 * Fun: Register timer
4159 * Desc: This function is used to register a timer
4160 * function for the service user. System services
4161 * will invoke the timer activation function
4162 * passed to it at the specified intervals.
4166 * Notes: Timing is handled by the common timers. The
4167 * ticks are handled by a thread that uses
4168 * nanosleep() and thus timing precision will not
4176 SsTmrEntry *tmr /* pointer to timer entry */
4184 /* initialize common timers */
4185 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4188 /* start the timer */
4189 arg.tq = osCp.dep.tmrTq;
4190 arg.tqCp = &osCp.dep.tmrTqCp;
4191 arg.timers = tmr->dep.timers;
4196 arg.max = TMR_DEF_MAX;
4197 arg.wait = tmr->interval;
4207 * Fun: Deregister timer
4209 * Desc: This function is used to deregister a timer function.
4220 SsTmrEntry *tmr /* pointer to timer entry */
4228 /* stop the timer */
4229 arg.tq = osCp.dep.tmrTq;
4230 arg.tqCp = &osCp.dep.tmrTqCp;
4231 arg.timers = tmr->dep.timers;
4236 arg.max = TMR_DEF_MAX;
4237 arg.wait = tmr->interval;
4247 * Fun: Critical error
4249 * Desc: This function is called when a critical error occurs.
4260 Seq seq, /* sequence number */
4261 Reason reason /* reset reason */
4271 /* get calling task ID */
4272 tId = pthread_self();
4275 /* set up the message to display */
4276 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4277 "reason = %d\n\n", (uint8_t)tId, seq, reason);
4281 /* delete all system tasks */
4282 for (i = 0; i < SS_MAX_STSKS; i++)
4284 if (osCp.sTskTbl[i].used
4285 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4287 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4293 pthread_exit(NULLP);
4296 /* won't reach here */
4305 * Desc: This function is called to log an error.
4316 Ent ent, /* Calling layer's entity id */
4317 Inst inst, /* Calling layer's instance id */
4318 ProcId procId, /* Calling layer's processor id */
4319 Txt *file, /* file name where error occured */
4320 S32 line, /* line in file where error occured */
4321 ErrCls errCls, /* error class */
4322 ErrCode errCode, /* layer unique error code */
4323 ErrVal errVal, /* error value */
4324 Txt *errDesc /* description of error */
4337 /* get calling task ID */
4339 tId = pthread_self();
4345 case ERRCLS_ADD_RES:
4346 errClsMsg = "ERRCLS_ADD_RES";
4349 case ERRCLS_INT_PAR:
4350 errClsMsg = "ERRCLS_INT_PAR";
4354 errClsMsg = "ERRCLS_DEBUG";
4357 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4359 errClsMsg = "ERRCLS_FTHA";
4363 errClsMsg = "INVALID ERROR CLASS!";
4368 /*mt009.301 Fixed 64BIT compilation warnings*/
4371 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4372 "file: %s line: %03d errcode: %05d errcls: %s\n"
4373 "errval: %05d errdesc: %s\n",
4374 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4377 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4378 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4379 "errval: %05ld errdesc: %s\n",
4380 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4382 SDisplay(0, errBuf);
4383 /* mt001.301 : Additions */
4384 #ifdef SS_LOGGER_SUPPORT
4386 #endif /* SS_LOGGER_SUPPORT */
4390 /* debug errors halt the system */
4391 if (errCls == ERRCLS_DEBUG)
4393 /* mt001.301 : Additions */
4394 #ifdef SS_LOGGER_SUPPORT
4396 #endif /* SS_LOGGER_SUPPORT */
4397 /* delete all system tasks */
4398 for (i = 0; i < SS_MAX_STSKS; i++)
4400 if (osCp.sTskTbl[i].used
4401 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4403 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4409 pthread_exit(NULLP);
4421 * Fun: Register driver task
4423 * Desc: This function is called to register the handlers for a
4435 SsDrvrTskEntry *drvrTsk /* driver task entry */
4442 /* mt001.30 : Additions */
4445 * Fun: Deregister driver task
4447 * Desc: This function is called to deregister the handlers for a
4459 SsDrvrTskEntry *drvrTsk /* driver task entry */
4472 * mt003.301 Additions - SDeRegTTsk fix
4474 #ifdef SS_MULTIPLE_PROCS
4481 #else /*SS_MULTIPLE_PROCS*/
4487 #endif /*SS_MULTIPLE_PROCS*/
4489 #ifdef SS_MULTIPLE_PROCS
4502 /* We check the sTsk element; if it is not NULLP, the
4503 * task is attached. So we have to detach it before
4504 * deregistering the task.
4506 ret = SLock(&osCp.sTskTblLock);
4509 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4512 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4515 #if (ERRCLASS & ERRCLS_DEBUG)
4516 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4518 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4520 #if (ERRCLASS & ERRCLS_DEBUG)
4521 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4529 #ifdef SS_MULTIPLE_PROCS
4531 if (tTsk->initTsk != NULLP)
4534 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4537 &(osCp.tTskTbl[idx].xxCb));
4539 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4542 &(osCp.tTskTbl[idx].xxCb));
4543 #endif /* USE_MEMCAL */
4545 #endif /* SS_MULTIPLE_PROCS */
4547 if (tTsk->sTsk != NULLP)
4551 sTsk->dep.ent = ent;
4552 sTsk->dep.inst = inst;
4554 for (n = 0; n < SS_MAX_TTSKS; n++)
4556 if (sTsk->tTsks[n] == idx)
4558 sTsk->tTsks[n] = SS_INVALID_IDX;
4564 /* call the implementation to detach the task */
4565 ssdDetachTTsk(tTsk);
4567 sTsk->dep.ent = ENTNC;
4568 sTsk->dep.inst = INSTNC;
4571 /* Now we empty the entry for this task and update the table
4574 #ifdef SS_MULTIPLE_PROCS
4575 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4576 #else /* SS_MULTIPLE_PROCS */
4577 osCp.tTskIds[ent][inst] = SS_TSKNC;
4578 #endif /* SS_MULTIPLE_PROCS */
4581 #ifdef SS_MULTIPLE_PROCS
4582 tTsk->proc = PROCNC;
4583 #endif /* SS_MULTIPLE_PROCS */
4585 tTsk->inst = INSTNC;
4586 tTsk->tskType = TTUND;
4587 tTsk->initTsk = NULLP;
4588 tTsk->actvTsk = NULLP;
4591 tTsk->nxt = osCp.nxtTTskEntry;
4592 osCp.nxtTTskEntry = idx;
4595 #ifdef SS_MULTIPLE_PROCS
4596 /* mark the control block for this task as invalid */
4597 osCp.tTskTbl[idx].xxCb = NULLP;
4600 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4601 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4603 #if (ERRCLASS & ERRCLS_DEBUG)
4604 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4611 //#ifndef SPLIT_RLC_DL_TASK
4612 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4613 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4614 Void ysMtTskHdlr(Void);
4615 Void ysMtPollPhyMsg(uint8_t region);
4616 Void ysMtRcvPhyMsg(Void);
4617 Void *mtTskHdlrT2kL2
4619 Ptr tskPtr /* pointer to task entry */
4625 /* wait for SS to come up */
4626 /* It is required to block on this semaphore before starting actual processing of
4627 the thread becasue the creator of this thread might want to cance it without
4628 doing any processing. When this semaphore is released, means the creator gives
4629 the go ahead for actual processing and we should never come back to this point */
4630 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4639 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4640 * (processes L1 msgs) */
4646 Void ysMtTskHdlr(Void);
4647 Void YsPhyRecvMsg();
4648 Void *mtTskHdlrT2kL2
4650 Ptr tskPtr /* pointer to task entry */
4656 /* get out the system task entry from the parameter */
4657 sTsk = (SsSTskEntry *) tskPtr;
4659 /* wait for SS to come up */
4660 /* It is required to block on this semaphore before starting actual processing of
4661 the thread becasue the creator of this thread might want to cance it without
4662 doing any processing. When this semaphore is released, means the creator gives
4663 the go ahead for actual processing and we should never come back to this point */
4664 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4667 #ifndef RGL_SPECIFIC_CHANGES
4675 #ifdef V5GTF_SPECIFIC_CHANGES
4678 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4679 * (processes L1 msgs) */
4681 /* get a message from the demand queue */
4684 ret = mtTskHdlMsg(sTsk);
4687 /* exit the for loop here */
4694 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4697 void *pthreadCreateHdlr(void * arg)
4700 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4701 /* mt038.201 changed how sem_wait is called */
4702 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4705 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4713 * Desc: This is the system task handler function. It blocks on
4714 * the system task's demand queue. On receiving a message,
4715 * it identifies the target TAPA task, verifies that the
4716 * TAPA task belongs to this system task and if so, calls
4717 * the activation function of that TAPA task with the
4718 * received message. The task activation function or the
4719 * timer activation function may be called.
4721 * Ret: (thread function)
4730 Ptr tskPtr /* pointer to task entry */
4736 /* get out the system task entry from the parameter */
4737 sTsk = (SsSTskEntry *) tskPtr;
4740 /* wait for SS to come up */
4742 /* mt038.201 changed how sem_wait is called */
4743 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4745 #ifdef XEON_SPECIFIC_CHANGES
4746 printf("\n**********MT Task Handler********\n");
4750 /* Wait for a message from the demand queue */
4751 #ifdef SS_CDMNDQ_SUPPORT
4752 ret = ssCDmndQWait(&sTsk->dQ);
4754 ret = ssDmndQWait(&sTsk->dQ);
4759 ret = mtTskHdlMsg(sTsk);
4774 * Desc: This is the system task handler function. It blocks on
4775 * the system task's demand queue. On receiving a message,
4776 * it identifies the target TAPA task, verifies that the
4777 * TAPA task belongs to this system task and if so, calls
4778 * the activation function of that TAPA task with the
4779 * received message. The task activation function or the
4780 * timer activation function may be called.
4782 * Ret: (thread function)
4797 SsTTskEntry *tTsk=NULLP;
4800 Buffer *mBuf2=NULLP;
4802 SsMsgInfo *mInfo=NULLP;
4804 /* mt028.201: modification: multiple procs support related changes */
4805 #ifndef SS_MULTIPLE_PROCS
4807 PAIFTMRS16 tmrActvFnMt = NULLP;
4809 /* mt015.301 Initialized the timer activation functions with NULLP */
4810 PFS16 tmrActvFn = NULLP;
4812 PAIFTMRS16 tmrActvFn =NULLP;
4813 uint16_t procIdIdx =0;
4814 #endif /* SS_MULTIPLE_PROCS */
4815 /* mt003.301 Modifications */
4816 #ifdef SS_THREAD_PROFILE
4818 #endif /* SS_THREAD_PROFILE */
4821 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4824 /* nothing to receive */
4828 /* if we can't lock this system task entry, return the message */
4829 ret = SLock(&sTsk->lock);
4833 #if (ERRCLASS & ERRCLS_DEBUG)
4834 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4835 "Could not lock system task entry");
4845 mBuf2 = mBuf->b_next;
4847 /* find out what kind of message this is */
4848 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4849 #ifdef SS_MEM_WL_DEBUG
4850 mtTskBuffer1 = mBuf2;
4852 mtTskBuffer2 = mBuf2->b_next;
4854 if(mInfo == 0x5050505)
4858 cmAnalyseBtInfo((PTR) mBuf,4);
4860 printf("\n In trouble .... \n");
4862 else if (mInfo == 0x2020202)
4865 cmAnalyseBtInfo((PTR) mBuf,1);
4866 printf("\n In trouble .... \n");
4868 #endif /* SS_MEM_WL_DEBUG */
4869 switch (mInfo->eventInfo.event)
4871 /* this is a termination event, we die */
4873 /* release the message */
4876 /* Unlock the system task entry and lock the system
4877 * task table to clean our entry up.
4879 SUnlock(&sTsk->lock);
4881 ret = SLock(&osCp.sTskTblLock);
4885 #if (ERRCLASS & ERRCLS_DEBUG)
4886 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
4887 "Could not lock system task table");
4889 /* what to do here? */
4893 /* clean up the system task entry */
4896 /* mt003.301 Modifications - SDeRegTTsk */
4897 /* sTsk->numTTsks = 0; */
4898 SDestroyLock(&sTsk->lock);
4899 ssDestroyDmndQ(&sTsk->dQ);
4901 /* lock for current executing TAPA task ID */
4903 /* make this entry available in the system task table */
4904 sTsk->nxt = osCp.nxtSTskEntry;
4905 for (i = 0; i < SS_MAX_STSKS; i++)
4907 if (sTsk == &osCp.sTskTbl[i])
4909 osCp.nxtSTskEntry = i;
4916 /* unlock the system task table */
4917 SUnlock(&osCp.sTskTblLock);
4922 /* this is a data message or a permanent task keep-alive message */
4924 case SS_EVNT_PERMTICK:
4925 /* message to a task. find the destination task */
4926 /* mt028.201: modification: multiple procs support related changes */
4927 #ifdef SS_MULTIPLE_PROCS
4928 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
4930 if (procIdIdx == SS_INV_PROCID_IDX)
4936 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
4937 #else /* SS_MULTIPLE_PROCS */
4938 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
4939 #endif /* SS_MULTIPLE_PROCS */
4941 /* verify that it hasn't been deregistered */
4942 if (idx == SS_TSKNC)
4948 /* verify that this system task is still running it */
4949 tTsk = &osCp.tTskTbl[idx];
4950 if (tTsk->sTsk != sTsk)
4956 /* set the current executing TAPA task ID */
4957 sTsk->dep.ent = mInfo->pst.dstEnt;
4958 sTsk->dep.inst = mInfo->pst.dstInst;
4960 /* copy the Pst structure into a local duplicate */
4961 for (i = 0; i < (S16) sizeof(Pst); i++)
4962 *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
4964 /* Give the message to the task activation function. If
4965 * its a normal data message, we pass it, if this is a
4966 * keep-alive message for a permanent task then we pass
4967 * NULLP in place of the message to the task activation
4970 if (mInfo->eventInfo.event == SS_EVNT_DATA)
4972 #ifndef RGL_SPECIFIC_CHANGES
4973 #ifdef SS_TSKLOG_ENABLE
4974 uint32_t t = MacGetTick();
4977 /* mt003.301 Modifications */
4978 #if SS_THREAD_PROFILE
4979 tTsk->curEvent = nPst.event;
4981 #endif /* SS_THREAD_PROFILE */
4982 tTsk->actvTsk(&nPst, mBuf);
4983 #ifndef RGL_SPECIFIC_CHANGES
4984 #ifdef SS_TSKLOG_ENABLE
4985 SStopTask(t,PID_SSI_TSK);
4988 #if SS_THREAD_PROFILE
4990 tTsk->curEvtTime = (uint32_t)(et2 - et1);
4991 tTsk->totTime += (uint64_t)tTsk->curEvtTime;
4992 #endif /* SS_THREAD_PROFILE */
4996 #if (ERRCLASS & ERRCLS_DEBUG)
4997 /* this message should only come to a permanent task */
4998 if (tTsk->tskType != SS_TSK_PERMANENT)
5000 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5004 tTsk->actvTsk(&nPst, NULLP);
5006 /* We need to re-send this message back to ourselves so
5007 * the permanent task continues to run.
5009 /* Check if this task got deregistered or detached
5010 * by the activation function; if so, there's nothing
5011 * more to do here, otherwise go ahead.
5014 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5016 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5017 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5021 /* failure here is a real problem */
5024 #if (ERRCLASS & ERRCLS_DEBUG)
5025 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5026 "Could not write to demand queue");
5032 /* unset the current executing TAPA task ID */
5033 sTsk->dep.ent = ENTNC;
5034 sTsk->dep.inst = INSTNC;
5039 /* timer event. find the timer entry */
5040 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5042 /* lock the timer table, coz we're going to peek in it */
5043 ret = SLock(&osCp.tmrTblLock);
5047 #if (ERRCLASS & ERRCLS_DEBUG)
5048 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5049 "Could not lock timer table");
5055 /* Verify that this timer entry is still around and that it
5056 * belongs to our task.
5058 if (osCp.tmrTbl[idx].used == FALSE
5059 /* mt028.201: modification: multiple procs support related changes */
5060 #ifdef SS_MULTIPLE_PROCS
5061 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5062 #endif /* SS_MULTIPLE_PROCS */
5063 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5064 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5066 SUnlock(&osCp.tmrTblLock);
5071 /* mt005.21: addition */
5072 /* set the current executing TAPA task ID */
5073 sTsk->dep.ent = mInfo->pst.dstEnt;
5074 sTsk->dep.inst = mInfo->pst.dstInst;
5076 #ifndef SS_MULTIPLE_PROCS
5078 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5079 tmrActvFnMt = NULLP;
5080 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5082 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5088 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5091 /* unlock the timer table */
5092 SUnlock(&osCp.tmrTblLock);
5094 /* activate the timer function */
5095 /* mt028.201: modification: multiple procs support related changes */
5096 #ifndef SS_MULTIPLE_PROCS
5100 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5101 osCp.tmrTbl[idx].ownerInst);
5109 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5110 osCp.tmrTbl[idx].ownerInst);
5111 #endif /* SS_MULTIPLE_PROCS */
5113 /*mt005.21: addition */
5114 /* unset the current executing TAPA task ID */
5115 sTsk->dep.ent = ENTNC;
5116 sTsk->dep.inst = INSTNC;
5119 /* return the message buffer */
5123 * mt003.301 - SDeRegTTsk fix
5125 case SS_EVNT_TTSK_TERM:
5126 #ifdef SS_MULTIPLE_PROCS
5127 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5129 if (procIdIdx == SS_INV_PROCID_IDX)
5135 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5136 #else /* SS_MULTIPLE_PROCS */
5137 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5138 #endif /* SS_MULTIPLE_PROCS */
5140 /* verify that it hasn't been deregistered */
5141 if (idx == SS_TSKNC)
5147 /* verify that this system task is still running it */
5148 tTsk = &osCp.tTskTbl[idx];
5149 if (tTsk->sTsk != sTsk)
5154 #ifdef SS_MULTIPLE_PROCS
5155 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5157 ssdProcTTskTerm(tTsk, idx);
5163 #if (ERRCLASS & ERRCLS_DEBUG)
5164 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5171 } while (mBuf != NULLP);
5174 /* unlock the system task entry */
5175 SUnlock(&sTsk->lock);
5178 /* yield for other threads */
5179 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5188 * Fun: mtTmrHdlrPublic
5190 Void mtTmrHdlrPublic()
5192 if (SLock(&osCp.tmrTblLock) != ROK)
5194 #if (ERRCLASS & ERRCLS_DEBUG)
5195 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5199 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5200 /* unlock the timer table */
5201 SUnlock(&osCp.tmrTblLock);
5209 * Desc: The timer handler thread function. Counts time
5210 * and invokes the common timer function on each
5213 * Ret: (thread function)
5220 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5221 static Void *mtTmrHdlr
5223 void *parm /* unused */
5226 /*mt004.301-addede new region*/
5227 /* mt010.301 Removed SS_FAP portion and
5228 * enabled oroginal code in function mtTmrHdlr */
5232 uint32_t i, cnt, oldTicks, newTicks;
5233 struct timeval tv1,tv2;
5234 /* mt038.201 added return */
5236 /* mt039.201 changes for nanosleep */
5237 struct timespec tsN;
5238 static uint32_t err_in_usec;
5240 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5245 /* mt027.201 - Modification for SRegCfgTmr support */
5246 /* check SS_TICKS_SEC */
5247 if (SS_1MS < SS_TICKS_SEC)
5249 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5252 /* mt025.201 - Addition to stop timer handler till task registration is done */
5253 /* wait for SS to come up */
5254 /* mt038.201 changed how sem_wait is called */
5255 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5258 /* mt027.201 - Modification for SRegCfgTmr support */
5259 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5261 ts.tv_nsec = (MT_TICK_CNT * 1000);
5262 /* mt039.201 changes for nanosleep */
5268 if (gettimeofday(&tv1, NULL) == -1)
5270 #if (ERRCLASS & ERRCLS_DEBUG)
5271 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5272 "Error in clock_gettime");
5282 #ifndef STUB_TTI_HANDLING_5GTF
5283 printf("\nReturning from mtTmrHdlr()\n");
5288 /* mt039.201 changes for nanosleep */
5289 /* sleep for MT_TICK_CNT milli seconds */
5290 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5291 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5293 ts.tv_nsec = tsN.tv_nsec;
5298 if (gettimeofday(&tv2,NULL) == -1)
5300 #if (ERRCLASS & ERRCLS_DEBUG)
5301 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5302 "Error in clock_gettime");
5306 /*mt013.301 : changed check while calculating timer to fix
5307 * diffrence between MTSS time and real unix time
5309 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5311 time_int = (tv2.tv_usec - tv1.tv_usec);
5313 else if (tv2.tv_sec > tv1.tv_sec)
5315 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5317 else /* ts2 < ts1, this will not happen in normal scenario */
5319 /* to make sure cnt = 1 */
5321 time_int = MT_TICK_CNT;
5324 oldTicks = osCp.dep.sysTicks;
5325 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5326 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5327 newTicks = osCp.dep.sysTicks;
5328 tv1.tv_usec = tv2.tv_usec;
5329 tv1.tv_sec = tv2.tv_sec;
5331 cnt = newTicks - oldTicks;
5333 while(err_in_usec >= MT_TICK_CNT)
5336 err_in_usec -= MT_TICK_CNT;
5338 if( cnt >= MT_MAX_TICK_CNT_VAL)
5339 cnt = MT_MIN_TICK_CNT_VAL;
5340 /* call the common timer tick handler */
5341 for (i = 0; i < cnt; i++)
5343 /* mt008.301: cmPrcTmr is guarded with a lock */
5344 /* lock the timer table */
5345 if (SLock(&osCp.tmrTblLock) != ROK)
5347 #if (ERRCLASS & ERRCLS_DEBUG)
5348 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5352 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5353 /* unlock the timer table */
5354 SUnlock(&osCp.tmrTblLock);
5358 /* mt009.21: addition */
5359 return ( (Void *) NULLP);
5360 /* will not reach here */
5368 * Desc: Process timer event. Called from the common timer
5369 * code when a timeout occurs.
5380 PTR tCb, /* control block */
5381 S16 evnt /* event */
5390 #ifndef TENB_RTLIN_CHANGES
5393 /* mt028.201: modification: multiple procs support related changes */
5394 #ifdef SS_MULTIPLE_PROCS
5396 #endif /* SS_MULTIPLE_PROCS */
5397 #ifdef RGL_SPECIFIC_CHANGES
5398 #ifdef MSPD_MLOG_NEW
5399 uint32_t t = GetTIMETICK();
5405 /* get the timer entry */
5406 tEnt = (SsTmrEntry *) tCb;
5409 /* if the timer was deleted, this will be NULL, so drop it */
5415 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5418 /* Hmmmm, the timer might have been deleted while we've been
5419 * working at getting here, so we just skip this.
5421 if (tEnt->used == FALSE)
5427 /* Set up and send a timer message to the destination tasks'
5430 #ifndef SS_MULTICORE_SUPPORT
5431 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5433 #ifdef RGL_SPECIFIC_CHANGES
5434 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5436 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5441 #if (ERRCLASS & ERRCLS_DEBUG)
5442 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5448 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5449 mInfo->eventInfo.event = SS_EVNT_TIMER;
5450 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5452 mInfo->pst.dstEnt = tEnt->ownerEnt;
5453 mInfo->pst.dstInst = tEnt->ownerInst;
5454 mInfo->pst.srcEnt = tEnt->ownerEnt;
5455 mInfo->pst.srcInst = tEnt->ownerInst;
5456 /* mt028.201: modification: multiple procs support related changes */
5457 #ifndef SS_MULTIPLE_PROCS
5458 mInfo->pst.dstProcId = SFndProcId();
5459 mInfo->pst.srcProcId = SFndProcId();
5460 #else /* SS_MULTIPLE_PROCS */
5461 mInfo->pst.dstProcId = tEnt->ownerProc;
5462 mInfo->pst.srcProcId = tEnt->ownerProc;
5463 #endif /* SS_MULTIPLE_PROCS */
5464 mInfo->pst.selector = SEL_LC_NEW;
5465 #ifndef SS_MULTICORE_SUPPORT
5466 mInfo->pst.region = DFLT_REGION;
5469 mInfo->pst.pool = DFLT_POOL;
5470 mInfo->pst.prior = PRIOR0;
5471 mInfo->pst.route = RTESPEC;
5472 mInfo->pst.event = 0;
5475 #ifndef TENB_RTLIN_CHANGES
5476 /* get a semaphore for the TAPA task table */
5477 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5482 #if (ERRCLASS & ERRCLS_DEBUG)
5483 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5491 /* find the owner TAPA task */
5492 /* mt028.201: modification: multiple procs support related changes */
5493 #ifdef SS_MULTIPLE_PROCS
5494 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5495 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5496 #else /* SS_MULTIPLE_PROCS */
5497 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5498 #endif /* SS_MULTIPLE_PROCS */
5499 if (idx == SS_TSKNC)
5501 #ifndef TENB_RTLIN_CHANGES
5502 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5509 /* ensure that the TAPA task is hale and hearty */
5510 tTsk = &osCp.tTskTbl[idx];
5513 #ifndef TENB_RTLIN_CHANGES
5514 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5519 /* Klock work fix ccpu00148484 */
5520 /* write the timer message to the queue of the destination task */
5521 /* mt008.301 : check sTsk before putting into it's DQ */
5522 if (tTsk->sTsk == NULLP)
5524 #ifndef TENB_RTLIN_CHANGES
5525 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5529 #if (ERRCLASS & ERRCLS_DEBUG)
5530 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5531 "Could not write to demand queue");
5536 #ifdef SS_LOCKLESS_MEMORY
5537 mInfo->pst.region = tTsk->sTsk->region;
5538 mInfo->region = tTsk->sTsk->region;
5539 #endif /* SS_LOCKLESS_MEMORY */
5540 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5541 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5543 #ifndef TENB_RTLIN_CHANGES
5544 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5548 #if (ERRCLASS & ERRCLS_DEBUG)
5549 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5550 "Could not write to demand queue");
5555 /* Fix for ccpu00130657 */
5556 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5557 if (tTsk->sTsk->tskPrior == PRIOR0)
5560 WLS_WakeUp(mtGetWlsHdl());
5567 /* release the semaphore for the TAPA task table */
5568 #ifndef TENB_RTLIN_CHANGES
5569 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5573 /* restart the timer */
5574 arg.tq = osCp.dep.tmrTq;
5575 arg.tqCp = &osCp.dep.tmrTqCp;
5576 arg.timers = tEnt->dep.timers;
5577 arg.cb = (PTR) tEnt;
5581 arg.max = TMR_DEF_MAX;
5582 arg.wait = tEnt->interval;
5584 #ifdef RGL_SPECIFIC_CHANGES
5585 #ifdef MSPD_MLOG_NEW
5586 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5598 * Desc: This thread reads the console and hands over any
5599 * data read to a user function.
5601 * Ret: (thread function)
5608 static Void *mtConHdlr
5610 Ptr parm /* unused */
5617 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5623 /* check if we have a console input file handle */
5624 if (osCp.dep.conInFp == NULLP)
5630 fd = fileno(osCp.dep.conInFp);
5635 if ((read(fd, &data, 1)) != 1)
5641 /* call rdConQ, defined by the system service user */
5651 #ifdef SS_DRVR_SUPPORT
5654 * Fun: Interrupt service task handler
5656 * Desc: This is the interrupt service task handler. It blocks
5657 * on a pipe from which it reads an isFlag structure. The
5658 * structure indicates which interrupt service task is to
5659 * be executed. The thread identifies the task, calls the
5660 * isTsk function and sends itself a message to repeat
5661 * this operation until it receives a message to cease.
5670 /* mt009.21: addition */
5671 static Void *mtIsTskHdlr
5673 Ptr tskPtr /* pointer to task entry */
5676 #if (ERRCLASS & ERRCLS_DEBUG)
5683 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5688 switch (isFlag.action)
5691 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5693 /* call the interrupt service task activation function */
5694 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5696 /* send self a message to keep doing this */
5697 isFlag.action = MT_IS_RESET;
5699 #if (ERRCLASS & ERRCLS_DEBUG)
5700 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5701 if (ret != sizeof(isFlag))
5703 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5704 "write() to pipe failed");
5707 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5714 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5719 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5721 /* call the interrupt service task activation function */
5722 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5724 #if (ERRCLASS & ERRCLS_DEBUG)
5725 /* send self a message to do this again */
5726 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5728 if (ret != sizeof(isFlag))
5730 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5731 "write() to pipe failed");
5734 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5742 /* where did THIS come from?? */
5746 /* mt009.21: addition */
5747 return ( (Void *) NULLP);
5751 #endif /* SS_DRVR_SUPPORT */
5752 #endif /* L2_L3_SPLIT */
5754 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5758 * Fun: mtIntSigHndlr
5760 * Desc: Exit function, shuts down.
5769 Void mtIntSigHndlr(int arg)
5772 osCp.dep.sigEvnt=TRUE;
5775 #ifdef TENB_RTLIN_CHANGES
5783 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5788 * Desc: function, shuts down.
5797 Void mtExitClnup(void)
5803 SGetSysTime(&ticks);
5805 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5807 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5809 #ifdef SS_HISTOGRAM_SUPPORT
5813 osCp.dep.sigEvnt=FALSE;
5815 if (osCp.dep.fileOutFp)
5817 fclose(osCp.dep.fileOutFp);
5825 Void SIncrementTtiCount(Void)
5830 Ticks SGetTtiCount(Void)
5839 * Desc: This function displays a string to a given output
5844 * Notes: Buffer should be null terminated.
5846 * channel 0 is reserved for backwards compatibility
5854 S16 chan, /* channel */
5855 Txt *buf /* buffer */
5859 /* mt020.201 - Fixed typo */
5860 #if (ERRCLASS & ERRCLS_INT_PAR)
5863 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
5868 #ifndef XEON_SPECIFIC_CHANGES
5869 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5870 ssMemlog(buf, strlen(buf));
5875 /* mt012.301 :FIX for LOG RELATED ISSUE */
5883 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
5889 if (osCp.dep.fileOutFp)
5890 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
5891 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
5894 fflush(osCp.dep.fileOutFp);
5907 * Desc: function, shuts down.
5919 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
5920 a loop to overcome the child processes being killed upon exiting the
5922 #ifdef SS_LINUX /* this should have already been defined */
5923 /* mt010.301 removed flag SLES9_PLUS */
5924 /* wait forever for children */
5928 if(osCp.dep.sigEvnt==TRUE)
5935 pthread_exit(NULLP);
5941 * Fun: Set date and time
5943 * Desc: This function is used to set the calendar
5948 * Notes: Unimplemented
5955 REG1 DateTime *dt /* date and time */
5968 * Fun: Get date and time
5970 * Desc: This function is used to determine the calendar
5971 * date and time. This information may be used for
5972 * some management functions.
5984 REG1 DateTime *dt /* date and time */
5987 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
5990 struct timespec ptime;
5992 struct timeval ptime;
5999 #if (ERRCLASS & ERRCLS_INT_PAR)
6002 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6011 localtime_r(&tt, &tme);
6014 clock_gettime(CLOCK_REALTIME, &ptime);
6016 gettimeofday(&ptime, NULL);
6018 localtime_r(&ptime.tv_sec, &tme);
6020 dt->month = (uint8_t) tme.tm_mon + 1;
6021 dt->day = (uint8_t) tme.tm_mday;
6022 dt->year = (uint8_t) tme.tm_year;
6023 dt->hour = (uint8_t) tme.tm_hour;
6024 dt->min = (uint8_t) tme.tm_min;
6025 dt->sec = (uint8_t) tme.tm_sec;
6028 #ifdef SS_DATETIME_USEC
6030 dt->usec = ptime.tv_nsec / 1000;
6032 dt->usec = ptime.tv_usec;
6034 #endif /*-- SS_DATETIME_USEC --*/
6040 * Get time from epoch in milliseconds
6042 * Fun: Get time from epoch in milliseconds
6044 * Desc: This function is used to get the time from epoch in milli seconds.
6045 * This information may be used for calculating a layer's activation function
6046 * execution time used for thread profiling.
6055 /* mt003.301 Modifications */
6058 EpcTime *et /* date and time */
6061 /* mt003.301 Modifications */
6062 static uint64_t now;
6063 uint64_t to_sec = 1000000;
6064 uint64_t to_nsec = 1000;
6066 struct timespec ptime;
6068 struct timeval ptime;
6073 #if (ERRCLASS & ERRCLS_INT_PAR)
6082 clock_gettime(CLOCK_REALTIME, &ptime);
6084 gettimeofday(&ptime, NULL);
6085 #endif /* SS_LINUX */
6087 now = (ptime.tv_sec * to_sec);
6090 now += (ptime.tv_nsec / to_nsec);
6091 #else /* SS_LINUX */
6092 now += (ptime.tv_usec);
6094 #endif /* SS_LINUX */
6095 now = (now / to_nsec);
6106 * Fun: Get system time
6108 * Desc: This function is used to determine the system time.
6112 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6119 Ticks *sysTime /* system time */
6124 #if (ERRCLASS & ERRCLS_INT_PAR)
6125 if (sysTime == NULLP)
6127 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6133 *sysTime = osCp.dep.sysTicks;
6139 /* mt021.201 - Addition of SGetRefTime function */
6142 * Fun: Get referenced time
6144 * Desc: This function is used to determine the time in seconds
6145 * and microseconds from a reference time. The reference
6146 * time is expressed in seconds from UTC EPOC, January 1,
6152 * Notes: Macros are defined for reference times:
6153 * SS_REFTIME_01_01_1970
6154 * SS_REFTIME_01_01_2002
6161 uint32_t refTime, /* reference time */
6168 struct timespec ptime;
6170 struct timeval ptime;
6175 clock_gettime(CLOCK_REALTIME, &ptime);
6177 gettimeofday(&ptime, NULL);
6180 #if (ERRCLASS & ERRCLS_INT_PAR)
6181 if (sec == NULLP || usec == NULLP)
6183 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6186 /* mt022.201 - Modification to fix compile warning */
6187 if (refTime > (uint32_t)(ptime.tv_sec))
6189 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6194 *sec = ptime.tv_sec - refTime;
6196 *usec = ptime.tv_nsec / 1000;
6198 *usec = ptime.tv_usec;
6208 * Fun: Get Random Number
6210 * Desc: Invoked by layer when a pseudorandom number is required.
6214 * Notes: Suggested approach uses shuffled Linear Congruential
6215 * Operators as described in Byte magazine October
6216 * 1984; "Generating and Testing Pseudorandom Numbers"
6223 Random *value /* random number */
6228 #if (ERRCLASS & ERRCLS_INT_PAR)
6231 /* mt011.21: addition */
6232 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6238 *value = (Random) rand_r(&osCp.dep.randSeed);
6249 * Desc: This function exits from a task.
6253 * Notes: Currently does nothing.
6268 * Fun: Exit Interrupt
6270 * Desc: This function exits from an interrupt.
6274 * Notes: Currently does nothing.
6289 * Fun: Hold Interrupt
6291 * Desc: This function prohibits interrupts from being enabled until
6292 * release interrupt. This function should be called when
6293 * interrupts are disabled and prior to any call to system
6294 * services either by entry to an interrupt service routine or
6295 * by explicit call to disable interrupt.
6299 * Notes: Currently does nothing
6314 * Fun: Release Interrupt
6316 * Desc: This function allows interrupts to be enabled.
6320 * Notes: Currently does nothing.
6337 * Desc: Enable interrupts
6339 * Ret: ROK on success
6342 * Notes: Currently does nothing.
6347 inline S16 SEnbInt(void)
6359 * Desc: Disable interrupts
6361 * Ret: ROK on success
6364 * Notes: Currently does nothing.
6369 inline S16 SDisInt(void)
6381 * Desc: This function gets the function address stored at the
6382 * specified interrupt vector.
6386 * Notes: Currently does nothing.
6393 VectNmb vectNmb, /* vector number */
6394 PIF *vectFnct /* vector function */
6411 * Desc: This function installs the specified function at the
6412 * specified interrupt vector.
6416 * Notes: Currently does nothing.
6423 VectNmb vectNmb, /* vector number */
6424 PIF vectFnct /* vector function */
6436 /* mt028.201: modification: multiple procs support related changes */
6437 #ifndef SS_MULTIPLE_PROCS
6443 * Desc: This function gets the current entity and instance.
6446 * RFAILED - failed, general (optional)
6448 * Notes: This function may be called by the OS or Layer 1
6456 Ent *ent, /* entity */
6457 Inst *inst /* instance */
6468 #if (ERRCLASS & ERRCLS_INT_PAR)
6469 /* check pointers */
6470 if (ent == NULLP || inst == NULLP)
6472 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6478 /* get the thread id */
6479 tId = pthread_self();
6482 /* find the system task in whose context we're running */
6484 ret = SLock(&osCp.sTskTblLock);
6489 for (i = 0; i < SS_MAX_STSKS; i++)
6491 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6493 sTsk = &osCp.sTskTbl[i];
6499 *ent = sTsk->dep.ent;
6500 *inst = sTsk->dep.inst;
6502 SUnlock(&osCp.sTskTblLock);
6505 return (ret == ROK ? ROK : RFAILED);
6513 * Desc: This function sets the current entity and instance.
6524 Ent ent, /* entity */
6525 Inst inst /* instance */
6536 #if (ERRCLASS & ERRCLS_INT_PAR)
6537 /* check entity and instance IDs */
6538 if (ent >= ENTNC || inst >= INSTNC)
6540 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6546 /* get the thread id */
6547 tId = pthread_self();
6550 /* find the system task in whose context we're running */
6552 ret = SLock(&osCp.sTskTblLock);
6557 for (i = 0; i < SS_MAX_STSKS; i++)
6559 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6561 sTsk = &osCp.sTskTbl[i];
6567 sTsk->dep.ent = ent;
6568 sTsk->dep.inst = inst;
6570 SUnlock(&osCp.sTskTblLock);
6573 return (ret == ROK ? ROK : RFAILED);
6576 #endif /* SS_MULTIPLE_PROCS */
6578 #ifdef SS_DRVR_SUPPORT
6584 * Desc: Set interrupt pending flag
6586 * Ret: ROK on success
6594 inline S16 SSetIntPend
6596 uint16_t id, /* driver task identifier */
6597 Bool flag /* flag */
6605 #if (ERRCLASS & ERRCLS_INT_PAR)
6606 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6608 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6615 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6617 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6625 #endif /* SS_DRVR_SUPPORT */
6628 #ifdef SS_LOCKLESS_MEMORY
6631 * Fun: SGlobMemInfoShow
6633 * Desc: This function displays the memory usage information
6634 * for the destined region. It will show the usage of
6635 * each configured bucket and the heap for the specified region.
6638 * RFAILED Region not registered
6643 S16 SGlobMemInfoShow(Void)
6647 CmMmGlobRegCb *globReg;
6650 globReg = osCp.globRegCb;
6652 sprintf(prntBuf, "--------------------------------------------------------------\n");
6653 SDisplay(0, prntBuf);
6654 sprintf(prntBuf, "Global Region Bucket Information\n");
6655 SDisplay(0, prntBuf);
6656 sprintf(prntBuf, "====================================================\n");
6657 SDisplay(0, prntBuf);
6658 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
6659 SDisplay(0, prntBuf);
6660 sprintf(prntBuf, "====================================================\n");
6661 SDisplay(0, prntBuf);
6664 for (idx = 0; idx < globReg->numBkts; idx++)
6666 #ifdef XEON_SPECIFIC_CHANGES
6667 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
6668 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6671 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
6672 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6674 sprintf(prntBuf, "%2u %12u %8u %9u\n",
6675 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6678 SDisplay(0, prntBuf);
6680 sprintf(prntBuf, "--------------------------------------------------------------\n");
6681 SDisplay(0, prntBuf);
6686 #endif /* SS_LOCKLESS_MEMORY */
6689 Bool IsMemoryThresholdHit(Region reg, Pool pool)
6691 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6693 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6696 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6697 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6704 /* mt022.201 - Addition of SRegInfoShow function */
6709 * Desc: This function displays the memory usage information
6710 * for the destined region. It will show the usage of
6711 * each configured bucket and the heap for the specified region.
6714 * RFAILED Region not registered
6716 * Notes: A Sample Output from the function
6717 * Bucket Memory: region 1
6718 * ====================================================
6719 * Bucket Number of Blks configured Size Allocated
6720 * ====================================================
6728 * Heap Memory: region 1
6731 * Heap Segmented blocks: 0
6747 #if (ERRCLASS & ERRCLS_INT_PAR)
6748 if (region > (SS_MAX_REGS-1) )
6750 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
6757 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
6758 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
6759 SDisplay(0, prntBuf);
6760 sprintf(prntBuf, "====================================================\n");
6761 SDisplay(0, prntBuf);
6762 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
6763 SDisplay(0, prntBuf);
6764 sprintf(prntBuf, "====================================================\n");
6765 SDisplay(0, prntBuf);
6769 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6771 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6773 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
6774 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6775 mtCMMRegCb[region]->bktTbl[idx].size,
6776 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6777 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6779 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
6780 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6781 mtCMMRegCb[region]->bktTbl[idx].size,
6782 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6783 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6786 /*mt009.301 Fixed 64BIT compilation warnings*/
6788 sprintf(prntBuf, "%2u %8u %5u %8u\n",
6789 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6790 mtCMMRegCb[region]->bktTbl[idx].size,
6791 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6793 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
6794 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6795 mtCMMRegCb[region]->bktTbl[idx].size,
6796 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6798 #endif /* not TENB_RTLIN_CHANGES */
6799 SDisplay(0, prntBuf);
6800 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
6801 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6802 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6804 sprintf(prntBuf, "\n---------------\n");
6805 SDisplay(0, prntBuf);
6806 sprintf(prntBuf, "Heap Memory: region %d\n", region);
6807 SDisplay(0, prntBuf);
6808 /*mt009.301 Fixed 64BIT compilation warnings*/
6810 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
6812 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
6814 SDisplay(0, prntBuf);
6815 /*mt009.301 Fixed 64BIT compilation warnings*/
6817 sprintf(prntBuf, "Heap Allocated: %u\n",
6818 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6820 sprintf(prntBuf, "Heap Allocated: %lu\n",
6821 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6823 SDisplay(0, prntBuf);
6824 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
6825 #if (ERRCLASS & ERRCLS_DEBUG)
6826 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
6827 mtCMMRegCb[region]->heapCb.numFragBlk);
6828 SDisplay(0, prntBuf);
6833 #ifdef XEON_SPECIFIC_CHANGES
6834 #define SSI_MAX_BKT_THRESHOLD 6
6835 #define SSI_MAX_REG_THRESHOLD 2
6836 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6837 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6838 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6840 static Void SInitMemThreshold
6847 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6849 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
6850 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
6851 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
6852 printf("\nREGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
6856 S16 SRegReachedMemThreshold
6863 uint8_t memStatus = 3;
6864 static uint8_t initFlag = 1;
6868 SInitMemThreshold(region, maxBkt);
6871 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6873 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
6878 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
6882 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
6890 /* mt033.201 - addition of API to return the memory statistical data */
6895 * Desc: This function returns the memory usage information
6896 * for the destined region. It will return the usage of
6897 * each configured bucket and the heap for the specified region.
6900 * RFAILED Region not registered
6910 SsMemDbgInfo *dbgInfo
6916 #if (ERRCLASS & ERRCLS_INT_PAR)
6917 if (region >= mtMemoCfg.numRegions )
6919 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
6924 dbgInfo->availmem = 0;
6926 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
6927 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
6929 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
6931 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
6933 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
6934 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
6935 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
6937 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
6938 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6939 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6942 dbgInfo->region = region;
6944 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
6946 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
6947 mtCMMRegCb[region]->heapCb.avlSize);
6949 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
6951 #if (ERRCLASS & ERRCLS_DEBUG)
6952 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
6964 /* Send number of Region available */
6965 *numRegion = mtMemoCfg.numRegions;
6966 /* Send number of Pools available */
6967 *numPool = cfgRegInfo[0].numPools;
6972 /* mt033.201 - addition of APIs to print the memory statistical data
6973 * as defined by SSI enhancements
6975 #ifdef SSI_DEBUG_LEVEL1
6978 * Fun: SPrintRegMemStatusInfo
6980 * Desc: This function displays the memory usage information
6981 * for the destined region. It will show the total memory
6982 * used for static and dynamic memory if typeFlag is
6983 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
6984 * memory block allocated for a particular size if typeFlag
6985 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
6986 * calling SRegPrintMemStats.
6995 S16 SPrintRegMemStatusInfo
7003 uint32_t statMemSize;
7004 uint32_t dynMemSize;
7007 #if (ERRCLASS & ERRCLS_INT_PAR)
7008 if (region >= mtMemoCfg.numRegions )
7010 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7015 /* initialize the counters*/
7019 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7021 /* total static and dynamic memory allocated from all the buckets in region requested */
7022 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7023 SDisplay(0, prntBuf);
7024 sprintf(prntBuf, "===========================================\n");
7025 SDisplay(0, prntBuf);
7026 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7027 SDisplay(0, prntBuf);
7028 sprintf(prntBuf, "===========================================\n");
7029 SDisplay(0, prntBuf);
7030 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7032 /*mt009.301 Fixed 64BIT compilation warnings*/
7034 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7035 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7036 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7038 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7039 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7040 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7042 SDisplay(0, prntBuf);
7043 /* update the total count */
7044 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7045 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7048 /*mt009.301 Fixed 64BIT compilation warnings*/
7050 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7051 SDisplay(0, prntBuf);
7052 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7054 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7055 SDisplay(0, prntBuf);
7056 /*mt010.301 fix for compilation error*/
7057 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7059 SDisplay(0, prntBuf);
7061 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7062 SDisplay(0, prntBuf);
7063 /*mt009.301 Fixed 64BIT compilation warnings*/
7065 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7066 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7068 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7069 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7071 SDisplay(0, prntBuf);
7073 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7075 /* Bucket Memory allocation Statistics */
7076 return (SPrintRegMemStats(region));
7081 sprintf(prntBuf, "\n Invalid choice \n");
7082 SDisplay(0, prntBuf);
7090 * Fun: SPrintRegMemStats
7092 * Desc: This function displays the memory usage information for
7093 * the destined region. It will show the number of memory
7094 * block allocated for a particular size from the hash list.
7103 static S16 SPrintRegMemStats(Region region)
7105 CmMmHashListCp *hashListCp;
7111 hashListCp = &mtCMMRegCb[region]->hashListCp;
7113 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7114 SDisplay(0, prntBuf);
7115 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7116 hashListCp->numOfbins, hashListCp->numOfEntries);
7117 SDisplay(0, prntBuf);
7118 sprintf(prntBuf, "===================================\n");
7119 SDisplay(0, prntBuf);
7120 sprintf(prntBuf, "Block Size Total number of requests\n");
7121 SDisplay(0, prntBuf);
7122 sprintf(prntBuf, "===================================\n");
7123 SDisplay(0, prntBuf);
7125 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7126 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7128 if (hashListCp->hashList[idx].numAttempts)
7131 /*mt009.301 Fixed 64BIT compilation warnings*/
7133 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7134 hashListCp->hashList[idx].numAttempts);
7136 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7137 hashListCp->hashList[idx].numAttempts);
7139 SDisplay(0, prntBuf);
7143 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7144 SDisplay(0, prntBuf);
7145 sprintf(prntBuf, "=================================================\n");
7146 SDisplay(0, prntBuf);
7147 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7148 SDisplay(0, prntBuf);
7149 sprintf(prntBuf, "=================================================\n");
7150 SDisplay(0, prntBuf);
7152 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7153 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7155 /*mt009.301 Fixed 64BIT compilation warnings*/
7157 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7158 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7159 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7161 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7162 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7163 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7165 SDisplay(0, prntBuf);
7167 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7168 SDisplay(0, prntBuf);
7169 /*mt009.301 Fixed 64BIT compilation warnings*/
7171 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7172 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7173 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7175 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7176 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7177 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7179 SDisplay(0, prntBuf);
7180 sprintf(prntBuf, "\n");
7181 SDisplay(0, prntBuf);
7188 * Fun: SRegMemErrHdlr
7190 * Desc: This function handles the errors returned from the memory
7191 * related functions. Customers are suggested to modify this
7192 * API according to their specific requirement.
7211 if (errCode == RDBLFREE)
7213 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7214 SDisplay(0, prntBuf);
7216 else if (errCode == RTRAMPLINGNOK)
7218 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7219 SDisplay(0, prntBuf);
7227 * Fun: SPrintRegMemProfile
7229 * Desc: This function displays the memory profile information
7230 * for the destined region. This function prints for:
7231 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7232 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7241 S16 SPrintRegMemProfile
7248 CmMmBlkHdr *curBktBlk;
7250 Size offsetToNxtBlk;
7258 #if (ERRCLASS & ERRCLS_INT_PAR)
7259 if (region >= mtMemoCfg.numRegions )
7261 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7266 regCb = mtCMMRegCb[region];
7268 /* memory profile */
7269 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7270 SDisplay(0, prntBuf);
7272 /* bucket profile */
7273 sprintf(prntBuf, "\nBucket Profile\n");
7274 SDisplay(0, prntBuf);
7276 for (idx = 0; idx < regCb->numBkts; idx++)
7279 /*mt009.301 Fixed 64BIT compilation warnings*/
7281 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7282 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7284 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7285 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7287 SDisplay(0, prntBuf);
7289 sprintf(prntBuf, "==========================================================================\n");
7290 SDisplay(0, prntBuf);
7291 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7292 SDisplay(0, prntBuf);
7293 sprintf(prntBuf, "==========================================================================\n");
7294 SDisplay(0, prntBuf);
7296 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7298 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7299 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7300 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7302 /*mt009.301 Fixed 64BIT compilation warnings*/
7304 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7306 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7308 SDisplay(0, prntBuf);
7309 /* check if it is a sane block, elxe jump to next block */
7310 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7312 sprintf(prntBuf, " Trampled \n");
7313 SDisplay(0, prntBuf);
7318 if (CMM_IS_STATIC(curBktBlk->memFlags))
7320 /*mt009.301 Fixed 64BIT compilation warnings*/
7322 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7324 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7326 SDisplay(0, prntBuf);
7328 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7330 /*mt009.301 Fixed 64BIT compilation warnings*/
7332 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7334 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7336 SDisplay(0, prntBuf);
7338 else if (CMM_IS_FREE(curBktBlk->memFlags))
7340 /*mt009.301 Fixed 64BIT compilation warnings*/
7342 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7344 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7346 SDisplay(0, prntBuf);
7350 sprintf(prntBuf, " Trampled \n");
7351 SDisplay(0, prntBuf);
7357 sprintf(prntBuf, "\nHeap Profile\n");
7358 SDisplay(0, prntBuf);
7360 /* point to heapCb */
7361 heapCb = &(regCb->heapCb);
7363 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7364 SDisplay(0, prntBuf);
7365 sprintf(prntBuf, "==========================================================================\n");
7366 SDisplay(0, prntBuf);
7367 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7368 SDisplay(0, prntBuf);
7369 sprintf(prntBuf, "==========================================================================\n");
7370 SDisplay(0, prntBuf);
7372 /* traverse the entire heap to output the heap profile */
7373 hdrSize = sizeof(CmHEntry);
7374 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7375 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7377 /*mt009.301 Fixed 64BIT compilation warnings*/
7379 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7381 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7383 SDisplay(0, prntBuf);
7385 /* check if it is a sane block, elxe jump to next block */
7386 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7388 sprintf(prntBuf, " Trampled \n");
7389 SDisplay(0, prntBuf);
7391 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7392 SDisplay(0, prntBuf);
7395 * To go to next block in the heap we do not have any offset value
7396 * other than curHBlk->size. As the block is already trampled
7397 * we cannot rely on this size. So it is better to stop here unless there
7398 * exists any other mechanism(?) to know the offset to next block.
7403 /*mt009.301 Fixed 64BIT compilation warnings*/
7405 sprintf(prntBuf, " %8u", curHBlk->size);
7407 sprintf(prntBuf, " %8lu", curHBlk->size);
7409 SDisplay(0, prntBuf);
7411 if (CMM_IS_STATIC(curHBlk->memFlags))
7413 /*mt009.301 Fixed 64BIT compilation warnings*/
7415 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7417 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7419 SDisplay(0, prntBuf);
7421 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7423 /*mt009.301 Fixed 64BIT compilation warnings*/
7425 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7427 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7429 SDisplay(0, prntBuf);
7431 else if (CMM_IS_FREE(curHBlk->memFlags))
7433 /*mt009.301 Fixed 64BIT compilation warnings*/
7435 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7437 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7439 SDisplay(0, prntBuf);
7443 sprintf(prntBuf, " Trampled \n");
7444 SDisplay(0, prntBuf);
7446 /* goto next block in the heap */
7447 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7453 #endif /* SSI_DEBUG_LEVEL1 */
7455 /*-- mt035.201 : Added new API for timestamp --*/
7458 * Fun: Get TimeStamp
7460 * Desc: This function is used to Get TimeStamp in micro seconds
7477 struct timespec ptime;
7479 struct timeval ptime;
7488 clock_gettime(CLOCK_REALTIME, &ptime);
7490 gettimeofday(&ptime, NULL);
7493 /* Obtain the time of day, and convert it to a tm struct. --*/
7494 ptm = localtime (&ptime.tv_sec);
7495 /* Klock work fix ccpu00148484 */
7498 /* Format the date and time, down to a single second. --*/
7499 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7502 /* Compute microseconds. --*/
7504 microseconds = ptime.tv_nsec / 1000;
7506 microseconds = ptime.tv_usec;
7509 /* Print the formatted time, in seconds, followed by a decimal point
7510 and the microseconds. --*/
7511 /*mt009.301 Fixed 64BIT compilation warnings*/
7513 sprintf(ts, "%s.%03d", time_string, microseconds);
7515 sprintf(ts, "%s.%03ld", time_string, microseconds);
7521 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7524 * Fun: Get SGetSystemTsk
7526 * Desc: This function is used to Get sytem task id
7535 uint32_t SGetSystemTsk(Void)
7538 return (pthread_self());
7540 } /* end of SGetSystemTsk */
7542 #ifdef SS_MULTICORE_SUPPORT
7545 * Fun: Add Timer thread into system task table
7547 * Desc: This function is used to add the system task
7548 * associated with Timer thread.
7557 static SsSTskEntry* ssdAddTmrSTsk(Void)
7563 /* lock the system task table */
7564 ret = SLock(&osCp.sTskTblLock);
7568 #if (ERRCLASS & ERRCLS_DEBUG)
7569 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7570 "Could not lock system task table");
7576 /* check count of system tasks */
7577 if (osCp.numSTsks == SS_MAX_STSKS)
7580 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7582 #if (ERRCLASS & ERRCLS_DEBUG)
7583 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7584 "Could not give the Semaphore");
7589 #if (ERRCLASS & ERRCLS_ADD_RES)
7590 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7597 /* initialize the system task entry with the information we have */
7598 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7600 /* store the system task priority */
7601 sTsk->tskPrior = SS_NORM_TSK_PRI;
7603 /* initialize the demand queue */
7604 if (ssInitDmndQ(&sTsk->dQ) != ROK)
7607 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7609 #if (ERRCLASS & ERRCLS_DEBUG)
7610 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7611 "Could not give the Semaphore");
7616 #if (ERRCLASS & ERRCLS_DEBUG)
7617 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7618 "Could not initialize demand queue");
7624 /* initialize the system task entry lock */
7625 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7627 ssDestroyDmndQ(&sTsk->dQ);
7629 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7631 #if (ERRCLASS & ERRCLS_DEBUG)
7632 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7633 "Could not give the Semaphore");
7638 #if (ERRCLASS & ERRCLS_DEBUG)
7639 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
7640 "Could not initialize system task entry lock");
7647 /* success, update the table */
7648 sTsk->tskId = osCp.nxtSTskEntry;
7650 sTsk->termPend = FALSE;
7651 osCp.nxtSTskEntry = sTsk->nxt;
7654 /* unlock the system task table */
7656 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7658 #if (ERRCLASS & ERRCLS_DEBUG)
7659 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
7660 "Could not give the Semaphore");
7667 #endif /* SS_MULTICORE_SUPPORT */
7668 /* mt003.301 Readwrite lock and recursive mutex additions */
7669 #ifdef SS_LOCK_SUPPORT
7672 * Fun: ssdInitLockNew
7674 * Desc: This function is used to initialise lock/mutex
7683 S16 ssdInitLockNew(SLockInfo *lockId,uint8_t lockType)
7686 #ifdef SS_REC_LOCK_SUPPORT
7687 pthread_mutexattr_t attr;
7688 #endif /* SS_REC_LOCK_SUPPORT */
7689 Txt prntBuf[PRNTSZE];
7695 #ifdef SS_RDWR_LOCK_SUPPORT
7698 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
7700 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
7701 SDisplay(0, prntBuf);
7706 #endif /* SS_RDWR_LOCK_SUPPORT */
7707 #ifdef SS_REC_LOCK_SUPPORT
7710 retVal = pthread_mutexattr_init(&attr);
7714 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
7719 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
7721 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
7725 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
7726 pthread_mutexattr_destroy(&attr);
7730 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
7733 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
7734 pthread_mutexattr_destroy(&attr);
7740 #endif /* SS_REC_LOCK_SUPPORT */
7743 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
7744 SDisplay(0, prntBuf);
7754 * Desc: This function is used to aquire the read write lock
7763 S16 ssdLockNew(SLockInfo *lockId,uint8_t lockType)
7766 Txt prntBuf[PRNTSZE];
7772 #ifdef SS_RDWR_LOCK_SUPPORT
7775 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
7777 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7778 SDisplay(0, prntBuf);
7785 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
7787 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
7788 SDisplay(0, prntBuf);
7795 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
7797 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7798 SDisplay(0, prntBuf);
7805 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
7807 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7808 SDisplay(0, prntBuf);
7813 #endif /* SS_RDWR_LOCK_SUPPORT */
7814 #ifdef SS_REC_LOCK_SUPPORT
7817 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
7819 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7820 SDisplay(0, prntBuf);
7825 #endif /* SS_REC_LOCK_SUPPORT */
7828 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
7829 SDisplay(0, prntBuf);
7842 * Desc: This function is used to Unlock the read write lock
7851 S16 ssdUnlockNew(SLockInfo *lockId,uint8_t lockType)
7854 Txt prntBuf[PRNTSZE];
7860 #ifdef SS_RDWR_LOCK_SUPPORT
7863 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
7865 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
7866 SDisplay(0, prntBuf);
7871 #endif /* SS_RDWR_LOCK_SUPPORT */
7872 #ifdef SS_REC_LOCK_SUPPORT
7875 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
7877 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7878 SDisplay(0, prntBuf);
7883 #endif /* SS_REC_LOCK_SUPPORT */
7886 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
7887 SDisplay(0, prntBuf);
7896 * Fun: ssdDestroyLockNew
7898 * Desc: This function is used to destroy the read write lock
7907 S16 ssdDestroyLockNew(SLockInfo *lockId,uint8_t lockType)
7909 Txt prntBuf[PRNTSZE];
7915 #ifdef SS_RDWR_LOCK_SUPPORT
7918 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
7920 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
7921 SDisplay(0, prntBuf);
7926 #endif /* SS_RDWR_LOCK_SUPPORT */
7927 #ifdef SS_REC_LOCK_SUPPORT
7930 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
7932 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
7933 SDisplay(0, prntBuf);
7938 #endif /* SS_REC_LOCK_SUPPORT */
7941 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
7942 SDisplay(0, prntBuf);
7948 #endif /* SS_LOCK_SUPPORT */
7950 /* mt005.301 : Cavium Changes */
7951 #ifdef SS_SEUM_CAVIUM
7955 * Fun: ssInitRcvWork
7957 * Desc: This is the initializtion function of receive
7961 * RFAILED - failed, general (optional)
7963 * Notes: Function to initialize the work queue packet
7964 * receiving thread. This creates the new thread to
7965 * receive the work and sets the affinity.
7970 S16 ssInitRcvWork(void)
7972 pthread_attr_t attr;
7976 /* set the required attributes */
7977 pthread_attr_init(&attr);
7978 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
7979 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
7980 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
7982 /* Create a new thread to receive the work queue messages */
7983 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
7985 pthread_attr_destroy(&attr);
7990 pthread_attr_destroy(&attr);
7994 }/* ssInitRcvWork */
8001 * Desc: This is the handler function of receive
8005 * RFAILED - failed, general (optional)
8007 * Notes:The handler function of the work queue receiver task.
8008 * This will be waiting for the work and after receiving
8009 * it, work will converted and posted to that entityt
8015 static void *workRcvTsk(Ptr ptr)
8018 cvmx_wqe_t *workPtr;
8019 Buffer *mBuf, *rcvdBuf;
8020 SsMsgInfo *minfoPtr;
8029 /* get the work if its avilable */
8030 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8032 if ( workPtr == NULLP )
8034 /* If there is no work then sleep for 10 usec */
8036 ts.tv_nsec = 500000;
8038 nanosleep(&ts, NULLP);
8042 switch(workPtr->tag)
8044 /* Switch over according to the tag value */
8045 case SS_CVMX_MBUF_TAG:
8047 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8049 /* Convert the physical address to Pointers */
8050 ret = SConvPhyPtr(&rcvdBuf);
8053 /* mt011.301: Cavium 32 bit changes */
8054 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8058 /* Copy the buffer to this region */
8059 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8062 /* mt011.301: Cavium 32 bit changes */
8063 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8067 /* mt011.301: Cavium 32 bit changes */
8068 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8070 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8072 /* Get the post strucutre and Post the message */
8073 if ( minfoPtr != NULLP)
8075 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8077 (Void)SPstTsk(&pst, mBuf);
8079 /* Free the buffer allocated if it cannot be sent */
8088 /* Invalid tag value, drop the work */
8089 /* mt011.301: Cavium 32 bit changes */
8090 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8099 #endif /* SS_SEUM_CAVIUM */
8101 #ifdef TENB_RTLIN_CHANGES
8102 S16 SInitLock(SLockId *l, uint8_t t)
8105 pthread_mutexattr_t prior;
8106 pthread_mutexattr_init(&prior);
8107 #ifndef RGL_SPECIFIC_CHANGES
8108 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8110 r = pthread_mutex_init(l, &prior);
8111 pthread_mutexattr_destroy(&prior);
8115 #ifdef SS_THR_REG_MAP
8118 * Fun: ssRegMainThread
8120 * Desc: This function is used to add the memory region
8121 * mapping for the main thread.
8123 * Ret: VOID (Always successful)
8131 Void ssRegMainThread(Void)
8134 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8136 printf("\nnot able to get different Id for main thread\n");
8139 /* Here the default region is added as we dont have any region associated with
8140 * Main thread. The thread should not perform any allocation except
8141 * the initial configuratin
8143 #ifdef XEON_SPECIFIC_CHANGES
8144 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8146 SS_GET_THREAD_MEM_REGION() =
8153 * Fun: ssCheckAndAddMemoryRegionMap
8155 * Desc: This function is used to add the memory region
8156 * mapping for the provided sTsk associated thread.
8157 * If the threadId can be placed in the thread memory
8158 * region mapping table and returns success if it is able
8159 * to place. If not, it keeps the thread ID in the static
8160 * local array and increments the count. Once thread Id
8161 * is successfully placed in the thread memory region mapping
8162 * table, pthread_cancel is sent for all the previous threads
8163 * which are failed to place in table.
8165 * Ret: TRUE - Thread ID successfully placed in thread memory region
8167 * FALSE - If thread Id is not placed in thread memory region
8170 * Notes:mapping tablemapping tablng tablee
8175 S32 ssCheckAndAddMemoryRegionMap
8177 pthread_t threadId, /* Thread Id of system task */
8178 Region region /* Region associated with thread */
8181 static uint32_t createdThreads;
8182 static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8186 /* Here 0xFF is considered as invalid region and if the mapping table
8187 * contains 0xFF, that mapping entry is free
8189 if(SS_INVALID_THREAD_REG_MAP !=
8190 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8192 /* Klock work fix ccpu00148484 */
8193 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8195 printf("\nfailed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8196 printf("\nNot able to get the different thread ID, exiting\n");
8199 createdThreadIds[createdThreads++] = threadId;
8202 /* If we found free mapping table entry, place the region and send pthread_cancel
8203 * for all the thread Ids which are created before this
8205 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8206 #ifdef XEON_SPECIFIC_CHANGES
8207 printf("\nThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8208 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8209 SS_MAX_THREAD_REGION_MAP), region);
8211 for(indx = 0; indx < createdThreads; indx++)
8213 #ifdef XEON_SPECIFIC_CHANGES
8214 printf("\nSending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8216 pthread_cancel(createdThreadIds[indx]);
8222 } /* ssCheckAndAddMemoryRegionMap */
8226 * Fun: ssCheckAndDelMemoryRegionMap
8228 * Desc: This function is used to add the memory region
8229 * mapping for the provided sTsk associated thread.
8230 * If the threadId can be placed in the thread memory
8231 * region mapping table and returns success if it is able
8232 * to place. If not, it keeps the thread ID in the static
8233 * local array and increments the count. Once thread Id
8234 * is successfully placed in the thread memory region mapping
8235 * table, pthread_cancel is sent for all the previous threads
8236 * which are failed to place in table.
8238 * Ret: TRUE - Thread ID successfully placed in thread memory region
8240 * FALSE - If thread Id is not placed in thread memory region
8243 * Notes:mapping tablemapping tablng tablee
8248 S32 ssCheckAndDelMemoryRegionMap
8250 pthread_t threadId /* Thread Id of system task */
8255 /* Raghu To-Do Check with team, is it necessary to acquire lock
8256 * as del and add may go parallel */
8257 /* Here 0xFF is considered as invalid region and if the mapping table
8258 * contains 0xFF, that mapping entry is free
8260 if(SS_INVALID_THREAD_REG_MAP ==
8261 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8264 printf("\nInvalid Thread ID (%ld)\n", (uint32_t)threadId);
8266 printf("\nInvalid Thread ID (%d)\n", (uint32_t)threadId);
8270 /* If we found free mapping table entry, place the region and send pthread_cancel
8271 * for all the thread Ids which are created before this
8273 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8277 } /* ssCheckAndAddMemoryRegionMap */
8281 #ifdef SS_TSKLOG_ENABLE
8286 * Desc: This function will return current time through input parameter.
8289 * RFAILED - failed, general (optional)
8297 volatile uint32_t *startTime,
8301 #ifdef MSPD_MLOG_NEW
8302 *startTime = GetTIMETICK();
8311 * Desc: This function will return current time through input parameter.
8312 * and take the difference of start time provided as input parameter
8316 * RFAILED - failed, general (optional)
8324 volatile uint32_t startTime,
8328 /*uint32_t stopTime;*/
8331 case PID_MAC_HARQ_IND:
8332 case PID_SCH_TTI_IND:
8334 case PID_MAC_DAT_IND:
8335 case PID_MAC_SF_ALLOC_REQ:
8336 case PID_MAC_STA_RSP:
8337 case PID_MAC_DL_SCHD:
8338 case PID_MAC_DL_CQI_IND:
8339 case PID_MAC_UL_CQI_IND:
8340 case PID_MAC_UL_SCHD:
8341 case PID_MAC_TTI_IND:
8342 case PID_CL_RCV_PHY_MSG:
8343 case PID_CL_HARQ_STA_IND:
8344 case PID_MAC_AM_HARQ_RLS:
8345 case PID_CL_DL_BATCH_PROC:
8346 case PID_CL_DLM_PRC_TTI_IND:
8347 case PID_CRC_IND_REAL:
8348 case PID_CRC_IND_DUMMY:
8349 case PID_TTI_LATENCY:
8350 case PID_RECPREQ_PROC:
8353 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8355 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8358 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8367 volatile uint32_t * startTime,
8377 volatile uint32_t startTime,
8384 #endif /*#ifdef SS_TSKLOG_ENABLE */
8385 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8387 * This primitive is used to calculate the CPU Utilization per Core
8392 * @return Void - function is always success
8394 Void UpdateSocCpuInfo
8396 CmCpuStatsInfo *cpuInfo,
8401 S8 mipsStr[MIPS_STRING_LEN];
8408 /* Open the file which holds the MIPS available value */
8409 mipsFd = fopen(MIPS_FILE, "r");
8416 /* Get the free mips available value from the file */
8417 if(NULLP == fgets(mipsStr, 24, mipsFd))
8419 printf("\nfgets to get the free mips available failed\n");
8424 strtok(mipsStr, " ");
8426 strPart = strtok(NULLP, " ");
8428 if(idx == CM_L2_CPU_UTIL)
8430 if(strPart != NULLP)
8432 l2FreeCpu = atoi(strPart);
8433 l2CpuUsed = 100 - l2FreeCpu;
8434 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8435 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
8436 cpuInfo->cpuUtil[0].numSamples++;
8439 if(idx == CM_L3_CPU_UTIL)
8441 strPart = strtok(NULLP, " ");
8442 if(strPart != NULLP)
8444 l3FreeCpu = atoi(strPart);
8445 l3CpuUsed = 100 - l3FreeCpu;
8446 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8447 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
8448 cpuInfo->cpuUtil[0].numSamples++;
8451 if(idx == CM_L2_CPU_UTIL)
8453 cpuInfo->numCores = CM_NUM_L2_CORES ;
8455 else if(idx == CM_L3_CPU_UTIL)
8457 cpuInfo->numCores = CM_NUM_L3_CORES ;
8463 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8464 #ifdef SS_MULTICORE_SUPPORT
8467 * Fun: Add Timer thread into system task table
8469 * Desc: This function is used to add the system task
8470 * associated with Timer thread.
8479 static SsSTskEntry* ssdReAddTmrSTsk(
8487 /* lock the system task table */
8488 ret = SLock(&osCp.sTskTblLock);
8492 #if (ERRCLASS & ERRCLS_DEBUG)
8493 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8494 "Could not lock system task table");
8500 /* initialize the system task entry with the information we have */
8501 sTsk = &osCp.sTskTbl[idx];
8506 SDestroyLock(&sTsk->lock);
8507 ssDestroyDmndQ(&sTsk->dQ);
8510 /* store the system task priority */
8511 sTsk->tskPrior = SS_NORM_TSK_PRI;
8513 /* initialize the demand queue */
8514 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8517 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8519 #if (ERRCLASS & ERRCLS_DEBUG)
8520 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8521 "Could not give the Semaphore");
8526 #if (ERRCLASS & ERRCLS_DEBUG)
8527 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8528 "Could not initialize demand queue");
8534 /* initialize the system task entry lock */
8535 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8537 ssDestroyDmndQ(&sTsk->dQ);
8539 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8541 #if (ERRCLASS & ERRCLS_DEBUG)
8542 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8543 "Could not give the Semaphore");
8548 #if (ERRCLASS & ERRCLS_DEBUG)
8549 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8550 "Could not initialize system task entry lock");
8557 /* success, update the table */
8558 sTsk->tskId = idx + 1;
8560 sTsk->termPend = FALSE;
8562 /* unlock the system task table */
8564 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8566 #if (ERRCLASS & ERRCLS_DEBUG)
8567 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8568 "Could not give the Semaphore");
8575 #endif /* SS_MULTICORE_SUPPORT */
8580 * Fun: Initialize timer table
8582 * Desc: This function initializes MTSS-specific information
8583 * in the timer table.
8592 S16 ssdReInitTmr(void)
8594 pthread_attr_t attr;
8595 struct sched_param param_sched;
8596 #ifndef XEON_SPECIFIC_CHANGES
8599 #ifdef SS_MULTICORE_SUPPORT
8601 #endif /* SS_MULTICORE_SUPPORT */
8602 #ifdef SS_THR_REG_MAP
8603 uint32_t threadCreated = FALSE;
8604 #endif /* SS_THR_REG_MAP */
8607 #ifndef XEON_SPECIFIC_CHANGES
8608 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
8611 #if (ERRCLASS & ERRCLS_DEBUG)
8612 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8613 "Could not give the Semaphore");
8619 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
8620 /* mt010.21: addition */
8622 #ifdef SS_MULTICORE_SUPPORT
8623 sTsk = ssdReAddTmrSTsk(0);
8628 #endif /* SS_MULTICORE_SUPPORT */
8629 /* create the timer handler thread */
8631 pthread_attr_init(&attr);
8632 /* mt021.201 - Addition to set stack size */
8633 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
8634 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8635 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8636 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
8637 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
8638 pthread_attr_setschedparam(&attr, ¶m_sched);
8641 #ifdef SS_THR_REG_MAP
8642 /* When the thread is created, we check for the memory mapping table if
8643 * threadId can be placed in thread memory map table. If it is not able to place
8644 * threadId is stored in tmporary array. Once thread is created successful,
8645 * thread_cancel is sent for each thread which are created before. All the
8646 * threads are made to wait on sema which is cancel point for thread.
8648 while(threadCreated == FALSE)
8651 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
8653 /* mt020.201 - Addition for destroying thread attribute object attr */
8654 pthread_attr_destroy(&attr);
8659 #ifdef SS_THR_REG_MAP
8660 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
8663 #endif /* SS_THR_REG_MAP */
8664 #ifdef SS_MEM_WL_DEBUG
8665 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
8668 /* mt020.201 - Addition for destroying thread attribute object attr */
8669 pthread_attr_destroy(&attr);
8670 sem_post(&osCp.dep.ssStarted);
8674 /**********************************************************************
8676 **********************************************************************/