1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: Multi-threaded System Services - Solaris
25 Desc: C source code for the MTSS-Solaris implementation of
30 *********************************************************************21*/
35 #ifndef _POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE 199309L
38 /* mt003.301 moved env files to use the __USE_UNIX98 flag in sys includes */
45 #include <sys/types.h>
50 /* mt003.301: included sys/time.h
51 * for both solaris and linux
54 /* mt008.21: addition */
59 /* header include files (.h) */
62 #include "common_def.h"
63 #include "mt_ss.h" /* MTSS specific */
64 #include "mt_err.h" /* MTSS error defines */
66 #include "ss_queue.h" /* queues */
67 #include "ss_task.h" /* tasking */
68 #include "ss_msg.h" /* messaging */
69 #include "ss_mem.h" /* memory management interface */
70 #include "ss_gen.h" /* general */
71 /* mt003.301 Additions - Task deregistration */
72 #include "ss_err.h" /* error */
73 #include "cm_mem.h" /* common memory manager */
74 /* mt001.301 : Additions */
75 #ifdef SS_THREAD_PROFILE
78 #ifdef SS_LOCKLESS_MEMORY
83 /* multi-core support enhancement */
84 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
85 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
91 #include <sys/types.h>
92 #include <sys/processor.h>
93 #include <sys/procset.h>
96 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
97 /* mt001.301 : Additions */
99 #include <sys/types.h>
100 #include <sys/socket.h>
101 #include <netinet/in.h>
102 #include <arpa/inet.h>
103 #endif /* SS_WATCHDOG */
105 #ifdef SS_USE_WLS_MEM
106 #include <rte_common.h>
107 #include <rte_debug.h>
111 /* header/extern include files (.x) */
113 #include "gen.x" /* general layer */
114 #include "ssi.x" /* system services */
116 #include "cm5.x" /* common timers */
118 #include "mt_ss.x" /* MTSS specific */
119 #ifdef SS_LOCKLESS_MEMORY
120 #include "mt_ss_wl.x" /* MTSS specific */
121 #endif /* SS_LOCKLESS_MEMORY */
123 #include "ss_queue.x" /* queues */
124 #include "ss_task.x" /* tasking */
125 #include "ss_timer.x" /* timers */
126 #include "ss_strm.x" /* STREAMS */
127 #include "ss_msg.x" /* messaging */
128 #include "ss_mem.x" /* memory management interface */
129 #include "ss_drvr.x" /* driver tasks */
130 #include "ss_gen.x" /* general */
131 #ifdef SS_LOCKLESS_MEMORY
132 #include "cm_llist.x"
134 #include "cm_mem_wl.x" /* common memory manager */
136 #include "cm_mem.x" /* common memory manager */
137 #endif /* SS_LOCKLESS_MEMORY */
138 #include "cm_lte.x" /* common memory manager */
139 /* mt001.301 : Additions */
140 #ifdef SS_LOGGER_SUPPORT
142 #endif /* SS_LOGGER_SUPPORT */
144 /*mt005.301: Cavium Changes */
145 #ifdef SS_SEUM_CAVIUM
146 /* cvmx includes files */
147 #include "cvmx-config.h"
149 #include "cvmx-pow.h"
150 #include "cvmx-tim.h"
151 #include "cvmx-fpa.h"
152 #include "cvmx-helper-fpa.h"
153 #include "cvmx-malloc.h"
154 #endif /* SS_SEUM_CAVIUM */
157 #include "mt_plat_t33.h"
158 #include "mt_plat_t33.x"
159 #include "sys/syscall.h"
162 #if defined(RGL_SPECIFIC_CHANGES) || defined(INTEL_WLS) || defined(SS_USE_WLS_MEM)
164 #include <hugetlbfs.h>
167 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
168 S16 rgBatchProc (Void);
170 #ifdef RLC_MAC_DAT_REQ_RBUF
171 S16 rgDlDatReqBatchProc ARGS((
174 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
175 S16 rgBatchProc ARGS((
179 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
180 /* general purpose debug zone */
181 char my_buffer2[4096 * 4] = { 0 };
182 char my_buffer[4096] = { 0 };
183 int my_buffer_idx = 0;
187 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
189 struct sigcontext my_uc_mcontext = { 0 };
194 #include <ucontext.h>
198 #define SIGSEGV_STACK_GENERIC
199 #define REGFORMAT "%x\n"
201 #ifdef XEON_SPECIFIC_CHANGES
202 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
205 void dump_external(void);
207 static Void mtDelSigals(Void)
211 memset(&sa, 0, sizeof(struct sigaction));
212 sigemptyset(&sa.sa_mask);
213 sa.sa_handler = SIG_DFL;
214 sigaction(SIGSEGV, &sa, NULL);
216 memset(&sa, 0, sizeof(struct sigaction));
217 sigemptyset(&sa.sa_mask);
218 sa.sa_handler = SIG_DFL;
219 sigaction(SIGILL, &sa, NULL);
223 static void signal_segv(int signum, siginfo_t * info, void *ptr)
225 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
228 ucontext_t *ucontext = (ucontext_t *) ptr;
229 #ifdef XEON_SPECIFIC_CHANGES
231 int *p32 = (int *) 0x2fff0000;
236 printf("segv ooops @ %p\n", info->si_addr);
239 printf("Segmentation Fault!\n");
240 printf("info.si_signo = %d\n", signum);
241 printf("info.si_errno = %d\n", info->si_errno);
242 printf("info.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
243 printf("info.si_addr = %p\n", info->si_addr);
245 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
248 #ifndef RGL_SPECIFIC_CHANGES
249 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
250 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
251 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
252 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
253 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
254 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
255 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
256 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
257 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
258 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
259 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
260 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
261 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
262 printf("reg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
263 printf("reg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
264 printf("reg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
265 printf("reg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
268 printf("Stack trace (non-dedicated):\n");
270 sz = backtrace(buffer, 50);
271 strings = backtrace_symbols(buffer, sz);
272 for (i = 0; i < sz; ++i)
273 printf("%s\n", strings[i]);
275 printf("End of stack trace.");
277 #ifdef XEON_SPECIFIC_CHANGES
282 /* Lets first print our debug information */
283 printf("Before dumping our Debug info\n");
285 printf("After dumping our Debug info\n");
287 /* Disable the signal and make the enodeb to dump. This will make
288 * eNB to generate the core with dumping the ccpu log
295 /* End printing debug information */
300 /*** TBD: IMPORTANT ***
301 *** The following definition is temporary. This must be removed
302 *** when all products have been updated with latest ssi.h file OR
303 *** all ssi.h files have been updated to contain this definitions
305 /* New error class for FTHA added */
307 #define ERRCLS_FTHA 0x8
308 #endif /* ERRCLS_FTHA */
310 typedef struct _SPThreadCreateArg
312 void *argument; /* argument that is to be passed to the actual pthread */
313 void *(*start_routine) (void *); /* function from which pthread starts */
316 void *pthreadCreateHdlr(void* arg);
318 #ifdef SS_LOCKLESS_MEMORY
319 Buffer *mtTskBuffer1;
320 Buffer *mtTskBuffer2;
322 pthread_t tmpRegTidMap[20];
324 S16 SGlobMemInfoShow(void);
325 #endif /* SS_LOCKLESS_MEMORY */
328 APP_CONTEXT AppContext;
332 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
333 unsigned int tlPost(void *handle);
336 /* forward references */
337 /* mt003.301 Modifications - Moved to ss_gen.x */
338 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
339 Void *mtTskHdlrT2kL2 ARGS((Void*));
340 void mtSigSegvHndlr ARGS((void));
341 void mtSigUsr2Hndlr ARGS((void));
344 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
345 static Void *mtTskHdlr ARGS((void *));
346 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
348 static Void *mtTmrHdlr ARGS((void *));
349 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
351 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
352 static Void mtIntSigHndlr ARGS((int));
353 static Void mtExitClnup ARGS((void));
356 static Void *mtConHdlr ARGS((void *));
360 #ifdef SS_DRVR_SUPPORT
361 static Void *mtIsTskHdlr ARGS((void *));
365 /* mt020.201 - Addition for no command line available */
367 static Void mtGetOpts ARGS((void));
368 /* mt003.301 Additions - File Based task registration made
369 * common for both MULTICORE and NON-MULTICORE
371 static Bool fileBasedMemCfg = FALSE;
374 /* mt033.201 - addition of local function to print the statistics such as
375 * (size vs. numAttempts) and (allocations vs. deallocations)
377 #ifdef SSI_DEBUG_LEVEL1
378 static S16 SPrintRegMemStats ARGS((Region region));
379 #endif /* SSI_DEBUG_LEVEL1 */
381 #ifdef SS_MULTICORE_SUPPORT
382 static SsSTskEntry* ssdAddTmrSTsk(Void);
383 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
384 #ifndef SS_LOCKLESS_MEMORY
385 #ifndef RGL_SPECIFIC_CHANGES
386 static S16 ssdInitMemInfo ARGS((void));
391 /* mt005.301: Cavium changes */
392 #ifdef SS_SEUM_CAVIUM
393 static Void *workRcvTsk ARGS((void *));
394 #endif /* SS_SEUM_CAVIUM */
396 #ifdef SS_THR_REG_MAP
397 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
399 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
400 #endif /* SS_THR_REG_MAP */
402 /* type declarations */
404 #ifdef SS_DRVR_SUPPORT
405 typedef struct mtIsFlag
415 /* public variable declarations */
417 Cntr cfgNumRegs = SS_MAX_REGS;
418 /* Set memory configuration as false.
419 * Set to true if memory configuration through file is successfull.
421 Bool memConfigured = FALSE;
422 /* mt022.201 - Modification for shared memory relay region and memcal tool */
423 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
426 SS_DFLT_REGION, 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_DYNAMIC, MT_POOL_4_DSIZE },
433 { SS_POOL_STATIC, 0 }
439 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
441 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
442 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
443 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
444 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
445 { SS_POOL_STATIC, 0 }
448 #endif /* INTEL_WLS */
450 #ifdef SS_LOCKLESS_MEMORY
453 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
455 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
456 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
457 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
458 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
459 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
460 { SS_POOL_STATIC, 0 }
464 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
466 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
467 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
468 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
469 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
470 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
471 { SS_POOL_STATIC, 0 }
475 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
477 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
478 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
479 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
480 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
481 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
482 { SS_POOL_STATIC, 0 }
486 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
488 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
489 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
490 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
491 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
492 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
493 { SS_POOL_STATIC, 0 }
497 SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
499 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
500 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
501 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
502 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
503 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
504 { SS_POOL_STATIC, 0 }
507 #endif /* SS_LOCKLESS_MEMORY */
509 /* mt003.301 Modifications - File Based task registration made
510 * common for both MULTICORE and NON-MULTICORE
513 #ifdef SS_LOCKLESS_MEMORY
514 MtDynMemCfg mtDynMemoCfg =
516 SS_MAX_REGS, /* number of regions */
519 SS_DFLT_REGION, /* region id */
520 MT_MAX_BKTS, /* number of buckets */
522 /* block size, no. of blocks, Upper threshold, lower threshold */
523 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
524 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
525 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
526 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
527 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
531 SS_DFLT_REGION + 1, /* region id */
532 MT_MAX_BKTS, /* number of buckets */
534 /* block size, no. of blocks, Upper threshold, lower threshold */
535 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
536 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
537 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
538 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
539 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
543 SS_DFLT_REGION + 2, /* region id */
544 MT_MAX_BKTS, /* number of buckets */
546 /* block size, no. of blocks, Upper threshold, lower threshold */
547 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_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}
555 SS_DFLT_REGION + 3, /* region id */
556 MT_MAX_BKTS, /* number of buckets */
558 /* block size, no. of blocks, Upper threshold, lower threshold */
559 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_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}
567 SS_DFLT_REGION + 4, /* region id */
568 MT_MAX_BKTS, /* number of buckets */
570 /* block size, no. of blocks, Upper threshold, lower threshold */
571 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_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}
579 SS_DFLT_REGION + 5, /* region id */
580 MT_MAX_BKTS, /* number of buckets */
582 /* block size, no. of blocks, Upper threshold, lower threshold */
583 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_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}
590 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
593 SS_DFLT_REGION + 4, /* region id */
594 MT_MAX_BKTS, /* number of buckets */
596 /* block size, no. of blocks, Upper threshold, lower 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}
608 MtGlobMemCfg mtGlobMemoCfg =
610 MT_MAX_BKTS, /* number of buckets */
613 /* block size, no. of blocks, Upper threshold, lower threshold */
614 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
615 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
616 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
617 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
618 {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
620 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
621 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
622 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
623 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
627 #endif /* SS_LOCKLESS_MEMORY */
629 /* mt022.201 - Modification for memory calculator tool */
630 /* mt018.201 - added memory configuration matrix */
634 SS_MAX_REGS - 1, /* number of regions */
636 #ifndef XEON_SPECIFIC_CHANGES
637 SS_MAX_REGS, /* number of regions */
644 SS_DFLT_REGION, /* region id */
645 MT_MAX_BKTS, /* number of buckets */
646 MT_HEAP_SIZE, /* heap size */
648 #ifndef XEON_SPECIFIC_CHANGES
649 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
650 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
651 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
652 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
653 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
655 {256, 491520}, /* 60 pages of 2M*/
656 {512, 12288}, /* 3 pages of 2M */
657 {2048, 99328}, /* 97 Pages of 2M */
658 {8192, 75008}, /* 293 Pages of 2M */
659 {16384, 4096} /* 32 pages of 2M */
664 #ifndef SS_LOCKLESS_MEMORY
666 SS_DFLT_REGION + 1, /* region id */
667 MT_MAX_BKTS, /* number of buckets */
668 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
670 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
671 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
672 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
673 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
681 #endif /* SS_LOCKLESS_MEMORY */
682 #endif /* INTEL_WLS */
683 #ifdef SS_LOCKLESS_MEMORY
685 SS_DFLT_REGION + 1, /* region id */
686 MT_MAX_BKTS, /* number of buckets */
687 MT_HEAP_SIZE, /* heap size */
689 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
690 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
691 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
692 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
693 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
697 SS_DFLT_REGION + 2, /* region id */
698 MT_MAX_BKTS, /* number of buckets */
699 MT_HEAP_SIZE, /* heap size */
701 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
702 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
703 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
704 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
705 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
709 SS_DFLT_REGION + 3, /* region id */
710 MT_MAX_BKTS, /* number of buckets */
711 MT_HEAP_SIZE, /* heap size */
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} /* block size, no. of blocks */
721 SS_DFLT_REGION + 4, /* region id */
722 MT_MAX_BKTS, /* number of buckets */
723 MT_HEAP_SIZE, /* heap size */
725 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
726 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
727 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
728 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
729 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
733 SS_DFLT_REGION + 5, /* region id */
734 MT_MAX_BKTS, /* number of buckets */
735 MT_HEAP_SIZE, /* heap size */
737 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
738 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
739 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
740 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
741 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
744 #endif /* SS_LOCKLESS_MEMORY */
748 /* mt003.301 Modifications - File Based task registration made
749 * common for both MULTICORE and NON-MULTICORE
750 * bucket info, as different regions may request for different no.
753 MtBktCfg mtBktInfo[MT_MAX_BKTS];
754 S16 msArgc; /* argc */
755 Txt **msArgv; /* argv */
756 S16 msOptInd; /* SGetOpt vars */
757 S8 *msOptArg; /* SGetOpt vars */
760 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
761 typedef struct _MtRegMemSz
767 #ifdef SS_USE_WLS_MEM
768 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
769 static S16 SPartitionWlsDynMem();
770 static S16 SAllocateWlsDynMem();
773 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
778 /* private variable declarations */
779 /* mt018.201 - change mtCMMRegCfg as array of pointers */
780 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
781 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
782 /* mt003.301 - Fixed compilation warnings */
783 /*mt004.301-addede new veriable for FAP*/
784 /*mt010.301 - removed veriable defined for FA*/
787 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
790 void mtSetNtlHdl(unsigned int hdl)
795 unsigned int mtGetNtlHdl()
797 return(osCp.ntl.hdl);
801 void mtGetWlsHdl(void **hdlr)
803 *hdlr = osCp.wls.intf;
806 #ifdef XEON_MULTIPLE_CELL_CHANGES
807 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
808 S16 smWrReadWlsConfigParams (Void);
811 static int SOpenWlsIntf()
815 #define WLS_DEVICE_NAME "wls0"
817 char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", WLS_DEVICE_NAME, "--iova-mode=pa"};
818 printf("Calling rte_eal_init: ");
819 for (i = 0; i < RTE_DIM(my_argv); i++)
821 printf("%s ", my_argv[i]);
825 if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
826 rte_panic("Cannot init EAL\n");
829 #ifdef XEON_SPECIFIC_CHANGES
830 #ifdef XEON_MULTIPLE_CELL_CHANGES
831 hdl = WLS_Open(gWrWlsDeviceName, 1);
833 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
836 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
843 printf("Could not open WLS Interface \n");
858 * Desc: This function is the entry point for the final binary. It
859 * calls SInit() in the common code. It can be replaced by a
860 * user function if required (SInit() must still be called).
862 * Ret: none on success
872 int argc, /* argument count */
873 char **argv /* argument vector */
877 #ifdef XEON_MULTIPLE_CELL_CHANGES
878 /* Read the WLS parameters from the file and copy into global control block */
879 if(smWrReadWlsConfigParams() != ROK)
881 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
883 } /* end of if statement */
886 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
889 #endif /* INTEL_WLS */
893 /* mt003.301 Modifications */
896 printf("\n SInit failed, SSI could not start \n");
897 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
901 /*mt010.301 cleanup part exposed to user*/
912 * Desc: This function is the entry point for the final binary. It
913 * calls SInit() in the common code. It can be replaced by a
914 * user function if required (SInit() must still be called).
916 * Ret: none on success
926 int argc, /* argument count */
927 char **argv /* argument vector */
943 * initialization functions
948 * Fun: Initialize OS control point
950 * Desc: This function initializes MTSS-specific information
951 * in the OS control point.
962 struct sigaction act;
964 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
969 /*mt014.301 : 4GMX release related changes*/
973 /* mt005.301 : Cavium changes */
974 #ifdef SS_SEUM_CAVIUM
975 /* set group mask for the core */
976 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
977 #endif /* SS_SEUM_CAVIUM */
979 osCp.dep.sysTicks = 0;
981 /* mt020.201 - Addition for no command line available */
983 /* parse command line */
985 /* mt003.301 Additions */
986 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
988 printf("\n File Based Memory configuration failed \n");
993 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
994 #ifndef SS_LOCKLESS_MEMORY
995 #ifdef SS_MULTICORE_SUPPORT
996 if(memConfigured == FALSE)
1002 /* initialize the started semaphore */
1003 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1008 /* mt028.201 added compile time flag to allow not to mask signals */
1010 /* mask all signals in the main thread */
1012 sigdelset(&set, SIGINT);
1013 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1014 sigdelset(&set, SIGSEGV);
1015 sigdelset(&set, SIGUSR2);
1016 sigdelset(&set, SIGILL);
1017 #ifdef XEON_SPECIFIC_CHANGES
1018 sigdelset(&set, SIGABRT);
1019 sigdelset(&set, SIGTERM);
1020 sigdelset(&set, SIGHUP);
1023 pthread_sigmask(SIG_SETMASK, &set, NULLP);
1024 #endif /* UNMASK_SIG */
1026 /* install a SIGINT handler to shutdown */
1027 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1029 /*Initialize SIGSEGV Signal */
1030 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1032 memset(&sa, 0, sizeof(struct sigaction));
1033 sigemptyset(&sa.sa_mask);
1034 sa.sa_sigaction = signal_segv;
1035 sa.sa_flags = SA_SIGINFO;
1036 #ifndef XEON_SPECIFIC_CHANGES
1037 sigaction(SIGSEGV, &sa, NULL);
1039 memset(&sa, 0, sizeof(struct sigaction));
1040 sigemptyset(&sa.sa_mask);
1041 sa.sa_sigaction = signal_segv;
1042 sa.sa_flags = SA_SIGINFO;
1044 sigaction(SIGILL, &sa, NULL);
1046 if(sigaction(SIGILL, &sa, NULL) != 0)
1048 printf("Failed to process sigaction for the SIGILL\n");
1051 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1053 printf("Failed to process sigaction for the SIGSEGV\n");
1056 if(sigaction(SIGABRT, &sa, NULL) != 0)
1058 printf("Failed to process sigaction for the SIGABRT\n");
1061 if(sigaction(SIGTERM, &sa, NULL) != 0)
1063 printf("Failed to process sigaction for the SIGTERM\n");
1066 if(sigaction(SIGHUP, &sa, NULL) != 0)
1068 printf("Failed to process sigaction for the SIGHUP\n");
1073 signal (SIGSEGV, mtSigSegvHndlr);
1074 signal (SIGKILL, mtSigSegvHndlr);
1075 signal (SIGUSR2, mtSigUsr2Hndlr);
1080 signal (SIGINT, mtStopHndlr);
1083 act.sa_handler = mtIntSigHndlr;
1084 sigfillset(&act.sa_mask);
1086 if (sigaction(SIGINT, &act, NULLP) != 0)
1092 /* mt040.201 initialise random seed */
1093 osCp.dep.randSeed = time(NULLP);
1101 * Fun: De-initialize OS control point
1103 * Desc: This function reverses the initialization in ssdInitGen().
1112 Void ssdDeinitGen(void)
1116 sem_destroy(&osCp.dep.ssStarted);
1121 #ifdef SS_LOCKLESS_MEMORY
1125 * Fun: ssPutDynMemBlkSet
1127 * Desc: Returns the set of dynamic Blocks into the global region
1130 * Ret: ROK - successful,
1131 * RFAILED - unsuccessful.
1138 S16 ssPutDynMemBlkSet
1140 uint8_t bktIdx, /* Index to bucket list */
1141 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1142 added to global region */
1145 CmMmGlobRegCb *globReg;
1146 CmMmGlobalBktCb *bktCb;
1150 globReg = osCp.globRegCb;
1152 #if (ERRCLASS & ERRCLS_INT_PAR)
1153 if(bktIdx >= globReg->numBkts)
1157 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1159 bktCb = &(globReg->bktTbl[bktIdx]);
1161 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1163 blkPtr = dynMemSetElem->nextBktPtr;
1164 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1165 free((Void *)blkPtr);
1168 dynMemSetElem->nextBktPtr = NULLP;
1169 dynMemSetElem->numFreeBlks = 0;
1176 * Fun: ssGetDynMemBlkSet
1178 * Desc: Gets the set of dynamic memory blocks from the global region
1181 * Ret: ROK - successful,
1182 * RFAILED - unsuccessful.
1189 S16 ssGetDynMemBlkSet
1191 uint8_t bktIdx, /* Index to bucket list */
1192 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1193 with new set values */
1197 CmMmGlobRegCb *globReg;
1198 CmMmGlobalBktCb *bktCb;
1203 globReg = osCp.globRegCb;
1205 #if (ERRCLASS & ERRCLS_INT_PAR)
1206 if(bktIdx >= globReg->numBkts)
1210 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1212 bktCb = &(globReg->bktTbl[bktIdx]);
1213 basePtr = &(dynMemSetElem->nextBktPtr);
1215 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1217 blkPtr = (Data *)malloc(bktCb->size);
1219 basePtr = (CmMmEntry **)blkPtr;
1222 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1226 } /* ssGetDynMemBlkSet */
1231 * Fun: ssPutDynMemBlkSet
1233 * Desc: Returns the set of dynamic Blocks into the global region
1236 * Ret: ROK - successful,
1237 * RFAILED - unsuccessful.
1244 S16 ssPutDynMemBlkSet
1246 uint8_t bktIdx, /* Index to bucket list */
1247 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1248 added to global region */
1249 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1252 CmMmGlobRegCb *globReg;
1253 CmMmGlobalBktCb *bktCb;
1255 CmMmBlkSetElement *globMemNode;
1259 globReg = osCp.globRegCb;
1261 #if (ERRCLASS & ERRCLS_INT_PAR)
1262 if(bktIdx >= globReg->numBkts)
1266 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1268 bktCb = &(globReg->bktTbl[bktIdx]);
1270 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1271 try lock is used as it is not required to block as it will be taken
1272 in the next go else it will be blocked for lock as we have to get the
1275 SLock(&(bktCb->bucketLock));
1281 /* Get a free node from the free node linked list */
1282 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1283 if(lstNode == NULLP)
1285 SUnlock(&(bktCb->bucketLock));
1289 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1291 /* Copy the content of the received element information on to free node
1292 * and add it to valid linked list */
1293 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1294 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1295 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1296 dynMemSetElem->numFreeBlks = 0;
1297 dynMemSetElem->nextBktPtr = NULLP;
1299 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1301 SUnlock(&(bktCb->bucketLock));
1309 * Fun: ssGetDynMemBlkSet
1311 * Desc: Gets the set of dynamic memory blocks from the global region
1314 * Ret: ROK - successful,
1315 * RFAILED - unsuccessful.
1317 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1323 S16 ssGetDynMemBlkSet
1325 uint8_t bktIdx, /* Index to bucket list */
1326 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1327 with new set values */
1328 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1331 CmMmGlobRegCb *globReg;
1332 CmMmGlobalBktCb *bktCb;
1334 CmMmBlkSetElement *globMemNode;
1338 globReg = osCp.globRegCb;
1340 #if (ERRCLASS & ERRCLS_INT_PAR)
1341 if(bktIdx >= globReg->numBkts)
1345 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1347 bktCb = &(globReg->bktTbl[bktIdx]);
1349 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1350 try lock is used as it is not required to block as it will be taken
1351 in the next go else it will be blocked for lock as we have to get the
1354 SLock(&(bktCb->bucketLock));
1359 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1361 if(lstNode == NULLP)
1363 SUnlock(&(bktCb->bucketLock));
1367 /* Delete the node from the valid linked list and copy the values of the
1368 * elements of structrues into pointer */
1369 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1370 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1371 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1372 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1374 /* Add this node to the free node linked list */
1375 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1377 SUnlock(&(bktCb->bucketLock));
1381 } /* ssGetDynMemBlkSet */
1384 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1385 uint32_t gDynMemAlrm[4];
1386 static uint32_t memoryCheckCounter;
1388 uint32_t isMemThreshReached(Region reg)
1390 CmMmGlobRegCb *globReg;
1391 CmMmGlobalBktCb *bktCb;
1392 uint8_t bktIdx= reg;
1394 globReg = osCp.globRegCb;
1396 #if (ERRCLASS & ERRCLS_INT_PAR)
1397 if(bktIdx >= globReg->numBkts)
1401 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1403 bktCb = &(globReg->bktTbl[bktIdx]);
1405 if(gDynMemAlrm[bktIdx])
1407 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1408 SLock(&(bktCb->bucketLock));
1409 if(bktCb->listValidBktSet.count > 25)
1411 gDynMemAlrm[bktIdx] = FALSE;
1412 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1414 SUnlock(&(bktCb->bucketLock));
1420 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1422 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1423 SLock(&(bktCb->bucketLock));
1424 if(bktCb->listValidBktSet.count < 15 )
1425 gDynMemAlrm[bktIdx] = TRUE;
1426 memoryCheckCounter = 0;
1427 SUnlock(&(bktCb->bucketLock));
1433 #endif /* USE_MALLOC */
1434 #endif /* SS_LOCKLESS_MEMORY */
1436 #ifdef SS_USE_ICC_MEMORY
1439 * Fun: Initialize region/pool tables
1441 * Desc: This function initializes MTSS-specific information
1442 * in the region/pool tables and configures the common
1443 * memory manager for use.
1452 Void * ssGetIccHdl(Region region)
1454 CmMmDynRegCb *dynRegCb;
1456 /* Klock work fix ccpu00148484 */
1457 if(!(region < SS_MAX_REGS))
1462 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1464 return (dynRegCb->iccHdl);
1466 #endif /* SS_USE_ICC_MEMORY */
1468 #ifdef T2K_MEM_LEAK_DBG
1469 RegionMemLeakInfo regMemLeakInfo;
1470 #endif /* T2K_MEM_LEAK_DBG */
1472 #ifdef SS_USE_WLS_MEM
1473 static S16 SPartitionWlsDynMem()
1476 uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1478 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1480 mtDynMemSz[i].startAddr = bktMemStrtAddr;
1481 bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1484 printf("Global Memory Info: \n");
1485 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1487 printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1492 static S16 SAllocateWlsDynMem()
1497 memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1499 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1501 reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1502 mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1504 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1505 #ifdef INTEL_L1_V19_10
1508 (reqdMemSz + (4 * 1024 * 1024)));
1510 printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1511 SPartitionWlsDynMem();
1519 S16 SPartitionWlsMemory()
1524 uint64_t pageSize[1], hugePageSize;
1527 long int pageSize[1], hugePageSize;
1530 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1532 uint8_t *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1534 gethugepagesizes(pageSize,1);
1535 hugePageSize = pageSize[0];
1536 for (i = 0; i < 1; i++)
1538 mtRegMemSz[i].startAddr = regMemStrtAddr;
1539 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1541 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1542 reqdSz = numHugePg * hugePageSize;
1543 regMemStrtAddr += reqdSz;
1544 #ifdef T2K_MEM_LEAK_DBG
1545 /* Since wls is region 0 */
1546 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1547 regMemLeakInfo.numActvRegions++;
1548 #endif /* T2K_MEM_LEAK_DBG */
1550 //Store last region addr for validation
1551 mtRegMemSz[i].startAddr = regMemStrtAddr;
1555 #ifdef SS_MEM_WL_DEBUG
1556 Void SChkAddrValid(int type, int region, PTR ptr)
1558 char *tryPtr = NULL;
1559 if(type == 0) //Global
1561 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1562 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1564 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1570 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1572 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1578 #endif /* SS_MEM_WL_DEBUG */
1580 S16 SPartitionStaticMemory(uint8_t *startAddr)
1585 uint8_t *regMemStrtAddr = (uint8_t *)startAddr;
1588 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1589 for (i = 1; i < mtMemoCfg.numRegions; i++)
1591 mtRegMemSz[i].startAddr = regMemStrtAddr;
1592 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1593 regMemStrtAddr += reqdSz;
1594 #ifdef T2K_MEM_LEAK_DBG
1595 { /* Since region 1 onwards are used for non wls */
1596 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1597 regMemLeakInfo.numActvRegions++;
1599 #endif /* T2K_MEM_LEAK_DBG */
1603 S16 SAllocateWlsMem()
1611 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1612 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1614 for (i = 0; i < 1; i++)
1616 /* allocate space for the region */
1617 region = &mtMemoCfg.region[i];
1618 reqdMemSz += region->heapsize;
1619 mtRegMemSz[i].reqdSz += region->heapsize;
1621 for (j = 0; j < region->numBkts; j++)
1623 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1624 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1627 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1628 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1630 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1632 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1634 SPartitionWlsMemory();
1637 S16 SAllocateStaticMem()
1646 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1648 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1649 for (i = 1; i < mtMemoCfg.numRegions; i++)
1651 /* allocate space for the region */
1652 region = &mtMemoCfg.region[i];
1653 reqdMemSz += region->heapsize;
1654 mtRegMemSz[i].reqdSz += region->heapsize;
1656 for (j = 0; j < region->numBkts; j++)
1658 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1659 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1663 startAddr = malloc(reqdMemSz + (1024 * 10));
1665 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1667 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1669 SPartitionStaticMemory(startAddr);
1672 #endif /* INTEL_WLS */
1678 * Fun: Initialize region/pool tables
1680 * Desc: This function initializes MTSS-specific information
1681 * in the region/pool tables and configures the common
1682 * memory manager for use.
1691 S16 ssdInitMem(void)
1693 /* mt018.201 - added local variable */
1698 Txt errMsg[256] = {'\0'};
1699 #ifdef SS_LOCKLESS_MEMORY
1700 CmMmDynRegCb *dynRegCb;
1701 #ifdef SS_USE_ICC_MEMORY
1703 CmMmGlobRegCb *globReg;
1706 #endif /* SS_LOCKLESS_MEMORY */
1709 /* Use the default SSI memory manager if the ICC memory manager is not
1710 * avilable. If ICC memory manager is avilable, it will be used for
1711 * all sharable memory allocation and de-allocation */
1712 #ifdef SS_LOCKLESS_MEMORY
1713 #ifdef SS_USE_ICC_MEMORY
1714 #ifndef YS_PHY_3_8_2
1716 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1718 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1719 if(dynRegCb == NULLP)
1723 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1725 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1727 dynRegCb->region = i;
1728 cmMmDynRegInit(dynRegCb);
1729 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1732 /* ysIccHdl = dynRegCb->iccHdl; */
1735 /* Initialize the global region first */
1736 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1738 if(osCp.globRegCb == NULLP)
1743 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1745 #ifdef SS_USE_WLS_MEM
1746 SAllocateWlsDynMem();
1749 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1751 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1752 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1753 globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1754 printf("Starting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1757 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1759 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1762 if(globReg->bktTbl[i].startAddr == NULLP)
1766 globReg->bktTbl[i].poolId = i;
1767 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1768 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1769 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1772 globReg->numBkts = mtGlobMemoCfg.numBkts;
1773 cmMmGlobRegInit(globReg);
1775 /* Initialize the dynamic task regions and sanity check for the theshold
1777 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1779 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1780 if(dynRegCb == NULLP)
1784 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1786 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1787 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1788 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1789 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1791 #ifdef XEON_SPECIFIC_CHANGES
1796 dynRegCb->bktTbl[k].poolId = k;
1797 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1798 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1799 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1800 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1801 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1803 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1806 dynRegCb->region = i;
1807 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1808 cmMmDynRegInit(dynRegCb);
1810 #endif /* SS_USE_ICC_MEMORY */
1811 #endif /* SS_LOCKLESS_MEMORY */
1813 #ifdef T2K_MEM_LEAK_DBG
1815 /* Initailize mem leak tool memorys for debguing */
1816 regMemLeakInfo.numActvRegions=0;
1817 for(reg=0; reg <SS_MAX_REGS; reg++)
1819 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1820 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1821 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1822 regMemLeakInfo.regStartAddr[reg] = 0;
1825 regMemLeakInfo.regStartAddr[reg] = 0;
1826 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1828 printf("\n mutex init failed\n");
1834 /* Now allocate WLS memory */
1836 SAllocateStaticMem();
1838 /* mt018.201 - CMM Initialization */
1839 for (i = 0; i < mtMemoCfg.numRegions; i++)
1841 /* allocate space for the region control block */
1842 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1843 #ifdef TENB_RTLIN_CHANGES
1844 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1846 if (mtCMMRegCb[i] == NULLP)
1848 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1849 for the Region:%d control block\n",i);
1851 for (k = 0; k < i; k++)
1853 cmMmRegDeInit(mtCMMRegCb[k]);
1854 free(mtCMMRegCfg[k]->vAddr);
1855 free(mtCMMRegCb[k]);
1856 free(mtCMMRegCfg[k]);
1861 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1862 #ifdef TENB_RTLIN_CHANGES
1863 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1865 if (mtCMMRegCfg[i] == NULLP)
1867 for (k = 0; k < i; k++)
1869 cmMmRegDeInit(mtCMMRegCb[k]);
1870 free(mtCMMRegCfg[k]->vAddr);
1871 free(mtCMMRegCb[k]);
1872 free(mtCMMRegCfg[k]);
1874 free(mtCMMRegCb[i]);
1879 /* allocate space for the region */
1880 region = &mtMemoCfg.region[i];
1881 mtCMMRegCfg[i]->size = region->heapsize;
1882 for (j = 0; j < region->numBkts; j++)
1884 /* mt033.201 - addition for including the header size while computing the total size */
1885 #ifdef SSI_DEBUG_LEVEL1
1886 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1887 (region->bkt[j].numBlks);
1889 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1890 #endif /* SSI_DEBUG_LEVEL1 */
1893 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1895 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1898 #ifdef XEON_SPECIFIC_CHANGES
1899 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1900 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1902 #ifdef TENB_RTLIN_CHANGES
1903 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1906 if (mtCMMRegCfg[i]->vAddr == NULLP)
1908 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1909 for the Region:%d \n",i);
1911 for (k = 0; k < i; k++)
1913 cmMmRegDeInit(mtCMMRegCb[k]);
1914 free(mtCMMRegCfg[k]->vAddr);
1915 free(mtCMMRegCb[k]);
1916 free(mtCMMRegCfg[k]);
1918 free(mtCMMRegCb[i]);
1919 free(mtCMMRegCfg[i]);
1924 /* set up the CMM configuration structure */
1925 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1926 mtCMMRegCfg[i]->chFlag = 0;
1927 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1928 mtCMMRegCfg[i]->numBkts = region->numBkts;
1930 for (j = 0; j < region->numBkts; j++)
1932 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1933 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1936 /* initialize the CMM */
1937 #ifdef SS_LOCKLESS_MEMORY
1938 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1940 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1941 #endif /* SS_LOCKLESS_MEMORY */
1943 for (k = 0; k < i; k++)
1945 cmMmRegDeInit(mtCMMRegCb[k]);
1946 free(mtCMMRegCfg[k]->vAddr);
1947 free(mtCMMRegCb[k]);
1948 free(mtCMMRegCfg[k]);
1950 free(mtCMMRegCfg[i]->vAddr);
1951 free(mtCMMRegCb[i]);
1952 free(mtCMMRegCfg[i]);
1957 /* initialize the STREAMS module */
1958 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1959 if (region->regionId == 0)
1961 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
1963 for (k = 0; k < i; k++)
1965 cmMmRegDeInit(mtCMMRegCb[k]);
1966 free(mtCMMRegCfg[k]->vAddr);
1967 free(mtCMMRegCb[k]);
1968 free(mtCMMRegCfg[k]);
1970 cmMmRegDeInit(mtCMMRegCb[i]);
1971 free(mtCMMRegCfg[i]->vAddr);
1972 free(mtCMMRegCb[i]);
1973 free(mtCMMRegCfg[i]);
1978 /* mt001.301 : Additions */
1979 #ifdef SS_MEM_LEAK_STS
1981 #endif /* SS_MEM_LEAK_STS */
1990 * Fun: De-initialize region/pool tables
1992 * Desc: This function reverses the initialization in ssdInitMem().
2001 Void ssdDeinitMem(void)
2003 /* mt018.201 - added local variables */
2006 /* mt008.301 Additions */
2007 #ifdef SS_MEM_LEAK_STS
2008 cmDeinitMemLeakMdl();
2009 #endif /* SS_MEM_LEAK_STS */
2011 for (i = 0; i < mtMemoCfg.numRegions; i++)
2013 cmMmRegDeInit(mtCMMRegCb[i]);
2014 free(mtCMMRegCfg[i]->vAddr);
2015 free(mtCMMRegCb[i]);
2016 free(mtCMMRegCfg[i]);
2025 * Fun: Initialize task table
2027 * Desc: This function initializes MTSS-specific information
2028 * in the task table.
2037 S16 ssdInitTsk(void)
2039 /* mt001.301 : Additions */
2040 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2041 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2042 uint32_t tskInd = 0;
2043 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2047 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2048 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2049 /* initialize system task information */
2050 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2052 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2054 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2061 * Fun: Deinitialize task table
2063 * Desc: This function reverses the initialization perfomed in
2073 Void ssdDeinitTsk(void)
2080 #ifdef SS_DRVR_SUPPORT
2083 * Fun: Initialize driver task table
2085 * Desc: This function initializes MTSS-specific information
2086 * in the driver task table.
2095 S16 ssdInitDrvr(void)
2099 pthread_attr_t attr;
2104 /* initialize the dependent portion of the driver task entries */
2105 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2107 osCp.drvrTskTbl[i].dep.flag = FALSE;
2111 /* create pipe for communication between SSetIntPend() and
2112 * the isTskHdlr thread.
2114 if (pipe(osCp.dep.isFildes) != 0)
2120 /* create the isTskHdlr thread */
2121 pthread_attr_init(&attr);
2122 /* mt021.201 - Addition to set stack size */
2123 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2124 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2125 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2126 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2128 /* mt020.201 - Addition for destroying thread attribute object attr */
2129 pthread_attr_destroy(&attr);
2135 /*mt014.301 : 4GMX release related changes*/
2136 #ifdef SS_4GMX_UCORE
2144 /* mt020.201 - Addition for destroying thread attribute object attr */
2145 pthread_attr_destroy(&attr);
2154 * Fun: Deinitialize driver information
2156 * Desc: This function reverses the initialization performed in
2166 Void ssdDeinitDrvr(void)
2168 /* mt008.301: Terminate the Driver Task on exit */
2169 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2172 TL_Close(AppContext.hUAII);
2173 if (clusterMode == RADIO_CLUSTER_MODE)
2175 TL_Close(AppContext.hUAII_second);
2181 #endif /* SS_DRVR_SUPPORT */
2186 * Fun: Initialize timer table
2188 * Desc: This function initializes MTSS-specific information
2189 * in the timer table.
2198 S16 ssdInitTmr(void)
2200 pthread_attr_t attr;
2201 struct sched_param param_sched;
2202 /* mt010.21: addition */
2204 #ifdef SS_MULTICORE_SUPPORT
2206 #endif /* SS_MULTICORE_SUPPORT */
2207 #ifdef SS_THR_REG_MAP
2208 uint32_t threadCreated = FALSE;
2209 #endif /* SS_THR_REG_MAP */
2213 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2214 /* mt010.21: addition */
2215 osCp.dep.tmrTqCp.nxtEnt = 0;
2216 for (i=0; i< SS_MAX_TMRS; i++)
2218 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2221 #ifdef SS_MULTICORE_SUPPORT
2222 sTsk = ssdAddTmrSTsk();
2227 #endif /* SS_MULTICORE_SUPPORT */
2228 /* create the timer handler thread */
2229 pthread_attr_init(&attr);
2230 /* mt021.201 - Addition to set stack size */
2231 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2232 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2233 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2234 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2235 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2236 pthread_attr_setschedparam(&attr, ¶m_sched);
2239 #ifdef SS_THR_REG_MAP
2240 /* When the thread is created, we check for the memory mapping table if
2241 * threadId can be placed in thread memory map table. If it is not able to place
2242 * threadId is stored in tmporary array. Once thread is created successful,
2243 * thread_cancel is sent for each thread which are created before. All the
2244 * threads are made to wait on sema which is cancel point for thread.
2246 while(threadCreated == FALSE)
2249 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2251 /* mt020.201 - Addition for destroying thread attribute object attr */
2252 pthread_attr_destroy(&attr);
2257 #ifdef SS_THR_REG_MAP
2258 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2261 #endif /* SS_THR_REG_MAP */
2262 #ifdef SS_MEM_WL_DEBUG
2263 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2266 /* mt020.201 - Addition for destroying thread attribute object attr */
2267 pthread_attr_destroy(&attr);
2276 * Fun: Deinitialize timer table
2278 * Desc: This function reverses the initialization performed in
2288 Void ssdDeinitTmr(void)
2290 #ifdef SS_MULTICORE_SUPPORT
2293 #endif /* SS_MULTICORE_SUPPORT */
2296 #ifdef SS_MULTICORE_SUPPORT
2297 ret = SLock(&osCp.sTskTblLock);
2301 #if (ERRCLASS & ERRCLS_DEBUG)
2302 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2303 "Could not lock system task table");
2307 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2308 /* clean up the system task entry */
2312 SDestroyLock(&sTsk->lock);
2313 ssDestroyDmndQ(&sTsk->dQ);
2316 /* make this entry available in the system task table */
2317 sTsk->nxt = osCp.nxtSTskEntry;
2318 osCp.nxtSTskEntry = 0;
2322 /* unlock the system task table */
2323 SUnlock(&osCp.sTskTblLock);
2325 #endif /* SS_MULTICORE_SUPPORT */
2326 /* mt008.301: Terminate the timer thread on exit */
2327 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2337 * Desc: Pre-tst() initialization.
2346 S16 ssdInitLog(void)
2348 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2352 pthread_attr_t attr;
2355 #endif /* CONSTDIO */
2360 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2365 osCp.dep.conInFp = (FILE *) stdin;
2366 osCp.dep.conOutFp = (FILE *) stdout;
2367 /* added compile time flag CONRD: mt017.21 */
2371 /* disable canonical input processing */
2372 fd = fileno(osCp.dep.conInFp);
2373 if ((tcgetattr(fd, &tio)) != 0)
2375 printf("Error: disable canonical input processing\n");
2379 tio.c_lflag &= ~ICANON;
2380 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2381 tio.c_cc[VTIME] = 0;
2382 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2384 printf("Error: while tcsetattr() processing\n");
2388 #endif /* CONSTDIO */
2391 /* set up the input fd to block when no data is available */
2392 fd = fileno(osCp.dep.conInFp);
2393 flags = fcntl(fd, F_GETFL, &flags);
2394 flags &= ~O_NONBLOCK;
2395 if (fcntl(fd, F_SETFL, flags) == -1)
2397 printf("Error: while fcntl processing\n");
2402 /* create the console handler thread */
2403 pthread_attr_init(&attr);
2404 /* mt021.201 - Addition to set stack size */
2405 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2406 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2407 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2410 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2412 /* mt020.201 - Addition for destroying thread attribute object attr */
2413 pthread_attr_destroy(&attr);
2415 printf("Error: Logging Thread creation failed \n");
2419 /* mt020.201 - Addition for destroying thread attribute object attr */
2420 pthread_attr_destroy(&attr);
2434 * Desc: This function reverses the initialization performed in
2444 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2445 Void ssdDeinitLog(void)
2447 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2450 /* mt008.301: Terminate the console reader on exit */
2451 while(pthread_cancel(osCp.dep.conHdlrTID));
2457 /* mt001.301 : Additions */
2461 S16 ssdInitWatchDog(uint16_t port)
2464 Txt prntBuf[PRNTSZE];
2467 #ifdef SS_WATCHDOG_IPV6
2468 struct sockaddr_in6 tmpaddr;
2470 struct sockaddr_in tmpaddr;
2471 #endif /* SS_WATCHDOG_IPV6 */
2472 #ifdef SS_MULTIPLE_PROCS
2473 ProcId procId = SS_WD_WDPROC;
2474 if (SAddProcIdLst(1, &procId) != ROK)
2478 #endif /* SS_MULTIPLE_PROCS */
2481 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2483 /* Create a watch dog system task */
2484 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2486 /* Create a watch dog reveiver system task */
2487 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2489 /* Register and attach watch dog TAPA task */
2490 #ifdef SS_MULTIPLE_PROCS
2491 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2492 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2494 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2495 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2496 #endif /* SS_MULTIPLE_PROCS */
2497 /* Register and attach watch dog receiver TAPA task */
2498 #ifdef SS_MULTIPLE_PROCS
2499 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2500 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2502 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2503 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2504 #endif /* SS_MULTIPLE_PROCS */
2506 #ifndef SS_MULTIPLE_PROCS
2507 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2508 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2510 osCp.wdCp.watchDgPst.srcProcId = procId;
2511 osCp.wdCp.watchDgPst.dstProcId = procId;
2512 #endif /* SS_MULTIPLE_PROCS */
2514 /* Initialise the pst structure */
2515 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2516 /* Initialize the watch dog timer resolution default is 1 sec */
2518 cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2519 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2520 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2521 for(idx = 0; idx < 1; idx++)
2523 osCp.wdCp.watchDgTs[idx].first = NULLP;
2524 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2526 #ifdef SS_MULTIPLE_PROCS
2527 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2529 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2530 #endif /* SS_MULTIPLE_PROCS */
2532 /* Create the watch dog receiver socket */
2533 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2534 if(osCp.wdCp.globWd.sock == -1)
2536 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2540 #ifdef SS_WATCHDOG_IPV6
2541 tmpaddr.sin6_len = sizeof(tmpadDr);
2542 tmpaddr.sin6_family = AF_INET6;
2543 tmpaddr.sin6_addr = in6addr_any;
2544 tmpaddr.sin6_port = htons(port);
2546 tmpaddr.sin_family = AF_INET;
2547 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2548 tmpaddr.sin_port = htons(port);
2549 #endif /* SS_WATCHDOG_IPV6 */
2551 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2554 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2558 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2562 #ifndef SS_MULTIPLE_PROCS
2563 pst.srcProcId = SFndProcId();
2564 pst.dstProcId = SFndProcId();
2566 pst.srcProcId = procId;
2567 pst.dstProcId = procId;
2568 #endif /* SS_MULTIPLE_PROCS */
2569 pst.event = EVTSSHRTBTREQ;
2570 ssdInitWatchDgPst(&pst);
2571 SPstTsk(&pst, mBuf);
2576 S16 ssdInitWatchDgPst(Pst *pst)
2579 pst->selector = SS_LOOSE_COUPLING;
2581 pst->region = DFLT_REGION; /* region */
2582 pst->pool = DFLT_POOL; /* pool */
2584 pst->prior = PRIOR0; /* priority */
2585 pst->route = RTESPEC; /* route */
2587 pst->dstEnt = ENTHB; /* destination entity */
2589 pst->srcEnt = ENTDW; /* source entity */
2595 #ifdef SS_MULTIPLE_PROCS
2596 S16 ssdWatchDgActvTmr
2603 S16 ssdWatchDgActvTmr(Void)
2604 #endif /* SS_MULTIPLE_PROCS */
2607 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2612 Void ssdWatchDgTmrEvt
2614 PTR cb, /* control block */
2615 S16 event /* timer number */
2618 /* mt003.301 Fixed warings */
2622 Txt prntBuf[PRNTSZE];
2631 SPrint("Timer Heartbeat Request Expired");
2633 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2638 SLock(&osCp.wdCp.wdLock);
2639 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2641 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2643 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2645 if(osCp.wdCp.globWd.callback != 0)
2647 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2651 SUnlock(&osCp.wdCp.wdLock);
2653 if(!osCp.wdCp.globWd.watchdogStop)
2655 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2656 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2666 Void ssdStartWatchDgTmr
2677 Txt prntBuf[PRNTSZE];
2681 /* mt003.301 Modifications */
2684 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2685 if(event == SS_TMR_HRTBT)
2687 SPrint("\nSTART SS_TMR_HRTBT");
2694 SLock(&osCp.wdCp.wdLock);
2695 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2697 osCp.wdCp.globWd.wdsta[i].status = 0;
2699 SUnlock(&osCp.wdCp.wdLock);
2701 arg.tq = osCp.wdCp.watchDgTs;
2702 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2703 arg.timers = osCp.wdCp.watchDgTmr;
2704 arg.cb = (PTR)NULLP;
2706 arg.wait = osCp.wdCp.globWd.timeout = wait;
2714 Void ssdStopWatchDgTmr
2723 Txt prntBuf[PRNTSZE];
2727 /* mt003.301 Modifications */
2730 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2731 if(event == SS_TMR_HRTBT)
2733 SPrint("STOP SS_TMR_HRTBT");
2737 SLock(&osCp.wdCp.wdLock);
2738 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2740 osCp.wdCp.globWd.wdsta[i].status = 0;
2742 SUnlock(&osCp.wdCp.wdLock);
2745 arg.tq = osCp.wdCp.watchDgTs;
2746 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2747 arg.timers = osCp.wdCp.watchDgTmr;
2748 arg.cb = (PTR)NULLP;
2767 Txt prntBuf[PRNTSZE];
2769 struct sockaddr_in tmpaddr;
2770 char hbMsg[SS_WD_HB_MSG_SIZE];
2777 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2781 /* Pack the message */
2782 strcpy(hbMsg, "<HB>REQ</HB>");
2784 /* Send the heartbeat messages to all the configured nodes */
2785 SLock(&osCp.wdCp.wdLock);
2786 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2788 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2793 /* Identify the destination node */
2794 #ifdef SS_WATCHDOG_IPV6
2795 tmpaddr.sin6_len = sizeof(tmpaddr);
2796 tmpaddr.sin6_family = AF_INET6;
2797 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2798 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2800 tmpaddr.sin_family = AF_INET;
2801 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2802 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2803 #endif /* SS_WATCHDOG_IPV6 */
2805 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2809 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2810 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2817 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2822 SUnlock(&osCp.wdCp.wdLock);
2827 #endif /* SS_WATCHDOG */
2831 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2837 * Desc: This function gets command line options.
2846 static Void mtGetOpts(void)
2853 FILE *memOpt; /* memory options file pointer */
2856 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2862 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2864 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2870 #ifdef SS_LOCKLESS_MEMORY
2885 osCp.dep.fileOutFp = (FILE *)NULLP;
2887 /* initialize memOpt */
2888 memOpt = (FILE *) NULLP;
2895 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2900 /* mt001.301 : Additions */
2901 #ifdef SS_MEM_LEAK_STS
2903 cmMemOpenMemLkFile(msOptArg);
2907 osCp.dep.fileOutFp = fopen(msOptArg, "w");
2910 fileBasedMemCfg = TRUE;
2911 memOpt = fopen(msOptArg, "r");
2913 /* if file does not exist or could not be opened then use the
2914 * default memory configuration as defined in mt_ss.h
2916 if (memOpt == (FILE *) NULLP)
2918 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
2919 be opened, using default mem configuration\n", msOptArg);
2924 while (fgets((Txt *)line, 256, memOpt) != NULLP)
2926 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
2932 case 0: /*** INPUT: Number of regions ***/
2933 sscanf(line, "%ld", (long *) &numReg);
2934 mtMemoCfg.numRegions = numReg;
2935 if(mtMemoCfg.numRegions > SS_MAX_REGS)
2937 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
2943 case 1: /*** INPUT: Number of buckets and number of Pools ***/
2944 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
2945 if(numBkts > MT_MAX_BKTS)
2947 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
2951 if(numPools > SS_MAX_POOLS_PER_REG)
2953 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
2958 * Delay updation from local variable to global
2959 * structure of number of regions and heap data to
2960 * counter error conditions present above.
2962 for(idx = 0; idx < cfgNumRegs; idx++)
2964 mtMemoCfg.region[idx].numBkts = numBkts;
2965 cfgRegInfo[idx].region = idx;
2966 cfgRegInfo[idx].numPools = numPools;
2968 * Initialize the pool info as static type with size zero
2970 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
2972 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
2973 cfgRegInfo[idx].pools[poolIdx].size = 0;
2978 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
2979 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
2981 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
2983 if(bktIdx >= numBkts)
2985 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
2990 mtBktInfo[bktIdx].blkSize = bktSz;
2992 if(bktUpdtCnt == numBkts)
2994 i++; /*done reading bkt info, start reading individual region info*/
2998 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
2999 sscanf(line,"%ld",(long *) ®Id);
3000 if(regId >= mtMemoCfg.numRegions)
3002 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3003 #ifndef XEON_SPECIFIC_CHANGES
3008 mtMemoCfg.region[regId].regionId = regId;
3011 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3012 if(bktUpdtCnt < numBkts)
3014 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3015 if(bktIdx >= numBkts)
3017 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3022 if(bktIdx < MT_MAX_BKTS)
3024 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3025 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3026 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3027 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3030 if(bktUpdtCnt == numBkts)
3037 case 5: /* INPUT: Heapsize ***/
3038 sscanf(line, "%ld", (long *) &heapSz);
3039 mtMemoCfg.region[regId].heapsize = heapSz;
3041 if(regUpdtCnt != mtMemoCfg.numRegions)
3050 #ifdef SS_LOCKLESS_MEMORY
3052 sscanf(line, "%ld", (long *) &numBkts);
3053 mtGlobMemoCfg.numBkts = numBkts;
3054 #ifndef XEON_SPECIFIC_CHANGES
3055 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3058 #ifdef XEON_SPECIFIC_CHANGES
3059 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3060 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3061 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3063 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3066 mtDynMemoCfg.region[idx].regionId = idx;
3067 mtDynMemoCfg.region[idx].numBkts = numBkts;
3075 if(bktUpdtCnt < numBkts)
3077 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3078 (long *) &bktSz, (long *) &bktNum,
3079 (long *) &bktSetSize, (long *) &bktRelThr,
3080 (long *) &bktAqurThr);
3081 /* Klock work fix ccpu00148484 */
3082 if(bktIdx < SS_MAX_POOLS_PER_REG)
3084 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3085 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3086 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3087 #ifdef XEON_SPECIFIC_CHANGES
3088 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3089 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3090 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3092 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3094 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3100 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3102 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3103 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3104 #ifdef XEON_SPECIFIC_CHANGES
3105 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3106 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3107 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3113 #ifdef XEON_SPECIFIC_CHANGES
3114 if(bktUpdtCnt == numBkts)
3120 case 8: /* INPUT: Global Heapsize ***/
3121 sscanf(line, "%ld", (long *) &heapSz);
3122 mtGlobMemoCfg.heapSize = heapSz;
3123 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3131 memConfigured = FALSE;
3135 memConfigured = TRUE;
3143 /* mt028.201: modification: multiple procs support related changes */
3144 #ifndef SS_MULTIPLE_PROCS
3147 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3149 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3152 #else /* SS_MULTIPLE_PROCS */
3156 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3158 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3160 SAddProcIdLst(1, &procId);
3163 #endif /* SS_MULTIPLE_PROCS */
3167 osCp.configFilePath = msOptArg;
3191 * Desc: Get options from command line
3193 * Ret: option - success
3195 * EOF - end of options
3197 * Notes: Handles command lines like the following
3200 * then command line should look like this...
3201 * -a foo -b foo1 -c -d foo
3205 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3210 * nloops = atoi(msArgv[msOptInd]);
3213 * state1 = atoi(msArgv[msOptInd]);
3225 int argc, /* argument count */
3226 char **argv, /* argument value */
3227 char *opts /* options */
3230 /* mt020.201 - Removed for no command line */
3238 /* mt020.201 - Addition for no command line */
3250 /*mt013.301 : Changes as per coding standards*/
3251 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3257 if (!strcmp(argv[msOptInd], "--"))
3262 else if (argv[msOptInd][0] != '-')
3270 c = argv[msOptInd][sp];
3271 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3273 if (argv[msOptInd][++sp] == '\0')
3284 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3287 if (++msOptInd >= (S16) argc)
3292 else msOptArg = argv[msOptInd++];
3299 if (argv[msOptInd][++sp] == '\0')
3311 #endif /* NOCMDLINE */
3319 * Desc: This function starts system services execution; the
3320 * permanent tasks are started and the system enters a
3337 /* mt025.201 - Modification for adding lock to timer handler */
3338 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3340 sem_post(&osCp.dep.ssStarted);
3349 * indirect interface functions to system services service user
3355 * Fun: ssdAttachTTsk
3357 * Desc: This function sends the initial tick message to a TAPA
3358 * task if the task is a permanent task.
3369 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3376 if (tTsk->tskType == SS_TSK_PERMANENT)
3378 /* Send a permanent tick message to this task, to start
3381 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3384 #if (ERRCLASS & ERRCLS_DEBUG)
3385 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3390 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3391 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3393 /* set up post structure */
3394 /* mt028.201: modification: multiple procs support related changes */
3395 #ifndef SS_MULTIPLE_PROCS
3396 mInfo->pst.dstProcId = SFndProcId();
3397 mInfo->pst.srcProcId = SFndProcId();
3398 #else /* SS_MULTIPLE_PROCS */
3399 mInfo->pst.dstProcId = tTsk->proc;
3400 mInfo->pst.srcProcId = tTsk->proc;
3401 #endif /* SS_MULTIPLE_PROCS */
3402 mInfo->pst.selector = SEL_LC_NEW;
3403 mInfo->pst.region = DFLT_REGION;
3404 mInfo->pst.pool = DFLT_POOL;
3405 mInfo->pst.prior = PRIOR3;
3406 mInfo->pst.route = RTESPEC;
3407 mInfo->pst.event = 0;
3408 mInfo->pst.dstEnt = tTsk->ent;
3409 mInfo->pst.dstInst = tTsk->inst;
3410 mInfo->pst.srcEnt = tTsk->ent;
3411 mInfo->pst.srcInst = tTsk->inst;
3413 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3414 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3420 #if (ERRCLASS & ERRCLS_DEBUG)
3421 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3422 "Could not write to demand queue");
3435 * Fun: ssdDetachTTsk
3437 * Desc: Does nothing.
3448 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3458 * Fun: ssdCreateSTsk
3460 * Desc: This function creates a system task. A thread is started
3461 * on the system task handler function defined later.
3472 SsSTskEntry *sTsk /* pointer to system task entry */
3476 pthread_attr_t attr;
3477 /* struct sched_param param_sched;*/
3479 #ifdef SS_THR_REG_MAP
3480 uint32_t threadCreated = FALSE;
3485 #ifdef SS_SINGLE_THREADED
3486 /* mt001.301 : Additions */
3488 #ifdef SS_MULTICORE_SUPPORT
3489 if (osCp.numSTsks > 1)
3491 if (osCp.numSTsks > 0)
3492 #endif /* SS_MULTICORE_SUPPORT */
3494 #ifdef SS_MULTICORE_SUPPORT
3495 if (osCp.numSTsks > 3)
3497 if (osCp.numSTsks > 2)
3498 #endif /* SS_MULTICORE_SUPPORT */
3499 #endif /* SS_WATCHDOG */
3506 /* set the current executing entity and instance IDs to
3507 * 'not configured'. create the lock to access them.
3509 sTsk->dep.ent = ENTNC;
3510 sTsk->dep.inst = INSTNC;
3513 /* create the thread */
3514 pthread_attr_init(&attr);
3515 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3517 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3518 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3519 if (sTsk->tskPrior == 0)
3521 printf("Creating RT thread #######################\n");
3522 #ifdef SS_THR_REG_MAP
3523 /* When the thread is created, we check for the memory mapping table if
3524 * threadId can be placed in thread memory map table. If it is not able to place
3525 * threadId is stored in tmporary array. Once thread is created successful,
3526 * thread_cancel is sent for each thread which are created before. All the
3527 * threads are made to wait on sema which is cancel point for thread.
3529 while(threadCreated == FALSE)
3532 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3535 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3536 pthread_attr_destroy(&attr);
3538 #if (ERRCLASS & ERRCLS_DEBUG)
3539 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3544 #ifdef SS_THR_REG_MAP
3545 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3553 #ifdef SS_THR_REG_MAP
3554 /* When the thread is created, we check for the memory mapping table if
3555 * threadId can be placed in thread memory map table. If it is not able to place
3556 * threadId is stored in tmporary array. Once thread is created successful,
3557 * thread_cancel is sent for each thread which are created before. All the
3558 * threads are made to wait on sema which is cancel point for thread.
3560 while(threadCreated == FALSE)
3563 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3567 /* mt020.201 - Addition for destroying thread attribute object attr */
3568 pthread_attr_destroy(&attr);
3570 #if (ERRCLASS & ERRCLS_DEBUG)
3571 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3576 #ifdef SS_THR_REG_MAP
3577 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3584 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3585 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3587 static uint32_t stLwpId = 3;
3588 sTsk->dep.lwpId = ++stLwpId;
3590 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3592 /* mt020.201 - Addition for destroying thread attribute object attr */
3593 pthread_attr_destroy(&attr);
3602 pthread_attr_t* attr,
3603 void *(*start_routine) (void *),
3608 #ifdef SS_THR_REG_MAP
3609 uint32_t threadCreated = FALSE;
3612 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3613 /* Klock work fix ccpu00148484 */
3614 if(threadArg == NULLP)
3618 threadArg->argument = arg;
3619 threadArg->start_routine = start_routine;
3622 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3624 #ifdef SS_THR_REG_MAP
3625 /* When the thread is created, we check for the memory mapping table if
3626 * threadId can be placed in thread memory map table. If it is not able to place
3627 * threadId is stored in tmporary array. Once thread is created successful,
3628 * thread_cancel is sent for each thread which are created before. All the
3629 * threads are made to wait on sema which is cancel point for thread.
3631 while(threadCreated == FALSE)
3634 /*pthreadCreateHdlr */
3635 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3640 #ifdef SS_THR_REG_MAP
3641 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3652 * Fun: Set Pthread Attributes
3654 * Desc: This function is used to set various explicit
3655 * pthread attributes like, priority scheduling,etc
3665 static S16 ssdSetPthreadAttr
3668 pthread_attr_t *attr
3671 struct sched_param param;
3674 SMemSet(¶m, 0, sizeof(param));
3676 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3677 param.sched_priority = 100 - 1 - tskPrior;
3679 param.sched_priority = 100 - 10 - tskPrior;
3682 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3683 /* TODO:: This can be avoided by reducing the priority
3684 * of iccserv thread in l1_master.sh*/
3686 if (clusterMode == RADIO_CLUSTER_MODE)
3688 if(tskPrior == PRIOR1)
3690 param.sched_priority = 91;
3697 printf("Set priority %u\n", param.sched_priority);
3699 /* Set Scheduler to explicit, without this non of the below
3700 pthread attr works */
3701 #ifdef TENB_RTLIN_CHANGES
3702 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3705 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3706 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3707 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3708 #ifdef TENB_RTLIN_CHANGES
3709 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3711 pthread_attr_setschedparam(attr, ¶m);
3715 } /* ssdSetPthreadAttr */
3717 /************* multi-core support **************/
3718 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3719 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3723 * Fun: Get the current core/cpu affinity for a thread/lwp
3725 * Desc: This function is used to get the current processor/core
3726 * affinity for a a system task (thread/lwp). It sets the
3727 * affinity based on the mode supplied by the caller.
3730 * RFAILED - failed, general (optional)
3739 SSTskId *tskId, /* filled in with system task ID */
3740 uint32_t *coreId /* the core/processor id to which the affinity is set */
3750 uint32_t cpuInd = 0;
3751 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3754 uint32_t lwpId = *tskId;
3758 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3760 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3762 tId = osCp.sTskTbl[tskInd].dep.tId;
3767 /* if tskId is not found in the tskTbl */
3768 if (tskInd == SS_MAX_STSKS)
3770 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3775 /* initialize the cpu mask */
3778 /* set thread affinity for linux */
3779 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3781 #if (ERRCLASS & ERRCLS_DEBUG)
3782 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3785 } /* end if pthread_setaffinity fails */
3787 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3789 if (CPU_ISSET (cpuInd, & cpuSet))
3798 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3800 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3802 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3807 /* if tskId is not found in the tskTbl */
3808 if (tskInd == SS_MAX_STSKS)
3810 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3814 /* set thread affinity for Solaris */
3815 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3817 #if (ERRCLASS & ERRCLS_DEBUG)
3818 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3821 } /* end if processor_bind fails */
3824 #endif /* SS_LINUX */
3828 } /* ssdGetAffinity */
3833 * Fun: Set the core/cpu affinity for a thread/lwp
3835 * Desc: This function is used to set processor/core affinity for a
3836 * a system task (thread/lwp). It sets the affinity based on the
3837 * mode supplied by the caller.
3840 * RFAILED - failed, general (optional)
3849 SSTskId *tskId, /* filled in with system task ID */
3850 uint32_t coreId /* the core/processor id to which the affinity has to be set */
3854 uint32_t tskInd = 0;
3859 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3862 uint32_t lwpId = *tskId;
3868 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3870 /* Here tskId can not be used as index as the task may be terminated if
3871 there is a TERM even for that tsk, thus breaking the task Id numbering
3873 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3875 tId = osCp.sTskTbl[tskInd].dep.tId;
3880 /* if tskId is not found in the tskTbl */
3881 if (tskInd == SS_MAX_STSKS)
3883 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3887 /* initialize the cpu mask */
3890 /* set the cpu mask */
3891 CPU_SET(coreId, &cpuSet);
3893 /* set thread affinity for linux */
3894 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3896 #if (ERRCLASS & ERRCLS_DEBUG)
3897 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
3900 } /* end if pthread_setaffinity fails */
3904 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3906 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
3907 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3909 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3914 /* if tskId is not found in the tskTbl */
3915 if (tskInd == SS_MAX_STSKS)
3917 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3921 /* set thread affinity for Solaris */
3922 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
3924 #if (ERRCLASS & ERRCLS_DEBUG)
3925 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
3928 } /* end if processor_bind fails */
3931 #endif /* SS_LINUX */
3933 } /* ssdSetAffinity */
3935 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3936 /************ end multi-core support *************/
3941 * Fun: ssdDestroySTsk
3943 * Desc: This function destroys a system task. A terminate
3944 * event message is sent to the thread function.
3955 SsSTskEntry *sTsk /* pointer to system task entry */
3964 /* we send a message to this system task to tell it to die */
3965 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
3968 #if (ERRCLASS & ERRCLASS_DEBUG)
3969 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
3975 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3976 mInfo->eventInfo.event = SS_EVNT_TERM;
3978 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
3982 #if (ERRCLASS & ERRCLASS_DEBUG)
3983 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
3984 "Could not write to demand queue");
3994 /* mt023.201 - Added SThreadYield function to yield CPU
3998 * Desc: This function defers thread execution to any other ready
4009 S16 SThreadYield(void)
4013 /* mt024.201 - seperated Linux and other UNIX implementations
4019 /* Set sleep value to 0 to yield CPU */
4023 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4025 #else /* other UNICes */
4027 return (sleep(0) == 0 ? ROK : RFAILED);
4029 #endif /* SS_LINUX */
4036 * Fun: Register timer
4038 * Desc: This function is used to register a timer
4039 * function for the service user. System services
4040 * will invoke the timer activation function
4041 * passed to it at the specified intervals.
4045 * Notes: Timing is handled by the common timers. The
4046 * ticks are handled by a thread that uses
4047 * nanosleep() and thus timing precision will not
4055 SsTmrEntry *tmr /* pointer to timer entry */
4063 /* initialize common timers */
4064 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4067 /* start the timer */
4068 arg.tq = osCp.dep.tmrTq;
4069 arg.tqCp = &osCp.dep.tmrTqCp;
4070 arg.timers = tmr->dep.timers;
4075 arg.max = TMR_DEF_MAX;
4076 arg.wait = tmr->interval;
4086 * Fun: Deregister timer
4088 * Desc: This function is used to deregister a timer function.
4099 SsTmrEntry *tmr /* pointer to timer entry */
4107 /* stop the timer */
4108 arg.tq = osCp.dep.tmrTq;
4109 arg.tqCp = &osCp.dep.tmrTqCp;
4110 arg.timers = tmr->dep.timers;
4115 arg.max = TMR_DEF_MAX;
4116 arg.wait = tmr->interval;
4126 * Fun: Critical error
4128 * Desc: This function is called when a critical error occurs.
4139 Seq seq, /* sequence number */
4140 Reason reason /* reset reason */
4150 /* get calling task ID */
4151 tId = pthread_self();
4154 /* set up the message to display */
4155 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4156 "reason = %d\n\n", (uint8_t)tId, seq, reason);
4160 /* delete all system tasks */
4161 for (i = 0; i < SS_MAX_STSKS; i++)
4163 if (osCp.sTskTbl[i].used
4164 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4166 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4172 pthread_exit(NULLP);
4175 /* won't reach here */
4184 * Desc: This function is called to log an error.
4195 Ent ent, /* Calling layer's entity id */
4196 Inst inst, /* Calling layer's instance id */
4197 ProcId procId, /* Calling layer's processor id */
4198 Txt *file, /* file name where error occured */
4199 S32 line, /* line in file where error occured */
4200 ErrCls errCls, /* error class */
4201 ErrCode errCode, /* layer unique error code */
4202 ErrVal errVal, /* error value */
4203 Txt *errDesc /* description of error */
4216 /* get calling task ID */
4218 tId = pthread_self();
4224 case ERRCLS_ADD_RES:
4225 errClsMsg = "ERRCLS_ADD_RES";
4228 case ERRCLS_INT_PAR:
4229 errClsMsg = "ERRCLS_INT_PAR";
4233 errClsMsg = "ERRCLS_DEBUG";
4236 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4238 errClsMsg = "ERRCLS_FTHA";
4242 errClsMsg = "INVALID ERROR CLASS!";
4247 /*mt009.301 Fixed 64BIT compilation warnings*/
4250 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4251 "file: %s line: %03d errcode: %05d errcls: %s\n"
4252 "errval: %05d errdesc: %s\n",
4253 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4256 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4257 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4258 "errval: %05ld errdesc: %s\n",
4259 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4261 SDisplay(0, errBuf);
4262 /* mt001.301 : Additions */
4263 #ifdef SS_LOGGER_SUPPORT
4265 #endif /* SS_LOGGER_SUPPORT */
4269 /* debug errors halt the system */
4270 if (errCls == ERRCLS_DEBUG)
4272 /* mt001.301 : Additions */
4273 #ifdef SS_LOGGER_SUPPORT
4275 #endif /* SS_LOGGER_SUPPORT */
4276 /* delete all system tasks */
4277 for (i = 0; i < SS_MAX_STSKS; i++)
4279 if (osCp.sTskTbl[i].used
4280 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4282 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4288 pthread_exit(NULLP);
4300 * Fun: Register driver task
4302 * Desc: This function is called to register the handlers for a
4314 SsDrvrTskEntry *drvrTsk /* driver task entry */
4321 /* mt001.30 : Additions */
4324 * Fun: Deregister driver task
4326 * Desc: This function is called to deregister the handlers for a
4338 SsDrvrTskEntry *drvrTsk /* driver task entry */
4351 * mt003.301 Additions - SDeRegTTsk fix
4353 #ifdef SS_MULTIPLE_PROCS
4360 #else /*SS_MULTIPLE_PROCS*/
4366 #endif /*SS_MULTIPLE_PROCS*/
4368 #ifdef SS_MULTIPLE_PROCS
4381 /* We check the sTsk element; if it is not NULLP, the
4382 * task is attached. So we have to detach it before
4383 * deregistering the task.
4385 ret = SLock(&osCp.sTskTblLock);
4388 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4391 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4394 #if (ERRCLASS & ERRCLS_DEBUG)
4395 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4397 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4399 #if (ERRCLASS & ERRCLS_DEBUG)
4400 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4408 #ifdef SS_MULTIPLE_PROCS
4410 if (tTsk->initTsk != NULLP)
4413 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4416 &(osCp.tTskTbl[idx].xxCb));
4418 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4421 &(osCp.tTskTbl[idx].xxCb));
4422 #endif /* USE_MEMCAL */
4424 #endif /* SS_MULTIPLE_PROCS */
4426 if (tTsk->sTsk != NULLP)
4430 sTsk->dep.ent = ent;
4431 sTsk->dep.inst = inst;
4433 for (n = 0; n < SS_MAX_TTSKS; n++)
4435 if (sTsk->tTsks[n] == idx)
4437 sTsk->tTsks[n] = SS_INVALID_IDX;
4443 /* call the implementation to detach the task */
4444 ssdDetachTTsk(tTsk);
4446 sTsk->dep.ent = ENTNC;
4447 sTsk->dep.inst = INSTNC;
4450 /* Now we empty the entry for this task and update the table
4453 #ifdef SS_MULTIPLE_PROCS
4454 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4455 #else /* SS_MULTIPLE_PROCS */
4456 osCp.tTskIds[ent][inst] = SS_TSKNC;
4457 #endif /* SS_MULTIPLE_PROCS */
4460 #ifdef SS_MULTIPLE_PROCS
4461 tTsk->proc = PROCNC;
4462 #endif /* SS_MULTIPLE_PROCS */
4464 tTsk->inst = INSTNC;
4465 tTsk->tskType = TTUND;
4466 tTsk->initTsk = NULLP;
4467 tTsk->actvTsk = NULLP;
4470 tTsk->nxt = osCp.nxtTTskEntry;
4471 osCp.nxtTTskEntry = idx;
4474 #ifdef SS_MULTIPLE_PROCS
4475 /* mark the control block for this task as invalid */
4476 osCp.tTskTbl[idx].xxCb = NULLP;
4479 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4480 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4482 #if (ERRCLASS & ERRCLS_DEBUG)
4483 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4490 //#ifndef SPLIT_RLC_DL_TASK
4491 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4492 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4493 Void ysMtTskHdlr(Void);
4494 Void ysMtPollPhyMsg(uint8_t region);
4495 Void ysMtRcvPhyMsg(Void);
4496 Void *mtTskHdlrT2kL2
4498 Ptr tskPtr /* pointer to task entry */
4504 /* wait for SS to come up */
4505 /* It is required to block on this semaphore before starting actual processing of
4506 the thread becasue the creator of this thread might want to cance it without
4507 doing any processing. When this semaphore is released, means the creator gives
4508 the go ahead for actual processing and we should never come back to this point */
4509 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4518 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4519 * (processes L1 msgs) */
4525 Void ysMtTskHdlr(Void);
4526 Void YsPhyRecvMsg();
4527 Void *mtTskHdlrT2kL2
4529 Ptr tskPtr /* pointer to task entry */
4535 /* get out the system task entry from the parameter */
4536 sTsk = (SsSTskEntry *) tskPtr;
4538 /* wait for SS to come up */
4539 /* It is required to block on this semaphore before starting actual processing of
4540 the thread becasue the creator of this thread might want to cance it without
4541 doing any processing. When this semaphore is released, means the creator gives
4542 the go ahead for actual processing and we should never come back to this point */
4543 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4546 #ifndef RGL_SPECIFIC_CHANGES
4554 #ifdef V5GTF_SPECIFIC_CHANGES
4557 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4558 * (processes L1 msgs) */
4560 /* get a message from the demand queue */
4562 #ifdef RLC_MAC_DAT_REQ_RBUF
4563 rgDlDatReqBatchProc();
4566 ret = mtTskHdlMsg(sTsk);
4569 /* exit the for loop here */
4572 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4579 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4582 void *pthreadCreateHdlr(void * arg)
4585 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4586 /* mt038.201 changed how sem_wait is called */
4587 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4590 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4598 * Desc: This is the system task handler function. It blocks on
4599 * the system task's demand queue. On receiving a message,
4600 * it identifies the target TAPA task, verifies that the
4601 * TAPA task belongs to this system task and if so, calls
4602 * the activation function of that TAPA task with the
4603 * received message. The task activation function or the
4604 * timer activation function may be called.
4606 * Ret: (thread function)
4615 Ptr tskPtr /* pointer to task entry */
4621 /* get out the system task entry from the parameter */
4622 sTsk = (SsSTskEntry *) tskPtr;
4625 /* wait for SS to come up */
4627 /* mt038.201 changed how sem_wait is called */
4628 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4630 #ifdef XEON_SPECIFIC_CHANGES
4631 printf("\n**********MT Task Handler********\n");
4635 /* Wait for a message from the demand queue */
4636 #ifdef SS_CDMNDQ_SUPPORT
4637 ret = ssCDmndQWait(&sTsk->dQ);
4639 ret = ssDmndQWait(&sTsk->dQ);
4644 ret = mtTskHdlMsg(sTsk);
4659 * Desc: This is the system task handler function. It blocks on
4660 * the system task's demand queue. On receiving a message,
4661 * it identifies the target TAPA task, verifies that the
4662 * TAPA task belongs to this system task and if so, calls
4663 * the activation function of that TAPA task with the
4664 * received message. The task activation function or the
4665 * timer activation function may be called.
4667 * Ret: (thread function)
4689 /* mt028.201: modification: multiple procs support related changes */
4690 #ifndef SS_MULTIPLE_PROCS
4692 PAIFTMRS16 tmrActvFnMt = NULLP;
4694 /* mt015.301 Initialized the timer activation functions with NULLP */
4695 PFS16 tmrActvFn = NULLP;
4697 PAIFTMRS16 tmrActvFn;
4699 #endif /* SS_MULTIPLE_PROCS */
4700 /* mt003.301 Modifications */
4701 #ifdef SS_THREAD_PROFILE
4703 #endif /* SS_THREAD_PROFILE */
4706 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4709 /* nothing to receive */
4713 /* if we can't lock this system task entry, return the message */
4714 ret = SLock(&sTsk->lock);
4718 #if (ERRCLASS & ERRCLS_DEBUG)
4719 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4720 "Could not lock system task entry");
4730 mBuf2 = mBuf->b_next;
4732 /* find out what kind of message this is */
4733 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4734 #ifdef SS_MEM_WL_DEBUG
4735 mtTskBuffer1 = mBuf2;
4737 mtTskBuffer2 = mBuf2->b_next;
4739 if(mInfo == 0x5050505)
4743 cmAnalyseBtInfo((PTR) mBuf,4);
4745 printf("\n In trouble .... \n");
4747 else if (mInfo == 0x2020202)
4750 cmAnalyseBtInfo((PTR) mBuf,1);
4751 printf("\n In trouble .... \n");
4753 #endif /* SS_MEM_WL_DEBUG */
4754 switch (mInfo->eventInfo.event)
4756 /* this is a termination event, we die */
4758 /* release the message */
4761 /* Unlock the system task entry and lock the system
4762 * task table to clean our entry up.
4764 SUnlock(&sTsk->lock);
4766 ret = SLock(&osCp.sTskTblLock);
4770 #if (ERRCLASS & ERRCLS_DEBUG)
4771 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
4772 "Could not lock system task table");
4774 /* what to do here? */
4778 /* clean up the system task entry */
4781 /* mt003.301 Modifications - SDeRegTTsk */
4782 /* sTsk->numTTsks = 0; */
4783 SDestroyLock(&sTsk->lock);
4784 ssDestroyDmndQ(&sTsk->dQ);
4786 /* lock for current executing TAPA task ID */
4788 /* make this entry available in the system task table */
4789 sTsk->nxt = osCp.nxtSTskEntry;
4790 for (i = 0; i < SS_MAX_STSKS; i++)
4792 if (sTsk == &osCp.sTskTbl[i])
4794 osCp.nxtSTskEntry = i;
4801 /* unlock the system task table */
4802 SUnlock(&osCp.sTskTblLock);
4807 /* this is a data message or a permanent task keep-alive message */
4809 case SS_EVNT_PERMTICK:
4810 /* message to a task. find the destination task */
4811 /* mt028.201: modification: multiple procs support related changes */
4812 #ifdef SS_MULTIPLE_PROCS
4813 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
4815 if (procIdIdx == SS_INV_PROCID_IDX)
4821 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
4822 #else /* SS_MULTIPLE_PROCS */
4823 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
4824 #endif /* SS_MULTIPLE_PROCS */
4826 /* verify that it hasn't been deregistered */
4827 if (idx == SS_TSKNC)
4833 /* verify that this system task is still running it */
4834 tTsk = &osCp.tTskTbl[idx];
4835 if (tTsk->sTsk != sTsk)
4841 /* set the current executing TAPA task ID */
4842 sTsk->dep.ent = mInfo->pst.dstEnt;
4843 sTsk->dep.inst = mInfo->pst.dstInst;
4845 /* copy the Pst structure into a local duplicate */
4846 for (i = 0; i < (S16) sizeof(Pst); i++)
4847 *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
4849 /* Give the message to the task activation function. If
4850 * its a normal data message, we pass it, if this is a
4851 * keep-alive message for a permanent task then we pass
4852 * NULLP in place of the message to the task activation
4855 if (mInfo->eventInfo.event == SS_EVNT_DATA)
4857 #ifndef RGL_SPECIFIC_CHANGES
4858 #ifdef SS_TSKLOG_ENABLE
4859 uint32_t t = MacGetTick();
4862 /* mt003.301 Modifications */
4863 #if SS_THREAD_PROFILE
4864 tTsk->curEvent = nPst.event;
4866 #endif /* SS_THREAD_PROFILE */
4867 tTsk->actvTsk(&nPst, mBuf);
4868 #ifndef RGL_SPECIFIC_CHANGES
4869 #ifdef SS_TSKLOG_ENABLE
4870 SStopTask(t,PID_SSI_TSK);
4873 #if SS_THREAD_PROFILE
4875 tTsk->curEvtTime = (uint32_t)(et2 - et1);
4876 tTsk->totTime += (uint64_t)tTsk->curEvtTime;
4877 #endif /* SS_THREAD_PROFILE */
4881 #if (ERRCLASS & ERRCLS_DEBUG)
4882 /* this message should only come to a permanent task */
4883 if (tTsk->tskType != SS_TSK_PERMANENT)
4885 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
4889 tTsk->actvTsk(&nPst, NULLP);
4891 /* We need to re-send this message back to ourselves so
4892 * the permanent task continues to run.
4894 /* Check if this task got deregistered or detached
4895 * by the activation function; if so, there's nothing
4896 * more to do here, otherwise go ahead.
4899 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
4901 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
4902 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
4906 /* failure here is a real problem */
4909 #if (ERRCLASS & ERRCLS_DEBUG)
4910 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
4911 "Could not write to demand queue");
4917 /* unset the current executing TAPA task ID */
4918 sTsk->dep.ent = ENTNC;
4919 sTsk->dep.inst = INSTNC;
4924 /* timer event. find the timer entry */
4925 idx = mInfo->eventInfo.u.tmr.tmrIdx;
4927 /* lock the timer table, coz we're going to peek in it */
4928 ret = SLock(&osCp.tmrTblLock);
4932 #if (ERRCLASS & ERRCLS_DEBUG)
4933 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
4934 "Could not lock timer table");
4940 /* Verify that this timer entry is still around and that it
4941 * belongs to our task.
4943 if (osCp.tmrTbl[idx].used == FALSE
4944 /* mt028.201: modification: multiple procs support related changes */
4945 #ifdef SS_MULTIPLE_PROCS
4946 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
4947 #endif /* SS_MULTIPLE_PROCS */
4948 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
4949 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
4951 SUnlock(&osCp.tmrTblLock);
4956 /* mt005.21: addition */
4957 /* set the current executing TAPA task ID */
4958 sTsk->dep.ent = mInfo->pst.dstEnt;
4959 sTsk->dep.inst = mInfo->pst.dstInst;
4961 #ifndef SS_MULTIPLE_PROCS
4963 /*mt006.301 Adding Initializing the tmrActvFnMt*/
4964 tmrActvFnMt = NULLP;
4965 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
4967 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
4973 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
4976 /* unlock the timer table */
4977 SUnlock(&osCp.tmrTblLock);
4979 /* activate the timer function */
4980 /* mt028.201: modification: multiple procs support related changes */
4981 #ifndef SS_MULTIPLE_PROCS
4985 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
4986 osCp.tmrTbl[idx].ownerInst);
4994 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
4995 osCp.tmrTbl[idx].ownerInst);
4996 #endif /* SS_MULTIPLE_PROCS */
4998 /*mt005.21: addition */
4999 /* unset the current executing TAPA task ID */
5000 sTsk->dep.ent = ENTNC;
5001 sTsk->dep.inst = INSTNC;
5004 /* return the message buffer */
5008 * mt003.301 - SDeRegTTsk fix
5010 case SS_EVNT_TTSK_TERM:
5011 #ifdef SS_MULTIPLE_PROCS
5012 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5014 if (procIdIdx == SS_INV_PROCID_IDX)
5020 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5021 #else /* SS_MULTIPLE_PROCS */
5022 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5023 #endif /* SS_MULTIPLE_PROCS */
5025 /* verify that it hasn't been deregistered */
5026 if (idx == SS_TSKNC)
5032 /* verify that this system task is still running it */
5033 tTsk = &osCp.tTskTbl[idx];
5034 if (tTsk->sTsk != sTsk)
5039 #ifdef SS_MULTIPLE_PROCS
5040 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5042 ssdProcTTskTerm(tTsk, idx);
5048 #if (ERRCLASS & ERRCLS_DEBUG)
5049 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5056 } while (mBuf != NULLP);
5059 /* unlock the system task entry */
5060 SUnlock(&sTsk->lock);
5063 /* yield for other threads */
5064 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5073 * Fun: mtTmrHdlrPublic
5075 Void mtTmrHdlrPublic()
5077 if (SLock(&osCp.tmrTblLock) != ROK)
5079 #if (ERRCLASS & ERRCLS_DEBUG)
5080 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5084 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5085 /* unlock the timer table */
5086 SUnlock(&osCp.tmrTblLock);
5094 * Desc: The timer handler thread function. Counts time
5095 * and invokes the common timer function on each
5098 * Ret: (thread function)
5105 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5106 static Void *mtTmrHdlr
5108 void *parm /* unused */
5111 /*mt004.301-addede new region*/
5112 /* mt010.301 Removed SS_FAP portion and
5113 * enabled oroginal code in function mtTmrHdlr */
5117 uint32_t i, cnt, oldTicks, newTicks;
5118 struct timeval tv1,tv2;
5119 /* mt038.201 added return */
5121 /* mt039.201 changes for nanosleep */
5122 struct timespec tsN;
5123 static uint32_t err_in_usec;
5125 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5130 /* mt027.201 - Modification for SRegCfgTmr support */
5131 /* check SS_TICKS_SEC */
5132 if (SS_1MS < SS_TICKS_SEC)
5134 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5137 /* mt025.201 - Addition to stop timer handler till task registration is done */
5138 /* wait for SS to come up */
5139 /* mt038.201 changed how sem_wait is called */
5140 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5143 /* mt027.201 - Modification for SRegCfgTmr support */
5144 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5146 ts.tv_nsec = (MT_TICK_CNT * 1000);
5147 /* mt039.201 changes for nanosleep */
5153 if (gettimeofday(&tv1, NULL) == -1)
5155 #if (ERRCLASS & ERRCLS_DEBUG)
5156 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5157 "Error in clock_gettime");
5167 #ifndef STUB_TTI_HANDLING_5GTF
5168 printf("Returning from mtTmrHdlr()\n");
5173 /* mt039.201 changes for nanosleep */
5174 /* sleep for MT_TICK_CNT milli seconds */
5175 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5176 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5178 ts.tv_nsec = tsN.tv_nsec;
5183 if (gettimeofday(&tv2,NULL) == -1)
5185 #if (ERRCLASS & ERRCLS_DEBUG)
5186 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5187 "Error in clock_gettime");
5191 /*mt013.301 : changed check while calculating timer to fix
5192 * diffrence between MTSS time and real unix time
5194 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5196 time_int = (tv2.tv_usec - tv1.tv_usec);
5198 else if (tv2.tv_sec > tv1.tv_sec)
5200 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5202 else /* ts2 < ts1, this will not happen in normal scenario */
5204 /* to make sure cnt = 1 */
5206 time_int = MT_TICK_CNT;
5209 oldTicks = osCp.dep.sysTicks;
5210 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5211 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5212 newTicks = osCp.dep.sysTicks;
5213 tv1.tv_usec = tv2.tv_usec;
5214 tv1.tv_sec = tv2.tv_sec;
5216 cnt = newTicks - oldTicks;
5218 while(err_in_usec >= MT_TICK_CNT)
5221 err_in_usec -= MT_TICK_CNT;
5223 if( cnt >= MT_MAX_TICK_CNT_VAL)
5224 cnt = MT_MIN_TICK_CNT_VAL;
5225 /* call the common timer tick handler */
5226 for (i = 0; i < cnt; i++)
5228 /* mt008.301: cmPrcTmr is guarded with a lock */
5229 /* lock the timer table */
5230 if (SLock(&osCp.tmrTblLock) != ROK)
5232 #if (ERRCLASS & ERRCLS_DEBUG)
5233 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5237 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5238 /* unlock the timer table */
5239 SUnlock(&osCp.tmrTblLock);
5243 /* mt009.21: addition */
5244 return ( (Void *) NULLP);
5245 /* will not reach here */
5253 * Desc: Process timer event. Called from the common timer
5254 * code when a timeout occurs.
5265 PTR tCb, /* control block */
5266 S16 evnt /* event */
5275 #ifndef TENB_RTLIN_CHANGES
5278 /* mt028.201: modification: multiple procs support related changes */
5279 #ifdef SS_MULTIPLE_PROCS
5281 #endif /* SS_MULTIPLE_PROCS */
5282 #ifdef RGL_SPECIFIC_CHANGES
5283 #ifdef MSPD_MLOG_NEW
5284 uint32_t t = GetTIMETICK();
5290 /* get the timer entry */
5291 tEnt = (SsTmrEntry *) tCb;
5294 /* if the timer was deleted, this will be NULL, so drop it */
5300 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5303 /* Hmmmm, the timer might have been deleted while we've been
5304 * working at getting here, so we just skip this.
5306 if (tEnt->used == FALSE)
5312 /* Set up and send a timer message to the destination tasks'
5315 #ifndef SS_MULTICORE_SUPPORT
5316 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5318 #ifdef RGL_SPECIFIC_CHANGES
5319 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5321 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5326 #if (ERRCLASS & ERRCLS_DEBUG)
5327 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5333 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5334 mInfo->eventInfo.event = SS_EVNT_TIMER;
5335 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5337 mInfo->pst.dstEnt = tEnt->ownerEnt;
5338 mInfo->pst.dstInst = tEnt->ownerInst;
5339 mInfo->pst.srcEnt = tEnt->ownerEnt;
5340 mInfo->pst.srcInst = tEnt->ownerInst;
5341 /* mt028.201: modification: multiple procs support related changes */
5342 #ifndef SS_MULTIPLE_PROCS
5343 mInfo->pst.dstProcId = SFndProcId();
5344 mInfo->pst.srcProcId = SFndProcId();
5345 #else /* SS_MULTIPLE_PROCS */
5346 mInfo->pst.dstProcId = tEnt->ownerProc;
5347 mInfo->pst.srcProcId = tEnt->ownerProc;
5348 #endif /* SS_MULTIPLE_PROCS */
5349 mInfo->pst.selector = SEL_LC_NEW;
5350 #ifndef SS_MULTICORE_SUPPORT
5351 mInfo->pst.region = DFLT_REGION;
5354 mInfo->pst.pool = DFLT_POOL;
5355 mInfo->pst.prior = PRIOR0;
5356 mInfo->pst.route = RTESPEC;
5357 mInfo->pst.event = 0;
5360 #ifndef TENB_RTLIN_CHANGES
5361 /* get a semaphore for the TAPA task table */
5362 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5367 #if (ERRCLASS & ERRCLS_DEBUG)
5368 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5376 /* find the owner TAPA task */
5377 /* mt028.201: modification: multiple procs support related changes */
5378 #ifdef SS_MULTIPLE_PROCS
5379 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5380 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5381 #else /* SS_MULTIPLE_PROCS */
5382 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5383 #endif /* SS_MULTIPLE_PROCS */
5384 if (idx == SS_TSKNC)
5386 #ifndef TENB_RTLIN_CHANGES
5387 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5394 /* ensure that the TAPA task is hale and hearty */
5395 tTsk = &osCp.tTskTbl[idx];
5398 #ifndef TENB_RTLIN_CHANGES
5399 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5404 /* Klock work fix ccpu00148484 */
5405 /* write the timer message to the queue of the destination task */
5406 /* mt008.301 : check sTsk before putting into it's DQ */
5407 if (tTsk->sTsk == NULLP)
5409 #ifndef TENB_RTLIN_CHANGES
5410 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5414 #if (ERRCLASS & ERRCLS_DEBUG)
5415 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5416 "Could not write to demand queue");
5421 #ifdef SS_LOCKLESS_MEMORY
5422 mInfo->pst.region = tTsk->sTsk->region;
5423 mInfo->region = tTsk->sTsk->region;
5424 #endif /* SS_LOCKLESS_MEMORY */
5425 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5426 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5428 #ifndef TENB_RTLIN_CHANGES
5429 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5433 #if (ERRCLASS & ERRCLS_DEBUG)
5434 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5435 "Could not write to demand queue");
5440 /* Fix for ccpu00130657 */
5441 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5442 if (tTsk->sTsk->tskPrior == PRIOR0)
5445 WLS_WakeUp(mtGetWlsHdl());
5452 /* release the semaphore for the TAPA task table */
5453 #ifndef TENB_RTLIN_CHANGES
5454 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5458 /* restart the timer */
5459 arg.tq = osCp.dep.tmrTq;
5460 arg.tqCp = &osCp.dep.tmrTqCp;
5461 arg.timers = tEnt->dep.timers;
5462 arg.cb = (PTR) tEnt;
5466 arg.max = TMR_DEF_MAX;
5467 arg.wait = tEnt->interval;
5469 #ifdef RGL_SPECIFIC_CHANGES
5470 #ifdef MSPD_MLOG_NEW
5471 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5483 * Desc: This thread reads the console and hands over any
5484 * data read to a user function.
5486 * Ret: (thread function)
5493 static Void *mtConHdlr
5495 Ptr parm /* unused */
5502 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5508 /* check if we have a console input file handle */
5509 if (osCp.dep.conInFp == NULLP)
5515 fd = fileno(osCp.dep.conInFp);
5520 if ((read(fd, &data, 1)) != 1)
5526 /* call rdConQ, defined by the system service user */
5536 #ifdef SS_DRVR_SUPPORT
5539 * Fun: Interrupt service task handler
5541 * Desc: This is the interrupt service task handler. It blocks
5542 * on a pipe from which it reads an isFlag structure. The
5543 * structure indicates which interrupt service task is to
5544 * be executed. The thread identifies the task, calls the
5545 * isTsk function and sends itself a message to repeat
5546 * this operation until it receives a message to cease.
5555 /* mt009.21: addition */
5556 static Void *mtIsTskHdlr
5558 Ptr tskPtr /* pointer to task entry */
5561 #if (ERRCLASS & ERRCLS_DEBUG)
5568 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5573 switch (isFlag.action)
5576 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5578 /* call the interrupt service task activation function */
5579 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5581 /* send self a message to keep doing this */
5582 isFlag.action = MT_IS_RESET;
5584 #if (ERRCLASS & ERRCLS_DEBUG)
5585 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5586 if (ret != sizeof(isFlag))
5588 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5589 "write() to pipe failed");
5592 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5599 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5604 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5606 /* call the interrupt service task activation function */
5607 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5609 #if (ERRCLASS & ERRCLS_DEBUG)
5610 /* send self a message to do this again */
5611 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5613 if (ret != sizeof(isFlag))
5615 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5616 "write() to pipe failed");
5619 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5627 /* where did THIS come from?? */
5631 /* mt009.21: addition */
5632 return ( (Void *) NULLP);
5636 #endif /* SS_DRVR_SUPPORT */
5637 #endif /* L2_L3_SPLIT */
5639 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5643 * Fun: mtIntSigHndlr
5645 * Desc: Exit function, shuts down.
5654 Void mtIntSigHndlr(int arg)
5657 osCp.dep.sigEvnt=TRUE;
5660 #ifdef TENB_RTLIN_CHANGES
5668 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5673 * Desc: function, shuts down.
5682 Void mtExitClnup(void)
5688 SGetSysTime(&ticks);
5690 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5692 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5694 #ifdef SS_HISTOGRAM_SUPPORT
5698 osCp.dep.sigEvnt=FALSE;
5700 if (osCp.dep.fileOutFp)
5702 fclose(osCp.dep.fileOutFp);
5710 Void SIncrementTtiCount(Void)
5715 Ticks SGetTtiCount(Void)
5724 * Desc: This function displays a string to a given output
5729 * Notes: Buffer should be null terminated.
5731 * channel 0 is reserved for backwards compatibility
5739 S16 chan, /* channel */
5740 Txt *buf /* buffer */
5744 /* mt020.201 - Fixed typo */
5745 #if (ERRCLASS & ERRCLS_INT_PAR)
5748 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
5753 #ifndef XEON_SPECIFIC_CHANGES
5754 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5755 ssMemlog(buf, strlen(buf));
5760 /* mt012.301 :FIX for LOG RELATED ISSUE */
5768 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
5774 if (osCp.dep.fileOutFp)
5775 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
5776 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
5779 fflush(osCp.dep.fileOutFp);
5792 * Desc: function, shuts down.
5804 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
5805 a loop to overcome the child processes being killed upon exiting the
5807 #ifdef SS_LINUX /* this should have already been defined */
5808 /* mt010.301 removed flag SLES9_PLUS */
5809 /* wait forever for children */
5813 if(osCp.dep.sigEvnt==TRUE)
5820 pthread_exit(NULLP);
5826 * Fun: Set date and time
5828 * Desc: This function is used to set the calendar
5833 * Notes: Unimplemented
5840 REG1 DateTime *dt /* date and time */
5853 * Fun: Get date and time
5855 * Desc: This function is used to determine the calendar
5856 * date and time. This information may be used for
5857 * some management functions.
5869 REG1 DateTime *dt /* date and time */
5872 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
5875 struct timespec ptime;
5877 struct timeval ptime;
5884 #if (ERRCLASS & ERRCLS_INT_PAR)
5887 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
5896 localtime_r(&tt, &tme);
5899 clock_gettime(CLOCK_REALTIME, &ptime);
5901 gettimeofday(&ptime, NULL);
5903 localtime_r(&ptime.tv_sec, &tme);
5905 dt->month = (uint8_t) tme.tm_mon + 1;
5906 dt->day = (uint8_t) tme.tm_mday;
5907 dt->year = (uint8_t) tme.tm_year;
5908 dt->hour = (uint8_t) tme.tm_hour;
5909 dt->min = (uint8_t) tme.tm_min;
5910 dt->sec = (uint8_t) tme.tm_sec;
5913 #ifdef SS_DATETIME_USEC
5915 dt->usec = ptime.tv_nsec / 1000;
5917 dt->usec = ptime.tv_usec;
5919 #endif /*-- SS_DATETIME_USEC --*/
5925 * Get time from epoch in milliseconds
5927 * Fun: Get time from epoch in milliseconds
5929 * Desc: This function is used to get the time from epoch in milli seconds.
5930 * This information may be used for calculating a layer's activation function
5931 * execution time used for thread profiling.
5940 /* mt003.301 Modifications */
5943 EpcTime *et /* date and time */
5946 /* mt003.301 Modifications */
5947 static uint64_t now;
5948 uint64_t to_sec = 1000000;
5949 uint64_t to_nsec = 1000;
5951 struct timespec ptime;
5953 struct timeval ptime;
5958 #if (ERRCLASS & ERRCLS_INT_PAR)
5967 clock_gettime(CLOCK_REALTIME, &ptime);
5969 gettimeofday(&ptime, NULL);
5970 #endif /* SS_LINUX */
5972 now = (ptime.tv_sec * to_sec);
5975 now += (ptime.tv_nsec / to_nsec);
5976 #else /* SS_LINUX */
5977 now += (ptime.tv_usec);
5979 #endif /* SS_LINUX */
5980 now = (now / to_nsec);
5991 * Fun: Get system time
5993 * Desc: This function is used to determine the system time.
5997 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6004 Ticks *sysTime /* system time */
6009 #if (ERRCLASS & ERRCLS_INT_PAR)
6010 if (sysTime == NULLP)
6012 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6018 *sysTime = osCp.dep.sysTicks;
6024 /* mt021.201 - Addition of SGetRefTime function */
6027 * Fun: Get referenced time
6029 * Desc: This function is used to determine the time in seconds
6030 * and microseconds from a reference time. The reference
6031 * time is expressed in seconds from UTC EPOC, January 1,
6037 * Notes: Macros are defined for reference times:
6038 * SS_REFTIME_01_01_1970
6039 * SS_REFTIME_01_01_2002
6046 uint32_t refTime, /* reference time */
6053 struct timespec ptime;
6055 struct timeval ptime;
6060 clock_gettime(CLOCK_REALTIME, &ptime);
6062 gettimeofday(&ptime, NULL);
6065 #if (ERRCLASS & ERRCLS_INT_PAR)
6066 if (sec == NULLP || usec == NULLP)
6068 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6071 /* mt022.201 - Modification to fix compile warning */
6072 if (refTime > (uint32_t)(ptime.tv_sec))
6074 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6079 *sec = ptime.tv_sec - refTime;
6081 *usec = ptime.tv_nsec / 1000;
6083 *usec = ptime.tv_usec;
6093 * Fun: Get Random Number
6095 * Desc: Invoked by layer when a pseudorandom number is required.
6099 * Notes: Suggested approach uses shuffled Linear Congruential
6100 * Operators as described in Byte magazine October
6101 * 1984; "Generating and Testing Pseudorandom Numbers"
6108 Random *value /* random number */
6113 #if (ERRCLASS & ERRCLS_INT_PAR)
6116 /* mt011.21: addition */
6117 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6123 *value = (Random) rand_r(&osCp.dep.randSeed);
6134 * Desc: This function exits from a task.
6138 * Notes: Currently does nothing.
6153 * Fun: Exit Interrupt
6155 * Desc: This function exits from an interrupt.
6159 * Notes: Currently does nothing.
6174 * Fun: Hold Interrupt
6176 * Desc: This function prohibits interrupts from being enabled until
6177 * release interrupt. This function should be called when
6178 * interrupts are disabled and prior to any call to system
6179 * services either by entry to an interrupt service routine or
6180 * by explicit call to disable interrupt.
6184 * Notes: Currently does nothing
6199 * Fun: Release Interrupt
6201 * Desc: This function allows interrupts to be enabled.
6205 * Notes: Currently does nothing.
6222 * Desc: Enable interrupts
6224 * Ret: ROK on success
6227 * Notes: Currently does nothing.
6232 inline S16 SEnbInt(void)
6244 * Desc: Disable interrupts
6246 * Ret: ROK on success
6249 * Notes: Currently does nothing.
6254 inline S16 SDisInt(void)
6266 * Desc: This function gets the function address stored at the
6267 * specified interrupt vector.
6271 * Notes: Currently does nothing.
6278 VectNmb vectNmb, /* vector number */
6279 PIF *vectFnct /* vector function */
6296 * Desc: This function installs the specified function at the
6297 * specified interrupt vector.
6301 * Notes: Currently does nothing.
6308 VectNmb vectNmb, /* vector number */
6309 PIF vectFnct /* vector function */
6321 /* mt028.201: modification: multiple procs support related changes */
6322 #ifndef SS_MULTIPLE_PROCS
6328 * Desc: This function gets the current entity and instance.
6331 * RFAILED - failed, general (optional)
6333 * Notes: This function may be called by the OS or Layer 1
6341 Ent *ent, /* entity */
6342 Inst *inst /* instance */
6353 #if (ERRCLASS & ERRCLS_INT_PAR)
6354 /* check pointers */
6355 if (ent == NULLP || inst == NULLP)
6357 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6363 /* get the thread id */
6364 tId = pthread_self();
6367 /* find the system task in whose context we're running */
6369 ret = SLock(&osCp.sTskTblLock);
6374 for (i = 0; i < SS_MAX_STSKS; i++)
6376 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6378 sTsk = &osCp.sTskTbl[i];
6384 *ent = sTsk->dep.ent;
6385 *inst = sTsk->dep.inst;
6387 SUnlock(&osCp.sTskTblLock);
6390 return (ret == ROK ? ROK : RFAILED);
6398 * Desc: This function sets the current entity and instance.
6409 Ent ent, /* entity */
6410 Inst inst /* instance */
6421 #if (ERRCLASS & ERRCLS_INT_PAR)
6422 /* check entity and instance IDs */
6423 if (ent >= ENTNC || inst >= INSTNC)
6425 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6431 /* get the thread id */
6432 tId = pthread_self();
6435 /* find the system task in whose context we're running */
6437 ret = SLock(&osCp.sTskTblLock);
6442 for (i = 0; i < SS_MAX_STSKS; i++)
6444 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6446 sTsk = &osCp.sTskTbl[i];
6452 sTsk->dep.ent = ent;
6453 sTsk->dep.inst = inst;
6455 SUnlock(&osCp.sTskTblLock);
6458 return (ret == ROK ? ROK : RFAILED);
6461 #endif /* SS_MULTIPLE_PROCS */
6463 #ifdef SS_DRVR_SUPPORT
6469 * Desc: Set interrupt pending flag
6471 * Ret: ROK on success
6479 inline S16 SSetIntPend
6481 uint16_t id, /* driver task identifier */
6482 Bool flag /* flag */
6490 #if (ERRCLASS & ERRCLS_INT_PAR)
6491 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6493 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6500 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6502 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6510 #endif /* SS_DRVR_SUPPORT */
6513 #ifdef SS_LOCKLESS_MEMORY
6516 * Fun: SGlobMemInfoShow
6518 * Desc: This function displays the memory usage information
6519 * for the destined region. It will show the usage of
6520 * each configured bucket and the heap for the specified region.
6523 * RFAILED Region not registered
6528 S16 SGlobMemInfoShow(Void)
6532 CmMmGlobRegCb *globReg;
6535 globReg = osCp.globRegCb;
6537 sprintf(prntBuf, "--------------------------------------------------------------\n");
6538 SDisplay(0, prntBuf);
6539 sprintf(prntBuf, "Global Region Bucket Information\n");
6540 SDisplay(0, prntBuf);
6541 sprintf(prntBuf, "====================================================\n");
6542 SDisplay(0, prntBuf);
6543 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
6544 SDisplay(0, prntBuf);
6545 sprintf(prntBuf, "====================================================\n");
6546 SDisplay(0, prntBuf);
6549 for (idx = 0; idx < globReg->numBkts; idx++)
6551 #ifdef XEON_SPECIFIC_CHANGES
6552 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
6553 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6556 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
6557 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6559 sprintf(prntBuf, "%2u %12u %8u %9u\n",
6560 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6563 SDisplay(0, prntBuf);
6565 sprintf(prntBuf, "--------------------------------------------------------------\n");
6566 SDisplay(0, prntBuf);
6571 #endif /* SS_LOCKLESS_MEMORY */
6574 Bool IsMemoryThresholdHit(Region reg, Pool pool)
6576 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6578 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6581 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6582 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6589 /* mt022.201 - Addition of SRegInfoShow function */
6594 * Desc: This function displays the memory usage information
6595 * for the destined region. It will show the usage of
6596 * each configured bucket and the heap for the specified region.
6599 * RFAILED Region not registered
6601 * Notes: A Sample Output from the function
6602 * Bucket Memory: region 1
6603 * ====================================================
6604 * Bucket Number of Blks configured Size Allocated
6605 * ====================================================
6613 * Heap Memory: region 1
6616 * Heap Segmented blocks: 0
6632 #if (ERRCLASS & ERRCLS_INT_PAR)
6633 if (region > (SS_MAX_REGS-1) )
6635 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
6642 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
6643 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
6644 SDisplay(0, prntBuf);
6645 sprintf(prntBuf, "====================================================\n");
6646 SDisplay(0, prntBuf);
6647 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
6648 SDisplay(0, prntBuf);
6649 sprintf(prntBuf, "====================================================\n");
6650 SDisplay(0, prntBuf);
6654 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6656 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6658 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
6659 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6660 mtCMMRegCb[region]->bktTbl[idx].size,
6661 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6662 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6664 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
6665 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6666 mtCMMRegCb[region]->bktTbl[idx].size,
6667 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6668 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6671 /*mt009.301 Fixed 64BIT compilation warnings*/
6673 sprintf(prntBuf, "%2u %8u %5u %8u\n",
6674 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6675 mtCMMRegCb[region]->bktTbl[idx].size,
6676 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6678 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
6679 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6680 mtCMMRegCb[region]->bktTbl[idx].size,
6681 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6683 #endif /* not TENB_RTLIN_CHANGES */
6684 SDisplay(0, prntBuf);
6685 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
6686 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6687 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6689 sprintf(prntBuf, "\n---------------\n");
6690 SDisplay(0, prntBuf);
6691 sprintf(prntBuf, "Heap Memory: region %d\n", region);
6692 SDisplay(0, prntBuf);
6693 /*mt009.301 Fixed 64BIT compilation warnings*/
6695 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
6697 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
6699 SDisplay(0, prntBuf);
6700 /*mt009.301 Fixed 64BIT compilation warnings*/
6702 sprintf(prntBuf, "Heap Allocated: %u\n",
6703 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6705 sprintf(prntBuf, "Heap Allocated: %lu\n",
6706 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6708 SDisplay(0, prntBuf);
6709 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
6710 #if (ERRCLASS & ERRCLS_DEBUG)
6711 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
6712 mtCMMRegCb[region]->heapCb.numFragBlk);
6713 SDisplay(0, prntBuf);
6718 #ifdef XEON_SPECIFIC_CHANGES
6719 #define SSI_MAX_BKT_THRESHOLD 6
6720 #define SSI_MAX_REG_THRESHOLD 2
6721 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6722 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6723 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6725 static Void SInitMemThreshold
6732 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6734 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
6735 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
6736 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
6737 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
6741 S16 SRegReachedMemThreshold
6748 uint8_t memStatus = 3;
6749 static uint8_t initFlag = 1;
6753 SInitMemThreshold(region, maxBkt);
6756 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6758 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
6763 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
6767 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
6775 /* mt033.201 - addition of API to return the memory statistical data */
6780 * Desc: This function returns the memory usage information
6781 * for the destined region. It will return the usage of
6782 * each configured bucket and the heap for the specified region.
6785 * RFAILED Region not registered
6795 SsMemDbgInfo *dbgInfo
6801 #if (ERRCLASS & ERRCLS_INT_PAR)
6802 if (region >= mtMemoCfg.numRegions )
6804 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
6809 dbgInfo->availmem = 0;
6811 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
6812 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
6814 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
6816 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
6818 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
6819 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
6820 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
6822 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
6823 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6824 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6827 dbgInfo->region = region;
6829 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
6831 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
6832 mtCMMRegCb[region]->heapCb.avlSize);
6834 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
6836 #if (ERRCLASS & ERRCLS_DEBUG)
6837 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
6849 /* Send number of Region available */
6850 *numRegion = mtMemoCfg.numRegions;
6851 /* Send number of Pools available */
6852 *numPool = cfgRegInfo[0].numPools;
6857 /* mt033.201 - addition of APIs to print the memory statistical data
6858 * as defined by SSI enhancements
6860 #ifdef SSI_DEBUG_LEVEL1
6863 * Fun: SPrintRegMemStatusInfo
6865 * Desc: This function displays the memory usage information
6866 * for the destined region. It will show the total memory
6867 * used for static and dynamic memory if typeFlag is
6868 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
6869 * memory block allocated for a particular size if typeFlag
6870 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
6871 * calling SRegPrintMemStats.
6880 S16 SPrintRegMemStatusInfo
6888 uint32_t statMemSize;
6889 uint32_t dynMemSize;
6892 #if (ERRCLASS & ERRCLS_INT_PAR)
6893 if (region >= mtMemoCfg.numRegions )
6895 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
6900 /* initialize the counters*/
6904 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
6906 /* total static and dynamic memory allocated from all the buckets in region requested */
6907 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
6908 SDisplay(0, prntBuf);
6909 sprintf(prntBuf, "===========================================\n");
6910 SDisplay(0, prntBuf);
6911 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
6912 SDisplay(0, prntBuf);
6913 sprintf(prntBuf, "===========================================\n");
6914 SDisplay(0, prntBuf);
6915 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6917 /*mt009.301 Fixed 64BIT compilation warnings*/
6919 sprintf(prntBuf, "%2u %8u %8u\n", idx,
6920 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
6921 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
6923 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
6924 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
6925 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
6927 SDisplay(0, prntBuf);
6928 /* update the total count */
6929 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
6930 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
6933 /*mt009.301 Fixed 64BIT compilation warnings*/
6935 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
6936 SDisplay(0, prntBuf);
6937 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
6939 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
6940 SDisplay(0, prntBuf);
6941 /*mt010.301 fix for compilation error*/
6942 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
6944 SDisplay(0, prntBuf);
6946 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
6947 SDisplay(0, prntBuf);
6948 /*mt009.301 Fixed 64BIT compilation warnings*/
6950 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
6951 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
6953 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
6954 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
6956 SDisplay(0, prntBuf);
6958 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
6960 /* Bucket Memory allocation Statistics */
6961 return (SPrintRegMemStats(region));
6966 sprintf(prntBuf, "\n Invalid choice \n");
6967 SDisplay(0, prntBuf);
6975 * Fun: SPrintRegMemStats
6977 * Desc: This function displays the memory usage information for
6978 * the destined region. It will show the number of memory
6979 * block allocated for a particular size from the hash list.
6988 static S16 SPrintRegMemStats(Region region)
6990 CmMmHashListCp *hashListCp;
6996 hashListCp = &mtCMMRegCb[region]->hashListCp;
6998 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
6999 SDisplay(0, prntBuf);
7000 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7001 hashListCp->numOfbins, hashListCp->numOfEntries);
7002 SDisplay(0, prntBuf);
7003 sprintf(prntBuf, "===================================\n");
7004 SDisplay(0, prntBuf);
7005 sprintf(prntBuf, "Block Size Total number of requests\n");
7006 SDisplay(0, prntBuf);
7007 sprintf(prntBuf, "===================================\n");
7008 SDisplay(0, prntBuf);
7010 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7011 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7013 if (hashListCp->hashList[idx].numAttempts)
7016 /*mt009.301 Fixed 64BIT compilation warnings*/
7018 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7019 hashListCp->hashList[idx].numAttempts);
7021 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7022 hashListCp->hashList[idx].numAttempts);
7024 SDisplay(0, prntBuf);
7028 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7029 SDisplay(0, prntBuf);
7030 sprintf(prntBuf, "=================================================\n");
7031 SDisplay(0, prntBuf);
7032 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7033 SDisplay(0, prntBuf);
7034 sprintf(prntBuf, "=================================================\n");
7035 SDisplay(0, prntBuf);
7037 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7038 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7040 /*mt009.301 Fixed 64BIT compilation warnings*/
7042 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7043 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7044 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7046 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7047 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7048 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7050 SDisplay(0, prntBuf);
7052 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7053 SDisplay(0, prntBuf);
7054 /*mt009.301 Fixed 64BIT compilation warnings*/
7056 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7057 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7058 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7060 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7061 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7062 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7064 SDisplay(0, prntBuf);
7065 sprintf(prntBuf, "\n");
7066 SDisplay(0, prntBuf);
7073 * Fun: SRegMemErrHdlr
7075 * Desc: This function handles the errors returned from the memory
7076 * related functions. Customers are suggested to modify this
7077 * API according to their specific requirement.
7096 if (errCode == RDBLFREE)
7098 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7099 SDisplay(0, prntBuf);
7101 else if (errCode == RTRAMPLINGNOK)
7103 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7104 SDisplay(0, prntBuf);
7112 * Fun: SPrintRegMemProfile
7114 * Desc: This function displays the memory profile information
7115 * for the destined region. This function prints for:
7116 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7117 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7126 S16 SPrintRegMemProfile
7133 CmMmBlkHdr *curBktBlk;
7135 Size offsetToNxtBlk;
7143 #if (ERRCLASS & ERRCLS_INT_PAR)
7144 if (region >= mtMemoCfg.numRegions )
7146 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7151 regCb = mtCMMRegCb[region];
7153 /* memory profile */
7154 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7155 SDisplay(0, prntBuf);
7157 /* bucket profile */
7158 sprintf(prntBuf, "\nBucket Profile\n");
7159 SDisplay(0, prntBuf);
7161 for (idx = 0; idx < regCb->numBkts; idx++)
7164 /*mt009.301 Fixed 64BIT compilation warnings*/
7166 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7167 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7169 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7170 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7172 SDisplay(0, prntBuf);
7174 sprintf(prntBuf, "==========================================================================\n");
7175 SDisplay(0, prntBuf);
7176 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7177 SDisplay(0, prntBuf);
7178 sprintf(prntBuf, "==========================================================================\n");
7179 SDisplay(0, prntBuf);
7181 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7183 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7184 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7185 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7187 /*mt009.301 Fixed 64BIT compilation warnings*/
7189 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7191 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7193 SDisplay(0, prntBuf);
7194 /* check if it is a sane block, elxe jump to next block */
7195 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7197 sprintf(prntBuf, " Trampled \n");
7198 SDisplay(0, prntBuf);
7203 if (CMM_IS_STATIC(curBktBlk->memFlags))
7205 /*mt009.301 Fixed 64BIT compilation warnings*/
7207 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7209 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7211 SDisplay(0, prntBuf);
7213 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7215 /*mt009.301 Fixed 64BIT compilation warnings*/
7217 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7219 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7221 SDisplay(0, prntBuf);
7223 else if (CMM_IS_FREE(curBktBlk->memFlags))
7225 /*mt009.301 Fixed 64BIT compilation warnings*/
7227 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7229 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7231 SDisplay(0, prntBuf);
7235 sprintf(prntBuf, " Trampled \n");
7236 SDisplay(0, prntBuf);
7242 sprintf(prntBuf, "\nHeap Profile\n");
7243 SDisplay(0, prntBuf);
7245 /* point to heapCb */
7246 heapCb = &(regCb->heapCb);
7248 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7249 SDisplay(0, prntBuf);
7250 sprintf(prntBuf, "==========================================================================\n");
7251 SDisplay(0, prntBuf);
7252 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7253 SDisplay(0, prntBuf);
7254 sprintf(prntBuf, "==========================================================================\n");
7255 SDisplay(0, prntBuf);
7257 /* traverse the entire heap to output the heap profile */
7258 hdrSize = sizeof(CmHEntry);
7259 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7260 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7262 /*mt009.301 Fixed 64BIT compilation warnings*/
7264 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7266 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7268 SDisplay(0, prntBuf);
7270 /* check if it is a sane block, elxe jump to next block */
7271 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7273 sprintf(prntBuf, " Trampled \n");
7274 SDisplay(0, prntBuf);
7276 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7277 SDisplay(0, prntBuf);
7280 * To go to next block in the heap we do not have any offset value
7281 * other than curHBlk->size. As the block is already trampled
7282 * we cannot rely on this size. So it is better to stop here unless there
7283 * exists any other mechanism(?) to know the offset to next block.
7288 /*mt009.301 Fixed 64BIT compilation warnings*/
7290 sprintf(prntBuf, " %8u", curHBlk->size);
7292 sprintf(prntBuf, " %8lu", curHBlk->size);
7294 SDisplay(0, prntBuf);
7296 if (CMM_IS_STATIC(curHBlk->memFlags))
7298 /*mt009.301 Fixed 64BIT compilation warnings*/
7300 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7302 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7304 SDisplay(0, prntBuf);
7306 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7308 /*mt009.301 Fixed 64BIT compilation warnings*/
7310 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7312 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7314 SDisplay(0, prntBuf);
7316 else if (CMM_IS_FREE(curHBlk->memFlags))
7318 /*mt009.301 Fixed 64BIT compilation warnings*/
7320 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7322 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7324 SDisplay(0, prntBuf);
7328 sprintf(prntBuf, " Trampled \n");
7329 SDisplay(0, prntBuf);
7331 /* goto next block in the heap */
7332 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7338 #endif /* SSI_DEBUG_LEVEL1 */
7340 /*-- mt035.201 : Added new API for timestamp --*/
7343 * Fun: Get TimeStamp
7345 * Desc: This function is used to Get TimeStamp in micro seconds
7362 struct timespec ptime;
7364 struct timeval ptime;
7373 clock_gettime(CLOCK_REALTIME, &ptime);
7375 gettimeofday(&ptime, NULL);
7378 /* Obtain the time of day, and convert it to a tm struct. --*/
7379 ptm = localtime (&ptime.tv_sec);
7380 /* Klock work fix ccpu00148484 */
7383 /* Format the date and time, down to a single second. --*/
7384 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7387 /* Compute microseconds. --*/
7389 microseconds = ptime.tv_nsec / 1000;
7391 microseconds = ptime.tv_usec;
7394 /* Print the formatted time, in seconds, followed by a decimal point
7395 and the microseconds. --*/
7396 /*mt009.301 Fixed 64BIT compilation warnings*/
7398 sprintf(ts, "%s.%03d", time_string, microseconds);
7400 sprintf(ts, "%s.%03ld", time_string, microseconds);
7406 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7409 * Fun: Get SGetSystemTsk
7411 * Desc: This function is used to Get sytem task id
7420 uint32_t SGetSystemTsk(Void)
7423 return (pthread_self());
7425 } /* end of SGetSystemTsk */
7427 #ifdef SS_MULTICORE_SUPPORT
7430 * Fun: Add Timer thread into system task table
7432 * Desc: This function is used to add the system task
7433 * associated with Timer thread.
7442 static SsSTskEntry* ssdAddTmrSTsk(Void)
7448 /* lock the system task table */
7449 ret = SLock(&osCp.sTskTblLock);
7453 #if (ERRCLASS & ERRCLS_DEBUG)
7454 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7455 "Could not lock system task table");
7461 /* check count of system tasks */
7462 if (osCp.numSTsks == SS_MAX_STSKS)
7465 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7467 #if (ERRCLASS & ERRCLS_DEBUG)
7468 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7469 "Could not give the Semaphore");
7474 #if (ERRCLASS & ERRCLS_ADD_RES)
7475 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7482 /* initialize the system task entry with the information we have */
7483 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7485 /* store the system task priority */
7486 sTsk->tskPrior = SS_NORM_TSK_PRI;
7488 /* initialize the demand queue */
7489 if (ssInitDmndQ(&sTsk->dQ) != ROK)
7492 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7494 #if (ERRCLASS & ERRCLS_DEBUG)
7495 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7496 "Could not give the Semaphore");
7501 #if (ERRCLASS & ERRCLS_DEBUG)
7502 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7503 "Could not initialize demand queue");
7509 /* initialize the system task entry lock */
7510 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7512 ssDestroyDmndQ(&sTsk->dQ);
7514 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7516 #if (ERRCLASS & ERRCLS_DEBUG)
7517 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7518 "Could not give the Semaphore");
7523 #if (ERRCLASS & ERRCLS_DEBUG)
7524 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
7525 "Could not initialize system task entry lock");
7532 /* success, update the table */
7533 sTsk->tskId = osCp.nxtSTskEntry;
7535 sTsk->termPend = FALSE;
7536 osCp.nxtSTskEntry = sTsk->nxt;
7539 /* unlock the system task table */
7541 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7543 #if (ERRCLASS & ERRCLS_DEBUG)
7544 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
7545 "Could not give the Semaphore");
7552 #endif /* SS_MULTICORE_SUPPORT */
7553 /* mt003.301 Readwrite lock and recursive mutex additions */
7554 #ifdef SS_LOCK_SUPPORT
7557 * Fun: ssdInitLockNew
7559 * Desc: This function is used to initialise lock/mutex
7568 S16 ssdInitLockNew(SLockInfo *lockId,uint8_t lockType)
7571 #ifdef SS_REC_LOCK_SUPPORT
7572 pthread_mutexattr_t attr;
7573 #endif /* SS_REC_LOCK_SUPPORT */
7574 Txt prntBuf[PRNTSZE];
7580 #ifdef SS_RDWR_LOCK_SUPPORT
7583 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
7585 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
7586 SDisplay(0, prntBuf);
7591 #endif /* SS_RDWR_LOCK_SUPPORT */
7592 #ifdef SS_REC_LOCK_SUPPORT
7595 retVal = pthread_mutexattr_init(&attr);
7599 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
7604 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
7606 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
7610 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
7611 pthread_mutexattr_destroy(&attr);
7615 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
7618 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
7619 pthread_mutexattr_destroy(&attr);
7625 #endif /* SS_REC_LOCK_SUPPORT */
7628 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
7629 SDisplay(0, prntBuf);
7639 * Desc: This function is used to aquire the read write lock
7648 S16 ssdLockNew(SLockInfo *lockId,uint8_t lockType)
7651 Txt prntBuf[PRNTSZE];
7657 #ifdef SS_RDWR_LOCK_SUPPORT
7660 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
7662 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7663 SDisplay(0, prntBuf);
7670 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
7672 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
7673 SDisplay(0, prntBuf);
7680 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
7682 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7683 SDisplay(0, prntBuf);
7690 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
7692 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7693 SDisplay(0, prntBuf);
7698 #endif /* SS_RDWR_LOCK_SUPPORT */
7699 #ifdef SS_REC_LOCK_SUPPORT
7702 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
7704 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7705 SDisplay(0, prntBuf);
7710 #endif /* SS_REC_LOCK_SUPPORT */
7713 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
7714 SDisplay(0, prntBuf);
7727 * Desc: This function is used to Unlock the read write lock
7736 S16 ssdUnlockNew(SLockInfo *lockId,uint8_t lockType)
7739 Txt prntBuf[PRNTSZE];
7745 #ifdef SS_RDWR_LOCK_SUPPORT
7748 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
7750 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
7751 SDisplay(0, prntBuf);
7756 #endif /* SS_RDWR_LOCK_SUPPORT */
7757 #ifdef SS_REC_LOCK_SUPPORT
7760 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
7762 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7763 SDisplay(0, prntBuf);
7768 #endif /* SS_REC_LOCK_SUPPORT */
7771 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
7772 SDisplay(0, prntBuf);
7781 * Fun: ssdDestroyLockNew
7783 * Desc: This function is used to destroy the read write lock
7792 S16 ssdDestroyLockNew(SLockInfo *lockId,uint8_t lockType)
7794 Txt prntBuf[PRNTSZE];
7800 #ifdef SS_RDWR_LOCK_SUPPORT
7803 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
7805 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
7806 SDisplay(0, prntBuf);
7811 #endif /* SS_RDWR_LOCK_SUPPORT */
7812 #ifdef SS_REC_LOCK_SUPPORT
7815 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
7817 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
7818 SDisplay(0, prntBuf);
7823 #endif /* SS_REC_LOCK_SUPPORT */
7826 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
7827 SDisplay(0, prntBuf);
7833 #endif /* SS_LOCK_SUPPORT */
7835 /* mt005.301 : Cavium Changes */
7836 #ifdef SS_SEUM_CAVIUM
7840 * Fun: ssInitRcvWork
7842 * Desc: This is the initializtion function of receive
7846 * RFAILED - failed, general (optional)
7848 * Notes: Function to initialize the work queue packet
7849 * receiving thread. This creates the new thread to
7850 * receive the work and sets the affinity.
7855 S16 ssInitRcvWork(void)
7857 pthread_attr_t attr;
7861 /* set the required attributes */
7862 pthread_attr_init(&attr);
7863 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
7864 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
7865 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
7867 /* Create a new thread to receive the work queue messages */
7868 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
7870 pthread_attr_destroy(&attr);
7875 pthread_attr_destroy(&attr);
7879 }/* ssInitRcvWork */
7886 * Desc: This is the handler function of receive
7890 * RFAILED - failed, general (optional)
7892 * Notes:The handler function of the work queue receiver task.
7893 * This will be waiting for the work and after receiving
7894 * it, work will converted and posted to that entityt
7900 static void *workRcvTsk(Ptr ptr)
7903 cvmx_wqe_t *workPtr;
7904 Buffer *mBuf, *rcvdBuf;
7905 SsMsgInfo *minfoPtr;
7914 /* get the work if its avilable */
7915 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
7917 if ( workPtr == NULLP )
7919 /* If there is no work then sleep for 10 usec */
7921 ts.tv_nsec = 500000;
7923 nanosleep(&ts, NULLP);
7927 switch(workPtr->tag)
7929 /* Switch over according to the tag value */
7930 case SS_CVMX_MBUF_TAG:
7932 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
7934 /* Convert the physical address to Pointers */
7935 ret = SConvPhyPtr(&rcvdBuf);
7938 /* mt011.301: Cavium 32 bit changes */
7939 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
7943 /* Copy the buffer to this region */
7944 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
7947 /* mt011.301: Cavium 32 bit changes */
7948 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
7952 /* mt011.301: Cavium 32 bit changes */
7953 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
7955 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
7957 /* Get the post strucutre and Post the message */
7958 if ( minfoPtr != NULLP)
7960 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
7962 (Void)SPstTsk(&pst, mBuf);
7964 /* Free the buffer allocated if it cannot be sent */
7973 /* Invalid tag value, drop the work */
7974 /* mt011.301: Cavium 32 bit changes */
7975 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
7984 #endif /* SS_SEUM_CAVIUM */
7986 #ifdef TENB_RTLIN_CHANGES
7987 S16 SInitLock(SLockId *l, uint8_t t)
7990 pthread_mutexattr_t prior;
7991 pthread_mutexattr_init(&prior);
7992 #ifndef RGL_SPECIFIC_CHANGES
7993 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
7995 r = pthread_mutex_init(l, &prior);
7996 pthread_mutexattr_destroy(&prior);
8000 #ifdef SS_THR_REG_MAP
8003 * Fun: ssRegMainThread
8005 * Desc: This function is used to add the memory region
8006 * mapping for the main thread.
8008 * Ret: VOID (Always successful)
8016 Void ssRegMainThread(Void)
8019 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8021 printf("not able to get different Id for main thread\n");
8024 /* Here the default region is added as we dont have any region associated with
8025 * Main thread. The thread should not perform any allocation except
8026 * the initial configuratin
8028 #ifdef XEON_SPECIFIC_CHANGES
8029 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8031 SS_GET_THREAD_MEM_REGION() =
8038 * Fun: ssCheckAndAddMemoryRegionMap
8040 * Desc: This function is used to add the memory region
8041 * mapping for the provided sTsk associated thread.
8042 * If the threadId can be placed in the thread memory
8043 * region mapping table and returns success if it is able
8044 * to place. If not, it keeps the thread ID in the static
8045 * local array and increments the count. Once thread Id
8046 * is successfully placed in the thread memory region mapping
8047 * table, pthread_cancel is sent for all the previous threads
8048 * which are failed to place in table.
8050 * Ret: TRUE - Thread ID successfully placed in thread memory region
8052 * FALSE - If thread Id is not placed in thread memory region
8055 * Notes:mapping tablemapping tablng tablee
8060 S32 ssCheckAndAddMemoryRegionMap
8062 pthread_t threadId, /* Thread Id of system task */
8063 Region region /* Region associated with thread */
8066 static uint32_t createdThreads;
8067 static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8071 /* Here 0xFF is considered as invalid region and if the mapping table
8072 * contains 0xFF, that mapping entry is free
8074 if(SS_INVALID_THREAD_REG_MAP !=
8075 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8077 /* Klock work fix ccpu00148484 */
8078 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8080 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8081 printf("Not able to get the different thread ID, exiting\n");
8084 createdThreadIds[createdThreads++] = threadId;
8087 /* If we found free mapping table entry, place the region and send pthread_cancel
8088 * for all the thread Ids which are created before this
8090 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8091 #ifdef XEON_SPECIFIC_CHANGES
8092 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8093 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8094 SS_MAX_THREAD_REGION_MAP), region);
8096 for(indx = 0; indx < createdThreads; indx++)
8098 #ifdef XEON_SPECIFIC_CHANGES
8099 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8101 pthread_cancel(createdThreadIds[indx]);
8107 } /* ssCheckAndAddMemoryRegionMap */
8111 * Fun: ssCheckAndDelMemoryRegionMap
8113 * Desc: This function is used to add the memory region
8114 * mapping for the provided sTsk associated thread.
8115 * If the threadId can be placed in the thread memory
8116 * region mapping table and returns success if it is able
8117 * to place. If not, it keeps the thread ID in the static
8118 * local array and increments the count. Once thread Id
8119 * is successfully placed in the thread memory region mapping
8120 * table, pthread_cancel is sent for all the previous threads
8121 * which are failed to place in table.
8123 * Ret: TRUE - Thread ID successfully placed in thread memory region
8125 * FALSE - If thread Id is not placed in thread memory region
8128 * Notes:mapping tablemapping tablng tablee
8133 S32 ssCheckAndDelMemoryRegionMap
8135 pthread_t threadId /* Thread Id of system task */
8140 /* Raghu To-Do Check with team, is it necessary to acquire lock
8141 * as del and add may go parallel */
8142 /* Here 0xFF is considered as invalid region and if the mapping table
8143 * contains 0xFF, that mapping entry is free
8145 if(SS_INVALID_THREAD_REG_MAP ==
8146 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8149 printf("Invalid Thread ID (%ld)\n", (uint32_t)threadId);
8151 printf("Invalid Thread ID (%d)\n", (uint32_t)threadId);
8155 /* If we found free mapping table entry, place the region and send pthread_cancel
8156 * for all the thread Ids which are created before this
8158 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8162 } /* ssCheckAndAddMemoryRegionMap */
8166 #ifdef SS_TSKLOG_ENABLE
8171 * Desc: This function will return current time through input parameter.
8174 * RFAILED - failed, general (optional)
8182 volatile uint32_t *startTime,
8186 #ifdef MSPD_MLOG_NEW
8187 *startTime = GetTIMETICK();
8196 * Desc: This function will return current time through input parameter.
8197 * and take the difference of start time provided as input parameter
8201 * RFAILED - failed, general (optional)
8209 volatile uint32_t startTime,
8213 /*uint32_t stopTime;*/
8216 case PID_MAC_HARQ_IND:
8217 case PID_SCH_TTI_IND:
8219 case PID_MAC_DAT_IND:
8220 case PID_MAC_SF_ALLOC_REQ:
8221 case PID_MAC_STA_RSP:
8222 case PID_MAC_DL_SCHD:
8223 case PID_MAC_DL_CQI_IND:
8224 case PID_MAC_UL_CQI_IND:
8225 case PID_MAC_UL_SCHD:
8226 case PID_MAC_TTI_IND:
8227 case PID_CL_RCV_PHY_MSG:
8228 case PID_CL_HARQ_STA_IND:
8229 case PID_MAC_AM_HARQ_RLS:
8230 case PID_CL_DL_BATCH_PROC:
8231 case PID_CL_DLM_PRC_TTI_IND:
8232 case PID_CRC_IND_REAL:
8233 case PID_CRC_IND_DUMMY:
8234 case PID_TTI_LATENCY:
8235 case PID_RECPREQ_PROC:
8238 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8240 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8243 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8252 volatile uint32_t * startTime,
8262 volatile uint32_t startTime,
8269 #endif /*#ifdef SS_TSKLOG_ENABLE */
8270 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8272 * This primitive is used to calculate the CPU Utilization per Core
8277 * @return Void - function is always success
8279 Void UpdateSocCpuInfo
8281 CmCpuStatsInfo *cpuInfo,
8286 S8 mipsStr[MIPS_STRING_LEN];
8293 /* Open the file which holds the MIPS available value */
8294 mipsFd = fopen(MIPS_FILE, "r");
8301 /* Get the free mips available value from the file */
8302 if(NULLP == fgets(mipsStr, 24, mipsFd))
8304 printf("fgets to get the free mips available failed\n");
8309 strtok(mipsStr, " ");
8311 strPart = strtok(NULLP, " ");
8313 if(idx == CM_L2_CPU_UTIL)
8315 if(strPart != NULLP)
8317 l2FreeCpu = atoi(strPart);
8318 l2CpuUsed = 100 - l2FreeCpu;
8319 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8320 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
8321 cpuInfo->cpuUtil[0].numSamples++;
8324 if(idx == CM_L3_CPU_UTIL)
8326 strPart = strtok(NULLP, " ");
8327 if(strPart != NULLP)
8329 l3FreeCpu = atoi(strPart);
8330 l3CpuUsed = 100 - l3FreeCpu;
8331 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8332 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
8333 cpuInfo->cpuUtil[0].numSamples++;
8336 if(idx == CM_L2_CPU_UTIL)
8338 cpuInfo->numCores = CM_NUM_L2_CORES ;
8340 else if(idx == CM_L3_CPU_UTIL)
8342 cpuInfo->numCores = CM_NUM_L3_CORES ;
8348 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8349 #ifdef SS_MULTICORE_SUPPORT
8352 * Fun: Add Timer thread into system task table
8354 * Desc: This function is used to add the system task
8355 * associated with Timer thread.
8364 static SsSTskEntry* ssdReAddTmrSTsk(
8372 /* lock the system task table */
8373 ret = SLock(&osCp.sTskTblLock);
8377 #if (ERRCLASS & ERRCLS_DEBUG)
8378 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8379 "Could not lock system task table");
8385 /* initialize the system task entry with the information we have */
8386 sTsk = &osCp.sTskTbl[idx];
8391 SDestroyLock(&sTsk->lock);
8392 ssDestroyDmndQ(&sTsk->dQ);
8395 /* store the system task priority */
8396 sTsk->tskPrior = SS_NORM_TSK_PRI;
8398 /* initialize the demand queue */
8399 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8402 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8404 #if (ERRCLASS & ERRCLS_DEBUG)
8405 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8406 "Could not give the Semaphore");
8411 #if (ERRCLASS & ERRCLS_DEBUG)
8412 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8413 "Could not initialize demand queue");
8419 /* initialize the system task entry lock */
8420 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8422 ssDestroyDmndQ(&sTsk->dQ);
8424 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8426 #if (ERRCLASS & ERRCLS_DEBUG)
8427 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8428 "Could not give the Semaphore");
8433 #if (ERRCLASS & ERRCLS_DEBUG)
8434 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8435 "Could not initialize system task entry lock");
8442 /* success, update the table */
8443 sTsk->tskId = idx + 1;
8445 sTsk->termPend = FALSE;
8447 /* unlock the system task table */
8449 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8451 #if (ERRCLASS & ERRCLS_DEBUG)
8452 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8453 "Could not give the Semaphore");
8460 #endif /* SS_MULTICORE_SUPPORT */
8465 * Fun: Initialize timer table
8467 * Desc: This function initializes MTSS-specific information
8468 * in the timer table.
8477 S16 ssdReInitTmr(void)
8479 pthread_attr_t attr;
8480 struct sched_param param_sched;
8481 #ifndef XEON_SPECIFIC_CHANGES
8484 #ifdef SS_MULTICORE_SUPPORT
8486 #endif /* SS_MULTICORE_SUPPORT */
8487 #ifdef SS_THR_REG_MAP
8488 uint32_t threadCreated = FALSE;
8489 #endif /* SS_THR_REG_MAP */
8492 #ifndef XEON_SPECIFIC_CHANGES
8493 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
8496 #if (ERRCLASS & ERRCLS_DEBUG)
8497 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8498 "Could not give the Semaphore");
8504 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
8505 /* mt010.21: addition */
8507 #ifdef SS_MULTICORE_SUPPORT
8508 sTsk = ssdReAddTmrSTsk(0);
8513 #endif /* SS_MULTICORE_SUPPORT */
8514 /* create the timer handler thread */
8516 pthread_attr_init(&attr);
8517 /* mt021.201 - Addition to set stack size */
8518 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
8519 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8520 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8521 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
8522 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
8523 pthread_attr_setschedparam(&attr, ¶m_sched);
8526 #ifdef SS_THR_REG_MAP
8527 /* When the thread is created, we check for the memory mapping table if
8528 * threadId can be placed in thread memory map table. If it is not able to place
8529 * threadId is stored in tmporary array. Once thread is created successful,
8530 * thread_cancel is sent for each thread which are created before. All the
8531 * threads are made to wait on sema which is cancel point for thread.
8533 while(threadCreated == FALSE)
8536 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
8538 /* mt020.201 - Addition for destroying thread attribute object attr */
8539 pthread_attr_destroy(&attr);
8544 #ifdef SS_THR_REG_MAP
8545 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
8548 #endif /* SS_THR_REG_MAP */
8549 #ifdef SS_MEM_WL_DEBUG
8550 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
8553 /* mt020.201 - Addition for destroying thread attribute object attr */
8554 pthread_attr_destroy(&attr);
8555 sem_post(&osCp.dep.ssStarted);
8559 /**********************************************************************
8561 **********************************************************************/