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);
208 static Void mtDelSigals
213 static Void mtDelSignals()
218 memset(&sa, 0, sizeof(struct sigaction));
219 sigemptyset(&sa.sa_mask);
220 sa.sa_handler = SIG_DFL;
221 sigaction(SIGSEGV, &sa, NULL);
223 memset(&sa, 0, sizeof(struct sigaction));
224 sigemptyset(&sa.sa_mask);
225 sa.sa_handler = SIG_DFL;
226 sigaction(SIGILL, &sa, NULL);
230 static void signal_segv(int signum, siginfo_t * info, void *ptr)
232 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
235 ucontext_t *ucontext = (ucontext_t *) ptr;
236 #ifdef XEON_SPECIFIC_CHANGES
238 int *p32 = (int *) 0x2fff0000;
243 printf("segv ooops @ %p\n", info->si_addr);
246 printf("Segmentation Fault!\n");
247 printf("info.si_signo = %d\n", signum);
248 printf("info.si_errno = %d\n", info->si_errno);
249 printf("info.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
250 printf("info.si_addr = %p\n", info->si_addr);
252 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
255 #ifndef RGL_SPECIFIC_CHANGES
256 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
257 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
258 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
259 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
260 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
261 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
262 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
263 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
264 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
265 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
266 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
267 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
268 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
269 printf("reg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
270 printf("reg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
271 printf("reg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
272 printf("reg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
275 printf("Stack trace (non-dedicated):\n");
277 sz = backtrace(buffer, 50);
278 strings = backtrace_symbols(buffer, sz);
279 for (i = 0; i < sz; ++i)
280 printf("%s\n", strings[i]);
282 printf("End of stack trace.");
284 #ifdef XEON_SPECIFIC_CHANGES
289 /* Lets first print our debug information */
290 printf("Before dumping our Debug info\n");
292 printf("After dumping our Debug info\n");
294 /* Disable the signal and make the enodeb to dump. This will make
295 * eNB to generate the core with dumping the ccpu log
302 /* End printing debug information */
307 /*** TBD: IMPORTANT ***
308 *** The following definition is temporary. This must be removed
309 *** when all products have been updated with latest ssi.h file OR
310 *** all ssi.h files have been updated to contain this definitions
312 /* New error class for FTHA added */
314 #define ERRCLS_FTHA 0x8
315 #endif /* ERRCLS_FTHA */
317 typedef struct _SPThreadCreateArg
319 void *argument; /* argument that is to be passed to the actual pthread */
320 void *(*start_routine) (void *); /* function from which pthread starts */
323 void *pthreadCreateHdlr(void* arg);
325 #ifdef SS_LOCKLESS_MEMORY
326 Buffer *mtTskBuffer1;
327 Buffer *mtTskBuffer2;
329 pthread_t tmpRegTidMap[20];
331 S16 SGlobMemInfoShow(void);
332 #endif /* SS_LOCKLESS_MEMORY */
335 APP_CONTEXT AppContext;
339 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
340 unsigned int tlPost(void *handle);
343 /* forward references */
344 /* mt003.301 Modifications - Moved to ss_gen.x */
345 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
346 Void *mtTskHdlrT2kL2 ARGS((Void*));
347 void mtSigSegvHndlr ARGS((void));
348 void mtSigUsr2Hndlr ARGS((void));
351 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
352 static Void *mtTskHdlr ARGS((void *));
353 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
355 static Void *mtTmrHdlr ARGS((void *));
356 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
358 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
359 static Void mtIntSigHndlr ARGS((int));
360 static Void mtExitClnup ARGS((void));
363 static Void *mtConHdlr ARGS((void *));
367 #ifdef SS_DRVR_SUPPORT
368 static Void *mtIsTskHdlr ARGS((void *));
372 /* mt020.201 - Addition for no command line available */
374 static Void mtGetOpts ARGS((void));
375 /* mt003.301 Additions - File Based task registration made
376 * common for both MULTICORE and NON-MULTICORE
378 static Bool fileBasedMemCfg = FALSE;
381 /* mt033.201 - addition of local function to print the statistics such as
382 * (size vs. numAttempts) and (allocations vs. deallocations)
384 #ifdef SSI_DEBUG_LEVEL1
385 static S16 SPrintRegMemStats ARGS((Region region));
386 #endif /* SSI_DEBUG_LEVEL1 */
388 #ifdef SS_MULTICORE_SUPPORT
389 static SsSTskEntry* ssdAddTmrSTsk(Void);
390 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
391 #ifndef SS_LOCKLESS_MEMORY
392 #ifndef RGL_SPECIFIC_CHANGES
393 static S16 ssdInitMemInfo ARGS((void));
398 /* mt005.301: Cavium changes */
399 #ifdef SS_SEUM_CAVIUM
400 static Void *workRcvTsk ARGS((void *));
401 #endif /* SS_SEUM_CAVIUM */
403 #ifdef SS_THR_REG_MAP
404 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
406 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
407 #endif /* SS_THR_REG_MAP */
409 /* type declarations */
411 #ifdef SS_DRVR_SUPPORT
412 typedef struct mtIsFlag
422 /* public variable declarations */
424 Cntr cfgNumRegs = SS_MAX_REGS;
425 /* Set memory configuration as false.
426 * Set to true if memory configuration through file is successfull.
428 Bool memConfigured = FALSE;
429 /* mt022.201 - Modification for shared memory relay region and memcal tool */
430 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
433 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
435 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
436 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
437 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
438 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
439 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
440 { SS_POOL_STATIC, 0 }
446 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
448 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
449 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
450 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
451 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
452 { SS_POOL_STATIC, 0 }
455 #endif /* INTEL_WLS */
457 #ifdef SS_LOCKLESS_MEMORY
460 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
462 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
463 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
464 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
465 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
466 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
467 { SS_POOL_STATIC, 0 }
471 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
473 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
474 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
475 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
476 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
477 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
478 { SS_POOL_STATIC, 0 }
482 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
484 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
485 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
486 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
487 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
488 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
489 { SS_POOL_STATIC, 0 }
493 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
495 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
496 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
497 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
498 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
499 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
500 { SS_POOL_STATIC, 0 }
504 SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
506 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
507 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
508 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
509 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
510 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
511 { SS_POOL_STATIC, 0 }
514 #endif /* SS_LOCKLESS_MEMORY */
516 /* mt003.301 Modifications - File Based task registration made
517 * common for both MULTICORE and NON-MULTICORE
520 #ifdef SS_LOCKLESS_MEMORY
521 MtDynMemCfg mtDynMemoCfg =
523 SS_MAX_REGS, /* number of regions */
526 SS_DFLT_REGION, /* region id */
527 MT_MAX_BKTS, /* number of buckets */
529 /* block size, no. of blocks, Upper threshold, lower threshold */
530 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
531 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
532 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
533 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
534 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
538 SS_DFLT_REGION + 1, /* region id */
539 MT_MAX_BKTS, /* number of buckets */
541 /* block size, no. of blocks, Upper threshold, lower threshold */
542 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
543 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
544 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
545 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
546 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
550 SS_DFLT_REGION + 2, /* region id */
551 MT_MAX_BKTS, /* number of buckets */
553 /* block size, no. of blocks, Upper threshold, lower threshold */
554 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
555 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
556 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
557 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
558 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
562 SS_DFLT_REGION + 3, /* region id */
563 MT_MAX_BKTS, /* number of buckets */
565 /* block size, no. of blocks, Upper threshold, lower threshold */
566 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
567 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
568 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
569 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
570 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
574 SS_DFLT_REGION + 4, /* region id */
575 MT_MAX_BKTS, /* number of buckets */
577 /* block size, no. of blocks, Upper threshold, lower threshold */
578 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
579 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
580 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
581 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
582 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
586 SS_DFLT_REGION + 5, /* region id */
587 MT_MAX_BKTS, /* number of buckets */
589 /* block size, no. of blocks, Upper threshold, lower threshold */
590 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
591 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
592 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
593 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
594 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
597 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
600 SS_DFLT_REGION + 4, /* region id */
601 MT_MAX_BKTS, /* number of buckets */
603 /* block size, no. of blocks, Upper threshold, lower threshold */
604 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
605 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
606 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
607 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
615 MtGlobMemCfg mtGlobMemoCfg =
617 MT_MAX_BKTS, /* number of buckets */
620 /* block size, no. of blocks, Upper threshold, lower threshold */
621 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
622 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
623 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
624 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
625 {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
627 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
628 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
629 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
630 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
634 #endif /* SS_LOCKLESS_MEMORY */
636 /* mt022.201 - Modification for memory calculator tool */
637 /* mt018.201 - added memory configuration matrix */
641 SS_MAX_REGS - 1, /* number of regions */
643 #ifndef XEON_SPECIFIC_CHANGES
644 SS_MAX_REGS, /* number of regions */
651 SS_DFLT_REGION, /* region id */
652 MT_MAX_BKTS, /* number of buckets */
653 MT_HEAP_SIZE, /* heap size */
655 #ifndef XEON_SPECIFIC_CHANGES
656 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
657 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
658 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
659 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
660 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
662 {256, 491520}, /* 60 pages of 2M*/
663 {512, 12288}, /* 3 pages of 2M */
664 {2048, 99328}, /* 97 Pages of 2M */
665 {8192, 75008}, /* 293 Pages of 2M */
666 {16384, 4096} /* 32 pages of 2M */
671 #ifndef SS_LOCKLESS_MEMORY
673 SS_DFLT_REGION + 1, /* region id */
674 MT_MAX_BKTS, /* number of buckets */
675 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
677 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
678 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
679 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
680 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
688 #endif /* SS_LOCKLESS_MEMORY */
689 #endif /* INTEL_WLS */
690 #ifdef SS_LOCKLESS_MEMORY
692 SS_DFLT_REGION + 1, /* region id */
693 MT_MAX_BKTS, /* number of buckets */
694 MT_HEAP_SIZE, /* heap size */
696 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
697 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
698 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
699 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
700 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
704 SS_DFLT_REGION + 2, /* region id */
705 MT_MAX_BKTS, /* number of buckets */
706 MT_HEAP_SIZE, /* heap size */
708 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
709 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
710 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
711 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
712 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
716 SS_DFLT_REGION + 3, /* region id */
717 MT_MAX_BKTS, /* number of buckets */
718 MT_HEAP_SIZE, /* heap size */
720 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
721 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
722 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
723 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
724 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
728 SS_DFLT_REGION + 4, /* region id */
729 MT_MAX_BKTS, /* number of buckets */
730 MT_HEAP_SIZE, /* heap size */
732 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
733 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
734 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
735 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
736 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
740 SS_DFLT_REGION + 5, /* region id */
741 MT_MAX_BKTS, /* number of buckets */
742 MT_HEAP_SIZE, /* heap size */
744 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
745 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
746 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
747 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
748 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
751 #endif /* SS_LOCKLESS_MEMORY */
755 /* mt003.301 Modifications - File Based task registration made
756 * common for both MULTICORE and NON-MULTICORE
757 * bucket info, as different regions may request for different no.
760 MtBktCfg mtBktInfo[MT_MAX_BKTS];
761 S16 msArgc; /* argc */
762 Txt **msArgv; /* argv */
763 S16 msOptInd; /* SGetOpt vars */
764 S8 *msOptArg; /* SGetOpt vars */
767 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
768 typedef struct _MtRegMemSz
774 #ifdef SS_USE_WLS_MEM
775 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
776 static S16 SPartitionWlsDynMem();
777 static S16 SAllocateWlsDynMem();
780 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
785 /* private variable declarations */
786 /* mt018.201 - change mtCMMRegCfg as array of pointers */
787 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
788 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
789 /* mt003.301 - Fixed compilation warnings */
790 /*mt004.301-addede new veriable for FAP*/
791 /*mt010.301 - removed veriable defined for FA*/
794 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
797 void mtSetNtlHdl(unsigned int hdl)
802 unsigned int mtGetNtlHdl()
804 return(osCp.ntl.hdl);
808 void mtGetWlsHdl(void **hdlr)
810 *hdlr = osCp.wls.intf;
813 #ifdef XEON_MULTIPLE_CELL_CHANGES
814 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
815 S16 smWrReadWlsConfigParams (Void);
818 static int SOpenWlsIntf()
822 #define WLS_DEVICE_NAME "wls0"
824 char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", WLS_DEVICE_NAME, "--iova-mode=pa"};
825 printf("Calling rte_eal_init: ");
826 for (i = 0; i < RTE_DIM(my_argv); i++)
828 printf("%s ", my_argv[i]);
832 if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
833 rte_panic("Cannot init EAL\n");
836 #ifdef XEON_SPECIFIC_CHANGES
837 #ifdef XEON_MULTIPLE_CELL_CHANGES
838 hdl = WLS_Open(gWrWlsDeviceName, 1);
840 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
843 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
850 printf("Could not open WLS Interface \n");
865 * Desc: This function is the entry point for the final binary. It
866 * calls SInit() in the common code. It can be replaced by a
867 * user function if required (SInit() must still be called).
869 * Ret: none on success
880 int argc, /* argument count */
881 char **argv /* argument vector */
885 int argc; /* argument count */
886 char **argv; /* argument vector */
890 #ifdef XEON_MULTIPLE_CELL_CHANGES
891 /* Read the WLS parameters from the file and copy into global control block */
892 if(smWrReadWlsConfigParams() != ROK)
894 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
896 } /* end of if statement */
899 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
902 #endif /* INTEL_WLS */
906 /* mt003.301 Modifications */
909 printf("\n SInit failed, SSI could not start \n");
910 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
914 /*mt010.301 cleanup part exposed to user*/
925 * Desc: This function is the entry point for the final binary. It
926 * calls SInit() in the common code. It can be replaced by a
927 * user function if required (SInit() must still be called).
929 * Ret: none on success
940 int argc, /* argument count */
941 char **argv /* argument vector */
944 int ssMain(argc, argv)
945 int argc; /* argument count */
946 char **argv; /* argument vector */
962 * initialization functions
967 * Fun: Initialize OS control point
969 * Desc: This function initializes MTSS-specific information
970 * in the OS control point.
988 struct sigaction act;
990 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
995 /*mt014.301 : 4GMX release related changes*/
999 /* mt005.301 : Cavium changes */
1000 #ifdef SS_SEUM_CAVIUM
1001 /* set group mask for the core */
1002 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
1003 #endif /* SS_SEUM_CAVIUM */
1005 osCp.dep.sysTicks = 0;
1007 /* mt020.201 - Addition for no command line available */
1009 /* parse command line */
1011 /* mt003.301 Additions */
1012 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
1014 printf("\n File Based Memory configuration failed \n");
1019 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
1020 #ifndef SS_LOCKLESS_MEMORY
1021 #ifdef SS_MULTICORE_SUPPORT
1022 if(memConfigured == FALSE)
1028 /* initialize the started semaphore */
1029 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1034 /* mt028.201 added compile time flag to allow not to mask signals */
1036 /* mask all signals in the main thread */
1038 sigdelset(&set, SIGINT);
1039 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1040 sigdelset(&set, SIGSEGV);
1041 sigdelset(&set, SIGUSR2);
1042 sigdelset(&set, SIGILL);
1043 #ifdef XEON_SPECIFIC_CHANGES
1044 sigdelset(&set, SIGABRT);
1045 sigdelset(&set, SIGTERM);
1046 sigdelset(&set, SIGHUP);
1049 pthread_sigmask(SIG_SETMASK, &set, NULLP);
1050 #endif /* UNMASK_SIG */
1052 /* install a SIGINT handler to shutdown */
1053 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1055 /*Initialize SIGSEGV Signal */
1056 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1058 memset(&sa, 0, sizeof(struct sigaction));
1059 sigemptyset(&sa.sa_mask);
1060 sa.sa_sigaction = signal_segv;
1061 sa.sa_flags = SA_SIGINFO;
1062 #ifndef XEON_SPECIFIC_CHANGES
1063 sigaction(SIGSEGV, &sa, NULL);
1065 memset(&sa, 0, sizeof(struct sigaction));
1066 sigemptyset(&sa.sa_mask);
1067 sa.sa_sigaction = signal_segv;
1068 sa.sa_flags = SA_SIGINFO;
1070 sigaction(SIGILL, &sa, NULL);
1072 if(sigaction(SIGILL, &sa, NULL) != 0)
1074 printf("Failed to process sigaction for the SIGILL\n");
1077 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1079 printf("Failed to process sigaction for the SIGSEGV\n");
1082 if(sigaction(SIGABRT, &sa, NULL) != 0)
1084 printf("Failed to process sigaction for the SIGABRT\n");
1087 if(sigaction(SIGTERM, &sa, NULL) != 0)
1089 printf("Failed to process sigaction for the SIGTERM\n");
1092 if(sigaction(SIGHUP, &sa, NULL) != 0)
1094 printf("Failed to process sigaction for the SIGHUP\n");
1099 signal (SIGSEGV, mtSigSegvHndlr);
1100 signal (SIGKILL, mtSigSegvHndlr);
1101 signal (SIGUSR2, mtSigUsr2Hndlr);
1106 signal (SIGINT, mtStopHndlr);
1109 act.sa_handler = mtIntSigHndlr;
1110 sigfillset(&act.sa_mask);
1112 if (sigaction(SIGINT, &act, NULLP) != 0)
1118 /* mt040.201 initialise random seed */
1119 osCp.dep.randSeed = time(NULLP);
1127 * Fun: De-initialize OS control point
1129 * Desc: This function reverses the initialization in ssdInitGen().
1149 sem_destroy(&osCp.dep.ssStarted);
1154 #ifdef SS_LOCKLESS_MEMORY
1158 * Fun: ssPutDynMemBlkSet
1160 * Desc: Returns the set of dynamic Blocks into the global region
1163 * Ret: ROK - successful,
1164 * RFAILED - unsuccessful.
1172 S16 ssPutDynMemBlkSet
1174 uint8_t bktIdx, /* Index to bucket list */
1175 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1176 added to global region */
1179 S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1180 uint8_t bktIdx; /* Index to bucket list */
1181 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1182 added to global region */
1185 CmMmGlobRegCb *globReg;
1186 CmMmGlobalBktCb *bktCb;
1190 globReg = osCp.globRegCb;
1192 #if (ERRCLASS & ERRCLS_INT_PAR)
1193 if(bktIdx >= globReg->numBkts)
1197 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1199 bktCb = &(globReg->bktTbl[bktIdx]);
1201 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1203 blkPtr = dynMemSetElem->nextBktPtr;
1204 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1205 free((Void *)blkPtr);
1208 dynMemSetElem->nextBktPtr = NULLP;
1209 dynMemSetElem->numFreeBlks = 0;
1216 * Fun: ssGetDynMemBlkSet
1218 * Desc: Gets the set of dynamic memory blocks from the global region
1221 * Ret: ROK - successful,
1222 * RFAILED - unsuccessful.
1230 S16 ssGetDynMemBlkSet
1232 uint8_t bktIdx, /* Index to bucket list */
1233 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1234 with new set values */
1237 S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1238 uint8_t bktIdx; /* Index to bucket list */
1239 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1240 with new set values */
1244 CmMmGlobRegCb *globReg;
1245 CmMmGlobalBktCb *bktCb;
1250 globReg = osCp.globRegCb;
1252 #if (ERRCLASS & ERRCLS_INT_PAR)
1253 if(bktIdx >= globReg->numBkts)
1257 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1259 bktCb = &(globReg->bktTbl[bktIdx]);
1260 basePtr = &(dynMemSetElem->nextBktPtr);
1262 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1264 blkPtr = (Data *)malloc(bktCb->size);
1266 basePtr = (CmMmEntry **)blkPtr;
1269 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1273 } /* ssGetDynMemBlkSet */
1278 * Fun: ssPutDynMemBlkSet
1280 * Desc: Returns the set of dynamic Blocks into the global region
1283 * Ret: ROK - successful,
1284 * RFAILED - unsuccessful.
1292 S16 ssPutDynMemBlkSet
1294 uint8_t bktIdx, /* Index to bucket list */
1295 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1296 added to global region */
1297 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1300 S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1301 uint8_t bktIdx; /* Index to bucket list */
1302 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1303 added to global region */
1304 uint32_t doNotBlockForLock; /* Boolean whether to block for lock or not */
1307 CmMmGlobRegCb *globReg;
1308 CmMmGlobalBktCb *bktCb;
1310 CmMmBlkSetElement *globMemNode;
1314 globReg = osCp.globRegCb;
1316 #if (ERRCLASS & ERRCLS_INT_PAR)
1317 if(bktIdx >= globReg->numBkts)
1321 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1323 bktCb = &(globReg->bktTbl[bktIdx]);
1325 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1326 try lock is used as it is not required to block as it will be taken
1327 in the next go else it will be blocked for lock as we have to get the
1330 SLock(&(bktCb->bucketLock));
1336 /* Get a free node from the free node linked list */
1337 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1338 if(lstNode == NULLP)
1340 SUnlock(&(bktCb->bucketLock));
1344 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1346 /* Copy the content of the received element information on to free node
1347 * and add it to valid linked list */
1348 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1349 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1350 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1351 dynMemSetElem->numFreeBlks = 0;
1352 dynMemSetElem->nextBktPtr = NULLP;
1354 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1356 SUnlock(&(bktCb->bucketLock));
1364 * Fun: ssGetDynMemBlkSet
1366 * Desc: Gets the set of dynamic memory blocks from the global region
1369 * Ret: ROK - successful,
1370 * RFAILED - unsuccessful.
1372 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1379 S16 ssGetDynMemBlkSet
1381 uint8_t bktIdx, /* Index to bucket list */
1382 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1383 with new set values */
1384 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1387 S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1388 uint8_t bktIdx; /* Index to bucket list */
1389 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1390 with new set values */
1391 uint32_t doNotBlockForLock; /* Boolean whether to block for lock or not */
1394 CmMmGlobRegCb *globReg;
1395 CmMmGlobalBktCb *bktCb;
1397 CmMmBlkSetElement *globMemNode;
1401 globReg = osCp.globRegCb;
1403 #if (ERRCLASS & ERRCLS_INT_PAR)
1404 if(bktIdx >= globReg->numBkts)
1408 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1410 bktCb = &(globReg->bktTbl[bktIdx]);
1412 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1413 try lock is used as it is not required to block as it will be taken
1414 in the next go else it will be blocked for lock as we have to get the
1417 SLock(&(bktCb->bucketLock));
1422 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1424 if(lstNode == NULLP)
1426 SUnlock(&(bktCb->bucketLock));
1430 /* Delete the node from the valid linked list and copy the values of the
1431 * elements of structrues into pointer */
1432 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1433 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1434 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1435 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1437 /* Add this node to the free node linked list */
1438 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1440 SUnlock(&(bktCb->bucketLock));
1444 } /* ssGetDynMemBlkSet */
1447 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1448 uint32_t gDynMemAlrm[4];
1449 static uint32_t memoryCheckCounter;
1452 uint32_t isMemThreshReached(
1456 uint32_t isMemThreshReached(reg)
1460 CmMmGlobRegCb *globReg;
1461 CmMmGlobalBktCb *bktCb;
1462 uint8_t bktIdx= reg;
1464 globReg = osCp.globRegCb;
1466 #if (ERRCLASS & ERRCLS_INT_PAR)
1467 if(bktIdx >= globReg->numBkts)
1471 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1473 bktCb = &(globReg->bktTbl[bktIdx]);
1475 if(gDynMemAlrm[bktIdx])
1477 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1478 SLock(&(bktCb->bucketLock));
1479 if(bktCb->listValidBktSet.count > 25)
1481 gDynMemAlrm[bktIdx] = FALSE;
1482 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1484 SUnlock(&(bktCb->bucketLock));
1490 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1492 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1493 SLock(&(bktCb->bucketLock));
1494 if(bktCb->listValidBktSet.count < 15 )
1495 gDynMemAlrm[bktIdx] = TRUE;
1496 memoryCheckCounter = 0;
1497 SUnlock(&(bktCb->bucketLock));
1503 #endif /* USE_MALLOC */
1504 #endif /* SS_LOCKLESS_MEMORY */
1506 #ifdef SS_USE_ICC_MEMORY
1509 * Fun: Initialize region/pool tables
1511 * Desc: This function initializes MTSS-specific information
1512 * in the region/pool tables and configures the common
1513 * memory manager for use.
1528 Void * ssGetIccHdl()
1532 CmMmDynRegCb *dynRegCb;
1534 /* Klock work fix ccpu00148484 */
1535 if(!(region < SS_MAX_REGS))
1540 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1542 return (dynRegCb->iccHdl);
1544 #endif /* SS_USE_ICC_MEMORY */
1546 #ifdef T2K_MEM_LEAK_DBG
1547 RegionMemLeakInfo regMemLeakInfo;
1548 #endif /* T2K_MEM_LEAK_DBG */
1550 #ifdef SS_USE_WLS_MEM
1551 static S16 SPartitionWlsDynMem()
1554 uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1556 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1558 mtDynMemSz[i].startAddr = bktMemStrtAddr;
1559 bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1562 printf("Global Memory Info: \n");
1563 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1565 printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1570 static S16 SAllocateWlsDynMem()
1575 memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1577 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1579 reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1580 mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1582 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1583 #ifdef INTEL_L1_V19_10
1586 (reqdMemSz + (4 * 1024 * 1024)));
1588 printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1589 SPartitionWlsDynMem();
1597 S16 SPartitionWlsMemory()
1602 uint64_t pageSize[1], hugePageSize;
1605 long int pageSize[1], hugePageSize;
1608 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1610 uint8_t *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1612 gethugepagesizes(pageSize,1);
1613 hugePageSize = pageSize[0];
1614 for (i = 0; i < 1; i++)
1616 mtRegMemSz[i].startAddr = regMemStrtAddr;
1617 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1619 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1620 reqdSz = numHugePg * hugePageSize;
1621 regMemStrtAddr += reqdSz;
1622 #ifdef T2K_MEM_LEAK_DBG
1623 /* Since wls is region 0 */
1624 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1625 regMemLeakInfo.numActvRegions++;
1626 #endif /* T2K_MEM_LEAK_DBG */
1628 //Store last region addr for validation
1629 mtRegMemSz[i].startAddr = regMemStrtAddr;
1633 #ifdef SS_MEM_WL_DEBUG
1634 Void SChkAddrValid(int type, int region, PTR ptr)
1636 char *tryPtr = NULL;
1637 if(type == 0) //Global
1639 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1640 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1642 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1648 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1650 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1656 #endif /* SS_MEM_WL_DEBUG */
1658 S16 SPartitionStaticMemory(uint8_t *startAddr)
1663 uint8_t *regMemStrtAddr = (uint8_t *)startAddr;
1666 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1667 for (i = 1; i < mtMemoCfg.numRegions; i++)
1669 mtRegMemSz[i].startAddr = regMemStrtAddr;
1670 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1671 regMemStrtAddr += reqdSz;
1672 #ifdef T2K_MEM_LEAK_DBG
1673 { /* Since region 1 onwards are used for non wls */
1674 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1675 regMemLeakInfo.numActvRegions++;
1677 #endif /* T2K_MEM_LEAK_DBG */
1681 S16 SAllocateWlsMem()
1689 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1690 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1692 for (i = 0; i < 1; i++)
1694 /* allocate space for the region */
1695 region = &mtMemoCfg.region[i];
1696 reqdMemSz += region->heapsize;
1697 mtRegMemSz[i].reqdSz += region->heapsize;
1699 for (j = 0; j < region->numBkts; j++)
1701 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1702 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1705 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1706 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1708 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1710 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1712 SPartitionWlsMemory();
1715 S16 SAllocateStaticMem()
1724 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1726 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1727 for (i = 1; i < mtMemoCfg.numRegions; i++)
1729 /* allocate space for the region */
1730 region = &mtMemoCfg.region[i];
1731 reqdMemSz += region->heapsize;
1732 mtRegMemSz[i].reqdSz += region->heapsize;
1734 for (j = 0; j < region->numBkts; j++)
1736 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1737 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1741 startAddr = malloc(reqdMemSz + (1024 * 10));
1743 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1745 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1747 SPartitionStaticMemory(startAddr);
1750 #endif /* INTEL_WLS */
1756 * Fun: Initialize region/pool tables
1758 * Desc: This function initializes MTSS-specific information
1759 * in the region/pool tables and configures the common
1760 * memory manager for use.
1778 /* mt018.201 - added local variable */
1783 Txt errMsg[256] = {'\0'};
1784 #ifdef SS_LOCKLESS_MEMORY
1785 CmMmDynRegCb *dynRegCb;
1786 #ifdef SS_USE_ICC_MEMORY
1788 CmMmGlobRegCb *globReg;
1791 #endif /* SS_LOCKLESS_MEMORY */
1794 /* Use the default SSI memory manager if the ICC memory manager is not
1795 * avilable. If ICC memory manager is avilable, it will be used for
1796 * all sharable memory allocation and de-allocation */
1797 #ifdef SS_LOCKLESS_MEMORY
1798 #ifdef SS_USE_ICC_MEMORY
1799 #ifndef YS_PHY_3_8_2
1801 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1803 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1804 if(dynRegCb == NULLP)
1808 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1810 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1812 dynRegCb->region = i;
1813 cmMmDynRegInit(dynRegCb);
1814 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1817 /* ysIccHdl = dynRegCb->iccHdl; */
1820 /* Initialize the global region first */
1821 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1823 if(osCp.globRegCb == NULLP)
1828 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1830 #ifdef SS_USE_WLS_MEM
1831 SAllocateWlsDynMem();
1834 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1836 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1837 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1838 globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1839 printf("Starting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1842 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1844 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1847 if(globReg->bktTbl[i].startAddr == NULLP)
1851 globReg->bktTbl[i].poolId = i;
1852 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1853 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1854 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1857 globReg->numBkts = mtGlobMemoCfg.numBkts;
1858 cmMmGlobRegInit(globReg);
1860 /* Initialize the dynamic task regions and sanity check for the theshold
1862 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1864 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1865 if(dynRegCb == NULLP)
1869 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1871 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1872 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1873 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1874 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1876 #ifdef XEON_SPECIFIC_CHANGES
1881 dynRegCb->bktTbl[k].poolId = k;
1882 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1883 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1884 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1885 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1886 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1888 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1891 dynRegCb->region = i;
1892 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1893 cmMmDynRegInit(dynRegCb);
1895 #endif /* SS_USE_ICC_MEMORY */
1896 #endif /* SS_LOCKLESS_MEMORY */
1898 #ifdef T2K_MEM_LEAK_DBG
1900 /* Initailize mem leak tool memorys for debguing */
1901 regMemLeakInfo.numActvRegions=0;
1902 for(reg=0; reg <SS_MAX_REGS; reg++)
1904 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1905 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1906 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1907 regMemLeakInfo.regStartAddr[reg] = 0;
1910 regMemLeakInfo.regStartAddr[reg] = 0;
1911 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1913 printf("\n mutex init failed\n");
1919 /* Now allocate WLS memory */
1921 SAllocateStaticMem();
1923 /* mt018.201 - CMM Initialization */
1924 for (i = 0; i < mtMemoCfg.numRegions; i++)
1926 /* allocate space for the region control block */
1927 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1928 #ifdef TENB_RTLIN_CHANGES
1929 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1931 if (mtCMMRegCb[i] == NULLP)
1933 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1934 for the Region:%d control block\n",i);
1936 for (k = 0; k < i; k++)
1938 cmMmRegDeInit(mtCMMRegCb[k]);
1939 free(mtCMMRegCfg[k]->vAddr);
1940 free(mtCMMRegCb[k]);
1941 free(mtCMMRegCfg[k]);
1946 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1947 #ifdef TENB_RTLIN_CHANGES
1948 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1950 if (mtCMMRegCfg[i] == NULLP)
1952 for (k = 0; k < i; k++)
1954 cmMmRegDeInit(mtCMMRegCb[k]);
1955 free(mtCMMRegCfg[k]->vAddr);
1956 free(mtCMMRegCb[k]);
1957 free(mtCMMRegCfg[k]);
1959 free(mtCMMRegCb[i]);
1964 /* allocate space for the region */
1965 region = &mtMemoCfg.region[i];
1966 mtCMMRegCfg[i]->size = region->heapsize;
1967 for (j = 0; j < region->numBkts; j++)
1969 /* mt033.201 - addition for including the header size while computing the total size */
1970 #ifdef SSI_DEBUG_LEVEL1
1971 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1972 (region->bkt[j].numBlks);
1974 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1975 #endif /* SSI_DEBUG_LEVEL1 */
1978 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1980 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1983 #ifdef XEON_SPECIFIC_CHANGES
1984 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1985 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1987 #ifdef TENB_RTLIN_CHANGES
1988 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1991 if (mtCMMRegCfg[i]->vAddr == NULLP)
1993 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1994 for the Region:%d \n",i);
1996 for (k = 0; k < i; k++)
1998 cmMmRegDeInit(mtCMMRegCb[k]);
1999 free(mtCMMRegCfg[k]->vAddr);
2000 free(mtCMMRegCb[k]);
2001 free(mtCMMRegCfg[k]);
2003 free(mtCMMRegCb[i]);
2004 free(mtCMMRegCfg[i]);
2009 /* set up the CMM configuration structure */
2010 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
2011 mtCMMRegCfg[i]->chFlag = 0;
2012 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
2013 mtCMMRegCfg[i]->numBkts = region->numBkts;
2015 for (j = 0; j < region->numBkts; j++)
2017 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
2018 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
2021 /* initialize the CMM */
2022 #ifdef SS_LOCKLESS_MEMORY
2023 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2025 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2026 #endif /* SS_LOCKLESS_MEMORY */
2028 for (k = 0; k < i; k++)
2030 cmMmRegDeInit(mtCMMRegCb[k]);
2031 free(mtCMMRegCfg[k]->vAddr);
2032 free(mtCMMRegCb[k]);
2033 free(mtCMMRegCfg[k]);
2035 free(mtCMMRegCfg[i]->vAddr);
2036 free(mtCMMRegCb[i]);
2037 free(mtCMMRegCfg[i]);
2042 /* initialize the STREAMS module */
2043 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
2044 if (region->regionId == 0)
2046 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
2048 for (k = 0; k < i; k++)
2050 cmMmRegDeInit(mtCMMRegCb[k]);
2051 free(mtCMMRegCfg[k]->vAddr);
2052 free(mtCMMRegCb[k]);
2053 free(mtCMMRegCfg[k]);
2055 cmMmRegDeInit(mtCMMRegCb[i]);
2056 free(mtCMMRegCfg[i]->vAddr);
2057 free(mtCMMRegCb[i]);
2058 free(mtCMMRegCfg[i]);
2063 /* mt001.301 : Additions */
2064 #ifdef SS_MEM_LEAK_STS
2066 #endif /* SS_MEM_LEAK_STS */
2075 * Fun: De-initialize region/pool tables
2077 * Desc: This function reverses the initialization in ssdInitMem().
2095 /* mt018.201 - added local variables */
2098 /* mt008.301 Additions */
2099 #ifdef SS_MEM_LEAK_STS
2100 cmDeinitMemLeakMdl();
2101 #endif /* SS_MEM_LEAK_STS */
2103 for (i = 0; i < mtMemoCfg.numRegions; i++)
2105 cmMmRegDeInit(mtCMMRegCb[i]);
2106 free(mtCMMRegCfg[i]->vAddr);
2107 free(mtCMMRegCb[i]);
2108 free(mtCMMRegCfg[i]);
2117 * Fun: Initialize task table
2119 * Desc: This function initializes MTSS-specific information
2120 * in the task table.
2138 /* mt001.301 : Additions */
2139 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2140 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2141 uint32_t tskInd = 0;
2142 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2146 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2147 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2148 /* initialize system task information */
2149 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2151 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2153 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2160 * Fun: Deinitialize task table
2162 * Desc: This function reverses the initialization perfomed in
2186 #ifdef SS_DRVR_SUPPORT
2189 * Fun: Initialize driver task table
2191 * Desc: This function initializes MTSS-specific information
2192 * in the driver task table.
2212 pthread_attr_t attr;
2217 /* initialize the dependent portion of the driver task entries */
2218 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2220 osCp.drvrTskTbl[i].dep.flag = FALSE;
2224 /* create pipe for communication between SSetIntPend() and
2225 * the isTskHdlr thread.
2227 if (pipe(osCp.dep.isFildes) != 0)
2233 /* create the isTskHdlr thread */
2234 pthread_attr_init(&attr);
2235 /* mt021.201 - Addition to set stack size */
2236 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2237 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2238 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2239 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2241 /* mt020.201 - Addition for destroying thread attribute object attr */
2242 pthread_attr_destroy(&attr);
2248 /*mt014.301 : 4GMX release related changes*/
2249 #ifdef SS_4GMX_UCORE
2257 /* mt020.201 - Addition for destroying thread attribute object attr */
2258 pthread_attr_destroy(&attr);
2267 * Fun: Deinitialize driver information
2269 * Desc: This function reverses the initialization performed in
2285 Void ssdDeinitDrvr()
2288 /* mt008.301: Terminate the Driver Task on exit */
2289 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2292 TL_Close(AppContext.hUAII);
2293 if (clusterMode == RADIO_CLUSTER_MODE)
2295 TL_Close(AppContext.hUAII_second);
2301 #endif /* SS_DRVR_SUPPORT */
2306 * Fun: Initialize timer table
2308 * Desc: This function initializes MTSS-specific information
2309 * in the timer table.
2327 pthread_attr_t attr;
2328 struct sched_param param_sched;
2329 /* mt010.21: addition */
2331 #ifdef SS_MULTICORE_SUPPORT
2333 #endif /* SS_MULTICORE_SUPPORT */
2334 #ifdef SS_THR_REG_MAP
2335 uint32_t threadCreated = FALSE;
2336 #endif /* SS_THR_REG_MAP */
2340 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2341 /* mt010.21: addition */
2342 osCp.dep.tmrTqCp.nxtEnt = 0;
2343 for (i=0; i< SS_MAX_TMRS; i++)
2345 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2348 #ifdef SS_MULTICORE_SUPPORT
2349 sTsk = ssdAddTmrSTsk();
2354 #endif /* SS_MULTICORE_SUPPORT */
2355 /* create the timer handler thread */
2356 pthread_attr_init(&attr);
2357 /* mt021.201 - Addition to set stack size */
2358 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2359 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2360 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2361 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2362 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2363 pthread_attr_setschedparam(&attr, ¶m_sched);
2366 #ifdef SS_THR_REG_MAP
2367 /* When the thread is created, we check for the memory mapping table if
2368 * threadId can be placed in thread memory map table. If it is not able to place
2369 * threadId is stored in tmporary array. Once thread is created successful,
2370 * thread_cancel is sent for each thread which are created before. All the
2371 * threads are made to wait on sema which is cancel point for thread.
2373 while(threadCreated == FALSE)
2376 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2378 /* mt020.201 - Addition for destroying thread attribute object attr */
2379 pthread_attr_destroy(&attr);
2384 #ifdef SS_THR_REG_MAP
2385 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2388 #endif /* SS_THR_REG_MAP */
2389 #ifdef SS_MEM_WL_DEBUG
2390 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2393 /* mt020.201 - Addition for destroying thread attribute object attr */
2394 pthread_attr_destroy(&attr);
2403 * Fun: Deinitialize timer table
2405 * Desc: This function reverses the initialization performed in
2424 #ifdef SS_MULTICORE_SUPPORT
2427 #endif /* SS_MULTICORE_SUPPORT */
2430 #ifdef SS_MULTICORE_SUPPORT
2431 ret = SLock(&osCp.sTskTblLock);
2435 #if (ERRCLASS & ERRCLS_DEBUG)
2436 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2437 "Could not lock system task table");
2441 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2442 /* clean up the system task entry */
2446 SDestroyLock(&sTsk->lock);
2447 ssDestroyDmndQ(&sTsk->dQ);
2450 /* make this entry available in the system task table */
2451 sTsk->nxt = osCp.nxtSTskEntry;
2452 osCp.nxtSTskEntry = 0;
2456 /* unlock the system task table */
2457 SUnlock(&osCp.sTskTblLock);
2459 #endif /* SS_MULTICORE_SUPPORT */
2460 /* mt008.301: Terminate the timer thread on exit */
2461 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2471 * Desc: Pre-tst() initialization.
2489 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2493 pthread_attr_t attr;
2496 #endif /* CONSTDIO */
2501 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2506 osCp.dep.conInFp = (FILE *) stdin;
2507 osCp.dep.conOutFp = (FILE *) stdout;
2508 /* added compile time flag CONRD: mt017.21 */
2512 /* disable canonical input processing */
2513 fd = fileno(osCp.dep.conInFp);
2514 if ((tcgetattr(fd, &tio)) != 0)
2516 printf("Error: disable canonical input processing\n");
2520 tio.c_lflag &= ~ICANON;
2521 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2522 tio.c_cc[VTIME] = 0;
2523 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2525 printf("Error: while tcsetattr() processing\n");
2529 #endif /* CONSTDIO */
2532 /* set up the input fd to block when no data is available */
2533 fd = fileno(osCp.dep.conInFp);
2534 flags = fcntl(fd, F_GETFL, &flags);
2535 flags &= ~O_NONBLOCK;
2536 if (fcntl(fd, F_SETFL, flags) == -1)
2538 printf("Error: while fcntl processing\n");
2543 /* create the console handler thread */
2544 pthread_attr_init(&attr);
2545 /* mt021.201 - Addition to set stack size */
2546 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2547 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2548 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2551 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2553 /* mt020.201 - Addition for destroying thread attribute object attr */
2554 pthread_attr_destroy(&attr);
2556 printf("Error: Logging Thread creation failed \n");
2560 /* mt020.201 - Addition for destroying thread attribute object attr */
2561 pthread_attr_destroy(&attr);
2575 * Desc: This function reverses the initialization performed in
2585 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2595 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2598 /* mt008.301: Terminate the console reader on exit */
2599 while(pthread_cancel(osCp.dep.conHdlrTID));
2605 /* mt001.301 : Additions */
2615 S16 ssdInitWatchDog(port)
2620 Txt prntBuf[PRNTSZE];
2623 #ifdef SS_WATCHDOG_IPV6
2624 struct sockaddr_in6 tmpaddr;
2626 struct sockaddr_in tmpaddr;
2627 #endif /* SS_WATCHDOG_IPV6 */
2628 #ifdef SS_MULTIPLE_PROCS
2629 ProcId procId = SS_WD_WDPROC;
2630 if (SAddProcIdLst(1, &procId) != ROK)
2634 #endif /* SS_MULTIPLE_PROCS */
2637 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2639 /* Create a watch dog system task */
2640 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2642 /* Create a watch dog reveiver system task */
2643 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2645 /* Register and attach watch dog TAPA task */
2646 #ifdef SS_MULTIPLE_PROCS
2647 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2648 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2650 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2651 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2652 #endif /* SS_MULTIPLE_PROCS */
2653 /* Register and attach watch dog receiver TAPA task */
2654 #ifdef SS_MULTIPLE_PROCS
2655 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2656 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2658 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2659 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2660 #endif /* SS_MULTIPLE_PROCS */
2662 #ifndef SS_MULTIPLE_PROCS
2663 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2664 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2666 osCp.wdCp.watchDgPst.srcProcId = procId;
2667 osCp.wdCp.watchDgPst.dstProcId = procId;
2668 #endif /* SS_MULTIPLE_PROCS */
2670 /* Initialise the pst structure */
2671 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2672 /* Initialize the watch dog timer resolution default is 1 sec */
2674 cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2675 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2676 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2677 for(idx = 0; idx < 1; idx++)
2679 osCp.wdCp.watchDgTs[idx].first = NULLP;
2680 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2682 #ifdef SS_MULTIPLE_PROCS
2683 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2685 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2686 #endif /* SS_MULTIPLE_PROCS */
2688 /* Create the watch dog receiver socket */
2689 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2690 if(osCp.wdCp.globWd.sock == -1)
2692 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2696 #ifdef SS_WATCHDOG_IPV6
2697 tmpaddr.sin6_len = sizeof(tmpadDr);
2698 tmpaddr.sin6_family = AF_INET6;
2699 tmpaddr.sin6_addr = in6addr_any;
2700 tmpaddr.sin6_port = htons(port);
2702 tmpaddr.sin_family = AF_INET;
2703 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2704 tmpaddr.sin_port = htons(port);
2705 #endif /* SS_WATCHDOG_IPV6 */
2707 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2710 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2714 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2718 #ifndef SS_MULTIPLE_PROCS
2719 pst.srcProcId = SFndProcId();
2720 pst.dstProcId = SFndProcId();
2722 pst.srcProcId = procId;
2723 pst.dstProcId = procId;
2724 #endif /* SS_MULTIPLE_PROCS */
2725 pst.event = EVTSSHRTBTREQ;
2726 ssdInitWatchDgPst(&pst);
2727 SPstTsk(&pst, mBuf);
2733 S16 ssdInitWatchDgPst
2738 S16 ssdInitWatchDgPst(pst)
2743 pst->selector = SS_LOOSE_COUPLING;
2745 pst->region = DFLT_REGION; /* region */
2746 pst->pool = DFLT_POOL; /* pool */
2748 pst->prior = PRIOR0; /* priority */
2749 pst->route = RTESPEC; /* route */
2751 pst->dstEnt = ENTHB; /* destination entity */
2753 pst->srcEnt = ENTDW; /* source entity */
2759 #ifdef SS_MULTIPLE_PROCS
2761 S16 ssdWatchDgActvTmr
2768 S16 ssdWatchDgActvTmr(proc, ent, inst)
2772 S16 ssdWatchDgActvTmr
2777 S16 ssdWatchDgActvTmr()
2779 #endif /* SS_MULTIPLE_PROCS */
2782 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2788 Void ssdWatchDgTmrEvt
2790 PTR cb, /* control block */
2791 S16 event /* timer number */
2794 Void ssdWatchDgTmrEvt(cb, event)
2795 PTR cb; /* control block */
2796 S16 event; /* timer number */
2799 /* mt003.301 Fixed warings */
2803 Txt prntBuf[PRNTSZE];
2812 SPrint("Timer Heartbeat Request Expired");
2814 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2819 SLock(&osCp.wdCp.wdLock);
2820 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2822 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2824 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2826 if(osCp.wdCp.globWd.callback != 0)
2828 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2832 SUnlock(&osCp.wdCp.wdLock);
2834 if(!osCp.wdCp.globWd.watchdogStop)
2836 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2837 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2848 Void ssdStartWatchDgTmr
2855 Void ssdStartWatchDgTmr(cb, event, wait)
2865 Txt prntBuf[PRNTSZE];
2869 /* mt003.301 Modifications */
2872 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2873 if(event == SS_TMR_HRTBT)
2875 SPrint("\nSTART SS_TMR_HRTBT");
2882 SLock(&osCp.wdCp.wdLock);
2883 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2885 osCp.wdCp.globWd.wdsta[i].status = 0;
2887 SUnlock(&osCp.wdCp.wdLock);
2889 arg.tq = osCp.wdCp.watchDgTs;
2890 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2891 arg.timers = osCp.wdCp.watchDgTmr;
2892 arg.cb = (PTR)NULLP;
2894 arg.wait = osCp.wdCp.globWd.timeout = wait;
2903 Void ssdStopWatchDgTmr
2909 Void ssdStopWatchDgTmr(cb, event)
2917 Txt prntBuf[PRNTSZE];
2921 /* mt003.301 Modifications */
2924 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2925 if(event == SS_TMR_HRTBT)
2927 SPrint("STOP SS_TMR_HRTBT");
2931 SLock(&osCp.wdCp.wdLock);
2932 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2934 osCp.wdCp.globWd.wdsta[i].status = 0;
2936 SUnlock(&osCp.wdCp.wdLock);
2939 arg.tq = osCp.wdCp.watchDgTs;
2940 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2941 arg.timers = osCp.wdCp.watchDgTmr;
2942 arg.cb = (PTR)NULLP;
2959 S16 ssdSndHrtBtMsg(restart, type)
2967 Txt prntBuf[PRNTSZE];
2969 struct sockaddr_in tmpaddr;
2970 char hbMsg[SS_WD_HB_MSG_SIZE];
2977 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2981 /* Pack the message */
2982 strcpy(hbMsg, "<HB>REQ</HB>");
2984 /* Send the heartbeat messages to all the configured nodes */
2985 SLock(&osCp.wdCp.wdLock);
2986 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2988 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2993 /* Identify the destination node */
2994 #ifdef SS_WATCHDOG_IPV6
2995 tmpaddr.sin6_len = sizeof(tmpaddr);
2996 tmpaddr.sin6_family = AF_INET6;
2997 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2998 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
3000 tmpaddr.sin_family = AF_INET;
3001 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
3002 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
3003 #endif /* SS_WATCHDOG_IPV6 */
3005 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
3009 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
3010 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
3017 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
3022 SUnlock(&osCp.wdCp.wdLock);
3027 #endif /* SS_WATCHDOG */
3031 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
3037 * Desc: This function gets command line options.
3047 static Void mtGetOpts
3052 static Void mtGetOpts()
3060 FILE *memOpt; /* memory options file pointer */
3063 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
3069 /*KWORK_FIX: Initializing the variable for avoidning corruption */
3071 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
3077 #ifdef SS_LOCKLESS_MEMORY
3092 osCp.dep.fileOutFp = (FILE *)NULLP;
3094 /* initialize memOpt */
3095 memOpt = (FILE *) NULLP;
3102 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
3107 /* mt001.301 : Additions */
3108 #ifdef SS_MEM_LEAK_STS
3110 cmMemOpenMemLkFile(msOptArg);
3114 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3117 fileBasedMemCfg = TRUE;
3118 memOpt = fopen(msOptArg, "r");
3120 /* if file does not exist or could not be opened then use the
3121 * default memory configuration as defined in mt_ss.h
3123 if (memOpt == (FILE *) NULLP)
3125 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3126 be opened, using default mem configuration\n", msOptArg);
3131 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3133 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3139 case 0: /*** INPUT: Number of regions ***/
3140 sscanf(line, "%ld", (long *) &numReg);
3141 mtMemoCfg.numRegions = numReg;
3142 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3144 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3150 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3151 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3152 if(numBkts > MT_MAX_BKTS)
3154 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3158 if(numPools > SS_MAX_POOLS_PER_REG)
3160 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3165 * Delay updation from local variable to global
3166 * structure of number of regions and heap data to
3167 * counter error conditions present above.
3169 for(idx = 0; idx < cfgNumRegs; idx++)
3171 mtMemoCfg.region[idx].numBkts = numBkts;
3172 cfgRegInfo[idx].region = idx;
3173 cfgRegInfo[idx].numPools = numPools;
3175 * Initialize the pool info as static type with size zero
3177 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3179 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3180 cfgRegInfo[idx].pools[poolIdx].size = 0;
3185 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3186 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3188 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3190 if(bktIdx >= numBkts)
3192 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3197 mtBktInfo[bktIdx].blkSize = bktSz;
3199 if(bktUpdtCnt == numBkts)
3201 i++; /*done reading bkt info, start reading individual region info*/
3205 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3206 sscanf(line,"%ld",(long *) ®Id);
3207 if(regId >= mtMemoCfg.numRegions)
3209 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3210 #ifndef XEON_SPECIFIC_CHANGES
3215 mtMemoCfg.region[regId].regionId = regId;
3218 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3219 if(bktUpdtCnt < numBkts)
3221 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3222 if(bktIdx >= numBkts)
3224 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3229 if(bktIdx < MT_MAX_BKTS)
3231 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3232 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3233 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3234 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3237 if(bktUpdtCnt == numBkts)
3244 case 5: /* INPUT: Heapsize ***/
3245 sscanf(line, "%ld", (long *) &heapSz);
3246 mtMemoCfg.region[regId].heapsize = heapSz;
3248 if(regUpdtCnt != mtMemoCfg.numRegions)
3257 #ifdef SS_LOCKLESS_MEMORY
3259 sscanf(line, "%ld", (long *) &numBkts);
3260 mtGlobMemoCfg.numBkts = numBkts;
3261 #ifndef XEON_SPECIFIC_CHANGES
3262 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3265 #ifdef XEON_SPECIFIC_CHANGES
3266 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3267 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3268 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3270 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3273 mtDynMemoCfg.region[idx].regionId = idx;
3274 mtDynMemoCfg.region[idx].numBkts = numBkts;
3282 if(bktUpdtCnt < numBkts)
3284 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3285 (long *) &bktSz, (long *) &bktNum,
3286 (long *) &bktSetSize, (long *) &bktRelThr,
3287 (long *) &bktAqurThr);
3288 /* Klock work fix ccpu00148484 */
3289 if(bktIdx < SS_MAX_POOLS_PER_REG)
3291 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3292 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3293 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3294 #ifdef XEON_SPECIFIC_CHANGES
3295 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3296 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3297 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3299 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3301 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3307 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3309 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3310 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3311 #ifdef XEON_SPECIFIC_CHANGES
3312 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3313 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3314 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3320 #ifdef XEON_SPECIFIC_CHANGES
3321 if(bktUpdtCnt == numBkts)
3327 case 8: /* INPUT: Global Heapsize ***/
3328 sscanf(line, "%ld", (long *) &heapSz);
3329 mtGlobMemoCfg.heapSize = heapSz;
3330 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3338 memConfigured = FALSE;
3342 memConfigured = TRUE;
3350 /* mt028.201: modification: multiple procs support related changes */
3351 #ifndef SS_MULTIPLE_PROCS
3354 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3356 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3359 #else /* SS_MULTIPLE_PROCS */
3363 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3365 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3367 SAddProcIdLst(1, &procId);
3370 #endif /* SS_MULTIPLE_PROCS */
3374 osCp.configFilePath = msOptArg;
3398 * Desc: Get options from command line
3400 * Ret: option - success
3402 * EOF - end of options
3404 * Notes: Handles command lines like the following
3407 * then command line should look like this...
3408 * -a foo -b foo1 -c -d foo
3412 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3417 * nloops = atoi(msArgv[msOptInd]);
3420 * state1 = atoi(msArgv[msOptInd]);
3433 int argc, /* argument count */
3434 char **argv, /* argument value */
3435 char *opts /* options */
3438 S16 SGetOpt(argc, argv, opts)
3439 int argc; /* argument count */
3440 char **argv; /* argument value */
3441 char *opts; /* options */
3444 /* mt020.201 - Removed for no command line */
3452 /* mt020.201 - Addition for no command line */
3464 /*mt013.301 : Changes as per coding standards*/
3465 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3471 if (!strcmp(argv[msOptInd], "--"))
3476 else if (argv[msOptInd][0] != '-')
3484 c = argv[msOptInd][sp];
3485 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3487 if (argv[msOptInd][++sp] == '\0')
3498 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3501 if (++msOptInd >= (S16) argc)
3506 else msOptArg = argv[msOptInd++];
3513 if (argv[msOptInd][++sp] == '\0')
3525 #endif /* NOCMDLINE */
3533 * Desc: This function starts system services execution; the
3534 * permanent tasks are started and the system enters a
3558 /* mt025.201 - Modification for adding lock to timer handler */
3559 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3561 sem_post(&osCp.dep.ssStarted);
3570 * indirect interface functions to system services service user
3576 * Fun: ssdAttachTTsk
3578 * Desc: This function sends the initial tick message to a TAPA
3579 * task if the task is a permanent task.
3591 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3594 S16 ssdAttachTTsk(tTsk)
3595 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3602 if (tTsk->tskType == SS_TSK_PERMANENT)
3604 /* Send a permanent tick message to this task, to start
3607 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3610 #if (ERRCLASS & ERRCLS_DEBUG)
3611 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3616 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3617 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3619 /* set up post structure */
3620 /* mt028.201: modification: multiple procs support related changes */
3621 #ifndef SS_MULTIPLE_PROCS
3622 mInfo->pst.dstProcId = SFndProcId();
3623 mInfo->pst.srcProcId = SFndProcId();
3624 #else /* SS_MULTIPLE_PROCS */
3625 mInfo->pst.dstProcId = tTsk->proc;
3626 mInfo->pst.srcProcId = tTsk->proc;
3627 #endif /* SS_MULTIPLE_PROCS */
3628 mInfo->pst.selector = SEL_LC_NEW;
3629 mInfo->pst.region = DFLT_REGION;
3630 mInfo->pst.pool = DFLT_POOL;
3631 mInfo->pst.prior = PRIOR3;
3632 mInfo->pst.route = RTESPEC;
3633 mInfo->pst.event = 0;
3634 mInfo->pst.dstEnt = tTsk->ent;
3635 mInfo->pst.dstInst = tTsk->inst;
3636 mInfo->pst.srcEnt = tTsk->ent;
3637 mInfo->pst.srcInst = tTsk->inst;
3639 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3640 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3646 #if (ERRCLASS & ERRCLS_DEBUG)
3647 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3648 "Could not write to demand queue");
3661 * Fun: ssdDetachTTsk
3663 * Desc: Does nothing.
3675 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3678 S16 ssdDetachTTsk(tTsk)
3679 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3689 * Fun: ssdCreateSTsk
3691 * Desc: This function creates a system task. A thread is started
3692 * on the system task handler function defined later.
3704 SsSTskEntry *sTsk /* pointer to system task entry */
3707 S16 ssdCreateSTsk(sTsk)
3708 SsSTskEntry *sTsk; /* pointer to system task entry */
3712 pthread_attr_t attr;
3713 /* struct sched_param param_sched;*/
3715 #ifdef SS_THR_REG_MAP
3716 uint32_t threadCreated = FALSE;
3721 #ifdef SS_SINGLE_THREADED
3722 /* mt001.301 : Additions */
3724 #ifdef SS_MULTICORE_SUPPORT
3725 if (osCp.numSTsks > 1)
3727 if (osCp.numSTsks > 0)
3728 #endif /* SS_MULTICORE_SUPPORT */
3730 #ifdef SS_MULTICORE_SUPPORT
3731 if (osCp.numSTsks > 3)
3733 if (osCp.numSTsks > 2)
3734 #endif /* SS_MULTICORE_SUPPORT */
3735 #endif /* SS_WATCHDOG */
3742 /* set the current executing entity and instance IDs to
3743 * 'not configured'. create the lock to access them.
3745 sTsk->dep.ent = ENTNC;
3746 sTsk->dep.inst = INSTNC;
3749 /* create the thread */
3750 pthread_attr_init(&attr);
3751 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3753 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3754 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3755 if (sTsk->tskPrior == 0)
3757 printf("Creating RT thread #######################\n");
3758 #ifdef SS_THR_REG_MAP
3759 /* When the thread is created, we check for the memory mapping table if
3760 * threadId can be placed in thread memory map table. If it is not able to place
3761 * threadId is stored in tmporary array. Once thread is created successful,
3762 * thread_cancel is sent for each thread which are created before. All the
3763 * threads are made to wait on sema which is cancel point for thread.
3765 while(threadCreated == FALSE)
3768 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3771 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3772 pthread_attr_destroy(&attr);
3774 #if (ERRCLASS & ERRCLS_DEBUG)
3775 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3780 #ifdef SS_THR_REG_MAP
3781 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3789 #ifdef SS_THR_REG_MAP
3790 /* When the thread is created, we check for the memory mapping table if
3791 * threadId can be placed in thread memory map table. If it is not able to place
3792 * threadId is stored in tmporary array. Once thread is created successful,
3793 * thread_cancel is sent for each thread which are created before. All the
3794 * threads are made to wait on sema which is cancel point for thread.
3796 while(threadCreated == FALSE)
3799 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3803 /* mt020.201 - Addition for destroying thread attribute object attr */
3804 pthread_attr_destroy(&attr);
3806 #if (ERRCLASS & ERRCLS_DEBUG)
3807 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3812 #ifdef SS_THR_REG_MAP
3813 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3820 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3821 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3823 static uint32_t stLwpId = 3;
3824 sTsk->dep.lwpId = ++stLwpId;
3826 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3828 /* mt020.201 - Addition for destroying thread attribute object attr */
3829 pthread_attr_destroy(&attr);
3839 pthread_attr_t* attr,
3840 void *(*start_routine) (void *),
3844 int SCreatePThread(tid, attr, start_routine, arg)
3846 pthread_attr_t* attr;
3847 void *(*start_routine) (void *);
3852 #ifdef SS_THR_REG_MAP
3853 uint32_t threadCreated = FALSE;
3856 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3857 /* Klock work fix ccpu00148484 */
3858 if(threadArg == NULLP)
3862 threadArg->argument = arg;
3863 threadArg->start_routine = start_routine;
3866 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3868 #ifdef SS_THR_REG_MAP
3869 /* When the thread is created, we check for the memory mapping table if
3870 * threadId can be placed in thread memory map table. If it is not able to place
3871 * threadId is stored in tmporary array. Once thread is created successful,
3872 * thread_cancel is sent for each thread which are created before. All the
3873 * threads are made to wait on sema which is cancel point for thread.
3875 while(threadCreated == FALSE)
3878 /*pthreadCreateHdlr */
3879 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3884 #ifdef SS_THR_REG_MAP
3885 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3896 * Fun: Set Pthread Attributes
3898 * Desc: This function is used to set various explicit
3899 * pthread attributes like, priority scheduling,etc
3910 static S16 ssdSetPthreadAttr
3913 pthread_attr_t *attr
3916 static S16 ssdSetPthreadAttr(sTsk, attr)
3918 pthread_attr_t *attr
3921 struct sched_param param;
3924 SMemSet(¶m, 0, sizeof(param));
3926 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3927 param.sched_priority = 100 - 1 - tskPrior;
3929 param.sched_priority = 100 - 10 - tskPrior;
3932 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3933 /* TODO:: This can be avoided by reducing the priority
3934 * of iccserv thread in l1_master.sh*/
3936 if (clusterMode == RADIO_CLUSTER_MODE)
3938 if(tskPrior == PRIOR1)
3940 param.sched_priority = 91;
3947 printf("Set priority %u\n", param.sched_priority);
3949 /* Set Scheduler to explicit, without this non of the below
3950 pthread attr works */
3951 #ifdef TENB_RTLIN_CHANGES
3952 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3955 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3956 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3957 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3958 #ifdef TENB_RTLIN_CHANGES
3959 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3961 pthread_attr_setschedparam(attr, ¶m);
3965 } /* ssdSetPthreadAttr */
3967 /************* multi-core support **************/
3968 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3969 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3973 * Fun: Get the current core/cpu affinity for a thread/lwp
3975 * Desc: This function is used to get the current processor/core
3976 * affinity for a a system task (thread/lwp). It sets the
3977 * affinity based on the mode supplied by the caller.
3980 * RFAILED - failed, general (optional)
3990 SSTskId *tskId, /* filled in with system task ID */
3991 uint32_t *coreId /* the core/processor id to which the affinity is set */
3994 S16 ssdGetAffinity(tskId, coreId)
3995 SSTskId *tskId; /* filled in with system task ID */
3996 uint32_t *coreId; /* the core/processor id to which the affinity is set */
4006 uint32_t cpuInd = 0;
4007 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4010 uint32_t lwpId = *tskId;
4014 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4016 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4018 tId = osCp.sTskTbl[tskInd].dep.tId;
4023 /* if tskId is not found in the tskTbl */
4024 if (tskInd == SS_MAX_STSKS)
4026 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4031 /* initialize the cpu mask */
4034 /* set thread affinity for linux */
4035 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4037 #if (ERRCLASS & ERRCLS_DEBUG)
4038 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
4041 } /* end if pthread_setaffinity fails */
4043 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
4045 if (CPU_ISSET (cpuInd, & cpuSet))
4054 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4056 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4058 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4063 /* if tskId is not found in the tskTbl */
4064 if (tskInd == SS_MAX_STSKS)
4066 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4070 /* set thread affinity for Solaris */
4071 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
4073 #if (ERRCLASS & ERRCLS_DEBUG)
4074 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
4077 } /* end if processor_bind fails */
4080 #endif /* SS_LINUX */
4084 } /* ssdGetAffinity */
4089 * Fun: Set the core/cpu affinity for a thread/lwp
4091 * Desc: This function is used to set processor/core affinity for a
4092 * a system task (thread/lwp). It sets the affinity based on the
4093 * mode supplied by the caller.
4096 * RFAILED - failed, general (optional)
4106 SSTskId *tskId, /* filled in with system task ID */
4107 uint32_t coreId /* the core/processor id to which the affinity has to be set */
4110 S16 ssdSetAffinity(tskId, coreId)
4111 SSTskId *tskId; /* filled in with system task ID */
4112 uint32_t coreId; /* the core/processor id to which the affinity has to be set */
4116 uint32_t tskInd = 0;
4121 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4124 uint32_t lwpId = *tskId;
4130 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4132 /* Here tskId can not be used as index as the task may be terminated if
4133 there is a TERM even for that tsk, thus breaking the task Id numbering
4135 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4137 tId = osCp.sTskTbl[tskInd].dep.tId;
4142 /* if tskId is not found in the tskTbl */
4143 if (tskInd == SS_MAX_STSKS)
4145 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4149 /* initialize the cpu mask */
4152 /* set the cpu mask */
4153 CPU_SET(coreId, &cpuSet);
4155 /* set thread affinity for linux */
4156 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4158 #if (ERRCLASS & ERRCLS_DEBUG)
4159 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4162 } /* end if pthread_setaffinity fails */
4166 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4168 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4169 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4171 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4176 /* if tskId is not found in the tskTbl */
4177 if (tskInd == SS_MAX_STSKS)
4179 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4183 /* set thread affinity for Solaris */
4184 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4186 #if (ERRCLASS & ERRCLS_DEBUG)
4187 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4190 } /* end if processor_bind fails */
4193 #endif /* SS_LINUX */
4195 } /* ssdSetAffinity */
4197 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4198 /************ end multi-core support *************/
4203 * Fun: ssdDestroySTsk
4205 * Desc: This function destroys a system task. A terminate
4206 * event message is sent to the thread function.
4218 SsSTskEntry *sTsk /* pointer to system task entry */
4221 S16 ssdDestroySTsk(sTsk)
4222 SsSTskEntry *sTsk; /* pointer to system task entry */
4231 /* we send a message to this system task to tell it to die */
4232 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4235 #if (ERRCLASS & ERRCLASS_DEBUG)
4236 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4242 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4243 mInfo->eventInfo.event = SS_EVNT_TERM;
4245 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4249 #if (ERRCLASS & ERRCLASS_DEBUG)
4250 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4251 "Could not write to demand queue");
4261 /* mt023.201 - Added SThreadYield function to yield CPU
4265 * Desc: This function defers thread execution to any other ready
4287 /* mt024.201 - seperated Linux and other UNIX implementations
4293 /* Set sleep value to 0 to yield CPU */
4297 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4299 #else /* other UNICes */
4301 return (sleep(0) == 0 ? ROK : RFAILED);
4303 #endif /* SS_LINUX */
4310 * Fun: Register timer
4312 * Desc: This function is used to register a timer
4313 * function for the service user. System services
4314 * will invoke the timer activation function
4315 * passed to it at the specified intervals.
4319 * Notes: Timing is handled by the common timers. The
4320 * ticks are handled by a thread that uses
4321 * nanosleep() and thus timing precision will not
4330 SsTmrEntry *tmr /* pointer to timer entry */
4334 SsTmrEntry *tmr; /* pointer to timer entry */
4342 /* initialize common timers */
4343 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4346 /* start the timer */
4347 arg.tq = osCp.dep.tmrTq;
4348 arg.tqCp = &osCp.dep.tmrTqCp;
4349 arg.timers = tmr->dep.timers;
4354 arg.max = TMR_DEF_MAX;
4355 arg.wait = tmr->interval;
4365 * Fun: Deregister timer
4367 * Desc: This function is used to deregister a timer function.
4379 SsTmrEntry *tmr /* pointer to timer entry */
4382 S16 ssdDeregTmr(tmr)
4383 SsTmrEntry *tmr; /* pointer to timer entry */
4391 /* stop the timer */
4392 arg.tq = osCp.dep.tmrTq;
4393 arg.tqCp = &osCp.dep.tmrTqCp;
4394 arg.timers = tmr->dep.timers;
4399 arg.max = TMR_DEF_MAX;
4400 arg.wait = tmr->interval;
4410 * Fun: Critical error
4412 * Desc: This function is called when a critical error occurs.
4424 Seq seq, /* sequence number */
4425 Reason reason /* reset reason */
4428 S16 ssdError(seq, reason)
4429 Seq seq; /* sequence number */
4430 Reason reason; /* reset reason */
4440 /* get calling task ID */
4441 tId = pthread_self();
4444 /* set up the message to display */
4445 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4446 "reason = %d\n\n", (uint8_t)tId, seq, reason);
4450 /* delete all system tasks */
4451 for (i = 0; i < SS_MAX_STSKS; i++)
4453 if (osCp.sTskTbl[i].used
4454 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4456 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4462 pthread_exit(NULLP);
4465 /* won't reach here */
4474 * Desc: This function is called to log an error.
4486 Ent ent, /* Calling layer's entity id */
4487 Inst inst, /* Calling layer's instance id */
4488 ProcId procId, /* Calling layer's processor id */
4489 Txt *file, /* file name where error occured */
4490 S32 line, /* line in file where error occured */
4491 ErrCls errCls, /* error class */
4492 ErrCode errCode, /* layer unique error code */
4493 ErrVal errVal, /* error value */
4494 Txt *errDesc /* description of error */
4497 Void ssdLogError(ent, inst, procId, file, line,
4498 errCls, errCode, errVal, errDesc)
4499 Ent ent; /* Calling layer's entity id */
4500 Inst inst; /* Calling layer's instance id */
4501 ProcId procId; /* Calling layer's processor id */
4502 Txt *file; /* file name where error occured */
4503 S32 line; /* line in file where error occured */
4504 ErrCls errCls; /* error class */
4505 ErrCode errCode; /* layer unique error code */
4506 ErrVal errVal; /* error value */
4507 Txt *errDesc; /* description of error */
4520 /* get calling task ID */
4522 tId = pthread_self();
4528 case ERRCLS_ADD_RES:
4529 errClsMsg = "ERRCLS_ADD_RES";
4532 case ERRCLS_INT_PAR:
4533 errClsMsg = "ERRCLS_INT_PAR";
4537 errClsMsg = "ERRCLS_DEBUG";
4540 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4542 errClsMsg = "ERRCLS_FTHA";
4546 errClsMsg = "INVALID ERROR CLASS!";
4551 /*mt009.301 Fixed 64BIT compilation warnings*/
4554 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4555 "file: %s line: %03d errcode: %05d errcls: %s\n"
4556 "errval: %05d errdesc: %s\n",
4557 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4560 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4561 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4562 "errval: %05ld errdesc: %s\n",
4563 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4565 SDisplay(0, errBuf);
4566 /* mt001.301 : Additions */
4567 #ifdef SS_LOGGER_SUPPORT
4569 #endif /* SS_LOGGER_SUPPORT */
4573 /* debug errors halt the system */
4574 if (errCls == ERRCLS_DEBUG)
4576 /* mt001.301 : Additions */
4577 #ifdef SS_LOGGER_SUPPORT
4579 #endif /* SS_LOGGER_SUPPORT */
4580 /* delete all system tasks */
4581 for (i = 0; i < SS_MAX_STSKS; i++)
4583 if (osCp.sTskTbl[i].used
4584 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4586 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4592 pthread_exit(NULLP);
4604 * Fun: Register driver task
4606 * Desc: This function is called to register the handlers for a
4619 SsDrvrTskEntry *drvrTsk /* driver task entry */
4622 S16 ssdRegDrvrTsk(drvrTsk)
4623 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4630 /* mt001.30 : Additions */
4633 * Fun: Deregister driver task
4635 * Desc: This function is called to deregister the handlers for a
4648 SsDrvrTskEntry *drvrTsk /* driver task entry */
4651 S16 ssdDeregDrvrTsk(drvrTsk)
4652 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4665 * mt003.301 Additions - SDeRegTTsk fix
4667 #ifdef SS_MULTIPLE_PROCS
4676 S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4681 #else /*SS_MULTIPLE_PROCS*/
4689 S16 ssdProcTTskTerm(tTsk, idx)
4693 #endif /*SS_MULTIPLE_PROCS*/
4695 #ifdef SS_MULTIPLE_PROCS
4708 /* We check the sTsk element; if it is not NULLP, the
4709 * task is attached. So we have to detach it before
4710 * deregistering the task.
4712 ret = SLock(&osCp.sTskTblLock);
4715 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4718 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4721 #if (ERRCLASS & ERRCLS_DEBUG)
4722 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4724 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4726 #if (ERRCLASS & ERRCLS_DEBUG)
4727 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4735 #ifdef SS_MULTIPLE_PROCS
4737 if (tTsk->initTsk != NULLP)
4740 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4743 &(osCp.tTskTbl[idx].xxCb));
4745 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4748 &(osCp.tTskTbl[idx].xxCb));
4749 #endif /* USE_MEMCAL */
4751 #endif /* SS_MULTIPLE_PROCS */
4753 if (tTsk->sTsk != NULLP)
4757 sTsk->dep.ent = ent;
4758 sTsk->dep.inst = inst;
4760 for (n = 0; n < SS_MAX_TTSKS; n++)
4762 if (sTsk->tTsks[n] == idx)
4764 sTsk->tTsks[n] = SS_INVALID_IDX;
4770 /* call the implementation to detach the task */
4771 ssdDetachTTsk(tTsk);
4773 sTsk->dep.ent = ENTNC;
4774 sTsk->dep.inst = INSTNC;
4777 /* Now we empty the entry for this task and update the table
4780 #ifdef SS_MULTIPLE_PROCS
4781 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4782 #else /* SS_MULTIPLE_PROCS */
4783 osCp.tTskIds[ent][inst] = SS_TSKNC;
4784 #endif /* SS_MULTIPLE_PROCS */
4787 #ifdef SS_MULTIPLE_PROCS
4788 tTsk->proc = PROCNC;
4789 #endif /* SS_MULTIPLE_PROCS */
4791 tTsk->inst = INSTNC;
4792 tTsk->tskType = TTUND;
4793 tTsk->initTsk = NULLP;
4794 tTsk->actvTsk = NULLP;
4797 tTsk->nxt = osCp.nxtTTskEntry;
4798 osCp.nxtTTskEntry = idx;
4801 #ifdef SS_MULTIPLE_PROCS
4802 /* mark the control block for this task as invalid */
4803 osCp.tTskTbl[idx].xxCb = NULLP;
4806 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4807 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4809 #if (ERRCLASS & ERRCLS_DEBUG)
4810 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4817 //#ifndef SPLIT_RLC_DL_TASK
4818 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4819 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4820 Void ysMtTskHdlr(Void);
4821 Void ysMtPollPhyMsg(uint8_t region);
4822 Void ysMtRcvPhyMsg(Void);
4824 Void *mtTskHdlrT2kL2
4826 Ptr tskPtr /* pointer to task entry */
4829 Void *mtTskHdlrT2kL2(tskPtr)
4830 Ptr tskPtr; /* pointer to task entry */
4836 /* wait for SS to come up */
4837 /* It is required to block on this semaphore before starting actual processing of
4838 the thread becasue the creator of this thread might want to cance it without
4839 doing any processing. When this semaphore is released, means the creator gives
4840 the go ahead for actual processing and we should never come back to this point */
4841 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4850 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4851 * (processes L1 msgs) */
4857 Void ysMtTskHdlr(Void);
4858 Void YsPhyRecvMsg();
4860 Void *mtTskHdlrT2kL2
4862 Ptr tskPtr /* pointer to task entry */
4865 Void *mtTskHdlrT2kL2(tskPtr)
4866 Ptr tskPtr; /* pointer to task entry */
4872 /* get out the system task entry from the parameter */
4873 sTsk = (SsSTskEntry *) tskPtr;
4875 /* wait for SS to come up */
4876 /* It is required to block on this semaphore before starting actual processing of
4877 the thread becasue the creator of this thread might want to cance it without
4878 doing any processing. When this semaphore is released, means the creator gives
4879 the go ahead for actual processing and we should never come back to this point */
4880 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4883 #ifndef RGL_SPECIFIC_CHANGES
4891 #ifdef V5GTF_SPECIFIC_CHANGES
4894 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4895 * (processes L1 msgs) */
4897 /* get a message from the demand queue */
4899 #ifdef RLC_MAC_DAT_REQ_RBUF
4900 rgDlDatReqBatchProc();
4903 ret = mtTskHdlMsg(sTsk);
4906 /* exit the for loop here */
4909 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4916 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4920 void *pthreadCreateHdlr
4925 void *pthreadCreateHdlr(pthreadCreateArg)
4930 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4931 /* mt038.201 changed how sem_wait is called */
4932 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4935 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4943 * Desc: This is the system task handler function. It blocks on
4944 * the system task's demand queue. On receiving a message,
4945 * it identifies the target TAPA task, verifies that the
4946 * TAPA task belongs to this system task and if so, calls
4947 * the activation function of that TAPA task with the
4948 * received message. The task activation function or the
4949 * timer activation function may be called.
4951 * Ret: (thread function)
4961 Ptr tskPtr /* pointer to task entry */
4964 Void *mtTskHdlr(tskPtr)
4965 Ptr tskPtr; /* pointer to task entry */
4971 /* get out the system task entry from the parameter */
4972 sTsk = (SsSTskEntry *) tskPtr;
4975 /* wait for SS to come up */
4977 /* mt038.201 changed how sem_wait is called */
4978 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4980 #ifdef XEON_SPECIFIC_CHANGES
4981 printf("\n**********MT Task Handler********\n");
4985 /* Wait for a message from the demand queue */
4986 #ifdef SS_CDMNDQ_SUPPORT
4987 ret = ssCDmndQWait(&sTsk->dQ);
4989 ret = ssDmndQWait(&sTsk->dQ);
4994 ret = mtTskHdlMsg(sTsk);
5009 * Desc: This is the system task handler function. It blocks on
5010 * the system task's demand queue. On receiving a message,
5011 * it identifies the target TAPA task, verifies that the
5012 * TAPA task belongs to this system task and if so, calls
5013 * the activation function of that TAPA task with the
5014 * received message. The task activation function or the
5015 * timer activation function may be called.
5017 * Ret: (thread function)
5030 S16 mtTskHdlMsg(sTsk)
5044 /* mt028.201: modification: multiple procs support related changes */
5045 #ifndef SS_MULTIPLE_PROCS
5047 PAIFTMRS16 tmrActvFnMt = NULLP;
5049 /* mt015.301 Initialized the timer activation functions with NULLP */
5050 PFS16 tmrActvFn = NULLP;
5052 PAIFTMRS16 tmrActvFn;
5054 #endif /* SS_MULTIPLE_PROCS */
5055 /* mt003.301 Modifications */
5056 #ifdef SS_THREAD_PROFILE
5058 #endif /* SS_THREAD_PROFILE */
5061 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
5064 /* nothing to receive */
5068 /* if we can't lock this system task entry, return the message */
5069 ret = SLock(&sTsk->lock);
5073 #if (ERRCLASS & ERRCLS_DEBUG)
5074 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
5075 "Could not lock system task entry");
5085 mBuf2 = mBuf->b_next;
5087 /* find out what kind of message this is */
5088 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5089 #ifdef SS_MEM_WL_DEBUG
5090 mtTskBuffer1 = mBuf2;
5092 mtTskBuffer2 = mBuf2->b_next;
5094 if(mInfo == 0x5050505)
5098 cmAnalyseBtInfo((PTR) mBuf,4);
5100 printf("\n In trouble .... \n");
5102 else if (mInfo == 0x2020202)
5105 cmAnalyseBtInfo((PTR) mBuf,1);
5106 printf("\n In trouble .... \n");
5108 #endif /* SS_MEM_WL_DEBUG */
5109 switch (mInfo->eventInfo.event)
5111 /* this is a termination event, we die */
5113 /* release the message */
5116 /* Unlock the system task entry and lock the system
5117 * task table to clean our entry up.
5119 SUnlock(&sTsk->lock);
5121 ret = SLock(&osCp.sTskTblLock);
5125 #if (ERRCLASS & ERRCLS_DEBUG)
5126 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5127 "Could not lock system task table");
5129 /* what to do here? */
5133 /* clean up the system task entry */
5136 /* mt003.301 Modifications - SDeRegTTsk */
5137 /* sTsk->numTTsks = 0; */
5138 SDestroyLock(&sTsk->lock);
5139 ssDestroyDmndQ(&sTsk->dQ);
5141 /* lock for current executing TAPA task ID */
5143 /* make this entry available in the system task table */
5144 sTsk->nxt = osCp.nxtSTskEntry;
5145 for (i = 0; i < SS_MAX_STSKS; i++)
5147 if (sTsk == &osCp.sTskTbl[i])
5149 osCp.nxtSTskEntry = i;
5156 /* unlock the system task table */
5157 SUnlock(&osCp.sTskTblLock);
5162 /* this is a data message or a permanent task keep-alive message */
5164 case SS_EVNT_PERMTICK:
5165 /* message to a task. find the destination task */
5166 /* mt028.201: modification: multiple procs support related changes */
5167 #ifdef SS_MULTIPLE_PROCS
5168 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5170 if (procIdIdx == SS_INV_PROCID_IDX)
5176 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5177 #else /* SS_MULTIPLE_PROCS */
5178 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5179 #endif /* SS_MULTIPLE_PROCS */
5181 /* verify that it hasn't been deregistered */
5182 if (idx == SS_TSKNC)
5188 /* verify that this system task is still running it */
5189 tTsk = &osCp.tTskTbl[idx];
5190 if (tTsk->sTsk != sTsk)
5196 /* set the current executing TAPA task ID */
5197 sTsk->dep.ent = mInfo->pst.dstEnt;
5198 sTsk->dep.inst = mInfo->pst.dstInst;
5200 /* copy the Pst structure into a local duplicate */
5201 for (i = 0; i < (S16) sizeof(Pst); i++)
5202 *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
5204 /* Give the message to the task activation function. If
5205 * its a normal data message, we pass it, if this is a
5206 * keep-alive message for a permanent task then we pass
5207 * NULLP in place of the message to the task activation
5210 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5212 #ifndef RGL_SPECIFIC_CHANGES
5213 #ifdef SS_TSKLOG_ENABLE
5214 uint32_t t = MacGetTick();
5217 /* mt003.301 Modifications */
5218 #if SS_THREAD_PROFILE
5219 tTsk->curEvent = nPst.event;
5221 #endif /* SS_THREAD_PROFILE */
5222 tTsk->actvTsk(&nPst, mBuf);
5223 #ifndef RGL_SPECIFIC_CHANGES
5224 #ifdef SS_TSKLOG_ENABLE
5225 SStopTask(t,PID_SSI_TSK);
5228 #if SS_THREAD_PROFILE
5230 tTsk->curEvtTime = (uint32_t)(et2 - et1);
5231 tTsk->totTime += (uint64_t)tTsk->curEvtTime;
5232 #endif /* SS_THREAD_PROFILE */
5236 #if (ERRCLASS & ERRCLS_DEBUG)
5237 /* this message should only come to a permanent task */
5238 if (tTsk->tskType != SS_TSK_PERMANENT)
5240 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5244 tTsk->actvTsk(&nPst, NULLP);
5246 /* We need to re-send this message back to ourselves so
5247 * the permanent task continues to run.
5249 /* Check if this task got deregistered or detached
5250 * by the activation function; if so, there's nothing
5251 * more to do here, otherwise go ahead.
5254 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5256 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5257 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5261 /* failure here is a real problem */
5264 #if (ERRCLASS & ERRCLS_DEBUG)
5265 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5266 "Could not write to demand queue");
5272 /* unset the current executing TAPA task ID */
5273 sTsk->dep.ent = ENTNC;
5274 sTsk->dep.inst = INSTNC;
5279 /* timer event. find the timer entry */
5280 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5282 /* lock the timer table, coz we're going to peek in it */
5283 ret = SLock(&osCp.tmrTblLock);
5287 #if (ERRCLASS & ERRCLS_DEBUG)
5288 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5289 "Could not lock timer table");
5295 /* Verify that this timer entry is still around and that it
5296 * belongs to our task.
5298 if (osCp.tmrTbl[idx].used == FALSE
5299 /* mt028.201: modification: multiple procs support related changes */
5300 #ifdef SS_MULTIPLE_PROCS
5301 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5302 #endif /* SS_MULTIPLE_PROCS */
5303 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5304 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5306 SUnlock(&osCp.tmrTblLock);
5311 /* mt005.21: addition */
5312 /* set the current executing TAPA task ID */
5313 sTsk->dep.ent = mInfo->pst.dstEnt;
5314 sTsk->dep.inst = mInfo->pst.dstInst;
5316 #ifndef SS_MULTIPLE_PROCS
5318 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5319 tmrActvFnMt = NULLP;
5320 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5322 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5328 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5331 /* unlock the timer table */
5332 SUnlock(&osCp.tmrTblLock);
5334 /* activate the timer function */
5335 /* mt028.201: modification: multiple procs support related changes */
5336 #ifndef SS_MULTIPLE_PROCS
5340 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5341 osCp.tmrTbl[idx].ownerInst);
5349 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5350 osCp.tmrTbl[idx].ownerInst);
5351 #endif /* SS_MULTIPLE_PROCS */
5353 /*mt005.21: addition */
5354 /* unset the current executing TAPA task ID */
5355 sTsk->dep.ent = ENTNC;
5356 sTsk->dep.inst = INSTNC;
5359 /* return the message buffer */
5363 * mt003.301 - SDeRegTTsk fix
5365 case SS_EVNT_TTSK_TERM:
5366 #ifdef SS_MULTIPLE_PROCS
5367 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5369 if (procIdIdx == SS_INV_PROCID_IDX)
5375 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5376 #else /* SS_MULTIPLE_PROCS */
5377 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5378 #endif /* SS_MULTIPLE_PROCS */
5380 /* verify that it hasn't been deregistered */
5381 if (idx == SS_TSKNC)
5387 /* verify that this system task is still running it */
5388 tTsk = &osCp.tTskTbl[idx];
5389 if (tTsk->sTsk != sTsk)
5394 #ifdef SS_MULTIPLE_PROCS
5395 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5397 ssdProcTTskTerm(tTsk, idx);
5403 #if (ERRCLASS & ERRCLS_DEBUG)
5404 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5411 } while (mBuf != NULLP);
5414 /* unlock the system task entry */
5415 SUnlock(&sTsk->lock);
5418 /* yield for other threads */
5419 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5428 * Fun: mtTmrHdlrPublic
5431 Void mtTmrHdlrPublic
5435 Void mtTmrHdlrPublic()
5438 if (SLock(&osCp.tmrTblLock) != ROK)
5440 #if (ERRCLASS & ERRCLS_DEBUG)
5441 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5445 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5446 /* unlock the timer table */
5447 SUnlock(&osCp.tmrTblLock);
5455 * Desc: The timer handler thread function. Counts time
5456 * and invokes the common timer function on each
5459 * Ret: (thread function)
5466 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5468 static Void *mtTmrHdlr
5470 void *parm /* unused */
5473 /* mt009.21: addition */
5474 static Void *mtTmrHdlr(parm)
5475 void *parm; /* unused */
5478 /*mt004.301-addede new region*/
5479 /* mt010.301 Removed SS_FAP portion and
5480 * enabled oroginal code in function mtTmrHdlr */
5484 uint32_t i, cnt, oldTicks, newTicks;
5485 struct timeval tv1,tv2;
5486 /* mt038.201 added return */
5488 /* mt039.201 changes for nanosleep */
5489 struct timespec tsN;
5490 static uint32_t err_in_usec;
5492 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5497 /* mt027.201 - Modification for SRegCfgTmr support */
5498 /* check SS_TICKS_SEC */
5499 if (SS_1MS < SS_TICKS_SEC)
5501 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5504 /* mt025.201 - Addition to stop timer handler till task registration is done */
5505 /* wait for SS to come up */
5506 /* mt038.201 changed how sem_wait is called */
5507 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5510 /* mt027.201 - Modification for SRegCfgTmr support */
5511 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5513 ts.tv_nsec = (MT_TICK_CNT * 1000);
5514 /* mt039.201 changes for nanosleep */
5520 if (gettimeofday(&tv1, NULL) == -1)
5522 #if (ERRCLASS & ERRCLS_DEBUG)
5523 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5524 "Error in clock_gettime");
5534 #ifndef STUB_TTI_HANDLING_5GTF
5535 printf("Returning from mtTmrHdlr()\n");
5540 /* mt039.201 changes for nanosleep */
5541 /* sleep for MT_TICK_CNT milli seconds */
5542 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5543 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5545 ts.tv_nsec = tsN.tv_nsec;
5550 if (gettimeofday(&tv2,NULL) == -1)
5552 #if (ERRCLASS & ERRCLS_DEBUG)
5553 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5554 "Error in clock_gettime");
5558 /*mt013.301 : changed check while calculating timer to fix
5559 * diffrence between MTSS time and real unix time
5561 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5563 time_int = (tv2.tv_usec - tv1.tv_usec);
5565 else if (tv2.tv_sec > tv1.tv_sec)
5567 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5569 else /* ts2 < ts1, this will not happen in normal scenario */
5571 /* to make sure cnt = 1 */
5573 time_int = MT_TICK_CNT;
5576 oldTicks = osCp.dep.sysTicks;
5577 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5578 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5579 newTicks = osCp.dep.sysTicks;
5580 tv1.tv_usec = tv2.tv_usec;
5581 tv1.tv_sec = tv2.tv_sec;
5583 cnt = newTicks - oldTicks;
5585 while(err_in_usec >= MT_TICK_CNT)
5588 err_in_usec -= MT_TICK_CNT;
5590 if( cnt >= MT_MAX_TICK_CNT_VAL)
5591 cnt = MT_MIN_TICK_CNT_VAL;
5592 /* call the common timer tick handler */
5593 for (i = 0; i < cnt; i++)
5595 /* mt008.301: cmPrcTmr is guarded with a lock */
5596 /* lock the timer table */
5597 if (SLock(&osCp.tmrTblLock) != ROK)
5599 #if (ERRCLASS & ERRCLS_DEBUG)
5600 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5604 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5605 /* unlock the timer table */
5606 SUnlock(&osCp.tmrTblLock);
5610 /* mt009.21: addition */
5611 return ( (Void *) NULLP);
5612 /* will not reach here */
5620 * Desc: Process timer event. Called from the common timer
5621 * code when a timeout occurs.
5633 PTR tCb, /* control block */
5634 S16 evnt /* event */
5637 Void mtTimeout(tCb, evnt)
5638 PTR tCb; /* control block */
5639 S16 evnt; /* event */
5648 #ifndef TENB_RTLIN_CHANGES
5651 /* mt028.201: modification: multiple procs support related changes */
5652 #ifdef SS_MULTIPLE_PROCS
5654 #endif /* SS_MULTIPLE_PROCS */
5655 #ifdef RGL_SPECIFIC_CHANGES
5656 #ifdef MSPD_MLOG_NEW
5657 uint32_t t = GetTIMETICK();
5663 /* get the timer entry */
5664 tEnt = (SsTmrEntry *) tCb;
5667 /* if the timer was deleted, this will be NULL, so drop it */
5673 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5676 /* Hmmmm, the timer might have been deleted while we've been
5677 * working at getting here, so we just skip this.
5679 if (tEnt->used == FALSE)
5685 /* Set up and send a timer message to the destination tasks'
5688 #ifndef SS_MULTICORE_SUPPORT
5689 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5691 #ifdef RGL_SPECIFIC_CHANGES
5692 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5694 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5699 #if (ERRCLASS & ERRCLS_DEBUG)
5700 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5706 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5707 mInfo->eventInfo.event = SS_EVNT_TIMER;
5708 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5710 mInfo->pst.dstEnt = tEnt->ownerEnt;
5711 mInfo->pst.dstInst = tEnt->ownerInst;
5712 mInfo->pst.srcEnt = tEnt->ownerEnt;
5713 mInfo->pst.srcInst = tEnt->ownerInst;
5714 /* mt028.201: modification: multiple procs support related changes */
5715 #ifndef SS_MULTIPLE_PROCS
5716 mInfo->pst.dstProcId = SFndProcId();
5717 mInfo->pst.srcProcId = SFndProcId();
5718 #else /* SS_MULTIPLE_PROCS */
5719 mInfo->pst.dstProcId = tEnt->ownerProc;
5720 mInfo->pst.srcProcId = tEnt->ownerProc;
5721 #endif /* SS_MULTIPLE_PROCS */
5722 mInfo->pst.selector = SEL_LC_NEW;
5723 #ifndef SS_MULTICORE_SUPPORT
5724 mInfo->pst.region = DFLT_REGION;
5727 mInfo->pst.pool = DFLT_POOL;
5728 mInfo->pst.prior = PRIOR0;
5729 mInfo->pst.route = RTESPEC;
5730 mInfo->pst.event = 0;
5733 #ifndef TENB_RTLIN_CHANGES
5734 /* get a semaphore for the TAPA task table */
5735 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5740 #if (ERRCLASS & ERRCLS_DEBUG)
5741 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5749 /* find the owner TAPA task */
5750 /* mt028.201: modification: multiple procs support related changes */
5751 #ifdef SS_MULTIPLE_PROCS
5752 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5753 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5754 #else /* SS_MULTIPLE_PROCS */
5755 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5756 #endif /* SS_MULTIPLE_PROCS */
5757 if (idx == SS_TSKNC)
5759 #ifndef TENB_RTLIN_CHANGES
5760 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5767 /* ensure that the TAPA task is hale and hearty */
5768 tTsk = &osCp.tTskTbl[idx];
5771 #ifndef TENB_RTLIN_CHANGES
5772 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5777 /* Klock work fix ccpu00148484 */
5778 /* write the timer message to the queue of the destination task */
5779 /* mt008.301 : check sTsk before putting into it's DQ */
5780 if (tTsk->sTsk == NULLP)
5782 #ifndef TENB_RTLIN_CHANGES
5783 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5787 #if (ERRCLASS & ERRCLS_DEBUG)
5788 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5789 "Could not write to demand queue");
5794 #ifdef SS_LOCKLESS_MEMORY
5795 mInfo->pst.region = tTsk->sTsk->region;
5796 mInfo->region = tTsk->sTsk->region;
5797 #endif /* SS_LOCKLESS_MEMORY */
5798 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5799 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5801 #ifndef TENB_RTLIN_CHANGES
5802 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5806 #if (ERRCLASS & ERRCLS_DEBUG)
5807 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5808 "Could not write to demand queue");
5813 /* Fix for ccpu00130657 */
5814 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5815 if (tTsk->sTsk->tskPrior == PRIOR0)
5818 WLS_WakeUp(mtGetWlsHdl());
5825 /* release the semaphore for the TAPA task table */
5826 #ifndef TENB_RTLIN_CHANGES
5827 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5831 /* restart the timer */
5832 arg.tq = osCp.dep.tmrTq;
5833 arg.tqCp = &osCp.dep.tmrTqCp;
5834 arg.timers = tEnt->dep.timers;
5835 arg.cb = (PTR) tEnt;
5839 arg.max = TMR_DEF_MAX;
5840 arg.wait = tEnt->interval;
5842 #ifdef RGL_SPECIFIC_CHANGES
5843 #ifdef MSPD_MLOG_NEW
5844 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5856 * Desc: This thread reads the console and hands over any
5857 * data read to a user function.
5859 * Ret: (thread function)
5867 static Void *mtConHdlr
5869 Ptr parm /* unused */
5872 /* mt009.21: addition */
5873 static Void *mtConHdlr(parm)
5874 Ptr parm; /* unused */
5881 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5887 /* check if we have a console input file handle */
5888 if (osCp.dep.conInFp == NULLP)
5894 fd = fileno(osCp.dep.conInFp);
5899 if ((read(fd, &data, 1)) != 1)
5905 /* call rdConQ, defined by the system service user */
5915 #ifdef SS_DRVR_SUPPORT
5918 * Fun: Interrupt service task handler
5920 * Desc: This is the interrupt service task handler. It blocks
5921 * on a pipe from which it reads an isFlag structure. The
5922 * structure indicates which interrupt service task is to
5923 * be executed. The thread identifies the task, calls the
5924 * isTsk function and sends itself a message to repeat
5925 * this operation until it receives a message to cease.
5935 /* mt009.21: addition */
5936 static Void *mtIsTskHdlr
5938 Ptr tskPtr /* pointer to task entry */
5941 /* mt009.21: addition */
5942 static Void *mtIsTskHdlr(tskPtr)
5943 Ptr tskPtr; /* pointer to task entry */
5946 #if (ERRCLASS & ERRCLS_DEBUG)
5953 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5958 switch (isFlag.action)
5961 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5963 /* call the interrupt service task activation function */
5964 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5966 /* send self a message to keep doing this */
5967 isFlag.action = MT_IS_RESET;
5969 #if (ERRCLASS & ERRCLS_DEBUG)
5970 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5971 if (ret != sizeof(isFlag))
5973 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5974 "write() to pipe failed");
5977 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5984 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5989 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5991 /* call the interrupt service task activation function */
5992 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5994 #if (ERRCLASS & ERRCLS_DEBUG)
5995 /* send self a message to do this again */
5996 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5998 if (ret != sizeof(isFlag))
6000 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
6001 "write() to pipe failed");
6004 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
6012 /* where did THIS come from?? */
6016 /* mt009.21: addition */
6017 return ( (Void *) NULLP);
6021 #endif /* SS_DRVR_SUPPORT */
6022 #endif /* L2_L3_SPLIT */
6024 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
6028 * Fun: mtIntSigHndlr
6030 * Desc: Exit function, shuts down.
6045 Void mtIntSigHndlr(arg)
6050 osCp.dep.sigEvnt=TRUE;
6053 #ifdef TENB_RTLIN_CHANGES
6061 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
6066 * Desc: function, shuts down.
6088 SGetSysTime(&ticks);
6090 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
6092 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
6094 #ifdef SS_HISTOGRAM_SUPPORT
6098 osCp.dep.sigEvnt=FALSE;
6100 if (osCp.dep.fileOutFp)
6102 fclose(osCp.dep.fileOutFp);
6110 Void SIncrementTtiCount(Void)
6115 Ticks SGetTtiCount(Void)
6124 * Desc: This function displays a string to a given output
6129 * Notes: Buffer should be null terminated.
6131 * channel 0 is reserved for backwards compatibility
6140 S16 chan, /* channel */
6141 Txt *buf /* buffer */
6144 S16 SDisplay(chan, buf)
6145 S16 chan; /* channel */
6146 Txt *buf; /* buffer */
6150 /* mt020.201 - Fixed typo */
6151 #if (ERRCLASS & ERRCLS_INT_PAR)
6154 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6159 #ifndef XEON_SPECIFIC_CHANGES
6160 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6161 ssMemlog(buf, strlen(buf));
6166 /* mt012.301 :FIX for LOG RELATED ISSUE */
6174 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6180 if (osCp.dep.fileOutFp)
6181 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6182 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6185 fflush(osCp.dep.fileOutFp);
6198 * Desc: function, shuts down.
6217 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6218 a loop to overcome the child processes being killed upon exiting the
6220 #ifdef SS_LINUX /* this should have already been defined */
6221 /* mt010.301 removed flag SLES9_PLUS */
6222 /* wait forever for children */
6226 if(osCp.dep.sigEvnt==TRUE)
6233 pthread_exit(NULLP);
6239 * Fun: Set date and time
6241 * Desc: This function is used to set the calendar
6246 * Notes: Unimplemented
6254 REG1 DateTime *dt /* date and time */
6257 S16 SSetDateTime(dt)
6258 REG1 DateTime *dt; /* date and time */
6271 * Fun: Get date and time
6273 * Desc: This function is used to determine the calendar
6274 * date and time. This information may be used for
6275 * some management functions.
6288 REG1 DateTime *dt /* date and time */
6291 S16 SGetDateTime(dt)
6292 REG1 DateTime *dt; /* date and time */
6295 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6298 struct timespec ptime;
6300 struct timeval ptime;
6307 #if (ERRCLASS & ERRCLS_INT_PAR)
6310 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6319 localtime_r(&tt, &tme);
6322 clock_gettime(CLOCK_REALTIME, &ptime);
6324 gettimeofday(&ptime, NULL);
6326 localtime_r(&ptime.tv_sec, &tme);
6328 dt->month = (uint8_t) tme.tm_mon + 1;
6329 dt->day = (uint8_t) tme.tm_mday;
6330 dt->year = (uint8_t) tme.tm_year;
6331 dt->hour = (uint8_t) tme.tm_hour;
6332 dt->min = (uint8_t) tme.tm_min;
6333 dt->sec = (uint8_t) tme.tm_sec;
6336 #ifdef SS_DATETIME_USEC
6338 dt->usec = ptime.tv_nsec / 1000;
6340 dt->usec = ptime.tv_usec;
6342 #endif /*-- SS_DATETIME_USEC --*/
6348 * Get time from epoch in milliseconds
6350 * Fun: Get time from epoch in milliseconds
6352 * Desc: This function is used to get the time from epoch in milli seconds.
6353 * This information may be used for calculating a layer's activation function
6354 * execution time used for thread profiling.
6363 /* mt003.301 Modifications */
6367 EpcTime *et /* date and time */
6371 EpcTime *et; /* date and time */
6374 /* mt003.301 Modifications */
6375 static uint64_t now;
6376 uint64_t to_sec = 1000000;
6377 uint64_t to_nsec = 1000;
6379 struct timespec ptime;
6381 struct timeval ptime;
6386 #if (ERRCLASS & ERRCLS_INT_PAR)
6395 clock_gettime(CLOCK_REALTIME, &ptime);
6397 gettimeofday(&ptime, NULL);
6398 #endif /* SS_LINUX */
6400 now = (ptime.tv_sec * to_sec);
6403 now += (ptime.tv_nsec / to_nsec);
6404 #else /* SS_LINUX */
6405 now += (ptime.tv_usec);
6407 #endif /* SS_LINUX */
6408 now = (now / to_nsec);
6419 * Fun: Get system time
6421 * Desc: This function is used to determine the system time.
6425 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6433 Ticks *sysTime /* system time */
6436 S16 SGetSysTime(sysTime)
6437 Ticks *sysTime; /* system time */
6442 #if (ERRCLASS & ERRCLS_INT_PAR)
6443 if (sysTime == NULLP)
6445 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6451 *sysTime = osCp.dep.sysTicks;
6457 /* mt021.201 - Addition of SGetRefTime function */
6460 * Fun: Get referenced time
6462 * Desc: This function is used to determine the time in seconds
6463 * and microseconds from a reference time. The reference
6464 * time is expressed in seconds from UTC EPOC, January 1,
6470 * Notes: Macros are defined for reference times:
6471 * SS_REFTIME_01_01_1970
6472 * SS_REFTIME_01_01_2002
6480 uint32_t refTime, /* reference time */
6485 S16 SGetRefTime(refTime, sec, usec)
6486 uint32_t refTime; /* reference time */
6493 struct timespec ptime;
6495 struct timeval ptime;
6500 clock_gettime(CLOCK_REALTIME, &ptime);
6502 gettimeofday(&ptime, NULL);
6505 #if (ERRCLASS & ERRCLS_INT_PAR)
6506 if (sec == NULLP || usec == NULLP)
6508 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6511 /* mt022.201 - Modification to fix compile warning */
6512 if (refTime > (uint32_t)(ptime.tv_sec))
6514 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6519 *sec = ptime.tv_sec - refTime;
6521 *usec = ptime.tv_nsec / 1000;
6523 *usec = ptime.tv_usec;
6533 * Fun: Get Random Number
6535 * Desc: Invoked by layer when a pseudorandom number is required.
6539 * Notes: Suggested approach uses shuffled Linear Congruential
6540 * Operators as described in Byte magazine October
6541 * 1984; "Generating and Testing Pseudorandom Numbers"
6549 Random *value /* random number */
6553 Random *value; /* random number */
6558 #if (ERRCLASS & ERRCLS_INT_PAR)
6561 /* mt011.21: addition */
6562 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6568 *value = (Random) rand_r(&osCp.dep.randSeed);
6579 * Desc: This function exits from a task.
6583 * Notes: Currently does nothing.
6605 * Fun: Exit Interrupt
6607 * Desc: This function exits from an interrupt.
6611 * Notes: Currently does nothing.
6633 * Fun: Hold Interrupt
6635 * Desc: This function prohibits interrupts from being enabled until
6636 * release interrupt. This function should be called when
6637 * interrupts are disabled and prior to any call to system
6638 * services either by entry to an interrupt service routine or
6639 * by explicit call to disable interrupt.
6643 * Notes: Currently does nothing
6665 * Fun: Release Interrupt
6667 * Desc: This function allows interrupts to be enabled.
6671 * Notes: Currently does nothing.
6695 * Desc: Enable interrupts
6697 * Ret: ROK on success
6700 * Notes: Currently does nothing.
6711 inline S16 SEnbInt()
6724 * Desc: Disable interrupts
6726 * Ret: ROK on success
6729 * Notes: Currently does nothing.
6740 inline S16 SDisInt()
6753 * Desc: This function gets the function address stored at the
6754 * specified interrupt vector.
6758 * Notes: Currently does nothing.
6766 VectNmb vectNmb, /* vector number */
6767 PIF *vectFnct /* vector function */
6770 S16 SGetVect(vectNmb, vectFnct)
6771 VectNmb vectNmb; /* vector number */
6772 PIF *vectFnct; /* vector function */
6789 * Desc: This function installs the specified function at the
6790 * specified interrupt vector.
6794 * Notes: Currently does nothing.
6802 VectNmb vectNmb, /* vector number */
6803 PIF vectFnct /* vector function */
6806 S16 SPutVect(vectNmb, vectFnct)
6807 VectNmb vectNmb; /* vector number */
6808 PIF vectFnct; /* vector function */
6820 /* mt028.201: modification: multiple procs support related changes */
6821 #ifndef SS_MULTIPLE_PROCS
6827 * Desc: This function gets the current entity and instance.
6830 * RFAILED - failed, general (optional)
6832 * Notes: This function may be called by the OS or Layer 1
6841 Ent *ent, /* entity */
6842 Inst *inst /* instance */
6845 S16 SGetEntInst(ent, inst)
6846 Ent *ent; /* entity */
6847 Inst *inst; /* instance */
6858 #if (ERRCLASS & ERRCLS_INT_PAR)
6859 /* check pointers */
6860 if (ent == NULLP || inst == NULLP)
6862 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6868 /* get the thread id */
6869 tId = pthread_self();
6872 /* find the system task in whose context we're running */
6874 ret = SLock(&osCp.sTskTblLock);
6879 for (i = 0; i < SS_MAX_STSKS; i++)
6881 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6883 sTsk = &osCp.sTskTbl[i];
6889 *ent = sTsk->dep.ent;
6890 *inst = sTsk->dep.inst;
6892 SUnlock(&osCp.sTskTblLock);
6895 return (ret == ROK ? ROK : RFAILED);
6903 * Desc: This function sets the current entity and instance.
6915 Ent ent, /* entity */
6916 Inst inst /* instance */
6919 S16 SSetEntInst(ent, inst)
6920 Ent ent; /* entity */
6921 Inst inst; /* instance */
6932 #if (ERRCLASS & ERRCLS_INT_PAR)
6933 /* check entity and instance IDs */
6934 if (ent >= ENTNC || inst >= INSTNC)
6936 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6942 /* get the thread id */
6943 tId = pthread_self();
6946 /* find the system task in whose context we're running */
6948 ret = SLock(&osCp.sTskTblLock);
6953 for (i = 0; i < SS_MAX_STSKS; i++)
6955 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6957 sTsk = &osCp.sTskTbl[i];
6963 sTsk->dep.ent = ent;
6964 sTsk->dep.inst = inst;
6966 SUnlock(&osCp.sTskTblLock);
6969 return (ret == ROK ? ROK : RFAILED);
6972 #endif /* SS_MULTIPLE_PROCS */
6974 #ifdef SS_DRVR_SUPPORT
6980 * Desc: Set interrupt pending flag
6982 * Ret: ROK on success
6991 inline S16 SSetIntPend
6993 uint16_t id, /* driver task identifier */
6994 Bool flag /* flag */
6997 inline S16 SSetIntPend(id, flag)
6998 uint16_t id; /* driver task identifier */
6999 Bool flag; /* flag */
7007 #if (ERRCLASS & ERRCLS_INT_PAR)
7008 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
7010 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
7017 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
7019 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
7027 #endif /* SS_DRVR_SUPPORT */
7030 #ifdef SS_LOCKLESS_MEMORY
7033 * Fun: SGlobMemInfoShow
7035 * Desc: This function displays the memory usage information
7036 * for the destined region. It will show the usage of
7037 * each configured bucket and the heap for the specified region.
7040 * RFAILED Region not registered
7046 S16 SGlobMemInfoShow
7051 S16 SGlobMemInfoShow()
7056 CmMmGlobRegCb *globReg;
7059 globReg = osCp.globRegCb;
7061 sprintf(prntBuf, "--------------------------------------------------------------\n");
7062 SDisplay(0, prntBuf);
7063 sprintf(prntBuf, "Global Region Bucket Information\n");
7064 SDisplay(0, prntBuf);
7065 sprintf(prntBuf, "====================================================\n");
7066 SDisplay(0, prntBuf);
7067 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
7068 SDisplay(0, prntBuf);
7069 sprintf(prntBuf, "====================================================\n");
7070 SDisplay(0, prntBuf);
7073 for (idx = 0; idx < globReg->numBkts; idx++)
7075 #ifdef XEON_SPECIFIC_CHANGES
7076 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
7077 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7080 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
7081 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7083 sprintf(prntBuf, "%2u %12u %8u %9u\n",
7084 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7087 SDisplay(0, prntBuf);
7089 sprintf(prntBuf, "--------------------------------------------------------------\n");
7090 SDisplay(0, prntBuf);
7095 #endif /* SS_LOCKLESS_MEMORY */
7098 Bool IsMemoryThresholdHit(Region reg, Pool pool)
7100 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
7102 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
7105 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
7106 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
7113 /* mt022.201 - Addition of SRegInfoShow function */
7118 * Desc: This function displays the memory usage information
7119 * for the destined region. It will show the usage of
7120 * each configured bucket and the heap for the specified region.
7123 * RFAILED Region not registered
7125 * Notes: A Sample Output from the function
7126 * Bucket Memory: region 1
7127 * ====================================================
7128 * Bucket Number of Blks configured Size Allocated
7129 * ====================================================
7137 * Heap Memory: region 1
7140 * Heap Segmented blocks: 0
7153 S16 SRegInfoShow(region, availmem)
7162 #if (ERRCLASS & ERRCLS_INT_PAR)
7163 if (region > (SS_MAX_REGS-1) )
7165 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7172 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7173 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7174 SDisplay(0, prntBuf);
7175 sprintf(prntBuf, "====================================================\n");
7176 SDisplay(0, prntBuf);
7177 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7178 SDisplay(0, prntBuf);
7179 sprintf(prntBuf, "====================================================\n");
7180 SDisplay(0, prntBuf);
7184 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7186 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7188 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7189 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7190 mtCMMRegCb[region]->bktTbl[idx].size,
7191 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7192 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7194 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7195 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7196 mtCMMRegCb[region]->bktTbl[idx].size,
7197 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7198 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7201 /*mt009.301 Fixed 64BIT compilation warnings*/
7203 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7204 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7205 mtCMMRegCb[region]->bktTbl[idx].size,
7206 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7208 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7209 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7210 mtCMMRegCb[region]->bktTbl[idx].size,
7211 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7213 #endif /* not TENB_RTLIN_CHANGES */
7214 SDisplay(0, prntBuf);
7215 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7216 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7217 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7219 sprintf(prntBuf, "\n---------------\n");
7220 SDisplay(0, prntBuf);
7221 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7222 SDisplay(0, prntBuf);
7223 /*mt009.301 Fixed 64BIT compilation warnings*/
7225 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7227 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7229 SDisplay(0, prntBuf);
7230 /*mt009.301 Fixed 64BIT compilation warnings*/
7232 sprintf(prntBuf, "Heap Allocated: %u\n",
7233 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7235 sprintf(prntBuf, "Heap Allocated: %lu\n",
7236 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7238 SDisplay(0, prntBuf);
7239 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7240 #if (ERRCLASS & ERRCLS_DEBUG)
7241 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7242 mtCMMRegCb[region]->heapCb.numFragBlk);
7243 SDisplay(0, prntBuf);
7248 #ifdef XEON_SPECIFIC_CHANGES
7249 #define SSI_MAX_BKT_THRESHOLD 6
7250 #define SSI_MAX_REG_THRESHOLD 2
7251 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7252 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7253 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7256 static Void SInitMemThreshold
7262 static Void SInitMemThreshold(region, maxBkt)
7268 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7270 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7271 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7272 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7273 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7278 S16 SRegReachedMemThreshold
7284 S16 SRegReachedMemThreshold(region, maxBkt)
7290 uint8_t memStatus = 3;
7291 static uint8_t initFlag = 1;
7295 SInitMemThreshold(region, maxBkt);
7298 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7300 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7305 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7309 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7317 /* mt033.201 - addition of API to return the memory statistical data */
7322 * Desc: This function returns the memory usage information
7323 * for the destined region. It will return the usage of
7324 * each configured bucket and the heap for the specified region.
7327 * RFAILED Region not registered
7338 SsMemDbgInfo *dbgInfo
7341 S16 SGetRegInfo(region, dbgInfo)
7343 SsMemDbgInfo *dbgInfo;
7349 #if (ERRCLASS & ERRCLS_INT_PAR)
7350 if (region >= mtMemoCfg.numRegions )
7352 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7357 dbgInfo->availmem = 0;
7359 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7360 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7362 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7364 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7366 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7367 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7368 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7370 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7371 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7372 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7375 dbgInfo->region = region;
7377 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7379 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7380 mtCMMRegCb[region]->heapCb.avlSize);
7382 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7384 #if (ERRCLASS & ERRCLS_DEBUG)
7385 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7398 S16 SGetRegPoolInfo(numRegion, numPool)
7403 /* Send number of Region available */
7404 *numRegion = mtMemoCfg.numRegions;
7405 /* Send number of Pools available */
7406 *numPool = cfgRegInfo[0].numPools;
7411 /* mt033.201 - addition of APIs to print the memory statistical data
7412 * as defined by SSI enhancements
7414 #ifdef SSI_DEBUG_LEVEL1
7417 * Fun: SPrintRegMemStatusInfo
7419 * Desc: This function displays the memory usage information
7420 * for the destined region. It will show the total memory
7421 * used for static and dynamic memory if typeFlag is
7422 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7423 * memory block allocated for a particular size if typeFlag
7424 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7425 * calling SRegPrintMemStats.
7435 S16 SPrintRegMemStatusInfo
7441 S16 SPrintRegMemStatusInfo(region, typeFlag)
7448 uint32_t statMemSize;
7449 uint32_t dynMemSize;
7452 #if (ERRCLASS & ERRCLS_INT_PAR)
7453 if (region >= mtMemoCfg.numRegions )
7455 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7460 /* initialize the counters*/
7464 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7466 /* total static and dynamic memory allocated from all the buckets in region requested */
7467 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7468 SDisplay(0, prntBuf);
7469 sprintf(prntBuf, "===========================================\n");
7470 SDisplay(0, prntBuf);
7471 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7472 SDisplay(0, prntBuf);
7473 sprintf(prntBuf, "===========================================\n");
7474 SDisplay(0, prntBuf);
7475 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7477 /*mt009.301 Fixed 64BIT compilation warnings*/
7479 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7480 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7481 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7483 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7484 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7485 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7487 SDisplay(0, prntBuf);
7488 /* update the total count */
7489 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7490 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7493 /*mt009.301 Fixed 64BIT compilation warnings*/
7495 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7496 SDisplay(0, prntBuf);
7497 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7499 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7500 SDisplay(0, prntBuf);
7501 /*mt010.301 fix for compilation error*/
7502 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7504 SDisplay(0, prntBuf);
7506 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7507 SDisplay(0, prntBuf);
7508 /*mt009.301 Fixed 64BIT compilation warnings*/
7510 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7511 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7513 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7514 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7516 SDisplay(0, prntBuf);
7518 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7520 /* Bucket Memory allocation Statistics */
7521 return (SPrintRegMemStats(region));
7526 sprintf(prntBuf, "\n Invalid choice \n");
7527 SDisplay(0, prntBuf);
7535 * Fun: SPrintRegMemStats
7537 * Desc: This function displays the memory usage information for
7538 * the destined region. It will show the number of memory
7539 * block allocated for a particular size from the hash list.
7549 static S16 SPrintRegMemStats
7554 static S16 SPrintRegMemStats(region)
7558 CmMmHashListCp *hashListCp;
7564 hashListCp = &mtCMMRegCb[region]->hashListCp;
7566 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7567 SDisplay(0, prntBuf);
7568 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7569 hashListCp->numOfbins, hashListCp->numOfEntries);
7570 SDisplay(0, prntBuf);
7571 sprintf(prntBuf, "===================================\n");
7572 SDisplay(0, prntBuf);
7573 sprintf(prntBuf, "Block Size Total number of requests\n");
7574 SDisplay(0, prntBuf);
7575 sprintf(prntBuf, "===================================\n");
7576 SDisplay(0, prntBuf);
7578 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7579 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7581 if (hashListCp->hashList[idx].numAttempts)
7584 /*mt009.301 Fixed 64BIT compilation warnings*/
7586 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7587 hashListCp->hashList[idx].numAttempts);
7589 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7590 hashListCp->hashList[idx].numAttempts);
7592 SDisplay(0, prntBuf);
7596 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7597 SDisplay(0, prntBuf);
7598 sprintf(prntBuf, "=================================================\n");
7599 SDisplay(0, prntBuf);
7600 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7601 SDisplay(0, prntBuf);
7602 sprintf(prntBuf, "=================================================\n");
7603 SDisplay(0, prntBuf);
7605 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7606 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7608 /*mt009.301 Fixed 64BIT compilation warnings*/
7610 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7611 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7612 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7614 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7615 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7616 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7618 SDisplay(0, prntBuf);
7620 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7621 SDisplay(0, prntBuf);
7622 /*mt009.301 Fixed 64BIT compilation warnings*/
7624 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7625 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7626 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7628 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7629 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7630 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7632 SDisplay(0, prntBuf);
7633 sprintf(prntBuf, "\n");
7634 SDisplay(0, prntBuf);
7641 * Fun: SRegMemErrHdlr
7643 * Desc: This function handles the errors returned from the memory
7644 * related functions. Customers are suggested to modify this
7645 * API according to their specific requirement.
7662 Void SRegMemErrHdlr(region, ptr, errCode)
7671 if (errCode == RDBLFREE)
7673 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7674 SDisplay(0, prntBuf);
7676 else if (errCode == RTRAMPLINGNOK)
7678 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7679 SDisplay(0, prntBuf);
7687 * Fun: SPrintRegMemProfile
7689 * Desc: This function displays the memory profile information
7690 * for the destined region. This function prints for:
7691 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7692 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7702 S16 SPrintRegMemProfile
7707 S16 SPrintRegMemProfile(region)
7713 CmMmBlkHdr *curBktBlk;
7715 Size offsetToNxtBlk;
7723 #if (ERRCLASS & ERRCLS_INT_PAR)
7724 if (region >= mtMemoCfg.numRegions )
7726 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7731 regCb = mtCMMRegCb[region];
7733 /* memory profile */
7734 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7735 SDisplay(0, prntBuf);
7737 /* bucket profile */
7738 sprintf(prntBuf, "\nBucket Profile\n");
7739 SDisplay(0, prntBuf);
7741 for (idx = 0; idx < regCb->numBkts; idx++)
7744 /*mt009.301 Fixed 64BIT compilation warnings*/
7746 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7747 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7749 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7750 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7752 SDisplay(0, prntBuf);
7754 sprintf(prntBuf, "==========================================================================\n");
7755 SDisplay(0, prntBuf);
7756 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7757 SDisplay(0, prntBuf);
7758 sprintf(prntBuf, "==========================================================================\n");
7759 SDisplay(0, prntBuf);
7761 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7763 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7764 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7765 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7767 /*mt009.301 Fixed 64BIT compilation warnings*/
7769 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7771 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7773 SDisplay(0, prntBuf);
7774 /* check if it is a sane block, elxe jump to next block */
7775 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7777 sprintf(prntBuf, " Trampled \n");
7778 SDisplay(0, prntBuf);
7783 if (CMM_IS_STATIC(curBktBlk->memFlags))
7785 /*mt009.301 Fixed 64BIT compilation warnings*/
7787 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7789 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7791 SDisplay(0, prntBuf);
7793 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7795 /*mt009.301 Fixed 64BIT compilation warnings*/
7797 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7799 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7801 SDisplay(0, prntBuf);
7803 else if (CMM_IS_FREE(curBktBlk->memFlags))
7805 /*mt009.301 Fixed 64BIT compilation warnings*/
7807 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7809 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7811 SDisplay(0, prntBuf);
7815 sprintf(prntBuf, " Trampled \n");
7816 SDisplay(0, prntBuf);
7822 sprintf(prntBuf, "\nHeap Profile\n");
7823 SDisplay(0, prntBuf);
7825 /* point to heapCb */
7826 heapCb = &(regCb->heapCb);
7828 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7829 SDisplay(0, prntBuf);
7830 sprintf(prntBuf, "==========================================================================\n");
7831 SDisplay(0, prntBuf);
7832 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7833 SDisplay(0, prntBuf);
7834 sprintf(prntBuf, "==========================================================================\n");
7835 SDisplay(0, prntBuf);
7837 /* traverse the entire heap to output the heap profile */
7838 hdrSize = sizeof(CmHEntry);
7839 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7840 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7842 /*mt009.301 Fixed 64BIT compilation warnings*/
7844 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7846 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7848 SDisplay(0, prntBuf);
7850 /* check if it is a sane block, elxe jump to next block */
7851 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7853 sprintf(prntBuf, " Trampled \n");
7854 SDisplay(0, prntBuf);
7856 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7857 SDisplay(0, prntBuf);
7860 * To go to next block in the heap we do not have any offset value
7861 * other than curHBlk->size. As the block is already trampled
7862 * we cannot rely on this size. So it is better to stop here unless there
7863 * exists any other mechanism(?) to know the offset to next block.
7868 /*mt009.301 Fixed 64BIT compilation warnings*/
7870 sprintf(prntBuf, " %8u", curHBlk->size);
7872 sprintf(prntBuf, " %8lu", curHBlk->size);
7874 SDisplay(0, prntBuf);
7876 if (CMM_IS_STATIC(curHBlk->memFlags))
7878 /*mt009.301 Fixed 64BIT compilation warnings*/
7880 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7882 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7884 SDisplay(0, prntBuf);
7886 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7888 /*mt009.301 Fixed 64BIT compilation warnings*/
7890 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7892 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7894 SDisplay(0, prntBuf);
7896 else if (CMM_IS_FREE(curHBlk->memFlags))
7898 /*mt009.301 Fixed 64BIT compilation warnings*/
7900 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7902 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7904 SDisplay(0, prntBuf);
7908 sprintf(prntBuf, " Trampled \n");
7909 SDisplay(0, prntBuf);
7911 /* goto next block in the heap */
7912 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7918 #endif /* SSI_DEBUG_LEVEL1 */
7920 /*-- mt035.201 : Added new API for timestamp --*/
7923 * Fun: Get TimeStamp
7925 * Desc: This function is used to Get TimeStamp in micro seconds
7941 S16 SGetTimeStamp(ts)
7947 struct timespec ptime;
7949 struct timeval ptime;
7958 clock_gettime(CLOCK_REALTIME, &ptime);
7960 gettimeofday(&ptime, NULL);
7963 /* Obtain the time of day, and convert it to a tm struct. --*/
7964 ptm = localtime (&ptime.tv_sec);
7965 /* Klock work fix ccpu00148484 */
7968 /* Format the date and time, down to a single second. --*/
7969 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7972 /* Compute microseconds. --*/
7974 microseconds = ptime.tv_nsec / 1000;
7976 microseconds = ptime.tv_usec;
7979 /* Print the formatted time, in seconds, followed by a decimal point
7980 and the microseconds. --*/
7981 /*mt009.301 Fixed 64BIT compilation warnings*/
7983 sprintf(ts, "%s.%03d", time_string, microseconds);
7985 sprintf(ts, "%s.%03ld", time_string, microseconds);
7991 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7994 * Fun: Get SGetSystemTsk
7996 * Desc: This function is used to Get sytem task id
8006 uint32_t SGetSystemTsk
8011 uint32_t SGetSystemTsk()
8015 return (pthread_self());
8017 } /* end of SGetSystemTsk */
8019 #ifdef SS_MULTICORE_SUPPORT
8022 * Fun: Add Timer thread into system task table
8024 * Desc: This function is used to add the system task
8025 * associated with Timer thread.
8035 static SsSTskEntry* ssdAddTmrSTsk(Void)
8037 static SsSTskEntry* ssdAddTmrSTsk()
8044 /* lock the system task table */
8045 ret = SLock(&osCp.sTskTblLock);
8049 #if (ERRCLASS & ERRCLS_DEBUG)
8050 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8051 "Could not lock system task table");
8057 /* check count of system tasks */
8058 if (osCp.numSTsks == SS_MAX_STSKS)
8061 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8063 #if (ERRCLASS & ERRCLS_DEBUG)
8064 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
8065 "Could not give the Semaphore");
8070 #if (ERRCLASS & ERRCLS_ADD_RES)
8071 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
8078 /* initialize the system task entry with the information we have */
8079 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
8081 /* store the system task priority */
8082 sTsk->tskPrior = SS_NORM_TSK_PRI;
8084 /* initialize the demand queue */
8085 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8088 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8090 #if (ERRCLASS & ERRCLS_DEBUG)
8091 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8092 "Could not give the Semaphore");
8097 #if (ERRCLASS & ERRCLS_DEBUG)
8098 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8099 "Could not initialize demand queue");
8105 /* initialize the system task entry lock */
8106 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8108 ssDestroyDmndQ(&sTsk->dQ);
8110 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8112 #if (ERRCLASS & ERRCLS_DEBUG)
8113 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8114 "Could not give the Semaphore");
8119 #if (ERRCLASS & ERRCLS_DEBUG)
8120 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8121 "Could not initialize system task entry lock");
8128 /* success, update the table */
8129 sTsk->tskId = osCp.nxtSTskEntry;
8131 sTsk->termPend = FALSE;
8132 osCp.nxtSTskEntry = sTsk->nxt;
8135 /* unlock the system task table */
8137 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8139 #if (ERRCLASS & ERRCLS_DEBUG)
8140 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8141 "Could not give the Semaphore");
8148 #endif /* SS_MULTICORE_SUPPORT */
8149 /* mt003.301 Readwrite lock and recursive mutex additions */
8150 #ifdef SS_LOCK_SUPPORT
8153 * Fun: ssdInitLockNew
8155 * Desc: This function is used to initialise lock/mutex
8171 S16 ssdInitLockNew(lockId, lockType)
8177 #ifdef SS_REC_LOCK_SUPPORT
8178 pthread_mutexattr_t attr;
8179 #endif /* SS_REC_LOCK_SUPPORT */
8180 Txt prntBuf[PRNTSZE];
8186 #ifdef SS_RDWR_LOCK_SUPPORT
8189 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8191 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8192 SDisplay(0, prntBuf);
8197 #endif /* SS_RDWR_LOCK_SUPPORT */
8198 #ifdef SS_REC_LOCK_SUPPORT
8201 retVal = pthread_mutexattr_init(&attr);
8205 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8210 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8212 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8216 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8217 pthread_mutexattr_destroy(&attr);
8221 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8224 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8225 pthread_mutexattr_destroy(&attr);
8231 #endif /* SS_REC_LOCK_SUPPORT */
8234 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8235 SDisplay(0, prntBuf);
8245 * Desc: This function is used to aquire the read write lock
8261 S16 ssdLockNew(lockId, lockType)
8267 Txt prntBuf[PRNTSZE];
8273 #ifdef SS_RDWR_LOCK_SUPPORT
8276 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8278 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8279 SDisplay(0, prntBuf);
8286 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8288 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8289 SDisplay(0, prntBuf);
8296 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8298 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8299 SDisplay(0, prntBuf);
8306 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8308 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8309 SDisplay(0, prntBuf);
8314 #endif /* SS_RDWR_LOCK_SUPPORT */
8315 #ifdef SS_REC_LOCK_SUPPORT
8318 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8320 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8321 SDisplay(0, prntBuf);
8326 #endif /* SS_REC_LOCK_SUPPORT */
8329 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8330 SDisplay(0, prntBuf);
8343 * Desc: This function is used to Unlock the read write lock
8359 S16 ssdUnlockNew(lockId, lockType)
8365 Txt prntBuf[PRNTSZE];
8371 #ifdef SS_RDWR_LOCK_SUPPORT
8374 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8376 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8377 SDisplay(0, prntBuf);
8382 #endif /* SS_RDWR_LOCK_SUPPORT */
8383 #ifdef SS_REC_LOCK_SUPPORT
8386 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8388 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8389 SDisplay(0, prntBuf);
8394 #endif /* SS_REC_LOCK_SUPPORT */
8397 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8398 SDisplay(0, prntBuf);
8407 * Fun: ssdDestroyLockNew
8409 * Desc: This function is used to destroy the read write lock
8419 S16 ssdDestroyLockNew
8425 S16 ssdDestroyLockNew(lockId, lockType)
8430 Txt prntBuf[PRNTSZE];
8436 #ifdef SS_RDWR_LOCK_SUPPORT
8439 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8441 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8442 SDisplay(0, prntBuf);
8447 #endif /* SS_RDWR_LOCK_SUPPORT */
8448 #ifdef SS_REC_LOCK_SUPPORT
8451 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8453 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8454 SDisplay(0, prntBuf);
8459 #endif /* SS_REC_LOCK_SUPPORT */
8462 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8463 SDisplay(0, prntBuf);
8469 #endif /* SS_LOCK_SUPPORT */
8471 /* mt005.301 : Cavium Changes */
8472 #ifdef SS_SEUM_CAVIUM
8476 * Fun: ssInitRcvWork
8478 * Desc: This is the initializtion function of receive
8482 * RFAILED - failed, general (optional)
8484 * Notes: Function to initialize the work queue packet
8485 * receiving thread. This creates the new thread to
8486 * receive the work and sets the affinity.
8500 pthread_attr_t attr;
8504 /* set the required attributes */
8505 pthread_attr_init(&attr);
8506 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8507 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8508 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8510 /* Create a new thread to receive the work queue messages */
8511 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8513 pthread_attr_destroy(&attr);
8518 pthread_attr_destroy(&attr);
8522 }/* ssInitRcvWork */
8529 * Desc: This is the handler function of receive
8533 * RFAILED - failed, general (optional)
8535 * Notes:The handler function of the work queue receiver task.
8536 * This will be waiting for the work and after receiving
8537 * it, work will converted and posted to that entityt
8544 static void *workRcvTsk
8549 static void *workRcvTsk (ptr)
8554 cvmx_wqe_t *workPtr;
8555 Buffer *mBuf, *rcvdBuf;
8556 SsMsgInfo *minfoPtr;
8565 /* get the work if its avilable */
8566 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8568 if ( workPtr == NULLP )
8570 /* If there is no work then sleep for 10 usec */
8572 ts.tv_nsec = 500000;
8574 nanosleep(&ts, NULLP);
8578 switch(workPtr->tag)
8580 /* Switch over according to the tag value */
8581 case SS_CVMX_MBUF_TAG:
8583 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8585 /* Convert the physical address to Pointers */
8586 ret = SConvPhyPtr(&rcvdBuf);
8589 /* mt011.301: Cavium 32 bit changes */
8590 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8594 /* Copy the buffer to this region */
8595 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8598 /* mt011.301: Cavium 32 bit changes */
8599 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8603 /* mt011.301: Cavium 32 bit changes */
8604 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8606 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8608 /* Get the post strucutre and Post the message */
8609 if ( minfoPtr != NULLP)
8611 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8613 (Void)SPstTsk(&pst, mBuf);
8615 /* Free the buffer allocated if it cannot be sent */
8624 /* Invalid tag value, drop the work */
8625 /* mt011.301: Cavium 32 bit changes */
8626 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8635 #endif /* SS_SEUM_CAVIUM */
8637 #ifdef TENB_RTLIN_CHANGES
8638 S16 SInitLock(SLockId *l, uint8_t t)
8641 pthread_mutexattr_t prior;
8642 pthread_mutexattr_init(&prior);
8643 #ifndef RGL_SPECIFIC_CHANGES
8644 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8646 r = pthread_mutex_init(l, &prior);
8647 pthread_mutexattr_destroy(&prior);
8651 #ifdef SS_THR_REG_MAP
8654 * Fun: ssRegMainThread
8656 * Desc: This function is used to add the memory region
8657 * mapping for the main thread.
8659 * Ret: VOID (Always successful)
8667 Void ssRegMainThread(Void)
8670 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8672 printf("not able to get different Id for main thread\n");
8675 /* Here the default region is added as we dont have any region associated with
8676 * Main thread. The thread should not perform any allocation except
8677 * the initial configuratin
8679 #ifdef XEON_SPECIFIC_CHANGES
8680 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8682 SS_GET_THREAD_MEM_REGION() =
8689 * Fun: ssCheckAndAddMemoryRegionMap
8691 * Desc: This function is used to add the memory region
8692 * mapping for the provided sTsk associated thread.
8693 * If the threadId can be placed in the thread memory
8694 * region mapping table and returns success if it is able
8695 * to place. If not, it keeps the thread ID in the static
8696 * local array and increments the count. Once thread Id
8697 * is successfully placed in the thread memory region mapping
8698 * table, pthread_cancel is sent for all the previous threads
8699 * which are failed to place in table.
8701 * Ret: TRUE - Thread ID successfully placed in thread memory region
8703 * FALSE - If thread Id is not placed in thread memory region
8706 * Notes:mapping tablemapping tablng tablee
8711 S32 ssCheckAndAddMemoryRegionMap
8713 pthread_t threadId, /* Thread Id of system task */
8714 Region region /* Region associated with thread */
8717 static uint32_t createdThreads;
8718 static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8722 /* Here 0xFF is considered as invalid region and if the mapping table
8723 * contains 0xFF, that mapping entry is free
8725 if(SS_INVALID_THREAD_REG_MAP !=
8726 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8728 /* Klock work fix ccpu00148484 */
8729 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8731 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8732 printf("Not able to get the different thread ID, exiting\n");
8735 createdThreadIds[createdThreads++] = threadId;
8738 /* If we found free mapping table entry, place the region and send pthread_cancel
8739 * for all the thread Ids which are created before this
8741 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8742 #ifdef XEON_SPECIFIC_CHANGES
8743 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8744 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8745 SS_MAX_THREAD_REGION_MAP), region);
8747 for(indx = 0; indx < createdThreads; indx++)
8749 #ifdef XEON_SPECIFIC_CHANGES
8750 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8752 pthread_cancel(createdThreadIds[indx]);
8758 } /* ssCheckAndAddMemoryRegionMap */
8762 * Fun: ssCheckAndDelMemoryRegionMap
8764 * Desc: This function is used to add the memory region
8765 * mapping for the provided sTsk associated thread.
8766 * If the threadId can be placed in the thread memory
8767 * region mapping table and returns success if it is able
8768 * to place. If not, it keeps the thread ID in the static
8769 * local array and increments the count. Once thread Id
8770 * is successfully placed in the thread memory region mapping
8771 * table, pthread_cancel is sent for all the previous threads
8772 * which are failed to place in table.
8774 * Ret: TRUE - Thread ID successfully placed in thread memory region
8776 * FALSE - If thread Id is not placed in thread memory region
8779 * Notes:mapping tablemapping tablng tablee
8784 S32 ssCheckAndDelMemoryRegionMap
8786 pthread_t threadId /* Thread Id of system task */
8791 /* Raghu To-Do Check with team, is it necessary to acquire lock
8792 * as del and add may go parallel */
8793 /* Here 0xFF is considered as invalid region and if the mapping table
8794 * contains 0xFF, that mapping entry is free
8796 if(SS_INVALID_THREAD_REG_MAP ==
8797 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8800 printf("Invalid Thread ID (%ld)\n", (uint32_t)threadId);
8802 printf("Invalid Thread ID (%d)\n", (uint32_t)threadId);
8806 /* If we found free mapping table entry, place the region and send pthread_cancel
8807 * for all the thread Ids which are created before this
8809 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8813 } /* ssCheckAndAddMemoryRegionMap */
8817 #ifdef SS_TSKLOG_ENABLE
8822 * Desc: This function will return current time through input parameter.
8825 * RFAILED - failed, general (optional)
8834 volatile uint32_t *startTime,
8838 S16 SStartTask(startTime, taskId)
8839 volatile uint32_t *startTime;
8843 #ifdef MSPD_MLOG_NEW
8844 *startTime = GetTIMETICK();
8853 * Desc: This function will return current time through input parameter.
8854 * and take the difference of start time provided as input parameter
8858 * RFAILED - failed, general (optional)
8867 volatile uint32_t startTime,
8871 S16 SStopTask(startTime, taskId)
8872 volatile uint32_t startTime;
8876 /*uint32_t stopTime;*/
8879 case PID_MAC_HARQ_IND:
8880 case PID_SCH_TTI_IND:
8882 case PID_MAC_DAT_IND:
8883 case PID_MAC_SF_ALLOC_REQ:
8884 case PID_MAC_STA_RSP:
8885 case PID_MAC_DL_SCHD:
8886 case PID_MAC_DL_CQI_IND:
8887 case PID_MAC_UL_CQI_IND:
8888 case PID_MAC_UL_SCHD:
8889 case PID_MAC_TTI_IND:
8890 case PID_CL_RCV_PHY_MSG:
8891 case PID_CL_HARQ_STA_IND:
8892 case PID_MAC_AM_HARQ_RLS:
8893 case PID_CL_DL_BATCH_PROC:
8894 case PID_CL_DLM_PRC_TTI_IND:
8895 case PID_CRC_IND_REAL:
8896 case PID_CRC_IND_DUMMY:
8897 case PID_TTI_LATENCY:
8898 case PID_RECPREQ_PROC:
8901 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8903 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8906 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8916 volatile uint32_t * startTime,
8920 S16 SStartTask(startTime, taskId)
8921 volatile uint32_t * startTime;
8932 volatile uint32_t startTime,
8936 S16 SStopTask(startTime, taskId)
8937 volatile uint32_t startTime;
8944 #endif /*#ifdef SS_TSKLOG_ENABLE */
8945 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8947 * This primitive is used to calculate the CPU Utilization per Core
8952 * @return Void - function is always success
8955 Void UpdateSocCpuInfo
8957 CmCpuStatsInfo *cpuInfo,
8961 Void UpdateSocCpuInfo(*cpuInfo, idx)
8962 CmCpuStatsInfo *cpuInfo;
8967 S8 mipsStr[MIPS_STRING_LEN];
8974 /* Open the file which holds the MIPS available value */
8975 mipsFd = fopen(MIPS_FILE, "r");
8982 /* Get the free mips available value from the file */
8983 if(NULLP == fgets(mipsStr, 24, mipsFd))
8985 printf("fgets to get the free mips available failed\n");
8990 strtok(mipsStr, " ");
8992 strPart = strtok(NULLP, " ");
8994 if(idx == CM_L2_CPU_UTIL)
8996 if(strPart != NULLP)
8998 l2FreeCpu = atoi(strPart);
8999 l2CpuUsed = 100 - l2FreeCpu;
9000 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
9001 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
9002 cpuInfo->cpuUtil[0].numSamples++;
9005 if(idx == CM_L3_CPU_UTIL)
9007 strPart = strtok(NULLP, " ");
9008 if(strPart != NULLP)
9010 l3FreeCpu = atoi(strPart);
9011 l3CpuUsed = 100 - l3FreeCpu;
9012 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
9013 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
9014 cpuInfo->cpuUtil[0].numSamples++;
9017 if(idx == CM_L2_CPU_UTIL)
9019 cpuInfo->numCores = CM_NUM_L2_CORES ;
9021 else if(idx == CM_L3_CPU_UTIL)
9023 cpuInfo->numCores = CM_NUM_L3_CORES ;
9029 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
9030 #ifdef SS_MULTICORE_SUPPORT
9033 * Fun: Add Timer thread into system task table
9035 * Desc: This function is used to add the system task
9036 * associated with Timer thread.
9046 static SsSTskEntry* ssdReAddTmrSTsk(
9050 static SsSTskEntry* ssdReAddTmrSTsk(idx)
9058 /* lock the system task table */
9059 ret = SLock(&osCp.sTskTblLock);
9063 #if (ERRCLASS & ERRCLS_DEBUG)
9064 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
9065 "Could not lock system task table");
9071 /* initialize the system task entry with the information we have */
9072 sTsk = &osCp.sTskTbl[idx];
9077 SDestroyLock(&sTsk->lock);
9078 ssDestroyDmndQ(&sTsk->dQ);
9081 /* store the system task priority */
9082 sTsk->tskPrior = SS_NORM_TSK_PRI;
9084 /* initialize the demand queue */
9085 if (ssInitDmndQ(&sTsk->dQ) != ROK)
9088 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9090 #if (ERRCLASS & ERRCLS_DEBUG)
9091 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
9092 "Could not give the Semaphore");
9097 #if (ERRCLASS & ERRCLS_DEBUG)
9098 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
9099 "Could not initialize demand queue");
9105 /* initialize the system task entry lock */
9106 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
9108 ssDestroyDmndQ(&sTsk->dQ);
9110 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9112 #if (ERRCLASS & ERRCLS_DEBUG)
9113 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
9114 "Could not give the Semaphore");
9119 #if (ERRCLASS & ERRCLS_DEBUG)
9120 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9121 "Could not initialize system task entry lock");
9128 /* success, update the table */
9129 sTsk->tskId = idx + 1;
9131 sTsk->termPend = FALSE;
9133 /* unlock the system task table */
9135 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9137 #if (ERRCLASS & ERRCLS_DEBUG)
9138 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9139 "Could not give the Semaphore");
9146 #endif /* SS_MULTICORE_SUPPORT */
9151 * Fun: Initialize timer table
9153 * Desc: This function initializes MTSS-specific information
9154 * in the timer table.
9172 pthread_attr_t attr;
9173 struct sched_param param_sched;
9174 #ifndef XEON_SPECIFIC_CHANGES
9177 #ifdef SS_MULTICORE_SUPPORT
9179 #endif /* SS_MULTICORE_SUPPORT */
9180 #ifdef SS_THR_REG_MAP
9181 uint32_t threadCreated = FALSE;
9182 #endif /* SS_THR_REG_MAP */
9185 #ifndef XEON_SPECIFIC_CHANGES
9186 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9189 #if (ERRCLASS & ERRCLS_DEBUG)
9190 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9191 "Could not give the Semaphore");
9197 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9198 /* mt010.21: addition */
9200 #ifdef SS_MULTICORE_SUPPORT
9201 sTsk = ssdReAddTmrSTsk(0);
9206 #endif /* SS_MULTICORE_SUPPORT */
9207 /* create the timer handler thread */
9209 pthread_attr_init(&attr);
9210 /* mt021.201 - Addition to set stack size */
9211 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9212 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9213 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9214 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9215 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9216 pthread_attr_setschedparam(&attr, ¶m_sched);
9219 #ifdef SS_THR_REG_MAP
9220 /* When the thread is created, we check for the memory mapping table if
9221 * threadId can be placed in thread memory map table. If it is not able to place
9222 * threadId is stored in tmporary array. Once thread is created successful,
9223 * thread_cancel is sent for each thread which are created before. All the
9224 * threads are made to wait on sema which is cancel point for thread.
9226 while(threadCreated == FALSE)
9229 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9231 /* mt020.201 - Addition for destroying thread attribute object attr */
9232 pthread_attr_destroy(&attr);
9237 #ifdef SS_THR_REG_MAP
9238 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9241 #endif /* SS_THR_REG_MAP */
9242 #ifdef SS_MEM_WL_DEBUG
9243 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9246 /* mt020.201 - Addition for destroying thread attribute object attr */
9247 pthread_attr_destroy(&attr);
9248 sem_post(&osCp.dep.ssStarted);
9252 /**********************************************************************
9254 **********************************************************************/