1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: Multi-threaded System Services - Solaris
25 Desc: C source code for the MTSS-Solaris implementation of
30 *********************************************************************21*/
35 #ifndef _POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE 199309L
38 /* mt003.301 moved env files to use the __USE_UNIX98 flag in sys includes */
45 #include <sys/types.h>
50 /* mt003.301: included sys/time.h
51 * for both solaris and linux
54 /* mt008.21: addition */
59 /* header include files (.h) */
62 #include "common_def.h"
63 #include "mt_ss.h" /* MTSS specific */
64 #include "mt_err.h" /* MTSS error defines */
66 #include "ss_queue.h" /* queues */
67 #include "ss_task.h" /* tasking */
68 #include "ss_msg.h" /* messaging */
69 #include "ss_mem.h" /* memory management interface */
70 #include "ss_gen.h" /* general */
71 /* mt003.301 Additions - Task deregistration */
72 #include "ss_err.h" /* error */
73 #include "cm_mem.h" /* common memory manager */
74 /* mt001.301 : Additions */
75 #ifdef SS_THREAD_PROFILE
78 #ifdef SS_LOCKLESS_MEMORY
83 /* multi-core support enhancement */
84 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
85 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
91 #include <sys/types.h>
92 #include <sys/processor.h>
93 #include <sys/procset.h>
96 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
97 /* mt001.301 : Additions */
99 #include <sys/types.h>
100 #include <sys/socket.h>
101 #include <netinet/in.h>
102 #include <arpa/inet.h>
103 #endif /* SS_WATCHDOG */
105 #ifdef SS_USE_WLS_MEM
106 #include <rte_common.h>
107 #include <rte_debug.h>
111 /* header/extern include files (.x) */
113 #include "gen.x" /* general layer */
114 #include "ssi.x" /* system services */
116 #include "cm5.x" /* common timers */
118 #include "mt_ss.x" /* MTSS specific */
119 #ifdef SS_LOCKLESS_MEMORY
120 #include "mt_ss_wl.x" /* MTSS specific */
121 #endif /* SS_LOCKLESS_MEMORY */
123 #include "ss_queue.x" /* queues */
124 #include "ss_task.x" /* tasking */
125 #include "ss_timer.x" /* timers */
126 #include "ss_strm.x" /* STREAMS */
127 #include "ss_msg.x" /* messaging */
128 #include "ss_mem.x" /* memory management interface */
129 #include "ss_drvr.x" /* driver tasks */
130 #include "ss_gen.x" /* general */
131 #ifdef SS_LOCKLESS_MEMORY
132 #include "cm_llist.x"
134 #include "cm_mem_wl.x" /* common memory manager */
136 #include "cm_mem.x" /* common memory manager */
137 #endif /* SS_LOCKLESS_MEMORY */
138 #include "cm_lte.x" /* common memory manager */
139 /* mt001.301 : Additions */
140 #ifdef SS_LOGGER_SUPPORT
142 #endif /* SS_LOGGER_SUPPORT */
144 /*mt005.301: Cavium Changes */
145 #ifdef SS_SEUM_CAVIUM
146 /* cvmx includes files */
147 #include "cvmx-config.h"
149 #include "cvmx-pow.h"
150 #include "cvmx-tim.h"
151 #include "cvmx-fpa.h"
152 #include "cvmx-helper-fpa.h"
153 #include "cvmx-malloc.h"
154 #endif /* SS_SEUM_CAVIUM */
157 #include "mt_plat_t33.h"
158 #include "mt_plat_t33.x"
159 #include "sys/syscall.h"
162 #if defined(RGL_SPECIFIC_CHANGES) || defined(INTEL_WLS) || defined(SS_USE_WLS_MEM)
164 #include <hugetlbfs.h>
167 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
168 /* general purpose debug zone */
169 char my_buffer2[4096 * 4] = { 0 };
170 char my_buffer[4096] = { 0 };
171 int my_buffer_idx = 0;
174 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
176 struct sigcontext my_uc_mcontext = { 0 };
181 #include <ucontext.h>
186 #define SIGSEGV_STACK_GENERIC
187 #define REGFORMAT "%x\n"
189 #ifdef XEON_SPECIFIC_CHANGES
190 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
193 void dump_external(void);
195 static Void mtDelSigals(Void)
199 memset(&sa, 0, sizeof(struct sigaction));
200 sigemptyset(&sa.sa_mask);
201 sa.sa_handler = SIG_DFL;
202 sigaction(SIGSEGV, &sa, NULL);
204 memset(&sa, 0, sizeof(struct sigaction));
205 sigemptyset(&sa.sa_mask);
206 sa.sa_handler = SIG_DFL;
207 sigaction(SIGILL, &sa, NULL);
211 static void signal_segv(int signum, siginfo_t * info, void *ptr)
213 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
216 ucontext_t *ucontext = (ucontext_t *) ptr;
217 #ifdef XEON_SPECIFIC_CHANGES
219 int *p32 = (int *) 0x2fff0000;
224 printf("\nsegv ooops @ %p\n", info->si_addr);
227 printf("\nSegmentation Fault!\n");
228 printf("\ninfo.si_signo = %d\n", signum);
229 printf("\ninfo.si_errno = %d\n", info->si_errno);
230 printf("\ninfo.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
231 printf("\ninfo.si_addr = %p\n", info->si_addr);
233 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
236 #ifndef RGL_SPECIFIC_CHANGES
237 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
238 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
239 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
240 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
241 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
242 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
243 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
244 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
245 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
246 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
247 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
248 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
249 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
250 printf("\nreg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
251 printf("\nreg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
252 printf("\nreg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
253 printf("\nreg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
256 printf("\nStack trace (non-dedicated):\n");
258 sz = backtrace(buffer, 50);
259 strings = backtrace_symbols(buffer, sz);
260 for (i = 0; i < sz; ++i)
261 printf("%s\n", strings[i]);
263 printf("\nEnd of stack trace\n");
265 #ifdef XEON_SPECIFIC_CHANGES
270 /* Lets first print our debug information */
271 printf("\nBefore dumping our Debug info\n");
273 printf("\nAfter dumping our Debug info\n");
275 /* Disable the signal and make the enodeb to dump. This will make
276 * eNB to generate the core with dumping the ccpu log
283 /* End printing debug information */
288 /*** TBD: IMPORTANT ***
289 *** The following definition is temporary. This must be removed
290 *** when all products have been updated with latest ssi.h file OR
291 *** all ssi.h files have been updated to contain this definitions
293 /* New error class for FTHA added */
295 #define ERRCLS_FTHA 0x8
296 #endif /* ERRCLS_FTHA */
298 typedef struct _SPThreadCreateArg
300 void *argument; /* argument that is to be passed to the actual pthread */
301 void *(*start_routine) (void *); /* function from which pthread starts */
304 void *pthreadCreateHdlr(void* arg);
306 #ifdef SS_LOCKLESS_MEMORY
307 Buffer *mtTskBuffer1;
308 Buffer *mtTskBuffer2;
310 extern pthread_t tmpRegTidMap[20];
311 extern uint8_t stopBtInfo;
312 S16 SGlobMemInfoShow(void);
313 #endif /* SS_LOCKLESS_MEMORY */
316 APP_CONTEXT AppContext;
320 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
321 unsigned int tlPost(void *handle);
324 /* forward references */
325 /* mt003.301 Modifications - Moved to ss_gen.x */
326 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
327 Void *mtTskHdlrT2kL2 ARGS((Void*));
328 void mtSigSegvHndlr ARGS((void));
329 void mtSigUsr2Hndlr ARGS((void));
332 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
333 static Void *mtTskHdlr ARGS((void *));
334 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
336 static Void *mtTmrHdlr ARGS((void *));
337 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
339 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
340 static Void mtIntSigHndlr ARGS((int));
341 static Void mtExitClnup ARGS((void));
344 static Void *mtConHdlr ARGS((void *));
348 #ifdef SS_DRVR_SUPPORT
349 static Void *mtIsTskHdlr ARGS((void *));
353 /* mt020.201 - Addition for no command line available */
355 static Void mtGetOpts ARGS((void));
356 /* mt003.301 Additions - File Based task registration made
357 * common for both MULTICORE and NON-MULTICORE
359 static Bool fileBasedMemCfg = FALSE;
362 /* mt033.201 - addition of local function to print the statistics such as
363 * (size vs. numAttempts) and (allocations vs. deallocations)
365 #ifdef SSI_DEBUG_LEVEL1
366 static S16 SPrintRegMemStats ARGS((Region region));
367 #endif /* SSI_DEBUG_LEVEL1 */
369 #ifdef SS_MULTICORE_SUPPORT
370 static SsSTskEntry* ssdAddTmrSTsk(Void);
371 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
372 #ifndef SS_LOCKLESS_MEMORY
373 #ifndef RGL_SPECIFIC_CHANGES
374 static S16 ssdInitMemInfo ARGS((void));
379 /* mt005.301: Cavium changes */
380 #ifdef SS_SEUM_CAVIUM
381 static Void *workRcvTsk ARGS((void *));
382 #endif /* SS_SEUM_CAVIUM */
384 #ifdef SS_THR_REG_MAP
385 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
387 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
388 #endif /* SS_THR_REG_MAP */
390 /* type declarations */
392 #ifdef SS_DRVR_SUPPORT
393 typedef struct mtIsFlag
403 /* public variable declarations */
405 Cntr cfgNumRegs = SS_MAX_REGS;
406 /* Set memory configuration as false.
407 * Set to true if memory configuration through file is successfull.
409 Bool memConfigured = FALSE;
410 /* mt022.201 - Modification for shared memory relay region and memcal tool */
411 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
414 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
416 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
417 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
418 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
419 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
420 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
421 { SS_POOL_STATIC, 0 }
427 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
429 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
430 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
431 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
432 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
433 { SS_POOL_STATIC, 0 }
436 #endif /* INTEL_WLS */
438 #ifdef SS_LOCKLESS_MEMORY
441 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
443 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
444 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
445 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
446 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
447 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
448 { SS_POOL_STATIC, 0 }
452 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
454 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
455 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
456 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
457 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
458 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
459 { SS_POOL_STATIC, 0 }
463 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
465 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
466 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
467 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
468 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
469 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
470 { SS_POOL_STATIC, 0 }
474 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
476 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
477 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
478 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
479 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
480 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
481 { SS_POOL_STATIC, 0 }
485 SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
487 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
488 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
489 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
490 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
491 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
492 { SS_POOL_STATIC, 0 }
496 SS_DFLT_REGION + 6, SS_MAX_POOLS_PER_REG - 1,
498 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
499 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
500 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
501 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
502 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
503 { SS_POOL_STATIC, 0 }
507 SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1,
509 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
510 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
511 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
512 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
513 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
514 { SS_POOL_STATIC, 0 }
518 #ifndef INTEL_WLS_MEM
521 SS_DFLT_REGION + 8, SS_MAX_POOLS_PER_REG - 1,
523 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
524 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
525 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
526 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
527 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
528 { SS_POOL_STATIC, 0 }
533 #endif /* SS_LOCKLESS_MEMORY */
535 /* mt003.301 Modifications - File Based task registration made
536 * common for both MULTICORE and NON-MULTICORE
539 #ifdef SS_LOCKLESS_MEMORY
540 MtDynMemCfg mtDynMemoCfg =
542 SS_MAX_REGS, /* number of regions */
545 SS_DFLT_REGION, /* region id */
546 MT_MAX_BKTS, /* number of buckets */
548 /* block size, no. of blocks, Upper threshold, lower threshold */
549 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
550 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
551 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
552 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
553 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
557 SS_DFLT_REGION + 1, /* region id */
558 MT_MAX_BKTS, /* number of buckets */
560 /* block size, no. of blocks, Upper threshold, lower threshold */
561 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
562 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
563 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
564 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
565 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
569 SS_DFLT_REGION + 2, /* region id */
570 MT_MAX_BKTS, /* number of buckets */
572 /* block size, no. of blocks, Upper threshold, lower threshold */
573 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
574 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
575 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
576 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
577 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
581 SS_DFLT_REGION + 3, /* region id */
582 MT_MAX_BKTS, /* number of buckets */
584 /* block size, no. of blocks, Upper threshold, lower threshold */
585 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
586 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
587 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
588 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
589 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
593 SS_DFLT_REGION + 4, /* region id */
594 MT_MAX_BKTS, /* number of buckets */
596 /* block size, no. of blocks, Upper threshold, lower threshold */
597 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
598 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
599 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
600 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
601 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
605 SS_DFLT_REGION + 5, /* region id */
606 MT_MAX_BKTS, /* number of buckets */
608 /* block size, no. of blocks, Upper threshold, lower threshold */
609 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
610 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
611 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
612 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
613 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
617 SS_DFLT_REGION + 6, /* region id */
618 MT_MAX_BKTS, /* number of buckets */
620 /* block size, no. of blocks, Upper threshold, lower threshold */
621 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
622 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
623 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
624 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
625 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
629 SS_DFLT_REGION + 7, /* region id */
630 MT_MAX_BKTS, /* number of buckets */
632 /* block size, no. of blocks, Upper threshold, lower threshold */
633 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
634 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
635 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
636 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
637 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
640 #ifndef INTEL_WLS_MEM
643 SS_DFLT_REGION + 8, /* region id */
644 MT_MAX_BKTS, /* number of buckets */
646 /* block size, no. of blocks, Upper threshold, lower threshold */
647 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
648 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
649 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
650 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
651 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
655 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
658 SS_DFLT_REGION + 7, /* region id */
659 MT_MAX_BKTS, /* number of buckets */
661 /* block size, no. of blocks, Upper threshold, lower threshold */
662 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
663 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
664 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
665 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
673 MtGlobMemCfg mtGlobMemoCfg =
675 MT_MAX_BKTS, /* number of buckets */
678 /* block size, no. of blocks, Upper threshold, lower threshold */
679 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
680 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
681 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
682 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
683 {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
685 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
686 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
687 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
688 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
692 #endif /* SS_LOCKLESS_MEMORY */
694 /* mt022.201 - Modification for memory calculator tool */
695 /* mt018.201 - added memory configuration matrix */
699 SS_MAX_REGS - 1, /* number of regions */
701 #ifndef XEON_SPECIFIC_CHANGES
702 SS_MAX_REGS, /* number of regions */
709 SS_DFLT_REGION, /* region id */
710 MT_MAX_BKTS, /* number of buckets */
711 MT_HEAP_SIZE, /* heap size */
713 #ifndef XEON_SPECIFIC_CHANGES
714 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
715 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
716 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
717 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
718 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
720 {256, 491520}, /* 60 pages of 2M*/
721 {512, 12288}, /* 3 pages of 2M */
722 {2048, 99328}, /* 97 Pages of 2M */
723 {8192, 75008}, /* 293 Pages of 2M */
724 {16384, 4096} /* 32 pages of 2M */
729 #ifndef SS_LOCKLESS_MEMORY
731 SS_DFLT_REGION + 1, /* region id */
732 MT_MAX_BKTS, /* number of buckets */
733 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
735 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
736 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
737 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
738 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
746 #endif /* SS_LOCKLESS_MEMORY */
747 #endif /* INTEL_WLS */
748 #ifdef SS_LOCKLESS_MEMORY
750 SS_DFLT_REGION + 1, /* region id */
751 MT_MAX_BKTS, /* number of buckets */
752 MT_HEAP_SIZE, /* heap size */
754 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
755 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
756 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
757 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
758 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
762 SS_DFLT_REGION + 2, /* region id */
763 MT_MAX_BKTS, /* number of buckets */
764 MT_HEAP_SIZE, /* heap size */
766 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
767 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
768 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
769 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
770 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
774 SS_DFLT_REGION + 3, /* region id */
775 MT_MAX_BKTS, /* number of buckets */
776 MT_HEAP_SIZE, /* heap size */
778 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
779 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
780 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
781 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
782 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
786 SS_DFLT_REGION + 4, /* region id */
787 MT_MAX_BKTS, /* number of buckets */
788 MT_HEAP_SIZE, /* heap size */
790 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
791 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
792 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
793 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
794 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
798 SS_DFLT_REGION + 5, /* region id */
799 MT_MAX_BKTS, /* number of buckets */
800 MT_HEAP_SIZE, /* heap size */
802 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
803 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
804 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
805 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
806 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
810 SS_DFLT_REGION + 6, /* region id */
811 MT_MAX_BKTS, /* number of buckets */
812 MT_HEAP_SIZE, /* heap size */
814 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
815 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
816 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
817 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
818 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
822 SS_DFLT_REGION + 7, /* region id */
823 MT_MAX_BKTS, /* number of buckets */
824 MT_HEAP_SIZE, /* heap size */
826 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
827 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
828 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
829 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
830 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
834 #ifndef INTEL_WLS_MEM
837 SS_DFLT_REGION + 8, /* region id */
838 MT_MAX_BKTS, /* number of buckets */
839 MT_HEAP_SIZE, /* heap size */
841 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
842 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
843 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
844 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
845 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
849 #endif /* SS_LOCKLESS_MEMORY */
853 /* mt003.301 Modifications - File Based task registration made
854 * common for both MULTICORE and NON-MULTICORE
855 * bucket info, as different regions may request for different no.
858 MtBktCfg mtBktInfo[MT_MAX_BKTS];
859 S16 msArgc; /* argc */
860 Txt **msArgv; /* argv */
861 S16 msOptInd; /* SGetOpt vars */
862 S8 *msOptArg; /* SGetOpt vars */
865 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
866 typedef struct _MtRegMemSz
872 #ifdef SS_USE_WLS_MEM
873 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
874 static S16 SPartitionWlsDynMem();
875 static S16 SAllocateWlsDynMem();
878 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
883 /* private variable declarations */
884 /* mt018.201 - change mtCMMRegCfg as array of pointers */
885 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
886 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
887 /* mt003.301 - Fixed compilation warnings */
888 /*mt004.301-addede new veriable for FAP*/
889 /*mt010.301 - removed veriable defined for FA*/
892 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
895 void mtSetNtlHdl(unsigned int hdl)
900 unsigned int mtGetNtlHdl()
902 return(osCp.ntl.hdl);
906 void mtGetWlsHdl(void **hdlr)
908 *hdlr = osCp.wls.intf;
911 #ifdef XEON_MULTIPLE_CELL_CHANGES
912 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
913 S16 smWrReadWlsConfigParams (Void);
916 /*WLS Memory Size variables*/
917 #ifdef INTEL_L1_V20_03_ONWARDS
918 uint64_t nWlsMacMemorySize = 0;
919 uint64_t nWlsPhyMemorySize = 0;
922 static int SOpenWlsIntf()
926 #define WLS_DEVICE_NAME "wls"
928 char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", "wls", "--iova-mode=pa"};
929 printf("\nCalling rte_eal_init: ");
930 for (i = 0; i < RTE_DIM(my_argv); i++)
932 printf("%s ", my_argv[i]);
936 if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
937 rte_panic("\nCannot init EAL\n");
940 #ifdef XEON_SPECIFIC_CHANGES
941 #ifdef XEON_MULTIPLE_CELL_CHANGES
942 hdl = WLS_Open(gWrWlsDeviceName, 1);
944 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
948 #ifdef INTEL_L1_V20_03_ONWARDS
949 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, &nWlsMacMemorySize, &nWlsPhyMemorySize);
952 printf("\nERROR: WLS_Open > DEVICE_NAME mismatch. WLS Device Name should be same as 'wls_dev_name' parameter in 'phycfg_xran.xml' file");
955 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
956 #endif /*INTEL_L1_V20_03_ONWARDS*/
964 printf("\nCould not open WLS Interface \n");
979 * Desc: This function is the entry point for the final binary. It
980 * calls SInit() in the common code. It can be replaced by a
981 * user function if required (SInit() must still be called).
983 * Ret: none on success
993 int argc, /* argument count */
994 char **argv /* argument vector */
998 #ifdef XEON_MULTIPLE_CELL_CHANGES
999 /* Read the WLS parameters from the file and copy into global control block */
1000 if(smWrReadWlsConfigParams() != ROK)
1002 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
1004 } /* end of if statement */
1007 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
1010 #endif /* INTEL_WLS */
1014 /* mt003.301 Modifications */
1017 printf("\n SInit failed, SSI could not start \n");
1018 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
1022 /*mt010.301 cleanup part exposed to user*/
1033 * Desc: This function is the entry point for the final binary. It
1034 * calls SInit() in the common code. It can be replaced by a
1035 * user function if required (SInit() must still be called).
1037 * Ret: none on success
1047 int argc, /* argument count */
1048 char **argv /* argument vector */
1064 * initialization functions
1069 * Fun: Initialize OS control point
1071 * Desc: This function initializes MTSS-specific information
1072 * in the OS control point.
1081 S16 ssdInitGen(void)
1083 struct sigaction act;
1085 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1086 struct sigaction sa;
1090 /*mt014.301 : 4GMX release related changes*/
1091 #ifdef SS_4GMX_UCORE
1094 /* mt005.301 : Cavium changes */
1095 #ifdef SS_SEUM_CAVIUM
1096 /* set group mask for the core */
1097 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
1098 #endif /* SS_SEUM_CAVIUM */
1100 osCp.dep.sysTicks = 0;
1102 /* mt020.201 - Addition for no command line available */
1104 /* parse command line */
1106 /* mt003.301 Additions */
1107 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
1109 printf("\n File Based Memory configuration failed \n");
1114 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
1115 #ifndef SS_LOCKLESS_MEMORY
1116 #ifdef SS_MULTICORE_SUPPORT
1117 if(memConfigured == FALSE)
1123 /* initialize the started semaphore */
1124 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1129 /* mt028.201 added compile time flag to allow not to mask signals */
1131 /* mask all signals in the main thread */
1133 sigdelset(&set, SIGINT);
1134 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1135 sigdelset(&set, SIGSEGV);
1136 sigdelset(&set, SIGUSR2);
1137 sigdelset(&set, SIGILL);
1138 #ifdef XEON_SPECIFIC_CHANGES
1139 sigdelset(&set, SIGABRT);
1140 sigdelset(&set, SIGTERM);
1141 sigdelset(&set, SIGHUP);
1144 pthread_sigmask(SIG_SETMASK, &set, NULLP);
1145 #endif /* UNMASK_SIG */
1147 /* install a SIGINT handler to shutdown */
1148 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1150 /*Initialize SIGSEGV Signal */
1151 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1153 memset(&sa, 0, sizeof(struct sigaction));
1154 sigemptyset(&sa.sa_mask);
1155 sa.sa_sigaction = signal_segv;
1156 sa.sa_flags = SA_SIGINFO;
1157 #ifndef XEON_SPECIFIC_CHANGES
1158 sigaction(SIGSEGV, &sa, NULL);
1160 memset(&sa, 0, sizeof(struct sigaction));
1161 sigemptyset(&sa.sa_mask);
1162 sa.sa_sigaction = signal_segv;
1163 sa.sa_flags = SA_SIGINFO;
1165 sigaction(SIGILL, &sa, NULL);
1167 if(sigaction(SIGILL, &sa, NULL) != 0)
1169 printf("\nFailed to process sigaction for the SIGILL\n");
1172 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1174 printf("\nFailed to process sigaction for the SIGSEGV\n");
1177 if(sigaction(SIGABRT, &sa, NULL) != 0)
1179 printf("\nFailed to process sigaction for the SIGABRT\n");
1182 if(sigaction(SIGTERM, &sa, NULL) != 0)
1184 printf("\nFailed to process sigaction for the SIGTERM\n");
1187 if(sigaction(SIGHUP, &sa, NULL) != 0)
1189 printf("\nFailed to process sigaction for the SIGHUP\n");
1194 signal (SIGSEGV, mtSigSegvHndlr);
1195 signal (SIGKILL, mtSigSegvHndlr);
1196 signal (SIGUSR2, mtSigUsr2Hndlr);
1201 signal (SIGINT, mtStopHndlr);
1204 act.sa_handler = mtIntSigHndlr;
1205 sigfillset(&act.sa_mask);
1207 if (sigaction(SIGINT, &act, NULLP) != 0)
1213 /* mt040.201 initialise random seed */
1214 osCp.dep.randSeed = time(NULLP);
1222 * Fun: De-initialize OS control point
1224 * Desc: This function reverses the initialization in ssdInitGen().
1233 Void ssdDeinitGen(void)
1237 sem_destroy(&osCp.dep.ssStarted);
1242 #ifdef SS_LOCKLESS_MEMORY
1246 * Fun: ssPutDynMemBlkSet
1248 * Desc: Returns the set of dynamic Blocks into the global region
1251 * Ret: ROK - successful,
1252 * RFAILED - unsuccessful.
1259 S16 ssPutDynMemBlkSet
1261 uint8_t bktIdx, /* Index to bucket list */
1262 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1263 added to global region */
1266 CmMmGlobRegCb *globReg;
1267 CmMmGlobalBktCb *bktCb;
1271 globReg = osCp.globRegCb;
1273 #if (ERRCLASS & ERRCLS_INT_PAR)
1274 if(bktIdx >= globReg->numBkts)
1278 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1280 bktCb = &(globReg->bktTbl[bktIdx]);
1282 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1284 blkPtr = dynMemSetElem->nextBktPtr;
1285 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1286 free((Void *)blkPtr);
1289 dynMemSetElem->nextBktPtr = NULLP;
1290 dynMemSetElem->numFreeBlks = 0;
1297 * Fun: ssGetDynMemBlkSet
1299 * Desc: Gets the set of dynamic memory blocks from the global region
1302 * Ret: ROK - successful,
1303 * RFAILED - unsuccessful.
1310 S16 ssGetDynMemBlkSet
1312 uint8_t bktIdx, /* Index to bucket list */
1313 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1314 with new set values */
1318 CmMmGlobRegCb *globReg;
1319 CmMmGlobalBktCb *bktCb;
1324 globReg = osCp.globRegCb;
1326 #if (ERRCLASS & ERRCLS_INT_PAR)
1327 if(bktIdx >= globReg->numBkts)
1331 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1333 bktCb = &(globReg->bktTbl[bktIdx]);
1334 basePtr = &(dynMemSetElem->nextBktPtr);
1336 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1338 blkPtr = (Data *)malloc(bktCb->size);
1340 basePtr = (CmMmEntry **)blkPtr;
1343 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1347 } /* ssGetDynMemBlkSet */
1352 * Fun: ssPutDynMemBlkSet
1354 * Desc: Returns the set of dynamic Blocks into the global region
1357 * Ret: ROK - successful,
1358 * RFAILED - unsuccessful.
1365 S16 ssPutDynMemBlkSet
1367 uint8_t bktIdx, /* Index to bucket list */
1368 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1369 added to global region */
1370 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1373 CmMmGlobRegCb *globReg;
1374 CmMmGlobalBktCb *bktCb;
1376 CmMmBlkSetElement *globMemNode;
1380 globReg = osCp.globRegCb;
1382 #if (ERRCLASS & ERRCLS_INT_PAR)
1383 if(bktIdx >= globReg->numBkts)
1387 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1389 bktCb = &(globReg->bktTbl[bktIdx]);
1391 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1392 try lock is used as it is not required to block as it will be taken
1393 in the next go else it will be blocked for lock as we have to get the
1396 SLock(&(bktCb->bucketLock));
1402 /* Get a free node from the free node linked list */
1403 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1404 if(lstNode == NULLP)
1406 SUnlock(&(bktCb->bucketLock));
1410 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1412 /* Copy the content of the received element information on to free node
1413 * and add it to valid linked list */
1414 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1415 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1416 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1417 dynMemSetElem->numFreeBlks = 0;
1418 dynMemSetElem->nextBktPtr = NULLP;
1420 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1422 SUnlock(&(bktCb->bucketLock));
1430 * Fun: ssGetDynMemBlkSet
1432 * Desc: Gets the set of dynamic memory blocks from the global region
1435 * Ret: ROK - successful,
1436 * RFAILED - unsuccessful.
1438 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1444 S16 ssGetDynMemBlkSet
1446 uint8_t bktIdx, /* Index to bucket list */
1447 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1448 with new set values */
1449 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1452 CmMmGlobRegCb *globReg;
1453 CmMmGlobalBktCb *bktCb;
1455 CmMmBlkSetElement *globMemNode;
1459 globReg = osCp.globRegCb;
1461 #if (ERRCLASS & ERRCLS_INT_PAR)
1462 if(bktIdx >= globReg->numBkts)
1466 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1468 bktCb = &(globReg->bktTbl[bktIdx]);
1470 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1471 try lock is used as it is not required to block as it will be taken
1472 in the next go else it will be blocked for lock as we have to get the
1475 SLock(&(bktCb->bucketLock));
1480 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1482 if(lstNode == NULLP)
1484 SUnlock(&(bktCb->bucketLock));
1488 /* Delete the node from the valid linked list and copy the values of the
1489 * elements of structrues into pointer */
1490 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1491 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1492 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1493 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1495 /* Add this node to the free node linked list */
1496 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1498 SUnlock(&(bktCb->bucketLock));
1502 } /* ssGetDynMemBlkSet */
1505 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1506 uint32_t gDynMemAlrm[4];
1507 static uint32_t memoryCheckCounter;
1509 uint32_t isMemThreshReached(Region reg)
1511 CmMmGlobRegCb *globReg;
1512 CmMmGlobalBktCb *bktCb;
1513 uint8_t bktIdx= reg;
1515 globReg = osCp.globRegCb;
1517 #if (ERRCLASS & ERRCLS_INT_PAR)
1518 if(bktIdx >= globReg->numBkts)
1522 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1524 bktCb = &(globReg->bktTbl[bktIdx]);
1526 if(gDynMemAlrm[bktIdx])
1528 // printf ("\nunder memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1529 SLock(&(bktCb->bucketLock));
1530 if(bktCb->listValidBktSet.count > 25)
1532 gDynMemAlrm[bktIdx] = FALSE;
1533 // printf ("\nrecoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1535 SUnlock(&(bktCb->bucketLock));
1541 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1543 // printf ("\nCHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1544 SLock(&(bktCb->bucketLock));
1545 if(bktCb->listValidBktSet.count < 15 )
1546 gDynMemAlrm[bktIdx] = TRUE;
1547 memoryCheckCounter = 0;
1548 SUnlock(&(bktCb->bucketLock));
1554 #endif /* USE_MALLOC */
1555 #endif /* SS_LOCKLESS_MEMORY */
1557 #ifdef SS_USE_ICC_MEMORY
1560 * Fun: Initialize region/pool tables
1562 * Desc: This function initializes MTSS-specific information
1563 * in the region/pool tables and configures the common
1564 * memory manager for use.
1573 Void * ssGetIccHdl(Region region)
1575 CmMmDynRegCb *dynRegCb;
1577 /* Klock work fix ccpu00148484 */
1578 if(!(region < SS_MAX_REGS))
1583 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1585 return (dynRegCb->iccHdl);
1587 #endif /* SS_USE_ICC_MEMORY */
1589 #ifdef T2K_MEM_LEAK_DBG
1590 RegionMemLeakInfo regMemLeakInfo;
1591 #endif /* T2K_MEM_LEAK_DBG */
1593 #ifdef SS_USE_WLS_MEM
1594 static S16 SPartitionWlsDynMem()
1597 uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1599 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1601 mtDynMemSz[i].startAddr = bktMemStrtAddr;
1602 bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1605 printf("\nGlobal Memory Info: \n");
1606 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1608 printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1613 static S16 SAllocateWlsDynMem()
1618 memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1620 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1622 reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1623 mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1625 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1626 #ifdef INTEL_L1_V20_03_ONWARDS
1627 nWlsMacMemorySize+nWlsPhyMemorySize);
1628 #elif INTEL_L1_V19_10
1631 (reqdMemSz + (4 * 1024 * 1024)));
1633 printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1634 SPartitionWlsDynMem();
1642 S16 SPartitionWlsMemory()
1647 uint64_t pageSize[1], hugePageSize;
1650 long int pageSize[1], hugePageSize;
1653 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1655 uint8_t *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1657 gethugepagesizes(pageSize,1);
1658 hugePageSize = pageSize[0];
1659 for (i = 0; i < 1; i++)
1661 mtRegMemSz[i].startAddr = regMemStrtAddr;
1662 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1664 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1665 reqdSz = numHugePg * hugePageSize;
1666 regMemStrtAddr += reqdSz;
1667 #ifdef T2K_MEM_LEAK_DBG
1668 /* Since wls is region 0 */
1669 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1670 regMemLeakInfo.numActvRegions++;
1671 #endif /* T2K_MEM_LEAK_DBG */
1673 //Store last region addr for validation
1674 mtRegMemSz[i].startAddr = regMemStrtAddr;
1678 #ifdef SS_MEM_WL_DEBUG
1679 Void SChkAddrValid(int type, int region, PTR ptr)
1681 char *tryPtr = NULL;
1682 if(type == 0) //Global
1684 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1685 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1687 printf("\n****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1693 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1695 printf("\n****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1701 #endif /* SS_MEM_WL_DEBUG */
1703 S16 SPartitionStaticMemory(uint8_t *startAddr)
1708 uint8_t *regMemStrtAddr = (uint8_t *)startAddr;
1711 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1712 for (i = 1; i < mtMemoCfg.numRegions; i++)
1714 mtRegMemSz[i].startAddr = regMemStrtAddr;
1715 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1716 regMemStrtAddr += reqdSz;
1717 #ifdef T2K_MEM_LEAK_DBG
1718 { /* Since region 1 onwards are used for non wls */
1719 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1720 regMemLeakInfo.numActvRegions++;
1722 #endif /* T2K_MEM_LEAK_DBG */
1726 S16 SAllocateWlsMem()
1734 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1735 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1737 for (i = 0; i < 1; i++)
1739 /* allocate space for the region */
1740 region = &mtMemoCfg.region[i];
1741 reqdMemSz += region->heapsize;
1742 mtRegMemSz[i].reqdSz += region->heapsize;
1744 for (j = 0; j < region->numBkts; j++)
1746 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1747 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1750 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1751 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1753 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1755 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1757 SPartitionWlsMemory();
1760 S16 SAllocateStaticMem()
1769 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1771 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1772 for (i = 1; i < mtMemoCfg.numRegions; i++)
1774 /* allocate space for the region */
1775 region = &mtMemoCfg.region[i];
1776 reqdMemSz += region->heapsize;
1777 mtRegMemSz[i].reqdSz += region->heapsize;
1779 for (j = 0; j < region->numBkts; j++)
1781 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1782 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1786 startAddr = malloc(reqdMemSz + (1024 * 10));
1788 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1790 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1792 SPartitionStaticMemory(startAddr);
1795 #endif /* INTEL_WLS */
1801 * Fun: Initialize region/pool tables
1803 * Desc: This function initializes MTSS-specific information
1804 * in the region/pool tables and configures the common
1805 * memory manager for use.
1814 S16 ssdInitMem(void)
1816 /* mt018.201 - added local variable */
1820 MtRegCfg *region = NULLP;
1821 Txt errMsg[256] = {'\0'};
1822 #ifdef SS_LOCKLESS_MEMORY
1823 CmMmDynRegCb *dynRegCb =0;
1824 #ifdef SS_USE_ICC_MEMORY
1826 CmMmGlobRegCb *globReg = NULLP;
1829 #endif /* SS_LOCKLESS_MEMORY */
1832 /* Use the default SSI memory manager if the ICC memory manager is not
1833 * avilable. If ICC memory manager is avilable, it will be used for
1834 * all sharable memory allocation and de-allocation */
1835 #ifdef SS_LOCKLESS_MEMORY
1836 #ifdef SS_USE_ICC_MEMORY
1837 #ifndef YS_PHY_3_8_2
1839 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1841 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1842 if(dynRegCb == NULLP)
1846 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1848 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1850 dynRegCb->region = i;
1851 cmMmDynRegInit(dynRegCb);
1852 printf("\niccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1855 /* ysIccHdl = dynRegCb->iccHdl; */
1858 /* Initialize the global region first */
1859 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1861 if(osCp.globRegCb == NULLP)
1866 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1868 #ifdef SS_USE_WLS_MEM
1869 SAllocateWlsDynMem();
1872 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1874 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1875 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1876 globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1877 printf("\nStarting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1880 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1882 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1885 if(globReg->bktTbl[i].startAddr == NULLP)
1889 globReg->bktTbl[i].poolId = i;
1890 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1891 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1892 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1895 globReg->numBkts = mtGlobMemoCfg.numBkts;
1896 cmMmGlobRegInit(globReg);
1898 /* Initialize the dynamic task regions and sanity check for the theshold
1900 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1902 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1903 if(dynRegCb == NULLP)
1907 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1909 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1910 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1911 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1912 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1914 #ifdef XEON_SPECIFIC_CHANGES
1919 dynRegCb->bktTbl[k].poolId = k;
1920 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1921 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1922 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1923 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1924 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1926 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1929 dynRegCb->region = i;
1930 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1931 cmMmDynRegInit(dynRegCb);
1933 #endif /* SS_USE_ICC_MEMORY */
1934 #endif /* SS_LOCKLESS_MEMORY */
1936 #ifdef T2K_MEM_LEAK_DBG
1938 /* Initailize mem leak tool memorys for debguing */
1939 regMemLeakInfo.numActvRegions=0;
1940 for(reg=0; reg <SS_MAX_REGS; reg++)
1942 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1943 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1944 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1945 regMemLeakInfo.regStartAddr[reg] = 0;
1948 regMemLeakInfo.regStartAddr[reg] = 0;
1949 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1951 printf("\n mutex init failed\n");
1957 /* Now allocate WLS memory */
1959 SAllocateStaticMem();
1961 /* mt018.201 - CMM Initialization */
1962 for (i = 0; i < mtMemoCfg.numRegions; i++)
1964 /* allocate space for the region control block */
1965 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1966 #ifdef TENB_RTLIN_CHANGES
1967 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1969 if (mtCMMRegCb[i] == NULLP)
1971 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1972 for the Region:%d control block\n",i);
1974 for (k = 0; k < i; k++)
1976 cmMmRegDeInit(mtCMMRegCb[k]);
1977 free(mtCMMRegCfg[k]->vAddr);
1978 free(mtCMMRegCb[k]);
1979 free(mtCMMRegCfg[k]);
1984 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1985 #ifdef TENB_RTLIN_CHANGES
1986 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1988 if (mtCMMRegCfg[i] == NULLP)
1990 for (k = 0; k < i; k++)
1992 cmMmRegDeInit(mtCMMRegCb[k]);
1993 free(mtCMMRegCfg[k]->vAddr);
1994 free(mtCMMRegCb[k]);
1995 free(mtCMMRegCfg[k]);
1997 free(mtCMMRegCb[i]);
2002 /* allocate space for the region */
2003 region = &mtMemoCfg.region[i];
2004 mtCMMRegCfg[i]->size = region->heapsize;
2005 for (j = 0; j < region->numBkts; j++)
2007 /* mt033.201 - addition for including the header size while computing the total size */
2008 #ifdef SSI_DEBUG_LEVEL1
2009 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
2010 (region->bkt[j].numBlks);
2012 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
2013 #endif /* SSI_DEBUG_LEVEL1 */
2016 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
2018 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
2021 #ifdef XEON_SPECIFIC_CHANGES
2022 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
2023 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
2025 #ifdef TENB_RTLIN_CHANGES
2026 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
2029 if (mtCMMRegCfg[i]->vAddr == NULLP)
2031 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
2032 for the Region:%d \n",i);
2034 for (k = 0; k < i; k++)
2036 cmMmRegDeInit(mtCMMRegCb[k]);
2037 free(mtCMMRegCfg[k]->vAddr);
2038 free(mtCMMRegCb[k]);
2039 free(mtCMMRegCfg[k]);
2041 free(mtCMMRegCb[i]);
2042 free(mtCMMRegCfg[i]);
2047 /* set up the CMM configuration structure */
2048 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
2049 mtCMMRegCfg[i]->chFlag = 0;
2050 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
2051 mtCMMRegCfg[i]->numBkts = region->numBkts;
2053 for (j = 0; j < region->numBkts; j++)
2055 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
2056 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
2059 /* initialize the CMM */
2060 #ifdef SS_LOCKLESS_MEMORY
2061 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2063 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2064 #endif /* SS_LOCKLESS_MEMORY */
2066 for (k = 0; k < i; k++)
2068 cmMmRegDeInit(mtCMMRegCb[k]);
2069 free(mtCMMRegCfg[k]->vAddr);
2070 free(mtCMMRegCb[k]);
2071 free(mtCMMRegCfg[k]);
2073 free(mtCMMRegCfg[i]->vAddr);
2074 free(mtCMMRegCb[i]);
2075 free(mtCMMRegCfg[i]);
2080 /* initialize the STREAMS module */
2081 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
2082 if (region->regionId == 0)
2084 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
2086 for (k = 0; k < i; k++)
2088 cmMmRegDeInit(mtCMMRegCb[k]);
2089 free(mtCMMRegCfg[k]->vAddr);
2090 free(mtCMMRegCb[k]);
2091 free(mtCMMRegCfg[k]);
2093 cmMmRegDeInit(mtCMMRegCb[i]);
2094 free(mtCMMRegCfg[i]->vAddr);
2095 free(mtCMMRegCb[i]);
2096 free(mtCMMRegCfg[i]);
2101 /* mt001.301 : Additions */
2102 #ifdef SS_MEM_LEAK_STS
2104 #endif /* SS_MEM_LEAK_STS */
2112 * Fun: De-initialize region/pool tables
2114 * Desc: This function reverses the initialization in ssdInitMem().
2123 Void ssdDeinitMem(void)
2125 /* mt018.201 - added local variables */
2128 /* mt008.301 Additions */
2129 #ifdef SS_MEM_LEAK_STS
2130 cmDeinitMemLeakMdl();
2131 #endif /* SS_MEM_LEAK_STS */
2133 for (i = 0; i < mtMemoCfg.numRegions; i++)
2135 cmMmRegDeInit(mtCMMRegCb[i]);
2136 free(mtCMMRegCfg[i]->vAddr);
2137 free(mtCMMRegCb[i]);
2138 free(mtCMMRegCfg[i]);
2147 * Fun: Initialize task table
2149 * Desc: This function initializes MTSS-specific information
2150 * in the task table.
2159 S16 ssdInitTsk(void)
2161 /* mt001.301 : Additions */
2162 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2163 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2164 uint32_t tskInd = 0;
2165 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2169 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2170 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2171 /* initialize system task information */
2172 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2174 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2176 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2183 * Fun: Deinitialize task table
2185 * Desc: This function reverses the initialization perfomed in
2195 Void ssdDeinitTsk(void)
2202 #ifdef SS_DRVR_SUPPORT
2205 * Fun: Initialize driver task table
2207 * Desc: This function initializes MTSS-specific information
2208 * in the driver task table.
2217 S16 ssdInitDrvr(void)
2221 pthread_attr_t attr;
2226 /* initialize the dependent portion of the driver task entries */
2227 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2229 osCp.drvrTskTbl[i].dep.flag = FALSE;
2233 /* create pipe for communication between SSetIntPend() and
2234 * the isTskHdlr thread.
2236 if (pipe(osCp.dep.isFildes) != 0)
2242 /* create the isTskHdlr thread */
2243 pthread_attr_init(&attr);
2244 /* mt021.201 - Addition to set stack size */
2245 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2246 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2247 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2248 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2250 /* mt020.201 - Addition for destroying thread attribute object attr */
2251 pthread_attr_destroy(&attr);
2257 /*mt014.301 : 4GMX release related changes*/
2258 #ifdef SS_4GMX_UCORE
2266 /* mt020.201 - Addition for destroying thread attribute object attr */
2267 pthread_attr_destroy(&attr);
2276 * Fun: Deinitialize driver information
2278 * Desc: This function reverses the initialization performed in
2288 Void ssdDeinitDrvr(void)
2290 /* mt008.301: Terminate the Driver Task on exit */
2291 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2294 TL_Close(AppContext.hUAII);
2295 if (clusterMode == RADIO_CLUSTER_MODE)
2297 TL_Close(AppContext.hUAII_second);
2303 #endif /* SS_DRVR_SUPPORT */
2308 * Fun: Initialize timer table
2310 * Desc: This function initializes MTSS-specific information
2311 * in the timer table.
2320 S16 ssdInitTmr(void)
2322 pthread_attr_t attr;
2323 struct sched_param param_sched;
2324 /* mt010.21: addition */
2326 #ifdef SS_MULTICORE_SUPPORT
2328 #endif /* SS_MULTICORE_SUPPORT */
2329 #ifdef SS_THR_REG_MAP
2330 uint32_t threadCreated = FALSE;
2331 #endif /* SS_THR_REG_MAP */
2335 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2336 /* mt010.21: addition */
2337 osCp.dep.tmrTqCp.nxtEnt = 0;
2338 for (i=0; i< SS_MAX_TMRS; i++)
2340 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2343 #ifdef SS_MULTICORE_SUPPORT
2344 sTsk = ssdAddTmrSTsk();
2349 #endif /* SS_MULTICORE_SUPPORT */
2350 /* create the timer handler thread */
2351 pthread_attr_init(&attr);
2352 /* mt021.201 - Addition to set stack size */
2353 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2354 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2355 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2356 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2357 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2358 pthread_attr_setschedparam(&attr, ¶m_sched);
2361 #ifdef SS_THR_REG_MAP
2362 /* When the thread is created, we check for the memory mapping table if
2363 * threadId can be placed in thread memory map table. If it is not able to place
2364 * threadId is stored in tmporary array. Once thread is created successful,
2365 * thread_cancel is sent for each thread which are created before. All the
2366 * threads are made to wait on sema which is cancel point for thread.
2368 while(threadCreated == FALSE)
2371 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2373 /* mt020.201 - Addition for destroying thread attribute object attr */
2374 pthread_attr_destroy(&attr);
2379 #ifdef SS_THR_REG_MAP
2380 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2383 #endif /* SS_THR_REG_MAP */
2384 #ifdef SS_MEM_WL_DEBUG
2385 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2388 /* mt020.201 - Addition for destroying thread attribute object attr */
2389 pthread_attr_destroy(&attr);
2398 * Fun: Deinitialize timer table
2400 * Desc: This function reverses the initialization performed in
2410 Void ssdDeinitTmr(void)
2412 #ifdef SS_MULTICORE_SUPPORT
2415 #endif /* SS_MULTICORE_SUPPORT */
2418 #ifdef SS_MULTICORE_SUPPORT
2419 ret = SLock(&osCp.sTskTblLock);
2423 #if (ERRCLASS & ERRCLS_DEBUG)
2424 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2425 "Could not lock system task table");
2429 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2430 /* clean up the system task entry */
2434 SDestroyLock(&sTsk->lock);
2435 ssDestroyDmndQ(&sTsk->dQ);
2438 /* make this entry available in the system task table */
2439 sTsk->nxt = osCp.nxtSTskEntry;
2440 osCp.nxtSTskEntry = 0;
2444 /* unlock the system task table */
2445 SUnlock(&osCp.sTskTblLock);
2447 #endif /* SS_MULTICORE_SUPPORT */
2448 /* mt008.301: Terminate the timer thread on exit */
2449 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2459 * Desc: Pre-tst() initialization.
2468 S16 ssdInitLog(void)
2470 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2474 pthread_attr_t attr;
2477 #endif /* CONSTDIO */
2482 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2487 osCp.dep.conInFp = (FILE *) stdin;
2488 osCp.dep.conOutFp = (FILE *) stdout;
2489 /* added compile time flag CONRD: mt017.21 */
2493 /* disable canonical input processing */
2494 fd = fileno(osCp.dep.conInFp);
2495 if ((tcgetattr(fd, &tio)) != 0)
2497 printf("\nError: disable canonical input processing\n");
2501 tio.c_lflag &= ~ICANON;
2502 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2503 tio.c_cc[VTIME] = 0;
2504 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2506 printf("\nError: while tcsetattr() processing\n");
2510 #endif /* CONSTDIO */
2513 /* set up the input fd to block when no data is available */
2514 fd = fileno(osCp.dep.conInFp);
2515 flags = fcntl(fd, F_GETFL, &flags);
2516 flags &= ~O_NONBLOCK;
2517 if (fcntl(fd, F_SETFL, flags) == -1)
2519 printf("\nError: while fcntl processing\n");
2524 /* create the console handler thread */
2525 pthread_attr_init(&attr);
2526 /* mt021.201 - Addition to set stack size */
2527 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2528 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2529 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2532 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2534 /* mt020.201 - Addition for destroying thread attribute object attr */
2535 pthread_attr_destroy(&attr);
2537 printf("\nError: Logging Thread creation failed \n");
2541 /* mt020.201 - Addition for destroying thread attribute object attr */
2542 pthread_attr_destroy(&attr);
2556 * Desc: This function reverses the initialization performed in
2566 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2567 Void ssdDeinitLog(void)
2569 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2572 /* mt008.301: Terminate the console reader on exit */
2573 while(pthread_cancel(osCp.dep.conHdlrTID));
2579 /* mt001.301 : Additions */
2583 S16 ssdInitWatchDog(uint16_t port)
2586 Txt prntBuf[PRNTSZE];
2589 #ifdef SS_WATCHDOG_IPV6
2590 struct sockaddr_in6 tmpaddr;
2592 struct sockaddr_in tmpaddr;
2593 #endif /* SS_WATCHDOG_IPV6 */
2594 #ifdef SS_MULTIPLE_PROCS
2595 ProcId procId = SS_WD_WDPROC;
2596 if (SAddProcIdLst(1, &procId) != ROK)
2600 #endif /* SS_MULTIPLE_PROCS */
2603 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2605 /* Create a watch dog system task */
2606 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2608 /* Create a watch dog reveiver system task */
2609 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2611 /* Register and attach watch dog TAPA task */
2612 #ifdef SS_MULTIPLE_PROCS
2613 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2614 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2616 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2617 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2618 #endif /* SS_MULTIPLE_PROCS */
2619 /* Register and attach watch dog receiver TAPA task */
2620 #ifdef SS_MULTIPLE_PROCS
2621 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2622 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2624 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2625 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2626 #endif /* SS_MULTIPLE_PROCS */
2628 #ifndef SS_MULTIPLE_PROCS
2629 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2630 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2632 osCp.wdCp.watchDgPst.srcProcId = procId;
2633 osCp.wdCp.watchDgPst.dstProcId = procId;
2634 #endif /* SS_MULTIPLE_PROCS */
2636 /* Initialise the pst structure */
2637 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2638 /* Initialize the watch dog timer resolution default is 1 sec */
2640 cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2641 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2642 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2643 for(idx = 0; idx < 1; idx++)
2645 osCp.wdCp.watchDgTs[idx].first = NULLP;
2646 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2648 #ifdef SS_MULTIPLE_PROCS
2649 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2651 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2652 #endif /* SS_MULTIPLE_PROCS */
2654 /* Create the watch dog receiver socket */
2655 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2656 if(osCp.wdCp.globWd.sock == -1)
2658 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2662 #ifdef SS_WATCHDOG_IPV6
2663 tmpaddr.sin6_len = sizeof(tmpadDr);
2664 tmpaddr.sin6_family = AF_INET6;
2665 tmpaddr.sin6_addr = in6addr_any;
2666 tmpaddr.sin6_port = htons(port);
2668 tmpaddr.sin_family = AF_INET;
2669 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2670 tmpaddr.sin_port = htons(port);
2671 #endif /* SS_WATCHDOG_IPV6 */
2673 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2676 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2680 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2684 #ifndef SS_MULTIPLE_PROCS
2685 pst.srcProcId = SFndProcId();
2686 pst.dstProcId = SFndProcId();
2688 pst.srcProcId = procId;
2689 pst.dstProcId = procId;
2690 #endif /* SS_MULTIPLE_PROCS */
2691 pst.event = EVTSSHRTBTREQ;
2692 ssdInitWatchDgPst(&pst);
2693 SPstTsk(&pst, mBuf);
2698 S16 ssdInitWatchDgPst(Pst *pst)
2701 pst->selector = SS_LOOSE_COUPLING;
2703 pst->region = DFLT_REGION; /* region */
2704 pst->pool = DFLT_POOL; /* pool */
2706 pst->prior = PRIOR0; /* priority */
2707 pst->route = RTESPEC; /* route */
2709 pst->dstEnt = ENTHB; /* destination entity */
2711 pst->srcEnt = ENTDW; /* source entity */
2717 #ifdef SS_MULTIPLE_PROCS
2718 S16 ssdWatchDgActvTmr
2725 S16 ssdWatchDgActvTmr(Void)
2726 #endif /* SS_MULTIPLE_PROCS */
2729 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2734 Void ssdWatchDgTmrEvt
2736 PTR cb, /* control block */
2737 S16 event /* timer number */
2740 /* mt003.301 Fixed warings */
2744 Txt prntBuf[PRNTSZE];
2753 SPrint("Timer Heartbeat Request Expired");
2755 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2760 SLock(&osCp.wdCp.wdLock);
2761 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2763 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2765 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2767 if(osCp.wdCp.globWd.callback != 0)
2769 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2773 SUnlock(&osCp.wdCp.wdLock);
2775 if(!osCp.wdCp.globWd.watchdogStop)
2777 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2778 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2788 Void ssdStartWatchDgTmr
2799 Txt prntBuf[PRNTSZE];
2803 /* mt003.301 Modifications */
2806 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2807 if(event == SS_TMR_HRTBT)
2809 SPrint("\nSTART SS_TMR_HRTBT");
2816 SLock(&osCp.wdCp.wdLock);
2817 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2819 osCp.wdCp.globWd.wdsta[i].status = 0;
2821 SUnlock(&osCp.wdCp.wdLock);
2823 arg.tq = osCp.wdCp.watchDgTs;
2824 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2825 arg.timers = osCp.wdCp.watchDgTmr;
2826 arg.cb = (PTR)NULLP;
2828 arg.wait = osCp.wdCp.globWd.timeout = wait;
2836 Void ssdStopWatchDgTmr
2845 Txt prntBuf[PRNTSZE];
2849 /* mt003.301 Modifications */
2852 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2853 if(event == SS_TMR_HRTBT)
2855 SPrint("STOP SS_TMR_HRTBT");
2859 SLock(&osCp.wdCp.wdLock);
2860 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2862 osCp.wdCp.globWd.wdsta[i].status = 0;
2864 SUnlock(&osCp.wdCp.wdLock);
2867 arg.tq = osCp.wdCp.watchDgTs;
2868 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2869 arg.timers = osCp.wdCp.watchDgTmr;
2870 arg.cb = (PTR)NULLP;
2889 Txt prntBuf[PRNTSZE];
2891 struct sockaddr_in tmpaddr;
2892 char hbMsg[SS_WD_HB_MSG_SIZE];
2899 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2903 /* Pack the message */
2904 strcpy(hbMsg, "<HB>REQ</HB>");
2906 /* Send the heartbeat messages to all the configured nodes */
2907 SLock(&osCp.wdCp.wdLock);
2908 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2910 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2915 /* Identify the destination node */
2916 #ifdef SS_WATCHDOG_IPV6
2917 tmpaddr.sin6_len = sizeof(tmpaddr);
2918 tmpaddr.sin6_family = AF_INET6;
2919 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2920 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2922 tmpaddr.sin_family = AF_INET;
2923 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2924 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2925 #endif /* SS_WATCHDOG_IPV6 */
2927 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2931 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2932 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2939 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2944 SUnlock(&osCp.wdCp.wdLock);
2949 #endif /* SS_WATCHDOG */
2953 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2959 * Desc: This function gets command line options.
2968 static Void mtGetOpts(void)
2975 FILE *memOpt; /* memory options file pointer */
2978 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2984 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2986 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2992 #ifdef SS_LOCKLESS_MEMORY
3007 osCp.dep.fileOutFp = (FILE *)NULLP;
3009 /* initialize memOpt */
3010 memOpt = (FILE *) NULLP;
3017 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
3022 /* mt001.301 : Additions */
3023 #ifdef SS_MEM_LEAK_STS
3025 cmMemOpenMemLkFile(msOptArg);
3029 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3032 fileBasedMemCfg = TRUE;
3033 memOpt = fopen(msOptArg, "r");
3035 /* if file does not exist or could not be opened then use the
3036 * default memory configuration as defined in mt_ss.h
3038 if (memOpt == (FILE *) NULLP)
3040 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3041 be opened, using default mem configuration\n", msOptArg);
3046 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3048 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3054 case 0: /*** INPUT: Number of regions ***/
3055 sscanf(line, "%ld", (long *) &numReg);
3056 mtMemoCfg.numRegions = numReg;
3057 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3059 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3065 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3066 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3067 if(numBkts > MT_MAX_BKTS)
3069 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3073 if(numPools > SS_MAX_POOLS_PER_REG)
3075 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3080 * Delay updation from local variable to global
3081 * structure of number of regions and heap data to
3082 * counter error conditions present above.
3084 for(idx = 0; idx < cfgNumRegs; idx++)
3086 mtMemoCfg.region[idx].numBkts = numBkts;
3087 cfgRegInfo[idx].region = idx;
3088 cfgRegInfo[idx].numPools = numPools;
3090 * Initialize the pool info as static type with size zero
3092 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3094 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3095 cfgRegInfo[idx].pools[poolIdx].size = 0;
3100 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3101 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3103 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3105 if(bktIdx >= numBkts)
3107 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3112 mtBktInfo[bktIdx].blkSize = bktSz;
3114 if(bktUpdtCnt == numBkts)
3116 i++; /*done reading bkt info, start reading individual region info*/
3120 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3121 sscanf(line,"%ld",(long *) ®Id);
3122 if(regId >= mtMemoCfg.numRegions)
3124 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3125 #ifndef XEON_SPECIFIC_CHANGES
3130 mtMemoCfg.region[regId].regionId = regId;
3133 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3134 if(bktUpdtCnt < numBkts)
3136 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3137 if(bktIdx >= numBkts)
3139 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3144 if(bktIdx < MT_MAX_BKTS)
3146 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3147 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3148 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3149 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3152 if(bktUpdtCnt == numBkts)
3159 case 5: /* INPUT: Heapsize ***/
3160 sscanf(line, "%ld", (long *) &heapSz);
3161 mtMemoCfg.region[regId].heapsize = heapSz;
3163 if(regUpdtCnt != mtMemoCfg.numRegions)
3172 #ifdef SS_LOCKLESS_MEMORY
3174 sscanf(line, "%ld", (long *) &numBkts);
3175 mtGlobMemoCfg.numBkts = numBkts;
3176 #ifndef XEON_SPECIFIC_CHANGES
3177 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3180 #ifdef XEON_SPECIFIC_CHANGES
3181 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3182 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3183 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3185 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3188 mtDynMemoCfg.region[idx].regionId = idx;
3189 mtDynMemoCfg.region[idx].numBkts = numBkts;
3197 if(bktUpdtCnt < numBkts)
3199 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3200 (long *) &bktSz, (long *) &bktNum,
3201 (long *) &bktSetSize, (long *) &bktRelThr,
3202 (long *) &bktAqurThr);
3203 /* Klock work fix ccpu00148484 */
3204 if(bktIdx < SS_MAX_POOLS_PER_REG)
3206 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3207 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3208 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3209 #ifdef XEON_SPECIFIC_CHANGES
3210 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3211 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3212 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3214 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3216 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3222 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3224 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3225 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3226 #ifdef XEON_SPECIFIC_CHANGES
3227 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3228 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3229 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3235 #ifdef XEON_SPECIFIC_CHANGES
3236 if(bktUpdtCnt == numBkts)
3242 case 8: /* INPUT: Global Heapsize ***/
3243 sscanf(line, "%ld", (long *) &heapSz);
3244 mtGlobMemoCfg.heapSize = heapSz;
3245 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3253 memConfigured = FALSE;
3257 memConfigured = TRUE;
3265 /* mt028.201: modification: multiple procs support related changes */
3266 #ifndef SS_MULTIPLE_PROCS
3269 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3271 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3274 #else /* SS_MULTIPLE_PROCS */
3278 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3280 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3282 SAddProcIdLst(1, &procId);
3285 #endif /* SS_MULTIPLE_PROCS */
3289 osCp.configFilePath = msOptArg;
3313 * Desc: Get options from command line
3315 * Ret: option - success
3317 * EOF - end of options
3319 * Notes: Handles command lines like the following
3322 * then command line should look like this...
3323 * -a foo -b foo1 -c -d foo
3327 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3332 * nloops = atoi(msArgv[msOptInd]);
3335 * state1 = atoi(msArgv[msOptInd]);
3347 int argc, /* argument count */
3348 char **argv, /* argument value */
3349 char *opts /* options */
3352 /* mt020.201 - Removed for no command line */
3360 /* mt020.201 - Addition for no command line */
3372 /*mt013.301 : Changes as per coding standards*/
3373 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3379 if (!strcmp(argv[msOptInd], "--"))
3384 else if (argv[msOptInd][0] != '-')
3392 c = argv[msOptInd][sp];
3393 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3395 if (argv[msOptInd][++sp] == '\0')
3406 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3409 if (++msOptInd >= (S16) argc)
3414 else msOptArg = argv[msOptInd++];
3421 if (argv[msOptInd][++sp] == '\0')
3433 #endif /* NOCMDLINE */
3441 * Desc: This function starts system services execution; the
3442 * permanent tasks are started and the system enters a
3459 /* mt025.201 - Modification for adding lock to timer handler */
3460 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3462 sem_post(&osCp.dep.ssStarted);
3471 * indirect interface functions to system services service user
3477 * Fun: ssdAttachTTsk
3479 * Desc: This function sends the initial tick message to a TAPA
3480 * task if the task is a permanent task.
3491 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3498 if (tTsk->tskType == SS_TSK_PERMANENT)
3500 /* Send a permanent tick message to this task, to start
3503 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3506 #if (ERRCLASS & ERRCLS_DEBUG)
3507 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3512 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3513 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3515 /* set up post structure */
3516 /* mt028.201: modification: multiple procs support related changes */
3517 #ifndef SS_MULTIPLE_PROCS
3518 mInfo->pst.dstProcId = SFndProcId();
3519 mInfo->pst.srcProcId = SFndProcId();
3520 #else /* SS_MULTIPLE_PROCS */
3521 mInfo->pst.dstProcId = tTsk->proc;
3522 mInfo->pst.srcProcId = tTsk->proc;
3523 #endif /* SS_MULTIPLE_PROCS */
3524 mInfo->pst.selector = SEL_LC_NEW;
3525 mInfo->pst.region = DFLT_REGION;
3526 mInfo->pst.pool = DFLT_POOL;
3527 mInfo->pst.prior = PRIOR3;
3528 mInfo->pst.route = RTESPEC;
3529 mInfo->pst.event = 0;
3530 mInfo->pst.dstEnt = tTsk->ent;
3531 mInfo->pst.dstInst = tTsk->inst;
3532 mInfo->pst.srcEnt = tTsk->ent;
3533 mInfo->pst.srcInst = tTsk->inst;
3535 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3536 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3542 #if (ERRCLASS & ERRCLS_DEBUG)
3543 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3544 "Could not write to demand queue");
3557 * Fun: ssdDetachTTsk
3559 * Desc: Does nothing.
3570 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3580 * Fun: ssdCreateSTsk
3582 * Desc: This function creates a system task. A thread is started
3583 * on the system task handler function defined later.
3594 SsSTskEntry *sTsk /* pointer to system task entry */
3598 pthread_attr_t attr;
3599 /* struct sched_param param_sched;*/
3601 #ifdef SS_THR_REG_MAP
3602 uint32_t threadCreated = FALSE;
3607 #ifdef SS_SINGLE_THREADED
3608 /* mt001.301 : Additions */
3610 #ifdef SS_MULTICORE_SUPPORT
3611 if (osCp.numSTsks > 1)
3613 if (osCp.numSTsks > 0)
3614 #endif /* SS_MULTICORE_SUPPORT */
3616 #ifdef SS_MULTICORE_SUPPORT
3617 if (osCp.numSTsks > 3)
3619 if (osCp.numSTsks > 2)
3620 #endif /* SS_MULTICORE_SUPPORT */
3621 #endif /* SS_WATCHDOG */
3628 /* set the current executing entity and instance IDs to
3629 * 'not configured'. create the lock to access them.
3631 sTsk->dep.ent = ENTNC;
3632 sTsk->dep.inst = INSTNC;
3635 /* create the thread */
3636 pthread_attr_init(&attr);
3637 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3639 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3640 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3641 if (sTsk->tskPrior == 0)
3643 printf("\nCreating RT thread #######################\n");
3644 #ifdef SS_THR_REG_MAP
3645 /* When the thread is created, we check for the memory mapping table if
3646 * threadId can be placed in thread memory map table. If it is not able to place
3647 * threadId is stored in tmporary array. Once thread is created successful,
3648 * thread_cancel is sent for each thread which are created before. All the
3649 * threads are made to wait on sema which is cancel point for thread.
3651 while(threadCreated == FALSE)
3654 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3657 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3658 pthread_attr_destroy(&attr);
3660 #if (ERRCLASS & ERRCLS_DEBUG)
3661 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3666 #ifdef SS_THR_REG_MAP
3667 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3675 #ifdef SS_THR_REG_MAP
3676 /* When the thread is created, we check for the memory mapping table if
3677 * threadId can be placed in thread memory map table. If it is not able to place
3678 * threadId is stored in tmporary array. Once thread is created successful,
3679 * thread_cancel is sent for each thread which are created before. All the
3680 * threads are made to wait on sema which is cancel point for thread.
3682 while(threadCreated == FALSE)
3685 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3689 /* mt020.201 - Addition for destroying thread attribute object attr */
3690 pthread_attr_destroy(&attr);
3692 #if (ERRCLASS & ERRCLS_DEBUG)
3693 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3698 #ifdef SS_THR_REG_MAP
3699 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3706 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3707 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3709 static uint32_t stLwpId = 3;
3710 sTsk->dep.lwpId = ++stLwpId;
3712 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3714 /* mt020.201 - Addition for destroying thread attribute object attr */
3715 pthread_attr_destroy(&attr);
3724 pthread_attr_t* attr,
3725 void *(*start_routine) (void *),
3730 #ifdef SS_THR_REG_MAP
3731 uint32_t threadCreated = FALSE;
3734 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3735 /* Klock work fix ccpu00148484 */
3736 if(threadArg == NULLP)
3740 threadArg->argument = arg;
3741 threadArg->start_routine = start_routine;
3744 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3746 #ifdef SS_THR_REG_MAP
3747 /* When the thread is created, we check for the memory mapping table if
3748 * threadId can be placed in thread memory map table. If it is not able to place
3749 * threadId is stored in tmporary array. Once thread is created successful,
3750 * thread_cancel is sent for each thread which are created before. All the
3751 * threads are made to wait on sema which is cancel point for thread.
3753 while(threadCreated == FALSE)
3756 /*pthreadCreateHdlr */
3757 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3762 #ifdef SS_THR_REG_MAP
3763 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3774 * Fun: Set Pthread Attributes
3776 * Desc: This function is used to set various explicit
3777 * pthread attributes like, priority scheduling,etc
3787 static S16 ssdSetPthreadAttr
3790 pthread_attr_t *attr
3793 struct sched_param param;
3796 SMemSet(¶m, 0, sizeof(param));
3798 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3799 param.sched_priority = 100 - 1 - tskPrior;
3801 param.sched_priority = 100 - 10 - tskPrior;
3804 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3805 /* TODO:: This can be avoided by reducing the priority
3806 * of iccserv thread in l1_master.sh*/
3808 if (clusterMode == RADIO_CLUSTER_MODE)
3810 if(tskPrior == PRIOR1)
3812 param.sched_priority = 91;
3819 printf("\nSet priority %u\n", param.sched_priority);
3821 /* Set Scheduler to explicit, without this non of the below
3822 pthread attr works */
3823 #ifdef TENB_RTLIN_CHANGES
3824 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3827 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3828 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3829 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3830 #ifdef TENB_RTLIN_CHANGES
3831 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3833 pthread_attr_setschedparam(attr, ¶m);
3837 } /* ssdSetPthreadAttr */
3839 /************* multi-core support **************/
3840 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3841 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3845 * Fun: Get the current core/cpu affinity for a thread/lwp
3847 * Desc: This function is used to get the current processor/core
3848 * affinity for a a system task (thread/lwp). It sets the
3849 * affinity based on the mode supplied by the caller.
3852 * RFAILED - failed, general (optional)
3861 SSTskId *tskId, /* filled in with system task ID */
3862 uint32_t *coreId /* the core/processor id to which the affinity is set */
3872 uint32_t cpuInd = 0;
3873 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3876 uint32_t lwpId = *tskId;
3880 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3882 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3884 tId = osCp.sTskTbl[tskInd].dep.tId;
3889 /* if tskId is not found in the tskTbl */
3890 if (tskInd == SS_MAX_STSKS)
3892 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3897 /* initialize the cpu mask */
3900 /* set thread affinity for linux */
3901 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3903 #if (ERRCLASS & ERRCLS_DEBUG)
3904 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3907 } /* end if pthread_setaffinity fails */
3909 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3911 if (CPU_ISSET (cpuInd, & cpuSet))
3920 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3922 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3924 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3929 /* if tskId is not found in the tskTbl */
3930 if (tskInd == SS_MAX_STSKS)
3932 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3936 /* set thread affinity for Solaris */
3937 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3939 #if (ERRCLASS & ERRCLS_DEBUG)
3940 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3943 } /* end if processor_bind fails */
3946 #endif /* SS_LINUX */
3950 } /* ssdGetAffinity */
3955 * Fun: Set the core/cpu affinity for a thread/lwp
3957 * Desc: This function is used to set processor/core affinity for a
3958 * a system task (thread/lwp). It sets the affinity based on the
3959 * mode supplied by the caller.
3962 * RFAILED - failed, general (optional)
3971 SSTskId *tskId, /* filled in with system task ID */
3972 uint32_t coreId /* the core/processor id to which the affinity has to be set */
3976 uint32_t tskInd = 0;
3981 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3984 uint32_t lwpId = *tskId;
3990 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3992 /* Here tskId can not be used as index as the task may be terminated if
3993 there is a TERM even for that tsk, thus breaking the task Id numbering
3995 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3997 tId = osCp.sTskTbl[tskInd].dep.tId;
4002 /* if tskId is not found in the tskTbl */
4003 if (tskInd == SS_MAX_STSKS)
4005 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4009 /* initialize the cpu mask */
4012 /* set the cpu mask */
4013 CPU_SET(coreId, &cpuSet);
4015 /* set thread affinity for linux */
4016 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4018 #if (ERRCLASS & ERRCLS_DEBUG)
4019 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4022 } /* end if pthread_setaffinity fails */
4026 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4028 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4029 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4031 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4036 /* if tskId is not found in the tskTbl */
4037 if (tskInd == SS_MAX_STSKS)
4039 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4043 /* set thread affinity for Solaris */
4044 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4046 #if (ERRCLASS & ERRCLS_DEBUG)
4047 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4050 } /* end if processor_bind fails */
4053 #endif /* SS_LINUX */
4055 } /* ssdSetAffinity */
4057 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4058 /************ end multi-core support *************/
4063 * Fun: ssdDestroySTsk
4065 * Desc: This function destroys a system task. A terminate
4066 * event message is sent to the thread function.
4077 SsSTskEntry *sTsk /* pointer to system task entry */
4086 /* we send a message to this system task to tell it to die */
4087 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4090 #if (ERRCLASS & ERRCLASS_DEBUG)
4091 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4097 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4098 mInfo->eventInfo.event = SS_EVNT_TERM;
4100 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4104 #if (ERRCLASS & ERRCLASS_DEBUG)
4105 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4106 "Could not write to demand queue");
4116 /* mt023.201 - Added SThreadYield function to yield CPU
4120 * Desc: This function defers thread execution to any other ready
4131 S16 SThreadYield(void)
4135 /* mt024.201 - seperated Linux and other UNIX implementations
4141 /* Set sleep value to 0 to yield CPU */
4145 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4147 #else /* other UNICes */
4149 return (sleep(0) == 0 ? ROK : RFAILED);
4151 #endif /* SS_LINUX */
4158 * Fun: Register timer
4160 * Desc: This function is used to register a timer
4161 * function for the service user. System services
4162 * will invoke the timer activation function
4163 * passed to it at the specified intervals.
4167 * Notes: Timing is handled by the common timers. The
4168 * ticks are handled by a thread that uses
4169 * nanosleep() and thus timing precision will not
4177 SsTmrEntry *tmr /* pointer to timer entry */
4185 /* initialize common timers */
4186 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4189 /* start the timer */
4190 arg.tq = osCp.dep.tmrTq;
4191 arg.tqCp = &osCp.dep.tmrTqCp;
4192 arg.timers = tmr->dep.timers;
4197 arg.max = TMR_DEF_MAX;
4198 arg.wait = tmr->interval;
4208 * Fun: Deregister timer
4210 * Desc: This function is used to deregister a timer function.
4221 SsTmrEntry *tmr /* pointer to timer entry */
4229 /* stop the timer */
4230 arg.tq = osCp.dep.tmrTq;
4231 arg.tqCp = &osCp.dep.tmrTqCp;
4232 arg.timers = tmr->dep.timers;
4237 arg.max = TMR_DEF_MAX;
4238 arg.wait = tmr->interval;
4248 * Fun: Critical error
4250 * Desc: This function is called when a critical error occurs.
4261 Seq seq, /* sequence number */
4262 Reason reason /* reset reason */
4272 /* get calling task ID */
4273 tId = pthread_self();
4276 /* set up the message to display */
4277 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4278 "reason = %d\n\n", (uint8_t)tId, seq, reason);
4282 /* delete all system tasks */
4283 for (i = 0; i < SS_MAX_STSKS; i++)
4285 if (osCp.sTskTbl[i].used
4286 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4288 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4294 pthread_exit(NULLP);
4297 /* won't reach here */
4306 * Desc: This function is called to log an error.
4317 Ent ent, /* Calling layer's entity id */
4318 Inst inst, /* Calling layer's instance id */
4319 ProcId procId, /* Calling layer's processor id */
4320 Txt *file, /* file name where error occured */
4321 S32 line, /* line in file where error occured */
4322 ErrCls errCls, /* error class */
4323 ErrCode errCode, /* layer unique error code */
4324 ErrVal errVal, /* error value */
4325 Txt *errDesc /* description of error */
4338 /* get calling task ID */
4340 tId = pthread_self();
4346 case ERRCLS_ADD_RES:
4347 errClsMsg = "ERRCLS_ADD_RES";
4350 case ERRCLS_INT_PAR:
4351 errClsMsg = "ERRCLS_INT_PAR";
4355 errClsMsg = "ERRCLS_DEBUG";
4358 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4360 errClsMsg = "ERRCLS_FTHA";
4364 errClsMsg = "INVALID ERROR CLASS!";
4369 /*mt009.301 Fixed 64BIT compilation warnings*/
4372 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4373 "file: %s line: %03d errcode: %05d errcls: %s\n"
4374 "errval: %05d errdesc: %s\n",
4375 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4378 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4379 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4380 "errval: %05ld errdesc: %s\n",
4381 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4383 SDisplay(0, errBuf);
4384 /* mt001.301 : Additions */
4385 #ifdef SS_LOGGER_SUPPORT
4387 #endif /* SS_LOGGER_SUPPORT */
4391 /* debug errors halt the system */
4392 if (errCls == ERRCLS_DEBUG)
4394 /* mt001.301 : Additions */
4395 #ifdef SS_LOGGER_SUPPORT
4397 #endif /* SS_LOGGER_SUPPORT */
4398 /* delete all system tasks */
4399 for (i = 0; i < SS_MAX_STSKS; i++)
4401 if (osCp.sTskTbl[i].used
4402 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4404 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4410 pthread_exit(NULLP);
4422 * Fun: Register driver task
4424 * Desc: This function is called to register the handlers for a
4436 SsDrvrTskEntry *drvrTsk /* driver task entry */
4443 /* mt001.30 : Additions */
4446 * Fun: Deregister driver task
4448 * Desc: This function is called to deregister the handlers for a
4460 SsDrvrTskEntry *drvrTsk /* driver task entry */
4473 * mt003.301 Additions - SDeRegTTsk fix
4475 #ifdef SS_MULTIPLE_PROCS
4482 #else /*SS_MULTIPLE_PROCS*/
4488 #endif /*SS_MULTIPLE_PROCS*/
4490 #ifdef SS_MULTIPLE_PROCS
4503 /* We check the sTsk element; if it is not NULLP, the
4504 * task is attached. So we have to detach it before
4505 * deregistering the task.
4507 ret = SLock(&osCp.sTskTblLock);
4510 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4513 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4516 #if (ERRCLASS & ERRCLS_DEBUG)
4517 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4519 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4521 #if (ERRCLASS & ERRCLS_DEBUG)
4522 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4530 #ifdef SS_MULTIPLE_PROCS
4532 if (tTsk->initTsk != NULLP)
4535 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4538 &(osCp.tTskTbl[idx].xxCb));
4540 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4543 &(osCp.tTskTbl[idx].xxCb));
4544 #endif /* USE_MEMCAL */
4546 #endif /* SS_MULTIPLE_PROCS */
4548 if (tTsk->sTsk != NULLP)
4552 sTsk->dep.ent = ent;
4553 sTsk->dep.inst = inst;
4555 for (n = 0; n < SS_MAX_TTSKS; n++)
4557 if (sTsk->tTsks[n] == idx)
4559 sTsk->tTsks[n] = SS_INVALID_IDX;
4565 /* call the implementation to detach the task */
4566 ssdDetachTTsk(tTsk);
4568 sTsk->dep.ent = ENTNC;
4569 sTsk->dep.inst = INSTNC;
4572 /* Now we empty the entry for this task and update the table
4575 #ifdef SS_MULTIPLE_PROCS
4576 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4577 #else /* SS_MULTIPLE_PROCS */
4578 osCp.tTskIds[ent][inst] = SS_TSKNC;
4579 #endif /* SS_MULTIPLE_PROCS */
4582 #ifdef SS_MULTIPLE_PROCS
4583 tTsk->proc = PROCNC;
4584 #endif /* SS_MULTIPLE_PROCS */
4586 tTsk->inst = INSTNC;
4587 tTsk->tskType = TTUND;
4588 tTsk->initTsk = NULLP;
4589 tTsk->actvTsk = NULLP;
4592 tTsk->nxt = osCp.nxtTTskEntry;
4593 osCp.nxtTTskEntry = idx;
4596 #ifdef SS_MULTIPLE_PROCS
4597 /* mark the control block for this task as invalid */
4598 osCp.tTskTbl[idx].xxCb = NULLP;
4601 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4602 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4604 #if (ERRCLASS & ERRCLS_DEBUG)
4605 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4612 //#ifndef SPLIT_RLC_DL_TASK
4613 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4614 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4615 Void ysMtTskHdlr(Void);
4616 Void ysMtPollPhyMsg(uint8_t region);
4617 Void ysMtRcvPhyMsg(Void);
4618 Void *mtTskHdlrT2kL2
4620 Ptr tskPtr /* pointer to task entry */
4626 /* wait for SS to come up */
4627 /* It is required to block on this semaphore before starting actual processing of
4628 the thread becasue the creator of this thread might want to cance it without
4629 doing any processing. When this semaphore is released, means the creator gives
4630 the go ahead for actual processing and we should never come back to this point */
4631 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4640 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4641 * (processes L1 msgs) */
4647 Void ysMtTskHdlr(Void);
4648 Void YsPhyRecvMsg();
4649 Void *mtTskHdlrT2kL2
4651 Ptr tskPtr /* pointer to task entry */
4657 /* get out the system task entry from the parameter */
4658 sTsk = (SsSTskEntry *) tskPtr;
4660 /* wait for SS to come up */
4661 /* It is required to block on this semaphore before starting actual processing of
4662 the thread becasue the creator of this thread might want to cance it without
4663 doing any processing. When this semaphore is released, means the creator gives
4664 the go ahead for actual processing and we should never come back to this point */
4665 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4668 #ifndef RGL_SPECIFIC_CHANGES
4676 #ifdef V5GTF_SPECIFIC_CHANGES
4679 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4680 * (processes L1 msgs) */
4682 /* get a message from the demand queue */
4685 ret = mtTskHdlMsg(sTsk);
4688 /* exit the for loop here */
4695 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4698 void *pthreadCreateHdlr(void * arg)
4701 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4702 /* mt038.201 changed how sem_wait is called */
4703 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4706 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4714 * Desc: This is the system task handler function. It blocks on
4715 * the system task's demand queue. On receiving a message,
4716 * it identifies the target TAPA task, verifies that the
4717 * TAPA task belongs to this system task and if so, calls
4718 * the activation function of that TAPA task with the
4719 * received message. The task activation function or the
4720 * timer activation function may be called.
4722 * Ret: (thread function)
4731 Ptr tskPtr /* pointer to task entry */
4737 /* get out the system task entry from the parameter */
4738 sTsk = (SsSTskEntry *) tskPtr;
4741 /* wait for SS to come up */
4743 /* mt038.201 changed how sem_wait is called */
4744 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4746 #ifdef XEON_SPECIFIC_CHANGES
4747 printf("\n**********MT Task Handler********\n");
4751 /* Wait for a message from the demand queue */
4752 #ifdef SS_CDMNDQ_SUPPORT
4753 ret = ssCDmndQWait(&sTsk->dQ);
4755 ret = ssDmndQWait(&sTsk->dQ);
4760 ret = mtTskHdlMsg(sTsk);
4775 * Desc: This is the system task handler function. It blocks on
4776 * the system task's demand queue. On receiving a message,
4777 * it identifies the target TAPA task, verifies that the
4778 * TAPA task belongs to this system task and if so, calls
4779 * the activation function of that TAPA task with the
4780 * received message. The task activation function or the
4781 * timer activation function may be called.
4783 * Ret: (thread function)
4798 SsTTskEntry *tTsk=NULLP;
4801 Buffer *mBuf2=NULLP;
4803 SsMsgInfo *mInfo=NULLP;
4805 /* mt028.201: modification: multiple procs support related changes */
4806 #ifndef SS_MULTIPLE_PROCS
4808 PAIFTMRS16 tmrActvFnMt = NULLP;
4810 /* mt015.301 Initialized the timer activation functions with NULLP */
4811 PFS16 tmrActvFn = NULLP;
4813 PAIFTMRS16 tmrActvFn =NULLP;
4814 uint16_t procIdIdx =0;
4815 #endif /* SS_MULTIPLE_PROCS */
4816 /* mt003.301 Modifications */
4817 #ifdef SS_THREAD_PROFILE
4819 #endif /* SS_THREAD_PROFILE */
4822 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4825 /* nothing to receive */
4829 /* if we can't lock this system task entry, return the message */
4830 ret = SLock(&sTsk->lock);
4834 #if (ERRCLASS & ERRCLS_DEBUG)
4835 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4836 "Could not lock system task entry");
4846 mBuf2 = mBuf->b_next;
4848 /* find out what kind of message this is */
4849 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4850 #ifdef SS_MEM_WL_DEBUG
4851 mtTskBuffer1 = mBuf2;
4853 mtTskBuffer2 = mBuf2->b_next;
4855 if(mInfo == 0x5050505)
4859 cmAnalyseBtInfo((PTR) mBuf,4);
4861 printf("\n In trouble .... \n");
4863 else if (mInfo == 0x2020202)
4866 cmAnalyseBtInfo((PTR) mBuf,1);
4867 printf("\n In trouble .... \n");
4869 #endif /* SS_MEM_WL_DEBUG */
4870 switch (mInfo->eventInfo.event)
4872 /* this is a termination event, we die */
4874 /* release the message */
4877 /* Unlock the system task entry and lock the system
4878 * task table to clean our entry up.
4880 SUnlock(&sTsk->lock);
4882 ret = SLock(&osCp.sTskTblLock);
4886 #if (ERRCLASS & ERRCLS_DEBUG)
4887 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
4888 "Could not lock system task table");
4890 /* what to do here? */
4894 /* clean up the system task entry */
4897 /* mt003.301 Modifications - SDeRegTTsk */
4898 /* sTsk->numTTsks = 0; */
4899 SDestroyLock(&sTsk->lock);
4900 ssDestroyDmndQ(&sTsk->dQ);
4902 /* lock for current executing TAPA task ID */
4904 /* make this entry available in the system task table */
4905 sTsk->nxt = osCp.nxtSTskEntry;
4906 for (i = 0; i < SS_MAX_STSKS; i++)
4908 if (sTsk == &osCp.sTskTbl[i])
4910 osCp.nxtSTskEntry = i;
4917 /* unlock the system task table */
4918 SUnlock(&osCp.sTskTblLock);
4923 /* this is a data message or a permanent task keep-alive message */
4925 case SS_EVNT_PERMTICK:
4926 /* message to a task. find the destination task */
4927 /* mt028.201: modification: multiple procs support related changes */
4928 #ifdef SS_MULTIPLE_PROCS
4929 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
4931 if (procIdIdx == SS_INV_PROCID_IDX)
4937 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
4938 #else /* SS_MULTIPLE_PROCS */
4939 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
4940 #endif /* SS_MULTIPLE_PROCS */
4942 /* verify that it hasn't been deregistered */
4943 if (idx == SS_TSKNC)
4949 /* verify that this system task is still running it */
4950 tTsk = &osCp.tTskTbl[idx];
4951 if (tTsk->sTsk != sTsk)
4957 /* set the current executing TAPA task ID */
4958 sTsk->dep.ent = mInfo->pst.dstEnt;
4959 sTsk->dep.inst = mInfo->pst.dstInst;
4961 /* copy the Pst structure into a local duplicate */
4962 for (i = 0; i < (S16) sizeof(Pst); i++)
4963 *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
4965 /* Give the message to the task activation function. If
4966 * its a normal data message, we pass it, if this is a
4967 * keep-alive message for a permanent task then we pass
4968 * NULLP in place of the message to the task activation
4971 if (mInfo->eventInfo.event == SS_EVNT_DATA)
4973 #ifndef RGL_SPECIFIC_CHANGES
4974 #ifdef SS_TSKLOG_ENABLE
4975 uint32_t t = MacGetTick();
4978 /* mt003.301 Modifications */
4979 #if SS_THREAD_PROFILE
4980 tTsk->curEvent = nPst.event;
4982 #endif /* SS_THREAD_PROFILE */
4983 tTsk->actvTsk(&nPst, mBuf);
4984 #ifndef RGL_SPECIFIC_CHANGES
4985 #ifdef SS_TSKLOG_ENABLE
4986 SStopTask(t,PID_SSI_TSK);
4989 #if SS_THREAD_PROFILE
4991 tTsk->curEvtTime = (uint32_t)(et2 - et1);
4992 tTsk->totTime += (uint64_t)tTsk->curEvtTime;
4993 #endif /* SS_THREAD_PROFILE */
4997 #if (ERRCLASS & ERRCLS_DEBUG)
4998 /* this message should only come to a permanent task */
4999 if (tTsk->tskType != SS_TSK_PERMANENT)
5001 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5005 tTsk->actvTsk(&nPst, NULLP);
5007 /* We need to re-send this message back to ourselves so
5008 * the permanent task continues to run.
5010 /* Check if this task got deregistered or detached
5011 * by the activation function; if so, there's nothing
5012 * more to do here, otherwise go ahead.
5015 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5017 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5018 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5022 /* failure here is a real problem */
5025 #if (ERRCLASS & ERRCLS_DEBUG)
5026 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5027 "Could not write to demand queue");
5033 /* unset the current executing TAPA task ID */
5034 sTsk->dep.ent = ENTNC;
5035 sTsk->dep.inst = INSTNC;
5040 /* timer event. find the timer entry */
5041 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5043 /* lock the timer table, coz we're going to peek in it */
5044 ret = SLock(&osCp.tmrTblLock);
5048 #if (ERRCLASS & ERRCLS_DEBUG)
5049 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5050 "Could not lock timer table");
5056 /* Verify that this timer entry is still around and that it
5057 * belongs to our task.
5059 if (osCp.tmrTbl[idx].used == FALSE
5060 /* mt028.201: modification: multiple procs support related changes */
5061 #ifdef SS_MULTIPLE_PROCS
5062 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5063 #endif /* SS_MULTIPLE_PROCS */
5064 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5065 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5067 SUnlock(&osCp.tmrTblLock);
5072 /* mt005.21: addition */
5073 /* set the current executing TAPA task ID */
5074 sTsk->dep.ent = mInfo->pst.dstEnt;
5075 sTsk->dep.inst = mInfo->pst.dstInst;
5077 #ifndef SS_MULTIPLE_PROCS
5079 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5080 tmrActvFnMt = NULLP;
5081 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5083 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5089 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5092 /* unlock the timer table */
5093 SUnlock(&osCp.tmrTblLock);
5095 /* activate the timer function */
5096 /* mt028.201: modification: multiple procs support related changes */
5097 #ifndef SS_MULTIPLE_PROCS
5101 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5102 osCp.tmrTbl[idx].ownerInst);
5110 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5111 osCp.tmrTbl[idx].ownerInst);
5112 #endif /* SS_MULTIPLE_PROCS */
5114 /*mt005.21: addition */
5115 /* unset the current executing TAPA task ID */
5116 sTsk->dep.ent = ENTNC;
5117 sTsk->dep.inst = INSTNC;
5120 /* return the message buffer */
5124 * mt003.301 - SDeRegTTsk fix
5126 case SS_EVNT_TTSK_TERM:
5127 #ifdef SS_MULTIPLE_PROCS
5128 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5130 if (procIdIdx == SS_INV_PROCID_IDX)
5136 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5137 #else /* SS_MULTIPLE_PROCS */
5138 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5139 #endif /* SS_MULTIPLE_PROCS */
5141 /* verify that it hasn't been deregistered */
5142 if (idx == SS_TSKNC)
5148 /* verify that this system task is still running it */
5149 tTsk = &osCp.tTskTbl[idx];
5150 if (tTsk->sTsk != sTsk)
5155 #ifdef SS_MULTIPLE_PROCS
5156 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5158 ssdProcTTskTerm(tTsk, idx);
5164 #if (ERRCLASS & ERRCLS_DEBUG)
5165 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5172 } while (mBuf != NULLP);
5175 /* unlock the system task entry */
5176 SUnlock(&sTsk->lock);
5179 /* yield for other threads */
5180 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5189 * Fun: mtTmrHdlrPublic
5191 Void mtTmrHdlrPublic()
5193 if (SLock(&osCp.tmrTblLock) != ROK)
5195 #if (ERRCLASS & ERRCLS_DEBUG)
5196 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5200 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5201 /* unlock the timer table */
5202 SUnlock(&osCp.tmrTblLock);
5210 * Desc: The timer handler thread function. Counts time
5211 * and invokes the common timer function on each
5214 * Ret: (thread function)
5221 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5222 static Void *mtTmrHdlr
5224 void *parm /* unused */
5227 /*mt004.301-addede new region*/
5228 /* mt010.301 Removed SS_FAP portion and
5229 * enabled oroginal code in function mtTmrHdlr */
5233 uint32_t i, cnt, oldTicks, newTicks;
5234 struct timeval tv1,tv2;
5235 /* mt038.201 added return */
5237 /* mt039.201 changes for nanosleep */
5238 struct timespec tsN;
5239 static uint32_t err_in_usec;
5241 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5246 /* mt027.201 - Modification for SRegCfgTmr support */
5247 /* check SS_TICKS_SEC */
5248 if (SS_1MS < SS_TICKS_SEC)
5250 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5253 /* mt025.201 - Addition to stop timer handler till task registration is done */
5254 /* wait for SS to come up */
5255 /* mt038.201 changed how sem_wait is called */
5256 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5259 /* mt027.201 - Modification for SRegCfgTmr support */
5260 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5262 ts.tv_nsec = (MT_TICK_CNT * 1000);
5263 /* mt039.201 changes for nanosleep */
5269 if (gettimeofday(&tv1, NULL) == -1)
5271 #if (ERRCLASS & ERRCLS_DEBUG)
5272 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5273 "Error in clock_gettime");
5283 #ifndef STUB_TTI_HANDLING_5GTF
5284 printf("\nReturning from mtTmrHdlr()\n");
5289 /* mt039.201 changes for nanosleep */
5290 /* sleep for MT_TICK_CNT milli seconds */
5291 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5292 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5294 ts.tv_nsec = tsN.tv_nsec;
5299 if (gettimeofday(&tv2,NULL) == -1)
5301 #if (ERRCLASS & ERRCLS_DEBUG)
5302 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5303 "Error in clock_gettime");
5307 /*mt013.301 : changed check while calculating timer to fix
5308 * diffrence between MTSS time and real unix time
5310 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5312 time_int = (tv2.tv_usec - tv1.tv_usec);
5314 else if (tv2.tv_sec > tv1.tv_sec)
5316 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5318 else /* ts2 < ts1, this will not happen in normal scenario */
5320 /* to make sure cnt = 1 */
5322 time_int = MT_TICK_CNT;
5325 oldTicks = osCp.dep.sysTicks;
5326 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5327 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5328 newTicks = osCp.dep.sysTicks;
5329 tv1.tv_usec = tv2.tv_usec;
5330 tv1.tv_sec = tv2.tv_sec;
5332 cnt = newTicks - oldTicks;
5334 while(err_in_usec >= MT_TICK_CNT)
5337 err_in_usec -= MT_TICK_CNT;
5339 if( cnt >= MT_MAX_TICK_CNT_VAL)
5340 cnt = MT_MIN_TICK_CNT_VAL;
5341 /* call the common timer tick handler */
5342 for (i = 0; i < cnt; i++)
5344 /* mt008.301: cmPrcTmr is guarded with a lock */
5345 /* lock the timer table */
5346 if (SLock(&osCp.tmrTblLock) != ROK)
5348 #if (ERRCLASS & ERRCLS_DEBUG)
5349 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5353 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5354 /* unlock the timer table */
5355 SUnlock(&osCp.tmrTblLock);
5359 /* mt009.21: addition */
5360 return ( (Void *) NULLP);
5361 /* will not reach here */
5369 * Desc: Process timer event. Called from the common timer
5370 * code when a timeout occurs.
5381 PTR tCb, /* control block */
5382 S16 evnt /* event */
5391 #ifndef TENB_RTLIN_CHANGES
5394 /* mt028.201: modification: multiple procs support related changes */
5395 #ifdef SS_MULTIPLE_PROCS
5397 #endif /* SS_MULTIPLE_PROCS */
5398 #ifdef RGL_SPECIFIC_CHANGES
5399 #ifdef MSPD_MLOG_NEW
5400 uint32_t t = GetTIMETICK();
5406 /* get the timer entry */
5407 tEnt = (SsTmrEntry *) tCb;
5410 /* if the timer was deleted, this will be NULL, so drop it */
5416 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5419 /* Hmmmm, the timer might have been deleted while we've been
5420 * working at getting here, so we just skip this.
5422 if (tEnt->used == FALSE)
5428 /* Set up and send a timer message to the destination tasks'
5431 #ifndef SS_MULTICORE_SUPPORT
5432 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5434 #ifdef RGL_SPECIFIC_CHANGES
5435 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5437 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5442 #if (ERRCLASS & ERRCLS_DEBUG)
5443 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5449 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5450 mInfo->eventInfo.event = SS_EVNT_TIMER;
5451 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5453 mInfo->pst.dstEnt = tEnt->ownerEnt;
5454 mInfo->pst.dstInst = tEnt->ownerInst;
5455 mInfo->pst.srcEnt = tEnt->ownerEnt;
5456 mInfo->pst.srcInst = tEnt->ownerInst;
5457 /* mt028.201: modification: multiple procs support related changes */
5458 #ifndef SS_MULTIPLE_PROCS
5459 mInfo->pst.dstProcId = SFndProcId();
5460 mInfo->pst.srcProcId = SFndProcId();
5461 #else /* SS_MULTIPLE_PROCS */
5462 mInfo->pst.dstProcId = tEnt->ownerProc;
5463 mInfo->pst.srcProcId = tEnt->ownerProc;
5464 #endif /* SS_MULTIPLE_PROCS */
5465 mInfo->pst.selector = SEL_LC_NEW;
5466 #ifndef SS_MULTICORE_SUPPORT
5467 mInfo->pst.region = DFLT_REGION;
5470 mInfo->pst.pool = DFLT_POOL;
5471 mInfo->pst.prior = PRIOR0;
5472 mInfo->pst.route = RTESPEC;
5473 mInfo->pst.event = 0;
5476 #ifndef TENB_RTLIN_CHANGES
5477 /* get a semaphore for the TAPA task table */
5478 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5483 #if (ERRCLASS & ERRCLS_DEBUG)
5484 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5492 /* find the owner TAPA task */
5493 /* mt028.201: modification: multiple procs support related changes */
5494 #ifdef SS_MULTIPLE_PROCS
5495 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5496 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5497 #else /* SS_MULTIPLE_PROCS */
5498 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5499 #endif /* SS_MULTIPLE_PROCS */
5500 if (idx == SS_TSKNC)
5502 #ifndef TENB_RTLIN_CHANGES
5503 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5510 /* ensure that the TAPA task is hale and hearty */
5511 tTsk = &osCp.tTskTbl[idx];
5514 #ifndef TENB_RTLIN_CHANGES
5515 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5520 /* Klock work fix ccpu00148484 */
5521 /* write the timer message to the queue of the destination task */
5522 /* mt008.301 : check sTsk before putting into it's DQ */
5523 if (tTsk->sTsk == NULLP)
5525 #ifndef TENB_RTLIN_CHANGES
5526 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5530 #if (ERRCLASS & ERRCLS_DEBUG)
5531 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5532 "Could not write to demand queue");
5537 #ifdef SS_LOCKLESS_MEMORY
5538 mInfo->pst.region = tTsk->sTsk->region;
5539 mInfo->region = tTsk->sTsk->region;
5540 #endif /* SS_LOCKLESS_MEMORY */
5541 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5542 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5544 #ifndef TENB_RTLIN_CHANGES
5545 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5549 #if (ERRCLASS & ERRCLS_DEBUG)
5550 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5551 "Could not write to demand queue");
5556 /* Fix for ccpu00130657 */
5557 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5558 if (tTsk->sTsk->tskPrior == PRIOR0)
5561 WLS_WakeUp(mtGetWlsHdl());
5568 /* release the semaphore for the TAPA task table */
5569 #ifndef TENB_RTLIN_CHANGES
5570 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5574 /* restart the timer */
5575 arg.tq = osCp.dep.tmrTq;
5576 arg.tqCp = &osCp.dep.tmrTqCp;
5577 arg.timers = tEnt->dep.timers;
5578 arg.cb = (PTR) tEnt;
5582 arg.max = TMR_DEF_MAX;
5583 arg.wait = tEnt->interval;
5585 #ifdef RGL_SPECIFIC_CHANGES
5586 #ifdef MSPD_MLOG_NEW
5587 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5599 * Desc: This thread reads the console and hands over any
5600 * data read to a user function.
5602 * Ret: (thread function)
5609 static Void *mtConHdlr
5611 Ptr parm /* unused */
5618 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5624 /* check if we have a console input file handle */
5625 if (osCp.dep.conInFp == NULLP)
5631 fd = fileno(osCp.dep.conInFp);
5636 if ((read(fd, &data, 1)) != 1)
5642 /* call rdConQ, defined by the system service user */
5652 #ifdef SS_DRVR_SUPPORT
5655 * Fun: Interrupt service task handler
5657 * Desc: This is the interrupt service task handler. It blocks
5658 * on a pipe from which it reads an isFlag structure. The
5659 * structure indicates which interrupt service task is to
5660 * be executed. The thread identifies the task, calls the
5661 * isTsk function and sends itself a message to repeat
5662 * this operation until it receives a message to cease.
5671 /* mt009.21: addition */
5672 static Void *mtIsTskHdlr
5674 Ptr tskPtr /* pointer to task entry */
5677 #if (ERRCLASS & ERRCLS_DEBUG)
5684 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5689 switch (isFlag.action)
5692 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5694 /* call the interrupt service task activation function */
5695 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5697 /* send self a message to keep doing this */
5698 isFlag.action = MT_IS_RESET;
5700 #if (ERRCLASS & ERRCLS_DEBUG)
5701 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5702 if (ret != sizeof(isFlag))
5704 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5705 "write() to pipe failed");
5708 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5715 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5720 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5722 /* call the interrupt service task activation function */
5723 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5725 #if (ERRCLASS & ERRCLS_DEBUG)
5726 /* send self a message to do this again */
5727 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5729 if (ret != sizeof(isFlag))
5731 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5732 "write() to pipe failed");
5735 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5743 /* where did THIS come from?? */
5747 /* mt009.21: addition */
5748 return ( (Void *) NULLP);
5752 #endif /* SS_DRVR_SUPPORT */
5753 #endif /* L2_L3_SPLIT */
5755 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5759 * Fun: mtIntSigHndlr
5761 * Desc: Exit function, shuts down.
5770 Void mtIntSigHndlr(int arg)
5773 osCp.dep.sigEvnt=TRUE;
5776 #ifdef TENB_RTLIN_CHANGES
5784 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5789 * Desc: function, shuts down.
5798 Void mtExitClnup(void)
5804 SGetSysTime(&ticks);
5806 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5808 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5810 #ifdef SS_HISTOGRAM_SUPPORT
5814 osCp.dep.sigEvnt=FALSE;
5816 if (osCp.dep.fileOutFp)
5818 fclose(osCp.dep.fileOutFp);
5826 Void SIncrementTtiCount(Void)
5831 Ticks SGetTtiCount(Void)
5840 * Desc: This function displays a string to a given output
5845 * Notes: Buffer should be null terminated.
5847 * channel 0 is reserved for backwards compatibility
5855 S16 chan, /* channel */
5856 Txt *buf /* buffer */
5860 /* mt020.201 - Fixed typo */
5861 #if (ERRCLASS & ERRCLS_INT_PAR)
5864 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
5869 #ifndef XEON_SPECIFIC_CHANGES
5870 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5871 ssMemlog(buf, strlen(buf));
5876 /* mt012.301 :FIX for LOG RELATED ISSUE */
5884 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
5890 if (osCp.dep.fileOutFp)
5891 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
5892 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
5895 fflush(osCp.dep.fileOutFp);
5908 * Desc: function, shuts down.
5920 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
5921 a loop to overcome the child processes being killed upon exiting the
5923 #ifdef SS_LINUX /* this should have already been defined */
5924 /* mt010.301 removed flag SLES9_PLUS */
5925 /* wait forever for children */
5929 if(osCp.dep.sigEvnt==TRUE)
5936 pthread_exit(NULLP);
5942 * Fun: Set date and time
5944 * Desc: This function is used to set the calendar
5949 * Notes: Unimplemented
5956 REG1 DateTime *dt /* date and time */
5969 * Fun: Get date and time
5971 * Desc: This function is used to determine the calendar
5972 * date and time. This information may be used for
5973 * some management functions.
5985 REG1 DateTime *dt /* date and time */
5988 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
5991 struct timespec ptime;
5993 struct timeval ptime;
6000 #if (ERRCLASS & ERRCLS_INT_PAR)
6003 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6012 localtime_r(&tt, &tme);
6015 clock_gettime(CLOCK_REALTIME, &ptime);
6017 gettimeofday(&ptime, NULL);
6019 localtime_r(&ptime.tv_sec, &tme);
6021 dt->month = (uint8_t) tme.tm_mon + 1;
6022 dt->day = (uint8_t) tme.tm_mday;
6023 dt->year = (uint8_t) tme.tm_year;
6024 dt->hour = (uint8_t) tme.tm_hour;
6025 dt->min = (uint8_t) tme.tm_min;
6026 dt->sec = (uint8_t) tme.tm_sec;
6029 #ifdef SS_DATETIME_USEC
6031 dt->usec = ptime.tv_nsec / 1000;
6033 dt->usec = ptime.tv_usec;
6035 #endif /*-- SS_DATETIME_USEC --*/
6041 * Get time from epoch in milliseconds
6043 * Fun: Get time from epoch in milliseconds
6045 * Desc: This function is used to get the time from epoch in milli seconds.
6046 * This information may be used for calculating a layer's activation function
6047 * execution time used for thread profiling.
6056 /* mt003.301 Modifications */
6059 EpcTime *et /* date and time */
6062 /* mt003.301 Modifications */
6063 static uint64_t now;
6064 uint64_t to_sec = 1000000;
6065 uint64_t to_nsec = 1000;
6067 struct timespec ptime;
6069 struct timeval ptime;
6074 #if (ERRCLASS & ERRCLS_INT_PAR)
6083 clock_gettime(CLOCK_REALTIME, &ptime);
6085 gettimeofday(&ptime, NULL);
6086 #endif /* SS_LINUX */
6088 now = (ptime.tv_sec * to_sec);
6091 now += (ptime.tv_nsec / to_nsec);
6092 #else /* SS_LINUX */
6093 now += (ptime.tv_usec);
6095 #endif /* SS_LINUX */
6096 now = (now / to_nsec);
6107 * Fun: Get system time
6109 * Desc: This function is used to determine the system time.
6113 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6120 Ticks *sysTime /* system time */
6125 #if (ERRCLASS & ERRCLS_INT_PAR)
6126 if (sysTime == NULLP)
6128 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6134 *sysTime = osCp.dep.sysTicks;
6140 /* mt021.201 - Addition of SGetRefTime function */
6143 * Fun: Get referenced time
6145 * Desc: This function is used to determine the time in seconds
6146 * and microseconds from a reference time. The reference
6147 * time is expressed in seconds from UTC EPOC, January 1,
6153 * Notes: Macros are defined for reference times:
6154 * SS_REFTIME_01_01_1970
6155 * SS_REFTIME_01_01_2002
6162 uint32_t refTime, /* reference time */
6169 struct timespec ptime;
6171 struct timeval ptime;
6176 clock_gettime(CLOCK_REALTIME, &ptime);
6178 gettimeofday(&ptime, NULL);
6181 #if (ERRCLASS & ERRCLS_INT_PAR)
6182 if (sec == NULLP || usec == NULLP)
6184 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6187 /* mt022.201 - Modification to fix compile warning */
6188 if (refTime > (uint32_t)(ptime.tv_sec))
6190 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6195 *sec = ptime.tv_sec - refTime;
6197 *usec = ptime.tv_nsec / 1000;
6199 *usec = ptime.tv_usec;
6209 * Fun: Get Random Number
6211 * Desc: Invoked by layer when a pseudorandom number is required.
6215 * Notes: Suggested approach uses shuffled Linear Congruential
6216 * Operators as described in Byte magazine October
6217 * 1984; "Generating and Testing Pseudorandom Numbers"
6224 Random *value /* random number */
6229 #if (ERRCLASS & ERRCLS_INT_PAR)
6232 /* mt011.21: addition */
6233 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6239 *value = (Random) rand_r(&osCp.dep.randSeed);
6250 * Desc: This function exits from a task.
6254 * Notes: Currently does nothing.
6269 * Fun: Exit Interrupt
6271 * Desc: This function exits from an interrupt.
6275 * Notes: Currently does nothing.
6290 * Fun: Hold Interrupt
6292 * Desc: This function prohibits interrupts from being enabled until
6293 * release interrupt. This function should be called when
6294 * interrupts are disabled and prior to any call to system
6295 * services either by entry to an interrupt service routine or
6296 * by explicit call to disable interrupt.
6300 * Notes: Currently does nothing
6315 * Fun: Release Interrupt
6317 * Desc: This function allows interrupts to be enabled.
6321 * Notes: Currently does nothing.
6338 * Desc: Enable interrupts
6340 * Ret: ROK on success
6343 * Notes: Currently does nothing.
6348 inline S16 SEnbInt(void)
6360 * Desc: Disable interrupts
6362 * Ret: ROK on success
6365 * Notes: Currently does nothing.
6370 inline S16 SDisInt(void)
6382 * Desc: This function gets the function address stored at the
6383 * specified interrupt vector.
6387 * Notes: Currently does nothing.
6394 VectNmb vectNmb, /* vector number */
6395 PIF *vectFnct /* vector function */
6412 * Desc: This function installs the specified function at the
6413 * specified interrupt vector.
6417 * Notes: Currently does nothing.
6424 VectNmb vectNmb, /* vector number */
6425 PIF vectFnct /* vector function */
6437 /* mt028.201: modification: multiple procs support related changes */
6438 #ifndef SS_MULTIPLE_PROCS
6444 * Desc: This function gets the current entity and instance.
6447 * RFAILED - failed, general (optional)
6449 * Notes: This function may be called by the OS or Layer 1
6457 Ent *ent, /* entity */
6458 Inst *inst /* instance */
6469 #if (ERRCLASS & ERRCLS_INT_PAR)
6470 /* check pointers */
6471 if (ent == NULLP || inst == NULLP)
6473 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6479 /* get the thread id */
6480 tId = pthread_self();
6483 /* find the system task in whose context we're running */
6485 ret = SLock(&osCp.sTskTblLock);
6490 for (i = 0; i < SS_MAX_STSKS; i++)
6492 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6494 sTsk = &osCp.sTskTbl[i];
6500 *ent = sTsk->dep.ent;
6501 *inst = sTsk->dep.inst;
6503 SUnlock(&osCp.sTskTblLock);
6506 return (ret == ROK ? ROK : RFAILED);
6514 * Desc: This function sets the current entity and instance.
6525 Ent ent, /* entity */
6526 Inst inst /* instance */
6537 #if (ERRCLASS & ERRCLS_INT_PAR)
6538 /* check entity and instance IDs */
6539 if (ent >= ENTNC || inst >= INSTNC)
6541 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6547 /* get the thread id */
6548 tId = pthread_self();
6551 /* find the system task in whose context we're running */
6553 ret = SLock(&osCp.sTskTblLock);
6558 for (i = 0; i < SS_MAX_STSKS; i++)
6560 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6562 sTsk = &osCp.sTskTbl[i];
6568 sTsk->dep.ent = ent;
6569 sTsk->dep.inst = inst;
6571 SUnlock(&osCp.sTskTblLock);
6574 return (ret == ROK ? ROK : RFAILED);
6577 #endif /* SS_MULTIPLE_PROCS */
6579 #ifdef SS_DRVR_SUPPORT
6585 * Desc: Set interrupt pending flag
6587 * Ret: ROK on success
6595 inline S16 SSetIntPend
6597 uint16_t id, /* driver task identifier */
6598 Bool flag /* flag */
6606 #if (ERRCLASS & ERRCLS_INT_PAR)
6607 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6609 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6616 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6618 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6626 #endif /* SS_DRVR_SUPPORT */
6629 #ifdef SS_LOCKLESS_MEMORY
6632 * Fun: SGlobMemInfoShow
6634 * Desc: This function displays the memory usage information
6635 * for the destined region. It will show the usage of
6636 * each configured bucket and the heap for the specified region.
6639 * RFAILED Region not registered
6644 S16 SGlobMemInfoShow(Void)
6648 CmMmGlobRegCb *globReg;
6651 globReg = osCp.globRegCb;
6653 sprintf(prntBuf, "--------------------------------------------------------------\n");
6654 SDisplay(0, prntBuf);
6655 sprintf(prntBuf, "Global Region Bucket Information\n");
6656 SDisplay(0, prntBuf);
6657 sprintf(prntBuf, "====================================================\n");
6658 SDisplay(0, prntBuf);
6659 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
6660 SDisplay(0, prntBuf);
6661 sprintf(prntBuf, "====================================================\n");
6662 SDisplay(0, prntBuf);
6665 for (idx = 0; idx < globReg->numBkts; idx++)
6667 #ifdef XEON_SPECIFIC_CHANGES
6668 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
6669 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6672 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
6673 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6675 sprintf(prntBuf, "%2u %12u %8u %9u\n",
6676 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6679 SDisplay(0, prntBuf);
6681 sprintf(prntBuf, "--------------------------------------------------------------\n");
6682 SDisplay(0, prntBuf);
6687 #endif /* SS_LOCKLESS_MEMORY */
6690 Bool IsMemoryThresholdHit(Region reg, Pool pool)
6692 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6694 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6697 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6698 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6705 /* mt022.201 - Addition of SRegInfoShow function */
6710 * Desc: This function displays the memory usage information
6711 * for the destined region. It will show the usage of
6712 * each configured bucket and the heap for the specified region.
6715 * RFAILED Region not registered
6717 * Notes: A Sample Output from the function
6718 * Bucket Memory: region 1
6719 * ====================================================
6720 * Bucket Number of Blks configured Size Allocated
6721 * ====================================================
6729 * Heap Memory: region 1
6732 * Heap Segmented blocks: 0
6748 #if (ERRCLASS & ERRCLS_INT_PAR)
6749 if (region > (SS_MAX_REGS-1) )
6751 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
6758 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
6759 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
6760 SDisplay(0, prntBuf);
6761 sprintf(prntBuf, "====================================================\n");
6762 SDisplay(0, prntBuf);
6763 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
6764 SDisplay(0, prntBuf);
6765 sprintf(prntBuf, "====================================================\n");
6766 SDisplay(0, prntBuf);
6770 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6772 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6774 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
6775 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6776 mtCMMRegCb[region]->bktTbl[idx].size,
6777 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6778 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6780 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
6781 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6782 mtCMMRegCb[region]->bktTbl[idx].size,
6783 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6784 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6787 /*mt009.301 Fixed 64BIT compilation warnings*/
6789 sprintf(prntBuf, "%2u %8u %5u %8u\n",
6790 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6791 mtCMMRegCb[region]->bktTbl[idx].size,
6792 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6794 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
6795 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6796 mtCMMRegCb[region]->bktTbl[idx].size,
6797 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6799 #endif /* not TENB_RTLIN_CHANGES */
6800 SDisplay(0, prntBuf);
6801 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
6802 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6803 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6805 sprintf(prntBuf, "\n---------------\n");
6806 SDisplay(0, prntBuf);
6807 sprintf(prntBuf, "Heap Memory: region %d\n", region);
6808 SDisplay(0, prntBuf);
6809 /*mt009.301 Fixed 64BIT compilation warnings*/
6811 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
6813 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
6815 SDisplay(0, prntBuf);
6816 /*mt009.301 Fixed 64BIT compilation warnings*/
6818 sprintf(prntBuf, "Heap Allocated: %u\n",
6819 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6821 sprintf(prntBuf, "Heap Allocated: %lu\n",
6822 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6824 SDisplay(0, prntBuf);
6825 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
6826 #if (ERRCLASS & ERRCLS_DEBUG)
6827 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
6828 mtCMMRegCb[region]->heapCb.numFragBlk);
6829 SDisplay(0, prntBuf);
6834 #ifdef XEON_SPECIFIC_CHANGES
6835 #define SSI_MAX_BKT_THRESHOLD 6
6836 #define SSI_MAX_REG_THRESHOLD 2
6837 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6838 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6839 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6841 static Void SInitMemThreshold
6848 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6850 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
6851 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
6852 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
6853 printf("\nREGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
6857 S16 SRegReachedMemThreshold
6864 uint8_t memStatus = 3;
6865 static uint8_t initFlag = 1;
6869 SInitMemThreshold(region, maxBkt);
6872 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6874 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
6879 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
6883 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
6891 /* mt033.201 - addition of API to return the memory statistical data */
6896 * Desc: This function returns the memory usage information
6897 * for the destined region. It will return the usage of
6898 * each configured bucket and the heap for the specified region.
6901 * RFAILED Region not registered
6911 SsMemDbgInfo *dbgInfo
6917 #if (ERRCLASS & ERRCLS_INT_PAR)
6918 if (region >= mtMemoCfg.numRegions )
6920 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
6925 dbgInfo->availmem = 0;
6927 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
6928 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
6930 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
6932 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
6934 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
6935 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
6936 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
6938 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
6939 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6940 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6943 dbgInfo->region = region;
6945 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
6947 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
6948 mtCMMRegCb[region]->heapCb.avlSize);
6950 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
6952 #if (ERRCLASS & ERRCLS_DEBUG)
6953 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
6965 /* Send number of Region available */
6966 *numRegion = mtMemoCfg.numRegions;
6967 /* Send number of Pools available */
6968 *numPool = cfgRegInfo[0].numPools;
6973 /* mt033.201 - addition of APIs to print the memory statistical data
6974 * as defined by SSI enhancements
6976 #ifdef SSI_DEBUG_LEVEL1
6979 * Fun: SPrintRegMemStatusInfo
6981 * Desc: This function displays the memory usage information
6982 * for the destined region. It will show the total memory
6983 * used for static and dynamic memory if typeFlag is
6984 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
6985 * memory block allocated for a particular size if typeFlag
6986 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
6987 * calling SRegPrintMemStats.
6996 S16 SPrintRegMemStatusInfo
7004 uint32_t statMemSize;
7005 uint32_t dynMemSize;
7008 #if (ERRCLASS & ERRCLS_INT_PAR)
7009 if (region >= mtMemoCfg.numRegions )
7011 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7016 /* initialize the counters*/
7020 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7022 /* total static and dynamic memory allocated from all the buckets in region requested */
7023 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7024 SDisplay(0, prntBuf);
7025 sprintf(prntBuf, "===========================================\n");
7026 SDisplay(0, prntBuf);
7027 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7028 SDisplay(0, prntBuf);
7029 sprintf(prntBuf, "===========================================\n");
7030 SDisplay(0, prntBuf);
7031 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7033 /*mt009.301 Fixed 64BIT compilation warnings*/
7035 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7036 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7037 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7039 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7040 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7041 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7043 SDisplay(0, prntBuf);
7044 /* update the total count */
7045 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7046 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7049 /*mt009.301 Fixed 64BIT compilation warnings*/
7051 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7052 SDisplay(0, prntBuf);
7053 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7055 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7056 SDisplay(0, prntBuf);
7057 /*mt010.301 fix for compilation error*/
7058 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7060 SDisplay(0, prntBuf);
7062 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7063 SDisplay(0, prntBuf);
7064 /*mt009.301 Fixed 64BIT compilation warnings*/
7066 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7067 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7069 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7070 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7072 SDisplay(0, prntBuf);
7074 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7076 /* Bucket Memory allocation Statistics */
7077 return (SPrintRegMemStats(region));
7082 sprintf(prntBuf, "\n Invalid choice \n");
7083 SDisplay(0, prntBuf);
7091 * Fun: SPrintRegMemStats
7093 * Desc: This function displays the memory usage information for
7094 * the destined region. It will show the number of memory
7095 * block allocated for a particular size from the hash list.
7104 static S16 SPrintRegMemStats(Region region)
7106 CmMmHashListCp *hashListCp;
7112 hashListCp = &mtCMMRegCb[region]->hashListCp;
7114 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7115 SDisplay(0, prntBuf);
7116 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7117 hashListCp->numOfbins, hashListCp->numOfEntries);
7118 SDisplay(0, prntBuf);
7119 sprintf(prntBuf, "===================================\n");
7120 SDisplay(0, prntBuf);
7121 sprintf(prntBuf, "Block Size Total number of requests\n");
7122 SDisplay(0, prntBuf);
7123 sprintf(prntBuf, "===================================\n");
7124 SDisplay(0, prntBuf);
7126 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7127 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7129 if (hashListCp->hashList[idx].numAttempts)
7132 /*mt009.301 Fixed 64BIT compilation warnings*/
7134 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7135 hashListCp->hashList[idx].numAttempts);
7137 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7138 hashListCp->hashList[idx].numAttempts);
7140 SDisplay(0, prntBuf);
7144 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7145 SDisplay(0, prntBuf);
7146 sprintf(prntBuf, "=================================================\n");
7147 SDisplay(0, prntBuf);
7148 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7149 SDisplay(0, prntBuf);
7150 sprintf(prntBuf, "=================================================\n");
7151 SDisplay(0, prntBuf);
7153 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7154 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7156 /*mt009.301 Fixed 64BIT compilation warnings*/
7158 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7159 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7160 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7162 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7163 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7164 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7166 SDisplay(0, prntBuf);
7168 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7169 SDisplay(0, prntBuf);
7170 /*mt009.301 Fixed 64BIT compilation warnings*/
7172 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7173 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7174 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7176 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7177 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7178 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7180 SDisplay(0, prntBuf);
7181 sprintf(prntBuf, "\n");
7182 SDisplay(0, prntBuf);
7189 * Fun: SRegMemErrHdlr
7191 * Desc: This function handles the errors returned from the memory
7192 * related functions. Customers are suggested to modify this
7193 * API according to their specific requirement.
7212 if (errCode == RDBLFREE)
7214 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7215 SDisplay(0, prntBuf);
7217 else if (errCode == RTRAMPLINGNOK)
7219 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7220 SDisplay(0, prntBuf);
7228 * Fun: SPrintRegMemProfile
7230 * Desc: This function displays the memory profile information
7231 * for the destined region. This function prints for:
7232 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7233 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7242 S16 SPrintRegMemProfile
7249 CmMmBlkHdr *curBktBlk;
7251 Size offsetToNxtBlk;
7259 #if (ERRCLASS & ERRCLS_INT_PAR)
7260 if (region >= mtMemoCfg.numRegions )
7262 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7267 regCb = mtCMMRegCb[region];
7269 /* memory profile */
7270 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7271 SDisplay(0, prntBuf);
7273 /* bucket profile */
7274 sprintf(prntBuf, "\nBucket Profile\n");
7275 SDisplay(0, prntBuf);
7277 for (idx = 0; idx < regCb->numBkts; idx++)
7280 /*mt009.301 Fixed 64BIT compilation warnings*/
7282 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7283 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7285 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7286 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7288 SDisplay(0, prntBuf);
7290 sprintf(prntBuf, "==========================================================================\n");
7291 SDisplay(0, prntBuf);
7292 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7293 SDisplay(0, prntBuf);
7294 sprintf(prntBuf, "==========================================================================\n");
7295 SDisplay(0, prntBuf);
7297 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7299 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7300 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7301 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7303 /*mt009.301 Fixed 64BIT compilation warnings*/
7305 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7307 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7309 SDisplay(0, prntBuf);
7310 /* check if it is a sane block, elxe jump to next block */
7311 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7313 sprintf(prntBuf, " Trampled \n");
7314 SDisplay(0, prntBuf);
7319 if (CMM_IS_STATIC(curBktBlk->memFlags))
7321 /*mt009.301 Fixed 64BIT compilation warnings*/
7323 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7325 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7327 SDisplay(0, prntBuf);
7329 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7331 /*mt009.301 Fixed 64BIT compilation warnings*/
7333 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7335 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7337 SDisplay(0, prntBuf);
7339 else if (CMM_IS_FREE(curBktBlk->memFlags))
7341 /*mt009.301 Fixed 64BIT compilation warnings*/
7343 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7345 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7347 SDisplay(0, prntBuf);
7351 sprintf(prntBuf, " Trampled \n");
7352 SDisplay(0, prntBuf);
7358 sprintf(prntBuf, "\nHeap Profile\n");
7359 SDisplay(0, prntBuf);
7361 /* point to heapCb */
7362 heapCb = &(regCb->heapCb);
7364 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7365 SDisplay(0, prntBuf);
7366 sprintf(prntBuf, "==========================================================================\n");
7367 SDisplay(0, prntBuf);
7368 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7369 SDisplay(0, prntBuf);
7370 sprintf(prntBuf, "==========================================================================\n");
7371 SDisplay(0, prntBuf);
7373 /* traverse the entire heap to output the heap profile */
7374 hdrSize = sizeof(CmHEntry);
7375 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7376 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7378 /*mt009.301 Fixed 64BIT compilation warnings*/
7380 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7382 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7384 SDisplay(0, prntBuf);
7386 /* check if it is a sane block, elxe jump to next block */
7387 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7389 sprintf(prntBuf, " Trampled \n");
7390 SDisplay(0, prntBuf);
7392 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7393 SDisplay(0, prntBuf);
7396 * To go to next block in the heap we do not have any offset value
7397 * other than curHBlk->size. As the block is already trampled
7398 * we cannot rely on this size. So it is better to stop here unless there
7399 * exists any other mechanism(?) to know the offset to next block.
7404 /*mt009.301 Fixed 64BIT compilation warnings*/
7406 sprintf(prntBuf, " %8u", curHBlk->size);
7408 sprintf(prntBuf, " %8lu", curHBlk->size);
7410 SDisplay(0, prntBuf);
7412 if (CMM_IS_STATIC(curHBlk->memFlags))
7414 /*mt009.301 Fixed 64BIT compilation warnings*/
7416 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7418 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7420 SDisplay(0, prntBuf);
7422 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7424 /*mt009.301 Fixed 64BIT compilation warnings*/
7426 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7428 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7430 SDisplay(0, prntBuf);
7432 else if (CMM_IS_FREE(curHBlk->memFlags))
7434 /*mt009.301 Fixed 64BIT compilation warnings*/
7436 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7438 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7440 SDisplay(0, prntBuf);
7444 sprintf(prntBuf, " Trampled \n");
7445 SDisplay(0, prntBuf);
7447 /* goto next block in the heap */
7448 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7454 #endif /* SSI_DEBUG_LEVEL1 */
7456 /*-- mt035.201 : Added new API for timestamp --*/
7459 * Fun: Get TimeStamp
7461 * Desc: This function is used to Get TimeStamp in micro seconds
7478 struct timespec ptime;
7480 struct timeval ptime;
7489 clock_gettime(CLOCK_REALTIME, &ptime);
7491 gettimeofday(&ptime, NULL);
7494 /* Obtain the time of day, and convert it to a tm struct. --*/
7495 ptm = localtime (&ptime.tv_sec);
7496 /* Klock work fix ccpu00148484 */
7499 /* Format the date and time, down to a single second. --*/
7500 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7503 /* Compute microseconds. --*/
7505 microseconds = ptime.tv_nsec / 1000;
7507 microseconds = ptime.tv_usec;
7510 /* Print the formatted time, in seconds, followed by a decimal point
7511 and the microseconds. --*/
7512 /*mt009.301 Fixed 64BIT compilation warnings*/
7514 sprintf(ts, "%s.%03d", time_string, microseconds);
7516 sprintf(ts, "%s.%03ld", time_string, microseconds);
7522 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7525 * Fun: Get SGetSystemTsk
7527 * Desc: This function is used to Get sytem task id
7536 uint32_t SGetSystemTsk(Void)
7539 return (pthread_self());
7541 } /* end of SGetSystemTsk */
7543 #ifdef SS_MULTICORE_SUPPORT
7546 * Fun: Add Timer thread into system task table
7548 * Desc: This function is used to add the system task
7549 * associated with Timer thread.
7558 static SsSTskEntry* ssdAddTmrSTsk(Void)
7564 /* lock the system task table */
7565 ret = SLock(&osCp.sTskTblLock);
7569 #if (ERRCLASS & ERRCLS_DEBUG)
7570 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7571 "Could not lock system task table");
7577 /* check count of system tasks */
7578 if (osCp.numSTsks == SS_MAX_STSKS)
7581 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7583 #if (ERRCLASS & ERRCLS_DEBUG)
7584 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7585 "Could not give the Semaphore");
7590 #if (ERRCLASS & ERRCLS_ADD_RES)
7591 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7598 /* initialize the system task entry with the information we have */
7599 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7601 /* store the system task priority */
7602 sTsk->tskPrior = SS_NORM_TSK_PRI;
7604 /* initialize the demand queue */
7605 if (ssInitDmndQ(&sTsk->dQ) != ROK)
7608 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7610 #if (ERRCLASS & ERRCLS_DEBUG)
7611 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7612 "Could not give the Semaphore");
7617 #if (ERRCLASS & ERRCLS_DEBUG)
7618 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7619 "Could not initialize demand queue");
7625 /* initialize the system task entry lock */
7626 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7628 ssDestroyDmndQ(&sTsk->dQ);
7630 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7632 #if (ERRCLASS & ERRCLS_DEBUG)
7633 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7634 "Could not give the Semaphore");
7639 #if (ERRCLASS & ERRCLS_DEBUG)
7640 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
7641 "Could not initialize system task entry lock");
7648 /* success, update the table */
7649 sTsk->tskId = osCp.nxtSTskEntry;
7651 sTsk->termPend = FALSE;
7652 osCp.nxtSTskEntry = sTsk->nxt;
7655 /* unlock the system task table */
7657 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7659 #if (ERRCLASS & ERRCLS_DEBUG)
7660 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
7661 "Could not give the Semaphore");
7668 #endif /* SS_MULTICORE_SUPPORT */
7669 /* mt003.301 Readwrite lock and recursive mutex additions */
7670 #ifdef SS_LOCK_SUPPORT
7673 * Fun: ssdInitLockNew
7675 * Desc: This function is used to initialise lock/mutex
7684 S16 ssdInitLockNew(SLockInfo *lockId,uint8_t lockType)
7687 #ifdef SS_REC_LOCK_SUPPORT
7688 pthread_mutexattr_t attr;
7689 #endif /* SS_REC_LOCK_SUPPORT */
7690 Txt prntBuf[PRNTSZE];
7696 #ifdef SS_RDWR_LOCK_SUPPORT
7699 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
7701 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
7702 SDisplay(0, prntBuf);
7707 #endif /* SS_RDWR_LOCK_SUPPORT */
7708 #ifdef SS_REC_LOCK_SUPPORT
7711 retVal = pthread_mutexattr_init(&attr);
7715 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
7720 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
7722 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
7726 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
7727 pthread_mutexattr_destroy(&attr);
7731 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
7734 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
7735 pthread_mutexattr_destroy(&attr);
7741 #endif /* SS_REC_LOCK_SUPPORT */
7744 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
7745 SDisplay(0, prntBuf);
7755 * Desc: This function is used to aquire the read write lock
7764 S16 ssdLockNew(SLockInfo *lockId,uint8_t lockType)
7767 Txt prntBuf[PRNTSZE];
7773 #ifdef SS_RDWR_LOCK_SUPPORT
7776 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
7778 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7779 SDisplay(0, prntBuf);
7786 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
7788 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
7789 SDisplay(0, prntBuf);
7796 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
7798 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7799 SDisplay(0, prntBuf);
7806 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
7808 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7809 SDisplay(0, prntBuf);
7814 #endif /* SS_RDWR_LOCK_SUPPORT */
7815 #ifdef SS_REC_LOCK_SUPPORT
7818 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
7820 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7821 SDisplay(0, prntBuf);
7826 #endif /* SS_REC_LOCK_SUPPORT */
7829 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
7830 SDisplay(0, prntBuf);
7843 * Desc: This function is used to Unlock the read write lock
7852 S16 ssdUnlockNew(SLockInfo *lockId,uint8_t lockType)
7855 Txt prntBuf[PRNTSZE];
7861 #ifdef SS_RDWR_LOCK_SUPPORT
7864 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
7866 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
7867 SDisplay(0, prntBuf);
7872 #endif /* SS_RDWR_LOCK_SUPPORT */
7873 #ifdef SS_REC_LOCK_SUPPORT
7876 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
7878 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7879 SDisplay(0, prntBuf);
7884 #endif /* SS_REC_LOCK_SUPPORT */
7887 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
7888 SDisplay(0, prntBuf);
7897 * Fun: ssdDestroyLockNew
7899 * Desc: This function is used to destroy the read write lock
7908 S16 ssdDestroyLockNew(SLockInfo *lockId,uint8_t lockType)
7910 Txt prntBuf[PRNTSZE];
7916 #ifdef SS_RDWR_LOCK_SUPPORT
7919 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
7921 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
7922 SDisplay(0, prntBuf);
7927 #endif /* SS_RDWR_LOCK_SUPPORT */
7928 #ifdef SS_REC_LOCK_SUPPORT
7931 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
7933 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
7934 SDisplay(0, prntBuf);
7939 #endif /* SS_REC_LOCK_SUPPORT */
7942 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
7943 SDisplay(0, prntBuf);
7949 #endif /* SS_LOCK_SUPPORT */
7951 /* mt005.301 : Cavium Changes */
7952 #ifdef SS_SEUM_CAVIUM
7956 * Fun: ssInitRcvWork
7958 * Desc: This is the initializtion function of receive
7962 * RFAILED - failed, general (optional)
7964 * Notes: Function to initialize the work queue packet
7965 * receiving thread. This creates the new thread to
7966 * receive the work and sets the affinity.
7971 S16 ssInitRcvWork(void)
7973 pthread_attr_t attr;
7977 /* set the required attributes */
7978 pthread_attr_init(&attr);
7979 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
7980 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
7981 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
7983 /* Create a new thread to receive the work queue messages */
7984 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
7986 pthread_attr_destroy(&attr);
7991 pthread_attr_destroy(&attr);
7995 }/* ssInitRcvWork */
8002 * Desc: This is the handler function of receive
8006 * RFAILED - failed, general (optional)
8008 * Notes:The handler function of the work queue receiver task.
8009 * This will be waiting for the work and after receiving
8010 * it, work will converted and posted to that entityt
8016 static void *workRcvTsk(Ptr ptr)
8019 cvmx_wqe_t *workPtr;
8020 Buffer *mBuf, *rcvdBuf;
8021 SsMsgInfo *minfoPtr;
8030 /* get the work if its avilable */
8031 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8033 if ( workPtr == NULLP )
8035 /* If there is no work then sleep for 10 usec */
8037 ts.tv_nsec = 500000;
8039 nanosleep(&ts, NULLP);
8043 switch(workPtr->tag)
8045 /* Switch over according to the tag value */
8046 case SS_CVMX_MBUF_TAG:
8048 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8050 /* Convert the physical address to Pointers */
8051 ret = SConvPhyPtr(&rcvdBuf);
8054 /* mt011.301: Cavium 32 bit changes */
8055 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8059 /* Copy the buffer to this region */
8060 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8063 /* mt011.301: Cavium 32 bit changes */
8064 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8068 /* mt011.301: Cavium 32 bit changes */
8069 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8071 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8073 /* Get the post strucutre and Post the message */
8074 if ( minfoPtr != NULLP)
8076 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8078 (Void)SPstTsk(&pst, mBuf);
8080 /* Free the buffer allocated if it cannot be sent */
8089 /* Invalid tag value, drop the work */
8090 /* mt011.301: Cavium 32 bit changes */
8091 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8100 #endif /* SS_SEUM_CAVIUM */
8102 #ifdef TENB_RTLIN_CHANGES
8103 S16 SInitLock(SLockId *l, uint8_t t)
8106 pthread_mutexattr_t prior;
8107 pthread_mutexattr_init(&prior);
8108 #ifndef RGL_SPECIFIC_CHANGES
8109 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8111 r = pthread_mutex_init(l, &prior);
8112 pthread_mutexattr_destroy(&prior);
8116 #ifdef SS_THR_REG_MAP
8119 * Fun: ssRegMainThread
8121 * Desc: This function is used to add the memory region
8122 * mapping for the main thread.
8124 * Ret: VOID (Always successful)
8132 Void ssRegMainThread(Void)
8135 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8137 printf("\nnot able to get different Id for main thread\n");
8140 /* Here the default region is added as we dont have any region associated with
8141 * Main thread. The thread should not perform any allocation except
8142 * the initial configuratin
8144 #ifdef XEON_SPECIFIC_CHANGES
8145 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8147 SS_GET_THREAD_MEM_REGION() =
8154 * Fun: ssCheckAndAddMemoryRegionMap
8156 * Desc: This function is used to add the memory region
8157 * mapping for the provided sTsk associated thread.
8158 * If the threadId can be placed in the thread memory
8159 * region mapping table and returns success if it is able
8160 * to place. If not, it keeps the thread ID in the static
8161 * local array and increments the count. Once thread Id
8162 * is successfully placed in the thread memory region mapping
8163 * table, pthread_cancel is sent for all the previous threads
8164 * which are failed to place in table.
8166 * Ret: TRUE - Thread ID successfully placed in thread memory region
8168 * FALSE - If thread Id is not placed in thread memory region
8171 * Notes:mapping tablemapping tablng tablee
8176 S32 ssCheckAndAddMemoryRegionMap
8178 pthread_t threadId, /* Thread Id of system task */
8179 Region region /* Region associated with thread */
8182 static uint32_t createdThreads;
8183 static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8187 /* Here 0xFF is considered as invalid region and if the mapping table
8188 * contains 0xFF, that mapping entry is free
8190 if(SS_INVALID_THREAD_REG_MAP !=
8191 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8193 /* Klock work fix ccpu00148484 */
8194 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8196 printf("\nfailed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8197 printf("\nNot able to get the different thread ID, exiting\n");
8200 createdThreadIds[createdThreads++] = threadId;
8203 /* If we found free mapping table entry, place the region and send pthread_cancel
8204 * for all the thread Ids which are created before this
8206 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8207 #ifdef XEON_SPECIFIC_CHANGES
8208 printf("\nThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8209 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8210 SS_MAX_THREAD_REGION_MAP), region);
8212 for(indx = 0; indx < createdThreads; indx++)
8214 #ifdef XEON_SPECIFIC_CHANGES
8215 printf("\nSending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8217 pthread_cancel(createdThreadIds[indx]);
8223 } /* ssCheckAndAddMemoryRegionMap */
8227 * Fun: ssCheckAndDelMemoryRegionMap
8229 * Desc: This function is used to add the memory region
8230 * mapping for the provided sTsk associated thread.
8231 * If the threadId can be placed in the thread memory
8232 * region mapping table and returns success if it is able
8233 * to place. If not, it keeps the thread ID in the static
8234 * local array and increments the count. Once thread Id
8235 * is successfully placed in the thread memory region mapping
8236 * table, pthread_cancel is sent for all the previous threads
8237 * which are failed to place in table.
8239 * Ret: TRUE - Thread ID successfully placed in thread memory region
8241 * FALSE - If thread Id is not placed in thread memory region
8244 * Notes:mapping tablemapping tablng tablee
8249 S32 ssCheckAndDelMemoryRegionMap
8251 pthread_t threadId /* Thread Id of system task */
8256 /* Raghu To-Do Check with team, is it necessary to acquire lock
8257 * as del and add may go parallel */
8258 /* Here 0xFF is considered as invalid region and if the mapping table
8259 * contains 0xFF, that mapping entry is free
8261 if(SS_INVALID_THREAD_REG_MAP ==
8262 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8265 printf("\nInvalid Thread ID (%ld)\n", (uint32_t)threadId);
8267 printf("\nInvalid Thread ID (%d)\n", (uint32_t)threadId);
8271 /* If we found free mapping table entry, place the region and send pthread_cancel
8272 * for all the thread Ids which are created before this
8274 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8278 } /* ssCheckAndAddMemoryRegionMap */
8282 #ifdef SS_TSKLOG_ENABLE
8287 * Desc: This function will return current time through input parameter.
8290 * RFAILED - failed, general (optional)
8298 volatile uint32_t *startTime,
8302 #ifdef MSPD_MLOG_NEW
8303 *startTime = GetTIMETICK();
8312 * Desc: This function will return current time through input parameter.
8313 * and take the difference of start time provided as input parameter
8317 * RFAILED - failed, general (optional)
8325 volatile uint32_t startTime,
8329 /*uint32_t stopTime;*/
8332 case PID_MAC_HARQ_IND:
8333 case PID_SCH_TTI_IND:
8335 case PID_MAC_DAT_IND:
8336 case PID_MAC_SF_ALLOC_REQ:
8337 case PID_MAC_STA_RSP:
8338 case PID_MAC_DL_SCHD:
8339 case PID_MAC_DL_CQI_IND:
8340 case PID_MAC_UL_CQI_IND:
8341 case PID_MAC_UL_SCHD:
8342 case PID_MAC_TTI_IND:
8343 case PID_CL_RCV_PHY_MSG:
8344 case PID_CL_HARQ_STA_IND:
8345 case PID_MAC_AM_HARQ_RLS:
8346 case PID_CL_DL_BATCH_PROC:
8347 case PID_CL_DLM_PRC_TTI_IND:
8348 case PID_CRC_IND_REAL:
8349 case PID_CRC_IND_DUMMY:
8350 case PID_TTI_LATENCY:
8351 case PID_RECPREQ_PROC:
8354 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8356 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8359 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8368 volatile uint32_t * startTime,
8378 volatile uint32_t startTime,
8385 #endif /*#ifdef SS_TSKLOG_ENABLE */
8386 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8388 * This primitive is used to calculate the CPU Utilization per Core
8393 * @return Void - function is always success
8395 Void UpdateSocCpuInfo
8397 CmCpuStatsInfo *cpuInfo,
8402 S8 mipsStr[MIPS_STRING_LEN];
8409 /* Open the file which holds the MIPS available value */
8410 mipsFd = fopen(MIPS_FILE, "r");
8417 /* Get the free mips available value from the file */
8418 if(NULLP == fgets(mipsStr, 24, mipsFd))
8420 printf("\nfgets to get the free mips available failed\n");
8425 strtok(mipsStr, " ");
8427 strPart = strtok(NULLP, " ");
8429 if(idx == CM_L2_CPU_UTIL)
8431 if(strPart != NULLP)
8433 l2FreeCpu = atoi(strPart);
8434 l2CpuUsed = 100 - l2FreeCpu;
8435 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8436 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
8437 cpuInfo->cpuUtil[0].numSamples++;
8440 if(idx == CM_L3_CPU_UTIL)
8442 strPart = strtok(NULLP, " ");
8443 if(strPart != NULLP)
8445 l3FreeCpu = atoi(strPart);
8446 l3CpuUsed = 100 - l3FreeCpu;
8447 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8448 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
8449 cpuInfo->cpuUtil[0].numSamples++;
8452 if(idx == CM_L2_CPU_UTIL)
8454 cpuInfo->numCores = CM_NUM_L2_CORES ;
8456 else if(idx == CM_L3_CPU_UTIL)
8458 cpuInfo->numCores = CM_NUM_L3_CORES ;
8464 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8465 #ifdef SS_MULTICORE_SUPPORT
8468 * Fun: Add Timer thread into system task table
8470 * Desc: This function is used to add the system task
8471 * associated with Timer thread.
8480 static SsSTskEntry* ssdReAddTmrSTsk(
8488 /* lock the system task table */
8489 ret = SLock(&osCp.sTskTblLock);
8493 #if (ERRCLASS & ERRCLS_DEBUG)
8494 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8495 "Could not lock system task table");
8501 /* initialize the system task entry with the information we have */
8502 sTsk = &osCp.sTskTbl[idx];
8507 SDestroyLock(&sTsk->lock);
8508 ssDestroyDmndQ(&sTsk->dQ);
8511 /* store the system task priority */
8512 sTsk->tskPrior = SS_NORM_TSK_PRI;
8514 /* initialize the demand queue */
8515 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8518 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8520 #if (ERRCLASS & ERRCLS_DEBUG)
8521 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8522 "Could not give the Semaphore");
8527 #if (ERRCLASS & ERRCLS_DEBUG)
8528 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8529 "Could not initialize demand queue");
8535 /* initialize the system task entry lock */
8536 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8538 ssDestroyDmndQ(&sTsk->dQ);
8540 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8542 #if (ERRCLASS & ERRCLS_DEBUG)
8543 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8544 "Could not give the Semaphore");
8549 #if (ERRCLASS & ERRCLS_DEBUG)
8550 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8551 "Could not initialize system task entry lock");
8558 /* success, update the table */
8559 sTsk->tskId = idx + 1;
8561 sTsk->termPend = FALSE;
8563 /* unlock the system task table */
8565 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8567 #if (ERRCLASS & ERRCLS_DEBUG)
8568 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8569 "Could not give the Semaphore");
8576 #endif /* SS_MULTICORE_SUPPORT */
8581 * Fun: Initialize timer table
8583 * Desc: This function initializes MTSS-specific information
8584 * in the timer table.
8593 S16 ssdReInitTmr(void)
8595 pthread_attr_t attr;
8596 struct sched_param param_sched;
8597 #ifndef XEON_SPECIFIC_CHANGES
8600 #ifdef SS_MULTICORE_SUPPORT
8602 #endif /* SS_MULTICORE_SUPPORT */
8603 #ifdef SS_THR_REG_MAP
8604 uint32_t threadCreated = FALSE;
8605 #endif /* SS_THR_REG_MAP */
8608 #ifndef XEON_SPECIFIC_CHANGES
8609 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
8612 #if (ERRCLASS & ERRCLS_DEBUG)
8613 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8614 "Could not give the Semaphore");
8620 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
8621 /* mt010.21: addition */
8623 #ifdef SS_MULTICORE_SUPPORT
8624 sTsk = ssdReAddTmrSTsk(0);
8629 #endif /* SS_MULTICORE_SUPPORT */
8630 /* create the timer handler thread */
8632 pthread_attr_init(&attr);
8633 /* mt021.201 - Addition to set stack size */
8634 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
8635 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8636 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8637 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
8638 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
8639 pthread_attr_setschedparam(&attr, ¶m_sched);
8642 #ifdef SS_THR_REG_MAP
8643 /* When the thread is created, we check for the memory mapping table if
8644 * threadId can be placed in thread memory map table. If it is not able to place
8645 * threadId is stored in tmporary array. Once thread is created successful,
8646 * thread_cancel is sent for each thread which are created before. All the
8647 * threads are made to wait on sema which is cancel point for thread.
8649 while(threadCreated == FALSE)
8652 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
8654 /* mt020.201 - Addition for destroying thread attribute object attr */
8655 pthread_attr_destroy(&attr);
8660 #ifdef SS_THR_REG_MAP
8661 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
8664 #endif /* SS_THR_REG_MAP */
8665 #ifdef SS_MEM_WL_DEBUG
8666 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
8669 /* mt020.201 - Addition for destroying thread attribute object attr */
8670 pthread_attr_destroy(&attr);
8671 sem_post(&osCp.dep.ssStarted);
8675 /**********************************************************************
8677 **********************************************************************/