1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: Multi-threaded System Services - Solaris
25 Desc: C source code for the MTSS-Solaris implementation of
30 *********************************************************************21*/
35 #ifndef _POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE 199309L
38 /* mt003.301 moved env files to use the __USE_UNIX98 flag in sys includes */
45 #include <sys/types.h>
50 /* mt003.301: included sys/time.h
51 * for both solaris and linux
54 /* mt008.21: addition */
59 /* header include files (.h) */
62 #include "common_def.h"
63 #include "mt_ss.h" /* MTSS specific */
64 #include "mt_err.h" /* MTSS error defines */
66 #include "ss_queue.h" /* queues */
67 #include "ss_task.h" /* tasking */
68 #include "ss_msg.h" /* messaging */
69 #include "ss_mem.h" /* memory management interface */
70 #include "ss_gen.h" /* general */
71 /* mt003.301 Additions - Task deregistration */
72 #include "ss_err.h" /* error */
73 #include "cm_mem.h" /* common memory manager */
74 /* mt001.301 : Additions */
75 #ifdef SS_THREAD_PROFILE
78 #ifdef SS_LOCKLESS_MEMORY
83 /* multi-core support enhancement */
84 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
85 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
91 #include <sys/types.h>
92 #include <sys/processor.h>
93 #include <sys/procset.h>
96 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
97 /* mt001.301 : Additions */
99 #include <sys/types.h>
100 #include <sys/socket.h>
101 #include <netinet/in.h>
102 #include <arpa/inet.h>
103 #endif /* SS_WATCHDOG */
105 #ifdef SS_USE_WLS_MEM
106 #include <rte_common.h>
107 #include <rte_debug.h>
111 /* header/extern include files (.x) */
113 #include "gen.x" /* general layer */
114 #include "ssi.x" /* system services */
116 #include "cm5.x" /* common timers */
118 #include "mt_ss.x" /* MTSS specific */
119 #ifdef SS_LOCKLESS_MEMORY
120 #include "mt_ss_wl.x" /* MTSS specific */
121 #endif /* SS_LOCKLESS_MEMORY */
123 #include "ss_queue.x" /* queues */
124 #include "ss_task.x" /* tasking */
125 #include "ss_timer.x" /* timers */
126 #include "ss_strm.x" /* STREAMS */
127 #include "ss_msg.x" /* messaging */
128 #include "ss_mem.x" /* memory management interface */
129 #include "ss_drvr.x" /* driver tasks */
130 #include "ss_gen.x" /* general */
131 #ifdef SS_LOCKLESS_MEMORY
132 #include "cm_llist.x"
134 #include "cm_mem_wl.x" /* common memory manager */
136 #include "cm_mem.x" /* common memory manager */
137 #endif /* SS_LOCKLESS_MEMORY */
138 #include "cm_lte.x" /* common memory manager */
139 /* mt001.301 : Additions */
140 #ifdef SS_LOGGER_SUPPORT
142 #endif /* SS_LOGGER_SUPPORT */
144 /*mt005.301: Cavium Changes */
145 #ifdef SS_SEUM_CAVIUM
146 /* cvmx includes files */
147 #include "cvmx-config.h"
149 #include "cvmx-pow.h"
150 #include "cvmx-tim.h"
151 #include "cvmx-fpa.h"
152 #include "cvmx-helper-fpa.h"
153 #include "cvmx-malloc.h"
154 #endif /* SS_SEUM_CAVIUM */
157 #include "mt_plat_t33.h"
158 #include "mt_plat_t33.x"
159 #include "sys/syscall.h"
162 #if defined(RGL_SPECIFIC_CHANGES) || defined(INTEL_WLS) || defined(SS_USE_WLS_MEM)
164 #include <hugetlbfs.h>
167 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
168 /* general purpose debug zone */
169 char my_buffer2[4096 * 4] = { 0 };
170 char my_buffer[4096] = { 0 };
171 int my_buffer_idx = 0;
174 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
176 struct sigcontext my_uc_mcontext = { 0 };
181 #include <ucontext.h>
185 #define SIGSEGV_STACK_GENERIC
186 #define REGFORMAT "%x\n"
188 #ifdef XEON_SPECIFIC_CHANGES
189 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
192 void dump_external(void);
194 static Void mtDelSigals(Void)
198 memset(&sa, 0, sizeof(struct sigaction));
199 sigemptyset(&sa.sa_mask);
200 sa.sa_handler = SIG_DFL;
201 sigaction(SIGSEGV, &sa, NULL);
203 memset(&sa, 0, sizeof(struct sigaction));
204 sigemptyset(&sa.sa_mask);
205 sa.sa_handler = SIG_DFL;
206 sigaction(SIGILL, &sa, NULL);
210 static void signal_segv(int signum, siginfo_t * info, void *ptr)
212 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
215 ucontext_t *ucontext = (ucontext_t *) ptr;
216 #ifdef XEON_SPECIFIC_CHANGES
218 int *p32 = (int *) 0x2fff0000;
223 printf("\nsegv ooops @ %p\n", info->si_addr);
226 printf("\nSegmentation Fault!\n");
227 printf("\ninfo.si_signo = %d\n", signum);
228 printf("\ninfo.si_errno = %d\n", info->si_errno);
229 printf("\ninfo.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
230 printf("\ninfo.si_addr = %p\n", info->si_addr);
232 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
235 #ifndef RGL_SPECIFIC_CHANGES
236 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
237 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
238 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
239 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
240 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
241 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
242 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
243 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
244 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
245 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
246 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
247 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
248 printf("\nreg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
249 printf("\nreg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
250 printf("\nreg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
251 printf("\nreg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
252 printf("\nreg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
255 printf("\nStack trace (non-dedicated):\n");
257 sz = backtrace(buffer, 50);
258 strings = backtrace_symbols(buffer, sz);
259 for (i = 0; i < sz; ++i)
260 printf("%s\n", strings[i]);
262 printf("\nEnd of stack trace\n");
264 #ifdef XEON_SPECIFIC_CHANGES
269 /* Lets first print our debug information */
270 printf("\nBefore dumping our Debug info\n");
272 printf("\nAfter dumping our Debug info\n");
274 /* Disable the signal and make the enodeb to dump. This will make
275 * eNB to generate the core with dumping the ccpu log
282 /* End printing debug information */
287 /*** TBD: IMPORTANT ***
288 *** The following definition is temporary. This must be removed
289 *** when all products have been updated with latest ssi.h file OR
290 *** all ssi.h files have been updated to contain this definitions
292 /* New error class for FTHA added */
294 #define ERRCLS_FTHA 0x8
295 #endif /* ERRCLS_FTHA */
297 typedef struct _SPThreadCreateArg
299 void *argument; /* argument that is to be passed to the actual pthread */
300 void *(*start_routine) (void *); /* function from which pthread starts */
303 void *pthreadCreateHdlr(void* arg);
305 #ifdef SS_LOCKLESS_MEMORY
306 Buffer *mtTskBuffer1;
307 Buffer *mtTskBuffer2;
309 pthread_t tmpRegTidMap[20];
311 S16 SGlobMemInfoShow(void);
312 #endif /* SS_LOCKLESS_MEMORY */
315 APP_CONTEXT AppContext;
319 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
320 unsigned int tlPost(void *handle);
323 /* forward references */
324 /* mt003.301 Modifications - Moved to ss_gen.x */
325 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
326 Void *mtTskHdlrT2kL2 ARGS((Void*));
327 void mtSigSegvHndlr ARGS((void));
328 void mtSigUsr2Hndlr ARGS((void));
331 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
332 static Void *mtTskHdlr ARGS((void *));
333 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
335 static Void *mtTmrHdlr ARGS((void *));
336 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
338 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
339 static Void mtIntSigHndlr ARGS((int));
340 static Void mtExitClnup ARGS((void));
343 static Void *mtConHdlr ARGS((void *));
347 #ifdef SS_DRVR_SUPPORT
348 static Void *mtIsTskHdlr ARGS((void *));
352 /* mt020.201 - Addition for no command line available */
354 static Void mtGetOpts ARGS((void));
355 /* mt003.301 Additions - File Based task registration made
356 * common for both MULTICORE and NON-MULTICORE
358 static Bool fileBasedMemCfg = FALSE;
361 /* mt033.201 - addition of local function to print the statistics such as
362 * (size vs. numAttempts) and (allocations vs. deallocations)
364 #ifdef SSI_DEBUG_LEVEL1
365 static S16 SPrintRegMemStats ARGS((Region region));
366 #endif /* SSI_DEBUG_LEVEL1 */
368 #ifdef SS_MULTICORE_SUPPORT
369 static SsSTskEntry* ssdAddTmrSTsk(Void);
370 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
371 #ifndef SS_LOCKLESS_MEMORY
372 #ifndef RGL_SPECIFIC_CHANGES
373 static S16 ssdInitMemInfo ARGS((void));
378 /* mt005.301: Cavium changes */
379 #ifdef SS_SEUM_CAVIUM
380 static Void *workRcvTsk ARGS((void *));
381 #endif /* SS_SEUM_CAVIUM */
383 #ifdef SS_THR_REG_MAP
384 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
386 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
387 #endif /* SS_THR_REG_MAP */
389 /* type declarations */
391 #ifdef SS_DRVR_SUPPORT
392 typedef struct mtIsFlag
402 /* public variable declarations */
404 Cntr cfgNumRegs = SS_MAX_REGS;
405 /* Set memory configuration as false.
406 * Set to true if memory configuration through file is successfull.
408 Bool memConfigured = FALSE;
409 /* mt022.201 - Modification for shared memory relay region and memcal tool */
410 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
413 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
415 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
416 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
417 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
418 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
419 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
420 { SS_POOL_STATIC, 0 }
426 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
428 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
429 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
430 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
431 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
432 { SS_POOL_STATIC, 0 }
435 #endif /* INTEL_WLS */
437 #ifdef SS_LOCKLESS_MEMORY
440 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
442 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
443 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
444 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
445 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
446 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
447 { SS_POOL_STATIC, 0 }
451 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
453 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
454 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
455 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
456 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
457 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
458 { SS_POOL_STATIC, 0 }
462 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
464 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
465 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
466 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
467 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
468 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
469 { SS_POOL_STATIC, 0 }
473 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
475 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
476 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
477 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
478 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
479 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
480 { SS_POOL_STATIC, 0 }
484 SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
486 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
487 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
488 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
489 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
490 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
491 { SS_POOL_STATIC, 0 }
495 SS_DFLT_REGION + 6, SS_MAX_POOLS_PER_REG - 1,
497 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
498 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
499 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
500 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
501 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
502 { SS_POOL_STATIC, 0 }
505 #ifndef INTEL_WLS_MEM
508 SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1,
510 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
511 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
512 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
513 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
514 { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
515 { SS_POOL_STATIC, 0 }
520 #endif /* SS_LOCKLESS_MEMORY */
522 /* mt003.301 Modifications - File Based task registration made
523 * common for both MULTICORE and NON-MULTICORE
526 #ifdef SS_LOCKLESS_MEMORY
527 MtDynMemCfg mtDynMemoCfg =
529 SS_MAX_REGS, /* number of regions */
532 SS_DFLT_REGION, /* region id */
533 MT_MAX_BKTS, /* number of buckets */
535 /* block size, no. of blocks, Upper threshold, lower threshold */
536 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
537 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
538 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
539 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
540 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
544 SS_DFLT_REGION + 1, /* region id */
545 MT_MAX_BKTS, /* number of buckets */
547 /* block size, no. of blocks, Upper threshold, lower threshold */
548 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
549 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
550 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
551 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
552 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
556 SS_DFLT_REGION + 2, /* region id */
557 MT_MAX_BKTS, /* number of buckets */
559 /* block size, no. of blocks, Upper threshold, lower threshold */
560 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
561 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
562 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
563 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
564 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
568 SS_DFLT_REGION + 3, /* region id */
569 MT_MAX_BKTS, /* number of buckets */
571 /* block size, no. of blocks, Upper threshold, lower threshold */
572 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
573 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
574 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
575 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
576 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
580 SS_DFLT_REGION + 4, /* region id */
581 MT_MAX_BKTS, /* number of buckets */
583 /* block size, no. of blocks, Upper threshold, lower threshold */
584 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
585 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
586 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
587 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
588 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
592 SS_DFLT_REGION + 5, /* region id */
593 MT_MAX_BKTS, /* number of buckets */
595 /* block size, no. of blocks, Upper threshold, lower threshold */
596 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
597 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
598 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
599 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
600 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
604 SS_DFLT_REGION + 6, /* region id */
605 MT_MAX_BKTS, /* number of buckets */
607 /* block size, no. of blocks, Upper threshold, lower threshold */
608 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
609 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
610 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
611 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
612 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
615 #ifndef INTEL_WLS_MEM
618 SS_DFLT_REGION + 7, /* region id */
619 MT_MAX_BKTS, /* number of buckets */
621 /* block size, no. of blocks, Upper threshold, lower threshold */
622 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
623 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
624 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
625 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
626 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
630 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
633 SS_DFLT_REGION + 7, /* region id */
634 MT_MAX_BKTS, /* number of buckets */
636 /* block size, no. of blocks, Upper threshold, lower threshold */
637 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
638 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
639 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
640 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
648 MtGlobMemCfg mtGlobMemoCfg =
650 MT_MAX_BKTS, /* number of buckets */
653 /* block size, no. of blocks, Upper threshold, lower threshold */
654 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
655 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
656 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
657 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
658 {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
660 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
661 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
662 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
663 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
667 #endif /* SS_LOCKLESS_MEMORY */
669 /* mt022.201 - Modification for memory calculator tool */
670 /* mt018.201 - added memory configuration matrix */
674 SS_MAX_REGS - 1, /* number of regions */
676 #ifndef XEON_SPECIFIC_CHANGES
677 SS_MAX_REGS, /* number of regions */
684 SS_DFLT_REGION, /* region id */
685 MT_MAX_BKTS, /* number of buckets */
686 MT_HEAP_SIZE, /* heap size */
688 #ifndef XEON_SPECIFIC_CHANGES
689 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
690 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
691 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
692 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
693 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
695 {256, 491520}, /* 60 pages of 2M*/
696 {512, 12288}, /* 3 pages of 2M */
697 {2048, 99328}, /* 97 Pages of 2M */
698 {8192, 75008}, /* 293 Pages of 2M */
699 {16384, 4096} /* 32 pages of 2M */
704 #ifndef SS_LOCKLESS_MEMORY
706 SS_DFLT_REGION + 1, /* region id */
707 MT_MAX_BKTS, /* number of buckets */
708 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
710 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
711 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
712 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
713 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
721 #endif /* SS_LOCKLESS_MEMORY */
722 #endif /* INTEL_WLS */
723 #ifdef SS_LOCKLESS_MEMORY
725 SS_DFLT_REGION + 1, /* region id */
726 MT_MAX_BKTS, /* number of buckets */
727 MT_HEAP_SIZE, /* heap size */
729 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
730 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
731 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
732 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
733 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
737 SS_DFLT_REGION + 2, /* region id */
738 MT_MAX_BKTS, /* number of buckets */
739 MT_HEAP_SIZE, /* heap size */
741 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
742 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
743 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
744 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
745 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
749 SS_DFLT_REGION + 3, /* region id */
750 MT_MAX_BKTS, /* number of buckets */
751 MT_HEAP_SIZE, /* heap size */
753 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
754 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
755 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
756 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
757 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
761 SS_DFLT_REGION + 4, /* region id */
762 MT_MAX_BKTS, /* number of buckets */
763 MT_HEAP_SIZE, /* heap size */
765 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
766 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
767 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
768 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
769 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
773 SS_DFLT_REGION + 5, /* region id */
774 MT_MAX_BKTS, /* number of buckets */
775 MT_HEAP_SIZE, /* heap size */
777 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
778 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
779 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
780 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
781 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
785 SS_DFLT_REGION + 6, /* region id */
786 MT_MAX_BKTS, /* number of buckets */
787 MT_HEAP_SIZE, /* heap size */
789 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
790 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
791 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
792 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
793 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
796 #ifndef INTEL_WLS_MEM
799 SS_DFLT_REGION + 7, /* region id */
800 MT_MAX_BKTS, /* number of buckets */
801 MT_HEAP_SIZE, /* heap size */
803 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
804 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
805 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
806 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */
807 {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */
811 #endif /* SS_LOCKLESS_MEMORY */
815 /* mt003.301 Modifications - File Based task registration made
816 * common for both MULTICORE and NON-MULTICORE
817 * bucket info, as different regions may request for different no.
820 MtBktCfg mtBktInfo[MT_MAX_BKTS];
821 S16 msArgc; /* argc */
822 Txt **msArgv; /* argv */
823 S16 msOptInd; /* SGetOpt vars */
824 S8 *msOptArg; /* SGetOpt vars */
827 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
828 typedef struct _MtRegMemSz
834 #ifdef SS_USE_WLS_MEM
835 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
836 static S16 SPartitionWlsDynMem();
837 static S16 SAllocateWlsDynMem();
840 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
845 /* private variable declarations */
846 /* mt018.201 - change mtCMMRegCfg as array of pointers */
847 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
848 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
849 /* mt003.301 - Fixed compilation warnings */
850 /*mt004.301-addede new veriable for FAP*/
851 /*mt010.301 - removed veriable defined for FA*/
854 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
857 void mtSetNtlHdl(unsigned int hdl)
862 unsigned int mtGetNtlHdl()
864 return(osCp.ntl.hdl);
868 void mtGetWlsHdl(void **hdlr)
870 *hdlr = osCp.wls.intf;
873 #ifdef XEON_MULTIPLE_CELL_CHANGES
874 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
875 S16 smWrReadWlsConfigParams (Void);
878 /*WLS Memory Size variables*/
879 #ifdef INTEL_L1_V20_03_ONWARDS
880 uint64_t nWlsMacMemorySize = 0;
881 uint64_t nWlsPhyMemorySize = 0;
884 static int SOpenWlsIntf()
888 #define WLS_DEVICE_NAME "wls0"
890 char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", "gnb0", "--iova-mode=pa"};
891 printf("\nCalling rte_eal_init: ");
892 for (i = 0; i < RTE_DIM(my_argv); i++)
894 printf("%s ", my_argv[i]);
898 if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
899 rte_panic("\nCannot init EAL\n");
902 #ifdef XEON_SPECIFIC_CHANGES
903 #ifdef XEON_MULTIPLE_CELL_CHANGES
904 hdl = WLS_Open(gWrWlsDeviceName, 1);
906 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
910 #ifdef INTEL_L1_V20_03_ONWARDS
911 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, &nWlsMacMemorySize, &nWlsPhyMemorySize);
914 printf("\nERROR: WLS_Open > DEVICE_NAME mismatch. WLS Device Name should be same as 'wls_dev_name' parameter in 'phycfg_xran.xml' file");
917 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
918 #endif /*INTEL_L1_V20_03_ONWARDS*/
926 printf("\nCould not open WLS Interface \n");
941 * Desc: This function is the entry point for the final binary. It
942 * calls SInit() in the common code. It can be replaced by a
943 * user function if required (SInit() must still be called).
945 * Ret: none on success
955 int argc, /* argument count */
956 char **argv /* argument vector */
960 #ifdef XEON_MULTIPLE_CELL_CHANGES
961 /* Read the WLS parameters from the file and copy into global control block */
962 if(smWrReadWlsConfigParams() != ROK)
964 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
966 } /* end of if statement */
969 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
972 #endif /* INTEL_WLS */
976 /* mt003.301 Modifications */
979 printf("\n SInit failed, SSI could not start \n");
980 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
984 /*mt010.301 cleanup part exposed to user*/
995 * Desc: This function is the entry point for the final binary. It
996 * calls SInit() in the common code. It can be replaced by a
997 * user function if required (SInit() must still be called).
999 * Ret: none on success
1009 int argc, /* argument count */
1010 char **argv /* argument vector */
1026 * initialization functions
1031 * Fun: Initialize OS control point
1033 * Desc: This function initializes MTSS-specific information
1034 * in the OS control point.
1043 S16 ssdInitGen(void)
1045 struct sigaction act;
1047 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1048 struct sigaction sa;
1052 /*mt014.301 : 4GMX release related changes*/
1053 #ifdef SS_4GMX_UCORE
1056 /* mt005.301 : Cavium changes */
1057 #ifdef SS_SEUM_CAVIUM
1058 /* set group mask for the core */
1059 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
1060 #endif /* SS_SEUM_CAVIUM */
1062 osCp.dep.sysTicks = 0;
1064 /* mt020.201 - Addition for no command line available */
1066 /* parse command line */
1068 /* mt003.301 Additions */
1069 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
1071 printf("\n File Based Memory configuration failed \n");
1076 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
1077 #ifndef SS_LOCKLESS_MEMORY
1078 #ifdef SS_MULTICORE_SUPPORT
1079 if(memConfigured == FALSE)
1085 /* initialize the started semaphore */
1086 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1091 /* mt028.201 added compile time flag to allow not to mask signals */
1093 /* mask all signals in the main thread */
1095 sigdelset(&set, SIGINT);
1096 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1097 sigdelset(&set, SIGSEGV);
1098 sigdelset(&set, SIGUSR2);
1099 sigdelset(&set, SIGILL);
1100 #ifdef XEON_SPECIFIC_CHANGES
1101 sigdelset(&set, SIGABRT);
1102 sigdelset(&set, SIGTERM);
1103 sigdelset(&set, SIGHUP);
1106 pthread_sigmask(SIG_SETMASK, &set, NULLP);
1107 #endif /* UNMASK_SIG */
1109 /* install a SIGINT handler to shutdown */
1110 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1112 /*Initialize SIGSEGV Signal */
1113 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1115 memset(&sa, 0, sizeof(struct sigaction));
1116 sigemptyset(&sa.sa_mask);
1117 sa.sa_sigaction = signal_segv;
1118 sa.sa_flags = SA_SIGINFO;
1119 #ifndef XEON_SPECIFIC_CHANGES
1120 sigaction(SIGSEGV, &sa, NULL);
1122 memset(&sa, 0, sizeof(struct sigaction));
1123 sigemptyset(&sa.sa_mask);
1124 sa.sa_sigaction = signal_segv;
1125 sa.sa_flags = SA_SIGINFO;
1127 sigaction(SIGILL, &sa, NULL);
1129 if(sigaction(SIGILL, &sa, NULL) != 0)
1131 printf("\nFailed to process sigaction for the SIGILL\n");
1134 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1136 printf("\nFailed to process sigaction for the SIGSEGV\n");
1139 if(sigaction(SIGABRT, &sa, NULL) != 0)
1141 printf("\nFailed to process sigaction for the SIGABRT\n");
1144 if(sigaction(SIGTERM, &sa, NULL) != 0)
1146 printf("\nFailed to process sigaction for the SIGTERM\n");
1149 if(sigaction(SIGHUP, &sa, NULL) != 0)
1151 printf("\nFailed to process sigaction for the SIGHUP\n");
1156 signal (SIGSEGV, mtSigSegvHndlr);
1157 signal (SIGKILL, mtSigSegvHndlr);
1158 signal (SIGUSR2, mtSigUsr2Hndlr);
1163 signal (SIGINT, mtStopHndlr);
1166 act.sa_handler = mtIntSigHndlr;
1167 sigfillset(&act.sa_mask);
1169 if (sigaction(SIGINT, &act, NULLP) != 0)
1175 /* mt040.201 initialise random seed */
1176 osCp.dep.randSeed = time(NULLP);
1184 * Fun: De-initialize OS control point
1186 * Desc: This function reverses the initialization in ssdInitGen().
1195 Void ssdDeinitGen(void)
1199 sem_destroy(&osCp.dep.ssStarted);
1204 #ifdef SS_LOCKLESS_MEMORY
1208 * Fun: ssPutDynMemBlkSet
1210 * Desc: Returns the set of dynamic Blocks into the global region
1213 * Ret: ROK - successful,
1214 * RFAILED - unsuccessful.
1221 S16 ssPutDynMemBlkSet
1223 uint8_t bktIdx, /* Index to bucket list */
1224 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1225 added to global region */
1228 CmMmGlobRegCb *globReg;
1229 CmMmGlobalBktCb *bktCb;
1233 globReg = osCp.globRegCb;
1235 #if (ERRCLASS & ERRCLS_INT_PAR)
1236 if(bktIdx >= globReg->numBkts)
1240 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1242 bktCb = &(globReg->bktTbl[bktIdx]);
1244 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1246 blkPtr = dynMemSetElem->nextBktPtr;
1247 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1248 free((Void *)blkPtr);
1251 dynMemSetElem->nextBktPtr = NULLP;
1252 dynMemSetElem->numFreeBlks = 0;
1259 * Fun: ssGetDynMemBlkSet
1261 * Desc: Gets the set of dynamic memory blocks from the global region
1264 * Ret: ROK - successful,
1265 * RFAILED - unsuccessful.
1272 S16 ssGetDynMemBlkSet
1274 uint8_t bktIdx, /* Index to bucket list */
1275 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1276 with new set values */
1280 CmMmGlobRegCb *globReg;
1281 CmMmGlobalBktCb *bktCb;
1286 globReg = osCp.globRegCb;
1288 #if (ERRCLASS & ERRCLS_INT_PAR)
1289 if(bktIdx >= globReg->numBkts)
1293 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1295 bktCb = &(globReg->bktTbl[bktIdx]);
1296 basePtr = &(dynMemSetElem->nextBktPtr);
1298 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1300 blkPtr = (Data *)malloc(bktCb->size);
1302 basePtr = (CmMmEntry **)blkPtr;
1305 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1309 } /* ssGetDynMemBlkSet */
1314 * Fun: ssPutDynMemBlkSet
1316 * Desc: Returns the set of dynamic Blocks into the global region
1319 * Ret: ROK - successful,
1320 * RFAILED - unsuccessful.
1327 S16 ssPutDynMemBlkSet
1329 uint8_t bktIdx, /* Index to bucket list */
1330 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1331 added to global region */
1332 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1335 CmMmGlobRegCb *globReg;
1336 CmMmGlobalBktCb *bktCb;
1338 CmMmBlkSetElement *globMemNode;
1342 globReg = osCp.globRegCb;
1344 #if (ERRCLASS & ERRCLS_INT_PAR)
1345 if(bktIdx >= globReg->numBkts)
1349 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1351 bktCb = &(globReg->bktTbl[bktIdx]);
1353 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1354 try lock is used as it is not required to block as it will be taken
1355 in the next go else it will be blocked for lock as we have to get the
1358 SLock(&(bktCb->bucketLock));
1364 /* Get a free node from the free node linked list */
1365 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1366 if(lstNode == NULLP)
1368 SUnlock(&(bktCb->bucketLock));
1372 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1374 /* Copy the content of the received element information on to free node
1375 * and add it to valid linked list */
1376 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1377 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1378 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1379 dynMemSetElem->numFreeBlks = 0;
1380 dynMemSetElem->nextBktPtr = NULLP;
1382 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1384 SUnlock(&(bktCb->bucketLock));
1392 * Fun: ssGetDynMemBlkSet
1394 * Desc: Gets the set of dynamic memory blocks from the global region
1397 * Ret: ROK - successful,
1398 * RFAILED - unsuccessful.
1400 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1406 S16 ssGetDynMemBlkSet
1408 uint8_t bktIdx, /* Index to bucket list */
1409 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1410 with new set values */
1411 uint32_t doNotBlockForLock /* Boolean whether to block for lock or not */
1414 CmMmGlobRegCb *globReg;
1415 CmMmGlobalBktCb *bktCb;
1417 CmMmBlkSetElement *globMemNode;
1421 globReg = osCp.globRegCb;
1423 #if (ERRCLASS & ERRCLS_INT_PAR)
1424 if(bktIdx >= globReg->numBkts)
1428 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1430 bktCb = &(globReg->bktTbl[bktIdx]);
1432 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1433 try lock is used as it is not required to block as it will be taken
1434 in the next go else it will be blocked for lock as we have to get the
1437 SLock(&(bktCb->bucketLock));
1442 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1444 if(lstNode == NULLP)
1446 SUnlock(&(bktCb->bucketLock));
1450 /* Delete the node from the valid linked list and copy the values of the
1451 * elements of structrues into pointer */
1452 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1453 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1454 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1455 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1457 /* Add this node to the free node linked list */
1458 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1460 SUnlock(&(bktCb->bucketLock));
1464 } /* ssGetDynMemBlkSet */
1467 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1468 uint32_t gDynMemAlrm[4];
1469 static uint32_t memoryCheckCounter;
1471 uint32_t isMemThreshReached(Region reg)
1473 CmMmGlobRegCb *globReg;
1474 CmMmGlobalBktCb *bktCb;
1475 uint8_t bktIdx= reg;
1477 globReg = osCp.globRegCb;
1479 #if (ERRCLASS & ERRCLS_INT_PAR)
1480 if(bktIdx >= globReg->numBkts)
1484 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1486 bktCb = &(globReg->bktTbl[bktIdx]);
1488 if(gDynMemAlrm[bktIdx])
1490 // printf ("\nunder memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1491 SLock(&(bktCb->bucketLock));
1492 if(bktCb->listValidBktSet.count > 25)
1494 gDynMemAlrm[bktIdx] = FALSE;
1495 // printf ("\nrecoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1497 SUnlock(&(bktCb->bucketLock));
1503 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1505 // printf ("\nCHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1506 SLock(&(bktCb->bucketLock));
1507 if(bktCb->listValidBktSet.count < 15 )
1508 gDynMemAlrm[bktIdx] = TRUE;
1509 memoryCheckCounter = 0;
1510 SUnlock(&(bktCb->bucketLock));
1516 #endif /* USE_MALLOC */
1517 #endif /* SS_LOCKLESS_MEMORY */
1519 #ifdef SS_USE_ICC_MEMORY
1522 * Fun: Initialize region/pool tables
1524 * Desc: This function initializes MTSS-specific information
1525 * in the region/pool tables and configures the common
1526 * memory manager for use.
1535 Void * ssGetIccHdl(Region region)
1537 CmMmDynRegCb *dynRegCb;
1539 /* Klock work fix ccpu00148484 */
1540 if(!(region < SS_MAX_REGS))
1545 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1547 return (dynRegCb->iccHdl);
1549 #endif /* SS_USE_ICC_MEMORY */
1551 #ifdef T2K_MEM_LEAK_DBG
1552 RegionMemLeakInfo regMemLeakInfo;
1553 #endif /* T2K_MEM_LEAK_DBG */
1555 #ifdef SS_USE_WLS_MEM
1556 static S16 SPartitionWlsDynMem()
1559 uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1561 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1563 mtDynMemSz[i].startAddr = bktMemStrtAddr;
1564 bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1567 printf("\nGlobal Memory Info: \n");
1568 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1570 printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1575 static S16 SAllocateWlsDynMem()
1580 memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1582 for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1584 reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1585 mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1587 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1588 #ifdef INTEL_L1_V20_03_ONWARDS
1589 nWlsMacMemorySize+nWlsPhyMemorySize);
1590 #elif INTEL_L1_V19_10
1593 (reqdMemSz + (4 * 1024 * 1024)));
1595 printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1596 SPartitionWlsDynMem();
1604 S16 SPartitionWlsMemory()
1609 uint64_t pageSize[1], hugePageSize;
1612 long int pageSize[1], hugePageSize;
1615 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1617 uint8_t *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1619 gethugepagesizes(pageSize,1);
1620 hugePageSize = pageSize[0];
1621 for (i = 0; i < 1; i++)
1623 mtRegMemSz[i].startAddr = regMemStrtAddr;
1624 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1626 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1627 reqdSz = numHugePg * hugePageSize;
1628 regMemStrtAddr += reqdSz;
1629 #ifdef T2K_MEM_LEAK_DBG
1630 /* Since wls is region 0 */
1631 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1632 regMemLeakInfo.numActvRegions++;
1633 #endif /* T2K_MEM_LEAK_DBG */
1635 //Store last region addr for validation
1636 mtRegMemSz[i].startAddr = regMemStrtAddr;
1640 #ifdef SS_MEM_WL_DEBUG
1641 Void SChkAddrValid(int type, int region, PTR ptr)
1643 char *tryPtr = NULL;
1644 if(type == 0) //Global
1646 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1647 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1649 printf("\n****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1655 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1657 printf("\n****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1663 #endif /* SS_MEM_WL_DEBUG */
1665 S16 SPartitionStaticMemory(uint8_t *startAddr)
1670 uint8_t *regMemStrtAddr = (uint8_t *)startAddr;
1673 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1674 for (i = 1; i < mtMemoCfg.numRegions; i++)
1676 mtRegMemSz[i].startAddr = regMemStrtAddr;
1677 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1678 regMemStrtAddr += reqdSz;
1679 #ifdef T2K_MEM_LEAK_DBG
1680 { /* Since region 1 onwards are used for non wls */
1681 regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1682 regMemLeakInfo.numActvRegions++;
1684 #endif /* T2K_MEM_LEAK_DBG */
1688 S16 SAllocateWlsMem()
1696 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1697 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1699 for (i = 0; i < 1; i++)
1701 /* allocate space for the region */
1702 region = &mtMemoCfg.region[i];
1703 reqdMemSz += region->heapsize;
1704 mtRegMemSz[i].reqdSz += region->heapsize;
1706 for (j = 0; j < region->numBkts; j++)
1708 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1709 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1712 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1713 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1715 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1717 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1719 SPartitionWlsMemory();
1722 S16 SAllocateStaticMem()
1731 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1733 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1734 for (i = 1; i < mtMemoCfg.numRegions; i++)
1736 /* allocate space for the region */
1737 region = &mtMemoCfg.region[i];
1738 reqdMemSz += region->heapsize;
1739 mtRegMemSz[i].reqdSz += region->heapsize;
1741 for (j = 0; j < region->numBkts; j++)
1743 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1744 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1748 startAddr = malloc(reqdMemSz + (1024 * 10));
1750 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1752 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1754 SPartitionStaticMemory(startAddr);
1757 #endif /* INTEL_WLS */
1763 * Fun: Initialize region/pool tables
1765 * Desc: This function initializes MTSS-specific information
1766 * in the region/pool tables and configures the common
1767 * memory manager for use.
1776 S16 ssdInitMem(void)
1778 /* mt018.201 - added local variable */
1782 MtRegCfg *region = NULLP;
1783 Txt errMsg[256] = {'\0'};
1784 #ifdef SS_LOCKLESS_MEMORY
1785 CmMmDynRegCb *dynRegCb =0;
1786 #ifdef SS_USE_ICC_MEMORY
1788 CmMmGlobRegCb *globReg = NULLP;
1791 #endif /* SS_LOCKLESS_MEMORY */
1794 /* Use the default SSI memory manager if the ICC memory manager is not
1795 * avilable. If ICC memory manager is avilable, it will be used for
1796 * all sharable memory allocation and de-allocation */
1797 #ifdef SS_LOCKLESS_MEMORY
1798 #ifdef SS_USE_ICC_MEMORY
1799 #ifndef YS_PHY_3_8_2
1801 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1803 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1804 if(dynRegCb == NULLP)
1808 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1810 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1812 dynRegCb->region = i;
1813 cmMmDynRegInit(dynRegCb);
1814 printf("\niccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1817 /* ysIccHdl = dynRegCb->iccHdl; */
1820 /* Initialize the global region first */
1821 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1823 if(osCp.globRegCb == NULLP)
1828 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1830 #ifdef SS_USE_WLS_MEM
1831 SAllocateWlsDynMem();
1834 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1836 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1837 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1838 globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1839 printf("\nStarting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1842 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1844 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1847 if(globReg->bktTbl[i].startAddr == NULLP)
1851 globReg->bktTbl[i].poolId = i;
1852 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1853 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1854 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1857 globReg->numBkts = mtGlobMemoCfg.numBkts;
1858 cmMmGlobRegInit(globReg);
1860 /* Initialize the dynamic task regions and sanity check for the theshold
1862 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1864 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1865 if(dynRegCb == NULLP)
1869 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1871 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1872 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1873 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1874 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1876 #ifdef XEON_SPECIFIC_CHANGES
1881 dynRegCb->bktTbl[k].poolId = k;
1882 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1883 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1884 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1885 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1886 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1888 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1891 dynRegCb->region = i;
1892 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1893 cmMmDynRegInit(dynRegCb);
1895 #endif /* SS_USE_ICC_MEMORY */
1896 #endif /* SS_LOCKLESS_MEMORY */
1898 #ifdef T2K_MEM_LEAK_DBG
1900 /* Initailize mem leak tool memorys for debguing */
1901 regMemLeakInfo.numActvRegions=0;
1902 for(reg=0; reg <SS_MAX_REGS; reg++)
1904 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1905 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1906 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1907 regMemLeakInfo.regStartAddr[reg] = 0;
1910 regMemLeakInfo.regStartAddr[reg] = 0;
1911 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1913 printf("\n mutex init failed\n");
1919 /* Now allocate WLS memory */
1921 SAllocateStaticMem();
1923 /* mt018.201 - CMM Initialization */
1924 for (i = 0; i < mtMemoCfg.numRegions; i++)
1926 /* allocate space for the region control block */
1927 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1928 #ifdef TENB_RTLIN_CHANGES
1929 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1931 if (mtCMMRegCb[i] == NULLP)
1933 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1934 for the Region:%d control block\n",i);
1936 for (k = 0; k < i; k++)
1938 cmMmRegDeInit(mtCMMRegCb[k]);
1939 free(mtCMMRegCfg[k]->vAddr);
1940 free(mtCMMRegCb[k]);
1941 free(mtCMMRegCfg[k]);
1946 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1947 #ifdef TENB_RTLIN_CHANGES
1948 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1950 if (mtCMMRegCfg[i] == NULLP)
1952 for (k = 0; k < i; k++)
1954 cmMmRegDeInit(mtCMMRegCb[k]);
1955 free(mtCMMRegCfg[k]->vAddr);
1956 free(mtCMMRegCb[k]);
1957 free(mtCMMRegCfg[k]);
1959 free(mtCMMRegCb[i]);
1964 /* allocate space for the region */
1965 region = &mtMemoCfg.region[i];
1966 mtCMMRegCfg[i]->size = region->heapsize;
1967 for (j = 0; j < region->numBkts; j++)
1969 /* mt033.201 - addition for including the header size while computing the total size */
1970 #ifdef SSI_DEBUG_LEVEL1
1971 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1972 (region->bkt[j].numBlks);
1974 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1975 #endif /* SSI_DEBUG_LEVEL1 */
1978 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1980 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1983 #ifdef XEON_SPECIFIC_CHANGES
1984 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1985 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1987 #ifdef TENB_RTLIN_CHANGES
1988 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1991 if (mtCMMRegCfg[i]->vAddr == NULLP)
1993 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1994 for the Region:%d \n",i);
1996 for (k = 0; k < i; k++)
1998 cmMmRegDeInit(mtCMMRegCb[k]);
1999 free(mtCMMRegCfg[k]->vAddr);
2000 free(mtCMMRegCb[k]);
2001 free(mtCMMRegCfg[k]);
2003 free(mtCMMRegCb[i]);
2004 free(mtCMMRegCfg[i]);
2009 /* set up the CMM configuration structure */
2010 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
2011 mtCMMRegCfg[i]->chFlag = 0;
2012 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
2013 mtCMMRegCfg[i]->numBkts = region->numBkts;
2015 for (j = 0; j < region->numBkts; j++)
2017 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
2018 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
2021 /* initialize the CMM */
2022 #ifdef SS_LOCKLESS_MEMORY
2023 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2025 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2026 #endif /* SS_LOCKLESS_MEMORY */
2028 for (k = 0; k < i; k++)
2030 cmMmRegDeInit(mtCMMRegCb[k]);
2031 free(mtCMMRegCfg[k]->vAddr);
2032 free(mtCMMRegCb[k]);
2033 free(mtCMMRegCfg[k]);
2035 free(mtCMMRegCfg[i]->vAddr);
2036 free(mtCMMRegCb[i]);
2037 free(mtCMMRegCfg[i]);
2042 /* initialize the STREAMS module */
2043 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
2044 if (region->regionId == 0)
2046 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
2048 for (k = 0; k < i; k++)
2050 cmMmRegDeInit(mtCMMRegCb[k]);
2051 free(mtCMMRegCfg[k]->vAddr);
2052 free(mtCMMRegCb[k]);
2053 free(mtCMMRegCfg[k]);
2055 cmMmRegDeInit(mtCMMRegCb[i]);
2056 free(mtCMMRegCfg[i]->vAddr);
2057 free(mtCMMRegCb[i]);
2058 free(mtCMMRegCfg[i]);
2063 /* mt001.301 : Additions */
2064 #ifdef SS_MEM_LEAK_STS
2066 #endif /* SS_MEM_LEAK_STS */
2074 * Fun: De-initialize region/pool tables
2076 * Desc: This function reverses the initialization in ssdInitMem().
2085 Void ssdDeinitMem(void)
2087 /* mt018.201 - added local variables */
2090 /* mt008.301 Additions */
2091 #ifdef SS_MEM_LEAK_STS
2092 cmDeinitMemLeakMdl();
2093 #endif /* SS_MEM_LEAK_STS */
2095 for (i = 0; i < mtMemoCfg.numRegions; i++)
2097 cmMmRegDeInit(mtCMMRegCb[i]);
2098 free(mtCMMRegCfg[i]->vAddr);
2099 free(mtCMMRegCb[i]);
2100 free(mtCMMRegCfg[i]);
2109 * Fun: Initialize task table
2111 * Desc: This function initializes MTSS-specific information
2112 * in the task table.
2121 S16 ssdInitTsk(void)
2123 /* mt001.301 : Additions */
2124 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2125 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2126 uint32_t tskInd = 0;
2127 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2131 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2132 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2133 /* initialize system task information */
2134 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2136 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2138 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2145 * Fun: Deinitialize task table
2147 * Desc: This function reverses the initialization perfomed in
2157 Void ssdDeinitTsk(void)
2164 #ifdef SS_DRVR_SUPPORT
2167 * Fun: Initialize driver task table
2169 * Desc: This function initializes MTSS-specific information
2170 * in the driver task table.
2179 S16 ssdInitDrvr(void)
2183 pthread_attr_t attr;
2188 /* initialize the dependent portion of the driver task entries */
2189 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2191 osCp.drvrTskTbl[i].dep.flag = FALSE;
2195 /* create pipe for communication between SSetIntPend() and
2196 * the isTskHdlr thread.
2198 if (pipe(osCp.dep.isFildes) != 0)
2204 /* create the isTskHdlr thread */
2205 pthread_attr_init(&attr);
2206 /* mt021.201 - Addition to set stack size */
2207 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2208 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2209 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2210 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2212 /* mt020.201 - Addition for destroying thread attribute object attr */
2213 pthread_attr_destroy(&attr);
2219 /*mt014.301 : 4GMX release related changes*/
2220 #ifdef SS_4GMX_UCORE
2228 /* mt020.201 - Addition for destroying thread attribute object attr */
2229 pthread_attr_destroy(&attr);
2238 * Fun: Deinitialize driver information
2240 * Desc: This function reverses the initialization performed in
2250 Void ssdDeinitDrvr(void)
2252 /* mt008.301: Terminate the Driver Task on exit */
2253 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2256 TL_Close(AppContext.hUAII);
2257 if (clusterMode == RADIO_CLUSTER_MODE)
2259 TL_Close(AppContext.hUAII_second);
2265 #endif /* SS_DRVR_SUPPORT */
2270 * Fun: Initialize timer table
2272 * Desc: This function initializes MTSS-specific information
2273 * in the timer table.
2282 S16 ssdInitTmr(void)
2284 pthread_attr_t attr;
2285 struct sched_param param_sched;
2286 /* mt010.21: addition */
2288 #ifdef SS_MULTICORE_SUPPORT
2290 #endif /* SS_MULTICORE_SUPPORT */
2291 #ifdef SS_THR_REG_MAP
2292 uint32_t threadCreated = FALSE;
2293 #endif /* SS_THR_REG_MAP */
2297 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2298 /* mt010.21: addition */
2299 osCp.dep.tmrTqCp.nxtEnt = 0;
2300 for (i=0; i< SS_MAX_TMRS; i++)
2302 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2305 #ifdef SS_MULTICORE_SUPPORT
2306 sTsk = ssdAddTmrSTsk();
2311 #endif /* SS_MULTICORE_SUPPORT */
2312 /* create the timer handler thread */
2313 pthread_attr_init(&attr);
2314 /* mt021.201 - Addition to set stack size */
2315 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2316 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2317 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2318 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2319 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2320 pthread_attr_setschedparam(&attr, ¶m_sched);
2323 #ifdef SS_THR_REG_MAP
2324 /* When the thread is created, we check for the memory mapping table if
2325 * threadId can be placed in thread memory map table. If it is not able to place
2326 * threadId is stored in tmporary array. Once thread is created successful,
2327 * thread_cancel is sent for each thread which are created before. All the
2328 * threads are made to wait on sema which is cancel point for thread.
2330 while(threadCreated == FALSE)
2333 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2335 /* mt020.201 - Addition for destroying thread attribute object attr */
2336 pthread_attr_destroy(&attr);
2341 #ifdef SS_THR_REG_MAP
2342 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2345 #endif /* SS_THR_REG_MAP */
2346 #ifdef SS_MEM_WL_DEBUG
2347 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2350 /* mt020.201 - Addition for destroying thread attribute object attr */
2351 pthread_attr_destroy(&attr);
2360 * Fun: Deinitialize timer table
2362 * Desc: This function reverses the initialization performed in
2372 Void ssdDeinitTmr(void)
2374 #ifdef SS_MULTICORE_SUPPORT
2377 #endif /* SS_MULTICORE_SUPPORT */
2380 #ifdef SS_MULTICORE_SUPPORT
2381 ret = SLock(&osCp.sTskTblLock);
2385 #if (ERRCLASS & ERRCLS_DEBUG)
2386 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2387 "Could not lock system task table");
2391 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2392 /* clean up the system task entry */
2396 SDestroyLock(&sTsk->lock);
2397 ssDestroyDmndQ(&sTsk->dQ);
2400 /* make this entry available in the system task table */
2401 sTsk->nxt = osCp.nxtSTskEntry;
2402 osCp.nxtSTskEntry = 0;
2406 /* unlock the system task table */
2407 SUnlock(&osCp.sTskTblLock);
2409 #endif /* SS_MULTICORE_SUPPORT */
2410 /* mt008.301: Terminate the timer thread on exit */
2411 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2421 * Desc: Pre-tst() initialization.
2430 S16 ssdInitLog(void)
2432 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2436 pthread_attr_t attr;
2439 #endif /* CONSTDIO */
2444 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2449 osCp.dep.conInFp = (FILE *) stdin;
2450 osCp.dep.conOutFp = (FILE *) stdout;
2451 /* added compile time flag CONRD: mt017.21 */
2455 /* disable canonical input processing */
2456 fd = fileno(osCp.dep.conInFp);
2457 if ((tcgetattr(fd, &tio)) != 0)
2459 printf("\nError: disable canonical input processing\n");
2463 tio.c_lflag &= ~ICANON;
2464 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2465 tio.c_cc[VTIME] = 0;
2466 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2468 printf("\nError: while tcsetattr() processing\n");
2472 #endif /* CONSTDIO */
2475 /* set up the input fd to block when no data is available */
2476 fd = fileno(osCp.dep.conInFp);
2477 flags = fcntl(fd, F_GETFL, &flags);
2478 flags &= ~O_NONBLOCK;
2479 if (fcntl(fd, F_SETFL, flags) == -1)
2481 printf("\nError: while fcntl processing\n");
2486 /* create the console handler thread */
2487 pthread_attr_init(&attr);
2488 /* mt021.201 - Addition to set stack size */
2489 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2490 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2491 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2494 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2496 /* mt020.201 - Addition for destroying thread attribute object attr */
2497 pthread_attr_destroy(&attr);
2499 printf("\nError: Logging Thread creation failed \n");
2503 /* mt020.201 - Addition for destroying thread attribute object attr */
2504 pthread_attr_destroy(&attr);
2518 * Desc: This function reverses the initialization performed in
2528 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2529 Void ssdDeinitLog(void)
2531 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2534 /* mt008.301: Terminate the console reader on exit */
2535 while(pthread_cancel(osCp.dep.conHdlrTID));
2541 /* mt001.301 : Additions */
2545 S16 ssdInitWatchDog(uint16_t port)
2548 Txt prntBuf[PRNTSZE];
2551 #ifdef SS_WATCHDOG_IPV6
2552 struct sockaddr_in6 tmpaddr;
2554 struct sockaddr_in tmpaddr;
2555 #endif /* SS_WATCHDOG_IPV6 */
2556 #ifdef SS_MULTIPLE_PROCS
2557 ProcId procId = SS_WD_WDPROC;
2558 if (SAddProcIdLst(1, &procId) != ROK)
2562 #endif /* SS_MULTIPLE_PROCS */
2565 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2567 /* Create a watch dog system task */
2568 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2570 /* Create a watch dog reveiver system task */
2571 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2573 /* Register and attach watch dog TAPA task */
2574 #ifdef SS_MULTIPLE_PROCS
2575 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2576 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2578 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2579 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2580 #endif /* SS_MULTIPLE_PROCS */
2581 /* Register and attach watch dog receiver TAPA task */
2582 #ifdef SS_MULTIPLE_PROCS
2583 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2584 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2586 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2587 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2588 #endif /* SS_MULTIPLE_PROCS */
2590 #ifndef SS_MULTIPLE_PROCS
2591 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2592 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2594 osCp.wdCp.watchDgPst.srcProcId = procId;
2595 osCp.wdCp.watchDgPst.dstProcId = procId;
2596 #endif /* SS_MULTIPLE_PROCS */
2598 /* Initialise the pst structure */
2599 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2600 /* Initialize the watch dog timer resolution default is 1 sec */
2602 cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2603 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2604 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2605 for(idx = 0; idx < 1; idx++)
2607 osCp.wdCp.watchDgTs[idx].first = NULLP;
2608 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2610 #ifdef SS_MULTIPLE_PROCS
2611 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2613 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2614 #endif /* SS_MULTIPLE_PROCS */
2616 /* Create the watch dog receiver socket */
2617 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2618 if(osCp.wdCp.globWd.sock == -1)
2620 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2624 #ifdef SS_WATCHDOG_IPV6
2625 tmpaddr.sin6_len = sizeof(tmpadDr);
2626 tmpaddr.sin6_family = AF_INET6;
2627 tmpaddr.sin6_addr = in6addr_any;
2628 tmpaddr.sin6_port = htons(port);
2630 tmpaddr.sin_family = AF_INET;
2631 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2632 tmpaddr.sin_port = htons(port);
2633 #endif /* SS_WATCHDOG_IPV6 */
2635 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2638 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2642 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2646 #ifndef SS_MULTIPLE_PROCS
2647 pst.srcProcId = SFndProcId();
2648 pst.dstProcId = SFndProcId();
2650 pst.srcProcId = procId;
2651 pst.dstProcId = procId;
2652 #endif /* SS_MULTIPLE_PROCS */
2653 pst.event = EVTSSHRTBTREQ;
2654 ssdInitWatchDgPst(&pst);
2655 SPstTsk(&pst, mBuf);
2660 S16 ssdInitWatchDgPst(Pst *pst)
2663 pst->selector = SS_LOOSE_COUPLING;
2665 pst->region = DFLT_REGION; /* region */
2666 pst->pool = DFLT_POOL; /* pool */
2668 pst->prior = PRIOR0; /* priority */
2669 pst->route = RTESPEC; /* route */
2671 pst->dstEnt = ENTHB; /* destination entity */
2673 pst->srcEnt = ENTDW; /* source entity */
2679 #ifdef SS_MULTIPLE_PROCS
2680 S16 ssdWatchDgActvTmr
2687 S16 ssdWatchDgActvTmr(Void)
2688 #endif /* SS_MULTIPLE_PROCS */
2691 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2696 Void ssdWatchDgTmrEvt
2698 PTR cb, /* control block */
2699 S16 event /* timer number */
2702 /* mt003.301 Fixed warings */
2706 Txt prntBuf[PRNTSZE];
2715 SPrint("Timer Heartbeat Request Expired");
2717 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2722 SLock(&osCp.wdCp.wdLock);
2723 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2725 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2727 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2729 if(osCp.wdCp.globWd.callback != 0)
2731 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2735 SUnlock(&osCp.wdCp.wdLock);
2737 if(!osCp.wdCp.globWd.watchdogStop)
2739 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2740 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2750 Void ssdStartWatchDgTmr
2761 Txt prntBuf[PRNTSZE];
2765 /* mt003.301 Modifications */
2768 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2769 if(event == SS_TMR_HRTBT)
2771 SPrint("\nSTART SS_TMR_HRTBT");
2778 SLock(&osCp.wdCp.wdLock);
2779 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2781 osCp.wdCp.globWd.wdsta[i].status = 0;
2783 SUnlock(&osCp.wdCp.wdLock);
2785 arg.tq = osCp.wdCp.watchDgTs;
2786 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2787 arg.timers = osCp.wdCp.watchDgTmr;
2788 arg.cb = (PTR)NULLP;
2790 arg.wait = osCp.wdCp.globWd.timeout = wait;
2798 Void ssdStopWatchDgTmr
2807 Txt prntBuf[PRNTSZE];
2811 /* mt003.301 Modifications */
2814 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2815 if(event == SS_TMR_HRTBT)
2817 SPrint("STOP SS_TMR_HRTBT");
2821 SLock(&osCp.wdCp.wdLock);
2822 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2824 osCp.wdCp.globWd.wdsta[i].status = 0;
2826 SUnlock(&osCp.wdCp.wdLock);
2829 arg.tq = osCp.wdCp.watchDgTs;
2830 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2831 arg.timers = osCp.wdCp.watchDgTmr;
2832 arg.cb = (PTR)NULLP;
2851 Txt prntBuf[PRNTSZE];
2853 struct sockaddr_in tmpaddr;
2854 char hbMsg[SS_WD_HB_MSG_SIZE];
2861 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2865 /* Pack the message */
2866 strcpy(hbMsg, "<HB>REQ</HB>");
2868 /* Send the heartbeat messages to all the configured nodes */
2869 SLock(&osCp.wdCp.wdLock);
2870 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2872 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2877 /* Identify the destination node */
2878 #ifdef SS_WATCHDOG_IPV6
2879 tmpaddr.sin6_len = sizeof(tmpaddr);
2880 tmpaddr.sin6_family = AF_INET6;
2881 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2882 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2884 tmpaddr.sin_family = AF_INET;
2885 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2886 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2887 #endif /* SS_WATCHDOG_IPV6 */
2889 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2893 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2894 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2901 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2906 SUnlock(&osCp.wdCp.wdLock);
2911 #endif /* SS_WATCHDOG */
2915 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2921 * Desc: This function gets command line options.
2930 static Void mtGetOpts(void)
2937 FILE *memOpt; /* memory options file pointer */
2940 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2946 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2948 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2954 #ifdef SS_LOCKLESS_MEMORY
2969 osCp.dep.fileOutFp = (FILE *)NULLP;
2971 /* initialize memOpt */
2972 memOpt = (FILE *) NULLP;
2979 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2984 /* mt001.301 : Additions */
2985 #ifdef SS_MEM_LEAK_STS
2987 cmMemOpenMemLkFile(msOptArg);
2991 osCp.dep.fileOutFp = fopen(msOptArg, "w");
2994 fileBasedMemCfg = TRUE;
2995 memOpt = fopen(msOptArg, "r");
2997 /* if file does not exist or could not be opened then use the
2998 * default memory configuration as defined in mt_ss.h
3000 if (memOpt == (FILE *) NULLP)
3002 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3003 be opened, using default mem configuration\n", msOptArg);
3008 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3010 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3016 case 0: /*** INPUT: Number of regions ***/
3017 sscanf(line, "%ld", (long *) &numReg);
3018 mtMemoCfg.numRegions = numReg;
3019 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3021 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3027 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3028 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3029 if(numBkts > MT_MAX_BKTS)
3031 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3035 if(numPools > SS_MAX_POOLS_PER_REG)
3037 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3042 * Delay updation from local variable to global
3043 * structure of number of regions and heap data to
3044 * counter error conditions present above.
3046 for(idx = 0; idx < cfgNumRegs; idx++)
3048 mtMemoCfg.region[idx].numBkts = numBkts;
3049 cfgRegInfo[idx].region = idx;
3050 cfgRegInfo[idx].numPools = numPools;
3052 * Initialize the pool info as static type with size zero
3054 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3056 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3057 cfgRegInfo[idx].pools[poolIdx].size = 0;
3062 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3063 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3065 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3067 if(bktIdx >= numBkts)
3069 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3074 mtBktInfo[bktIdx].blkSize = bktSz;
3076 if(bktUpdtCnt == numBkts)
3078 i++; /*done reading bkt info, start reading individual region info*/
3082 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3083 sscanf(line,"%ld",(long *) ®Id);
3084 if(regId >= mtMemoCfg.numRegions)
3086 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3087 #ifndef XEON_SPECIFIC_CHANGES
3092 mtMemoCfg.region[regId].regionId = regId;
3095 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3096 if(bktUpdtCnt < numBkts)
3098 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3099 if(bktIdx >= numBkts)
3101 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3106 if(bktIdx < MT_MAX_BKTS)
3108 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3109 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3110 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3111 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3114 if(bktUpdtCnt == numBkts)
3121 case 5: /* INPUT: Heapsize ***/
3122 sscanf(line, "%ld", (long *) &heapSz);
3123 mtMemoCfg.region[regId].heapsize = heapSz;
3125 if(regUpdtCnt != mtMemoCfg.numRegions)
3134 #ifdef SS_LOCKLESS_MEMORY
3136 sscanf(line, "%ld", (long *) &numBkts);
3137 mtGlobMemoCfg.numBkts = numBkts;
3138 #ifndef XEON_SPECIFIC_CHANGES
3139 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3142 #ifdef XEON_SPECIFIC_CHANGES
3143 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3144 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3145 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3147 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3150 mtDynMemoCfg.region[idx].regionId = idx;
3151 mtDynMemoCfg.region[idx].numBkts = numBkts;
3159 if(bktUpdtCnt < numBkts)
3161 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3162 (long *) &bktSz, (long *) &bktNum,
3163 (long *) &bktSetSize, (long *) &bktRelThr,
3164 (long *) &bktAqurThr);
3165 /* Klock work fix ccpu00148484 */
3166 if(bktIdx < SS_MAX_POOLS_PER_REG)
3168 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3169 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3170 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3171 #ifdef XEON_SPECIFIC_CHANGES
3172 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3173 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3174 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3176 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3178 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3184 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3186 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3187 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3188 #ifdef XEON_SPECIFIC_CHANGES
3189 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3190 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3191 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3197 #ifdef XEON_SPECIFIC_CHANGES
3198 if(bktUpdtCnt == numBkts)
3204 case 8: /* INPUT: Global Heapsize ***/
3205 sscanf(line, "%ld", (long *) &heapSz);
3206 mtGlobMemoCfg.heapSize = heapSz;
3207 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3215 memConfigured = FALSE;
3219 memConfigured = TRUE;
3227 /* mt028.201: modification: multiple procs support related changes */
3228 #ifndef SS_MULTIPLE_PROCS
3231 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3233 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3236 #else /* SS_MULTIPLE_PROCS */
3240 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3242 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3244 SAddProcIdLst(1, &procId);
3247 #endif /* SS_MULTIPLE_PROCS */
3251 osCp.configFilePath = msOptArg;
3275 * Desc: Get options from command line
3277 * Ret: option - success
3279 * EOF - end of options
3281 * Notes: Handles command lines like the following
3284 * then command line should look like this...
3285 * -a foo -b foo1 -c -d foo
3289 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3294 * nloops = atoi(msArgv[msOptInd]);
3297 * state1 = atoi(msArgv[msOptInd]);
3309 int argc, /* argument count */
3310 char **argv, /* argument value */
3311 char *opts /* options */
3314 /* mt020.201 - Removed for no command line */
3322 /* mt020.201 - Addition for no command line */
3334 /*mt013.301 : Changes as per coding standards*/
3335 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3341 if (!strcmp(argv[msOptInd], "--"))
3346 else if (argv[msOptInd][0] != '-')
3354 c = argv[msOptInd][sp];
3355 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3357 if (argv[msOptInd][++sp] == '\0')
3368 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3371 if (++msOptInd >= (S16) argc)
3376 else msOptArg = argv[msOptInd++];
3383 if (argv[msOptInd][++sp] == '\0')
3395 #endif /* NOCMDLINE */
3403 * Desc: This function starts system services execution; the
3404 * permanent tasks are started and the system enters a
3421 /* mt025.201 - Modification for adding lock to timer handler */
3422 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3424 sem_post(&osCp.dep.ssStarted);
3433 * indirect interface functions to system services service user
3439 * Fun: ssdAttachTTsk
3441 * Desc: This function sends the initial tick message to a TAPA
3442 * task if the task is a permanent task.
3453 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3460 if (tTsk->tskType == SS_TSK_PERMANENT)
3462 /* Send a permanent tick message to this task, to start
3465 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3468 #if (ERRCLASS & ERRCLS_DEBUG)
3469 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3474 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3475 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3477 /* set up post structure */
3478 /* mt028.201: modification: multiple procs support related changes */
3479 #ifndef SS_MULTIPLE_PROCS
3480 mInfo->pst.dstProcId = SFndProcId();
3481 mInfo->pst.srcProcId = SFndProcId();
3482 #else /* SS_MULTIPLE_PROCS */
3483 mInfo->pst.dstProcId = tTsk->proc;
3484 mInfo->pst.srcProcId = tTsk->proc;
3485 #endif /* SS_MULTIPLE_PROCS */
3486 mInfo->pst.selector = SEL_LC_NEW;
3487 mInfo->pst.region = DFLT_REGION;
3488 mInfo->pst.pool = DFLT_POOL;
3489 mInfo->pst.prior = PRIOR3;
3490 mInfo->pst.route = RTESPEC;
3491 mInfo->pst.event = 0;
3492 mInfo->pst.dstEnt = tTsk->ent;
3493 mInfo->pst.dstInst = tTsk->inst;
3494 mInfo->pst.srcEnt = tTsk->ent;
3495 mInfo->pst.srcInst = tTsk->inst;
3497 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3498 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3504 #if (ERRCLASS & ERRCLS_DEBUG)
3505 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3506 "Could not write to demand queue");
3519 * Fun: ssdDetachTTsk
3521 * Desc: Does nothing.
3532 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3542 * Fun: ssdCreateSTsk
3544 * Desc: This function creates a system task. A thread is started
3545 * on the system task handler function defined later.
3556 SsSTskEntry *sTsk /* pointer to system task entry */
3560 pthread_attr_t attr;
3561 /* struct sched_param param_sched;*/
3563 #ifdef SS_THR_REG_MAP
3564 uint32_t threadCreated = FALSE;
3569 #ifdef SS_SINGLE_THREADED
3570 /* mt001.301 : Additions */
3572 #ifdef SS_MULTICORE_SUPPORT
3573 if (osCp.numSTsks > 1)
3575 if (osCp.numSTsks > 0)
3576 #endif /* SS_MULTICORE_SUPPORT */
3578 #ifdef SS_MULTICORE_SUPPORT
3579 if (osCp.numSTsks > 3)
3581 if (osCp.numSTsks > 2)
3582 #endif /* SS_MULTICORE_SUPPORT */
3583 #endif /* SS_WATCHDOG */
3590 /* set the current executing entity and instance IDs to
3591 * 'not configured'. create the lock to access them.
3593 sTsk->dep.ent = ENTNC;
3594 sTsk->dep.inst = INSTNC;
3597 /* create the thread */
3598 pthread_attr_init(&attr);
3599 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3601 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3602 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3603 if (sTsk->tskPrior == 0)
3605 printf("\nCreating RT thread #######################\n");
3606 #ifdef SS_THR_REG_MAP
3607 /* When the thread is created, we check for the memory mapping table if
3608 * threadId can be placed in thread memory map table. If it is not able to place
3609 * threadId is stored in tmporary array. Once thread is created successful,
3610 * thread_cancel is sent for each thread which are created before. All the
3611 * threads are made to wait on sema which is cancel point for thread.
3613 while(threadCreated == FALSE)
3616 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3619 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3620 pthread_attr_destroy(&attr);
3622 #if (ERRCLASS & ERRCLS_DEBUG)
3623 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3628 #ifdef SS_THR_REG_MAP
3629 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3637 #ifdef SS_THR_REG_MAP
3638 /* When the thread is created, we check for the memory mapping table if
3639 * threadId can be placed in thread memory map table. If it is not able to place
3640 * threadId is stored in tmporary array. Once thread is created successful,
3641 * thread_cancel is sent for each thread which are created before. All the
3642 * threads are made to wait on sema which is cancel point for thread.
3644 while(threadCreated == FALSE)
3647 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3651 /* mt020.201 - Addition for destroying thread attribute object attr */
3652 pthread_attr_destroy(&attr);
3654 #if (ERRCLASS & ERRCLS_DEBUG)
3655 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3660 #ifdef SS_THR_REG_MAP
3661 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3668 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3669 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3671 static uint32_t stLwpId = 3;
3672 sTsk->dep.lwpId = ++stLwpId;
3674 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3676 /* mt020.201 - Addition for destroying thread attribute object attr */
3677 pthread_attr_destroy(&attr);
3686 pthread_attr_t* attr,
3687 void *(*start_routine) (void *),
3692 #ifdef SS_THR_REG_MAP
3693 uint32_t threadCreated = FALSE;
3696 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3697 /* Klock work fix ccpu00148484 */
3698 if(threadArg == NULLP)
3702 threadArg->argument = arg;
3703 threadArg->start_routine = start_routine;
3706 printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3708 #ifdef SS_THR_REG_MAP
3709 /* When the thread is created, we check for the memory mapping table if
3710 * threadId can be placed in thread memory map table. If it is not able to place
3711 * threadId is stored in tmporary array. Once thread is created successful,
3712 * thread_cancel is sent for each thread which are created before. All the
3713 * threads are made to wait on sema which is cancel point for thread.
3715 while(threadCreated == FALSE)
3718 /*pthreadCreateHdlr */
3719 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3724 #ifdef SS_THR_REG_MAP
3725 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3736 * Fun: Set Pthread Attributes
3738 * Desc: This function is used to set various explicit
3739 * pthread attributes like, priority scheduling,etc
3749 static S16 ssdSetPthreadAttr
3752 pthread_attr_t *attr
3755 struct sched_param param;
3758 SMemSet(¶m, 0, sizeof(param));
3760 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3761 param.sched_priority = 100 - 1 - tskPrior;
3763 param.sched_priority = 100 - 10 - tskPrior;
3766 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3767 /* TODO:: This can be avoided by reducing the priority
3768 * of iccserv thread in l1_master.sh*/
3770 if (clusterMode == RADIO_CLUSTER_MODE)
3772 if(tskPrior == PRIOR1)
3774 param.sched_priority = 91;
3781 printf("\nSet priority %u\n", param.sched_priority);
3783 /* Set Scheduler to explicit, without this non of the below
3784 pthread attr works */
3785 #ifdef TENB_RTLIN_CHANGES
3786 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3789 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3790 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3791 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3792 #ifdef TENB_RTLIN_CHANGES
3793 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3795 pthread_attr_setschedparam(attr, ¶m);
3799 } /* ssdSetPthreadAttr */
3801 /************* multi-core support **************/
3802 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3803 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3807 * Fun: Get the current core/cpu affinity for a thread/lwp
3809 * Desc: This function is used to get the current processor/core
3810 * affinity for a a system task (thread/lwp). It sets the
3811 * affinity based on the mode supplied by the caller.
3814 * RFAILED - failed, general (optional)
3823 SSTskId *tskId, /* filled in with system task ID */
3824 uint32_t *coreId /* the core/processor id to which the affinity is set */
3834 uint32_t cpuInd = 0;
3835 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3838 uint32_t lwpId = *tskId;
3842 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3844 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3846 tId = osCp.sTskTbl[tskInd].dep.tId;
3851 /* if tskId is not found in the tskTbl */
3852 if (tskInd == SS_MAX_STSKS)
3854 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3859 /* initialize the cpu mask */
3862 /* set thread affinity for linux */
3863 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3865 #if (ERRCLASS & ERRCLS_DEBUG)
3866 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3869 } /* end if pthread_setaffinity fails */
3871 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3873 if (CPU_ISSET (cpuInd, & cpuSet))
3882 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3884 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3886 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3891 /* if tskId is not found in the tskTbl */
3892 if (tskInd == SS_MAX_STSKS)
3894 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3898 /* set thread affinity for Solaris */
3899 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3901 #if (ERRCLASS & ERRCLS_DEBUG)
3902 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3905 } /* end if processor_bind fails */
3908 #endif /* SS_LINUX */
3912 } /* ssdGetAffinity */
3917 * Fun: Set the core/cpu affinity for a thread/lwp
3919 * Desc: This function is used to set processor/core affinity for a
3920 * a system task (thread/lwp). It sets the affinity based on the
3921 * mode supplied by the caller.
3924 * RFAILED - failed, general (optional)
3933 SSTskId *tskId, /* filled in with system task ID */
3934 uint32_t coreId /* the core/processor id to which the affinity has to be set */
3938 uint32_t tskInd = 0;
3943 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3946 uint32_t lwpId = *tskId;
3952 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3954 /* Here tskId can not be used as index as the task may be terminated if
3955 there is a TERM even for that tsk, thus breaking the task Id numbering
3957 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3959 tId = osCp.sTskTbl[tskInd].dep.tId;
3964 /* if tskId is not found in the tskTbl */
3965 if (tskInd == SS_MAX_STSKS)
3967 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3971 /* initialize the cpu mask */
3974 /* set the cpu mask */
3975 CPU_SET(coreId, &cpuSet);
3977 /* set thread affinity for linux */
3978 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3980 #if (ERRCLASS & ERRCLS_DEBUG)
3981 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
3984 } /* end if pthread_setaffinity fails */
3988 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3990 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
3991 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3993 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3998 /* if tskId is not found in the tskTbl */
3999 if (tskInd == SS_MAX_STSKS)
4001 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4005 /* set thread affinity for Solaris */
4006 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4008 #if (ERRCLASS & ERRCLS_DEBUG)
4009 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4012 } /* end if processor_bind fails */
4015 #endif /* SS_LINUX */
4017 } /* ssdSetAffinity */
4019 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4020 /************ end multi-core support *************/
4025 * Fun: ssdDestroySTsk
4027 * Desc: This function destroys a system task. A terminate
4028 * event message is sent to the thread function.
4039 SsSTskEntry *sTsk /* pointer to system task entry */
4048 /* we send a message to this system task to tell it to die */
4049 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4052 #if (ERRCLASS & ERRCLASS_DEBUG)
4053 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4059 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4060 mInfo->eventInfo.event = SS_EVNT_TERM;
4062 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4066 #if (ERRCLASS & ERRCLASS_DEBUG)
4067 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4068 "Could not write to demand queue");
4078 /* mt023.201 - Added SThreadYield function to yield CPU
4082 * Desc: This function defers thread execution to any other ready
4093 S16 SThreadYield(void)
4097 /* mt024.201 - seperated Linux and other UNIX implementations
4103 /* Set sleep value to 0 to yield CPU */
4107 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4109 #else /* other UNICes */
4111 return (sleep(0) == 0 ? ROK : RFAILED);
4113 #endif /* SS_LINUX */
4120 * Fun: Register timer
4122 * Desc: This function is used to register a timer
4123 * function for the service user. System services
4124 * will invoke the timer activation function
4125 * passed to it at the specified intervals.
4129 * Notes: Timing is handled by the common timers. The
4130 * ticks are handled by a thread that uses
4131 * nanosleep() and thus timing precision will not
4139 SsTmrEntry *tmr /* pointer to timer entry */
4147 /* initialize common timers */
4148 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4151 /* start the timer */
4152 arg.tq = osCp.dep.tmrTq;
4153 arg.tqCp = &osCp.dep.tmrTqCp;
4154 arg.timers = tmr->dep.timers;
4159 arg.max = TMR_DEF_MAX;
4160 arg.wait = tmr->interval;
4170 * Fun: Deregister timer
4172 * Desc: This function is used to deregister a timer function.
4183 SsTmrEntry *tmr /* pointer to timer entry */
4191 /* stop the timer */
4192 arg.tq = osCp.dep.tmrTq;
4193 arg.tqCp = &osCp.dep.tmrTqCp;
4194 arg.timers = tmr->dep.timers;
4199 arg.max = TMR_DEF_MAX;
4200 arg.wait = tmr->interval;
4210 * Fun: Critical error
4212 * Desc: This function is called when a critical error occurs.
4223 Seq seq, /* sequence number */
4224 Reason reason /* reset reason */
4234 /* get calling task ID */
4235 tId = pthread_self();
4238 /* set up the message to display */
4239 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4240 "reason = %d\n\n", (uint8_t)tId, seq, reason);
4244 /* delete all system tasks */
4245 for (i = 0; i < SS_MAX_STSKS; i++)
4247 if (osCp.sTskTbl[i].used
4248 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4250 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4256 pthread_exit(NULLP);
4259 /* won't reach here */
4268 * Desc: This function is called to log an error.
4279 Ent ent, /* Calling layer's entity id */
4280 Inst inst, /* Calling layer's instance id */
4281 ProcId procId, /* Calling layer's processor id */
4282 Txt *file, /* file name where error occured */
4283 S32 line, /* line in file where error occured */
4284 ErrCls errCls, /* error class */
4285 ErrCode errCode, /* layer unique error code */
4286 ErrVal errVal, /* error value */
4287 Txt *errDesc /* description of error */
4300 /* get calling task ID */
4302 tId = pthread_self();
4308 case ERRCLS_ADD_RES:
4309 errClsMsg = "ERRCLS_ADD_RES";
4312 case ERRCLS_INT_PAR:
4313 errClsMsg = "ERRCLS_INT_PAR";
4317 errClsMsg = "ERRCLS_DEBUG";
4320 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4322 errClsMsg = "ERRCLS_FTHA";
4326 errClsMsg = "INVALID ERROR CLASS!";
4331 /*mt009.301 Fixed 64BIT compilation warnings*/
4334 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4335 "file: %s line: %03d errcode: %05d errcls: %s\n"
4336 "errval: %05d errdesc: %s\n",
4337 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4340 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4341 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4342 "errval: %05ld errdesc: %s\n",
4343 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4345 SDisplay(0, errBuf);
4346 /* mt001.301 : Additions */
4347 #ifdef SS_LOGGER_SUPPORT
4349 #endif /* SS_LOGGER_SUPPORT */
4353 /* debug errors halt the system */
4354 if (errCls == ERRCLS_DEBUG)
4356 /* mt001.301 : Additions */
4357 #ifdef SS_LOGGER_SUPPORT
4359 #endif /* SS_LOGGER_SUPPORT */
4360 /* delete all system tasks */
4361 for (i = 0; i < SS_MAX_STSKS; i++)
4363 if (osCp.sTskTbl[i].used
4364 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4366 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4372 pthread_exit(NULLP);
4384 * Fun: Register driver task
4386 * Desc: This function is called to register the handlers for a
4398 SsDrvrTskEntry *drvrTsk /* driver task entry */
4405 /* mt001.30 : Additions */
4408 * Fun: Deregister driver task
4410 * Desc: This function is called to deregister the handlers for a
4422 SsDrvrTskEntry *drvrTsk /* driver task entry */
4435 * mt003.301 Additions - SDeRegTTsk fix
4437 #ifdef SS_MULTIPLE_PROCS
4444 #else /*SS_MULTIPLE_PROCS*/
4450 #endif /*SS_MULTIPLE_PROCS*/
4452 #ifdef SS_MULTIPLE_PROCS
4465 /* We check the sTsk element; if it is not NULLP, the
4466 * task is attached. So we have to detach it before
4467 * deregistering the task.
4469 ret = SLock(&osCp.sTskTblLock);
4472 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4475 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4478 #if (ERRCLASS & ERRCLS_DEBUG)
4479 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4481 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4483 #if (ERRCLASS & ERRCLS_DEBUG)
4484 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4492 #ifdef SS_MULTIPLE_PROCS
4494 if (tTsk->initTsk != NULLP)
4497 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4500 &(osCp.tTskTbl[idx].xxCb));
4502 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4505 &(osCp.tTskTbl[idx].xxCb));
4506 #endif /* USE_MEMCAL */
4508 #endif /* SS_MULTIPLE_PROCS */
4510 if (tTsk->sTsk != NULLP)
4514 sTsk->dep.ent = ent;
4515 sTsk->dep.inst = inst;
4517 for (n = 0; n < SS_MAX_TTSKS; n++)
4519 if (sTsk->tTsks[n] == idx)
4521 sTsk->tTsks[n] = SS_INVALID_IDX;
4527 /* call the implementation to detach the task */
4528 ssdDetachTTsk(tTsk);
4530 sTsk->dep.ent = ENTNC;
4531 sTsk->dep.inst = INSTNC;
4534 /* Now we empty the entry for this task and update the table
4537 #ifdef SS_MULTIPLE_PROCS
4538 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4539 #else /* SS_MULTIPLE_PROCS */
4540 osCp.tTskIds[ent][inst] = SS_TSKNC;
4541 #endif /* SS_MULTIPLE_PROCS */
4544 #ifdef SS_MULTIPLE_PROCS
4545 tTsk->proc = PROCNC;
4546 #endif /* SS_MULTIPLE_PROCS */
4548 tTsk->inst = INSTNC;
4549 tTsk->tskType = TTUND;
4550 tTsk->initTsk = NULLP;
4551 tTsk->actvTsk = NULLP;
4554 tTsk->nxt = osCp.nxtTTskEntry;
4555 osCp.nxtTTskEntry = idx;
4558 #ifdef SS_MULTIPLE_PROCS
4559 /* mark the control block for this task as invalid */
4560 osCp.tTskTbl[idx].xxCb = NULLP;
4563 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4564 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4566 #if (ERRCLASS & ERRCLS_DEBUG)
4567 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4574 //#ifndef SPLIT_RLC_DL_TASK
4575 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4576 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4577 Void ysMtTskHdlr(Void);
4578 Void ysMtPollPhyMsg(uint8_t region);
4579 Void ysMtRcvPhyMsg(Void);
4580 Void *mtTskHdlrT2kL2
4582 Ptr tskPtr /* pointer to task entry */
4588 /* wait for SS to come up */
4589 /* It is required to block on this semaphore before starting actual processing of
4590 the thread becasue the creator of this thread might want to cance it without
4591 doing any processing. When this semaphore is released, means the creator gives
4592 the go ahead for actual processing and we should never come back to this point */
4593 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4602 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4603 * (processes L1 msgs) */
4609 Void ysMtTskHdlr(Void);
4610 Void YsPhyRecvMsg();
4611 Void *mtTskHdlrT2kL2
4613 Ptr tskPtr /* pointer to task entry */
4619 /* get out the system task entry from the parameter */
4620 sTsk = (SsSTskEntry *) tskPtr;
4622 /* wait for SS to come up */
4623 /* It is required to block on this semaphore before starting actual processing of
4624 the thread becasue the creator of this thread might want to cance it without
4625 doing any processing. When this semaphore is released, means the creator gives
4626 the go ahead for actual processing and we should never come back to this point */
4627 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4630 #ifndef RGL_SPECIFIC_CHANGES
4638 #ifdef V5GTF_SPECIFIC_CHANGES
4641 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4642 * (processes L1 msgs) */
4644 /* get a message from the demand queue */
4647 ret = mtTskHdlMsg(sTsk);
4650 /* exit the for loop here */
4657 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4660 void *pthreadCreateHdlr(void * arg)
4663 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4664 /* mt038.201 changed how sem_wait is called */
4665 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4668 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4676 * Desc: This is the system task handler function. It blocks on
4677 * the system task's demand queue. On receiving a message,
4678 * it identifies the target TAPA task, verifies that the
4679 * TAPA task belongs to this system task and if so, calls
4680 * the activation function of that TAPA task with the
4681 * received message. The task activation function or the
4682 * timer activation function may be called.
4684 * Ret: (thread function)
4693 Ptr tskPtr /* pointer to task entry */
4699 /* get out the system task entry from the parameter */
4700 sTsk = (SsSTskEntry *) tskPtr;
4703 /* wait for SS to come up */
4705 /* mt038.201 changed how sem_wait is called */
4706 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4708 #ifdef XEON_SPECIFIC_CHANGES
4709 printf("\n**********MT Task Handler********\n");
4713 /* Wait for a message from the demand queue */
4714 #ifdef SS_CDMNDQ_SUPPORT
4715 ret = ssCDmndQWait(&sTsk->dQ);
4717 ret = ssDmndQWait(&sTsk->dQ);
4722 ret = mtTskHdlMsg(sTsk);
4737 * Desc: This is the system task handler function. It blocks on
4738 * the system task's demand queue. On receiving a message,
4739 * it identifies the target TAPA task, verifies that the
4740 * TAPA task belongs to this system task and if so, calls
4741 * the activation function of that TAPA task with the
4742 * received message. The task activation function or the
4743 * timer activation function may be called.
4745 * Ret: (thread function)
4760 SsTTskEntry *tTsk=NULLP;
4763 Buffer *mBuf2=NULLP;
4765 SsMsgInfo *mInfo=NULLP;
4767 /* mt028.201: modification: multiple procs support related changes */
4768 #ifndef SS_MULTIPLE_PROCS
4770 PAIFTMRS16 tmrActvFnMt = NULLP;
4772 /* mt015.301 Initialized the timer activation functions with NULLP */
4773 PFS16 tmrActvFn = NULLP;
4775 PAIFTMRS16 tmrActvFn =NULLP;
4776 uint16_t procIdIdx =0;
4777 #endif /* SS_MULTIPLE_PROCS */
4778 /* mt003.301 Modifications */
4779 #ifdef SS_THREAD_PROFILE
4781 #endif /* SS_THREAD_PROFILE */
4784 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4787 /* nothing to receive */
4791 /* if we can't lock this system task entry, return the message */
4792 ret = SLock(&sTsk->lock);
4796 #if (ERRCLASS & ERRCLS_DEBUG)
4797 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4798 "Could not lock system task entry");
4808 mBuf2 = mBuf->b_next;
4810 /* find out what kind of message this is */
4811 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4812 #ifdef SS_MEM_WL_DEBUG
4813 mtTskBuffer1 = mBuf2;
4815 mtTskBuffer2 = mBuf2->b_next;
4817 if(mInfo == 0x5050505)
4821 cmAnalyseBtInfo((PTR) mBuf,4);
4823 printf("\n In trouble .... \n");
4825 else if (mInfo == 0x2020202)
4828 cmAnalyseBtInfo((PTR) mBuf,1);
4829 printf("\n In trouble .... \n");
4831 #endif /* SS_MEM_WL_DEBUG */
4832 switch (mInfo->eventInfo.event)
4834 /* this is a termination event, we die */
4836 /* release the message */
4839 /* Unlock the system task entry and lock the system
4840 * task table to clean our entry up.
4842 SUnlock(&sTsk->lock);
4844 ret = SLock(&osCp.sTskTblLock);
4848 #if (ERRCLASS & ERRCLS_DEBUG)
4849 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
4850 "Could not lock system task table");
4852 /* what to do here? */
4856 /* clean up the system task entry */
4859 /* mt003.301 Modifications - SDeRegTTsk */
4860 /* sTsk->numTTsks = 0; */
4861 SDestroyLock(&sTsk->lock);
4862 ssDestroyDmndQ(&sTsk->dQ);
4864 /* lock for current executing TAPA task ID */
4866 /* make this entry available in the system task table */
4867 sTsk->nxt = osCp.nxtSTskEntry;
4868 for (i = 0; i < SS_MAX_STSKS; i++)
4870 if (sTsk == &osCp.sTskTbl[i])
4872 osCp.nxtSTskEntry = i;
4879 /* unlock the system task table */
4880 SUnlock(&osCp.sTskTblLock);
4885 /* this is a data message or a permanent task keep-alive message */
4887 case SS_EVNT_PERMTICK:
4888 /* message to a task. find the destination task */
4889 /* mt028.201: modification: multiple procs support related changes */
4890 #ifdef SS_MULTIPLE_PROCS
4891 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
4893 if (procIdIdx == SS_INV_PROCID_IDX)
4899 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
4900 #else /* SS_MULTIPLE_PROCS */
4901 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
4902 #endif /* SS_MULTIPLE_PROCS */
4904 /* verify that it hasn't been deregistered */
4905 if (idx == SS_TSKNC)
4911 /* verify that this system task is still running it */
4912 tTsk = &osCp.tTskTbl[idx];
4913 if (tTsk->sTsk != sTsk)
4919 /* set the current executing TAPA task ID */
4920 sTsk->dep.ent = mInfo->pst.dstEnt;
4921 sTsk->dep.inst = mInfo->pst.dstInst;
4923 /* copy the Pst structure into a local duplicate */
4924 for (i = 0; i < (S16) sizeof(Pst); i++)
4925 *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
4927 /* Give the message to the task activation function. If
4928 * its a normal data message, we pass it, if this is a
4929 * keep-alive message for a permanent task then we pass
4930 * NULLP in place of the message to the task activation
4933 if (mInfo->eventInfo.event == SS_EVNT_DATA)
4935 #ifndef RGL_SPECIFIC_CHANGES
4936 #ifdef SS_TSKLOG_ENABLE
4937 uint32_t t = MacGetTick();
4940 /* mt003.301 Modifications */
4941 #if SS_THREAD_PROFILE
4942 tTsk->curEvent = nPst.event;
4944 #endif /* SS_THREAD_PROFILE */
4945 tTsk->actvTsk(&nPst, mBuf);
4946 #ifndef RGL_SPECIFIC_CHANGES
4947 #ifdef SS_TSKLOG_ENABLE
4948 SStopTask(t,PID_SSI_TSK);
4951 #if SS_THREAD_PROFILE
4953 tTsk->curEvtTime = (uint32_t)(et2 - et1);
4954 tTsk->totTime += (uint64_t)tTsk->curEvtTime;
4955 #endif /* SS_THREAD_PROFILE */
4959 #if (ERRCLASS & ERRCLS_DEBUG)
4960 /* this message should only come to a permanent task */
4961 if (tTsk->tskType != SS_TSK_PERMANENT)
4963 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
4967 tTsk->actvTsk(&nPst, NULLP);
4969 /* We need to re-send this message back to ourselves so
4970 * the permanent task continues to run.
4972 /* Check if this task got deregistered or detached
4973 * by the activation function; if so, there's nothing
4974 * more to do here, otherwise go ahead.
4977 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
4979 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
4980 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
4984 /* failure here is a real problem */
4987 #if (ERRCLASS & ERRCLS_DEBUG)
4988 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
4989 "Could not write to demand queue");
4995 /* unset the current executing TAPA task ID */
4996 sTsk->dep.ent = ENTNC;
4997 sTsk->dep.inst = INSTNC;
5002 /* timer event. find the timer entry */
5003 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5005 /* lock the timer table, coz we're going to peek in it */
5006 ret = SLock(&osCp.tmrTblLock);
5010 #if (ERRCLASS & ERRCLS_DEBUG)
5011 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5012 "Could not lock timer table");
5018 /* Verify that this timer entry is still around and that it
5019 * belongs to our task.
5021 if (osCp.tmrTbl[idx].used == FALSE
5022 /* mt028.201: modification: multiple procs support related changes */
5023 #ifdef SS_MULTIPLE_PROCS
5024 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5025 #endif /* SS_MULTIPLE_PROCS */
5026 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5027 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5029 SUnlock(&osCp.tmrTblLock);
5034 /* mt005.21: addition */
5035 /* set the current executing TAPA task ID */
5036 sTsk->dep.ent = mInfo->pst.dstEnt;
5037 sTsk->dep.inst = mInfo->pst.dstInst;
5039 #ifndef SS_MULTIPLE_PROCS
5041 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5042 tmrActvFnMt = NULLP;
5043 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5045 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5051 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5054 /* unlock the timer table */
5055 SUnlock(&osCp.tmrTblLock);
5057 /* activate the timer function */
5058 /* mt028.201: modification: multiple procs support related changes */
5059 #ifndef SS_MULTIPLE_PROCS
5063 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5064 osCp.tmrTbl[idx].ownerInst);
5072 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5073 osCp.tmrTbl[idx].ownerInst);
5074 #endif /* SS_MULTIPLE_PROCS */
5076 /*mt005.21: addition */
5077 /* unset the current executing TAPA task ID */
5078 sTsk->dep.ent = ENTNC;
5079 sTsk->dep.inst = INSTNC;
5082 /* return the message buffer */
5086 * mt003.301 - SDeRegTTsk fix
5088 case SS_EVNT_TTSK_TERM:
5089 #ifdef SS_MULTIPLE_PROCS
5090 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5092 if (procIdIdx == SS_INV_PROCID_IDX)
5098 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5099 #else /* SS_MULTIPLE_PROCS */
5100 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5101 #endif /* SS_MULTIPLE_PROCS */
5103 /* verify that it hasn't been deregistered */
5104 if (idx == SS_TSKNC)
5110 /* verify that this system task is still running it */
5111 tTsk = &osCp.tTskTbl[idx];
5112 if (tTsk->sTsk != sTsk)
5117 #ifdef SS_MULTIPLE_PROCS
5118 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5120 ssdProcTTskTerm(tTsk, idx);
5126 #if (ERRCLASS & ERRCLS_DEBUG)
5127 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5134 } while (mBuf != NULLP);
5137 /* unlock the system task entry */
5138 SUnlock(&sTsk->lock);
5141 /* yield for other threads */
5142 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5151 * Fun: mtTmrHdlrPublic
5153 Void mtTmrHdlrPublic()
5155 if (SLock(&osCp.tmrTblLock) != ROK)
5157 #if (ERRCLASS & ERRCLS_DEBUG)
5158 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5162 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5163 /* unlock the timer table */
5164 SUnlock(&osCp.tmrTblLock);
5172 * Desc: The timer handler thread function. Counts time
5173 * and invokes the common timer function on each
5176 * Ret: (thread function)
5183 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5184 static Void *mtTmrHdlr
5186 void *parm /* unused */
5189 /*mt004.301-addede new region*/
5190 /* mt010.301 Removed SS_FAP portion and
5191 * enabled oroginal code in function mtTmrHdlr */
5195 uint32_t i, cnt, oldTicks, newTicks;
5196 struct timeval tv1,tv2;
5197 /* mt038.201 added return */
5199 /* mt039.201 changes for nanosleep */
5200 struct timespec tsN;
5201 static uint32_t err_in_usec;
5203 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5208 /* mt027.201 - Modification for SRegCfgTmr support */
5209 /* check SS_TICKS_SEC */
5210 if (SS_1MS < SS_TICKS_SEC)
5212 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5215 /* mt025.201 - Addition to stop timer handler till task registration is done */
5216 /* wait for SS to come up */
5217 /* mt038.201 changed how sem_wait is called */
5218 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5221 /* mt027.201 - Modification for SRegCfgTmr support */
5222 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5224 ts.tv_nsec = (MT_TICK_CNT * 1000);
5225 /* mt039.201 changes for nanosleep */
5231 if (gettimeofday(&tv1, NULL) == -1)
5233 #if (ERRCLASS & ERRCLS_DEBUG)
5234 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5235 "Error in clock_gettime");
5245 #ifndef STUB_TTI_HANDLING_5GTF
5246 printf("\nReturning from mtTmrHdlr()\n");
5251 /* mt039.201 changes for nanosleep */
5252 /* sleep for MT_TICK_CNT milli seconds */
5253 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5254 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5256 ts.tv_nsec = tsN.tv_nsec;
5261 if (gettimeofday(&tv2,NULL) == -1)
5263 #if (ERRCLASS & ERRCLS_DEBUG)
5264 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5265 "Error in clock_gettime");
5269 /*mt013.301 : changed check while calculating timer to fix
5270 * diffrence between MTSS time and real unix time
5272 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5274 time_int = (tv2.tv_usec - tv1.tv_usec);
5276 else if (tv2.tv_sec > tv1.tv_sec)
5278 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5280 else /* ts2 < ts1, this will not happen in normal scenario */
5282 /* to make sure cnt = 1 */
5284 time_int = MT_TICK_CNT;
5287 oldTicks = osCp.dep.sysTicks;
5288 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5289 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5290 newTicks = osCp.dep.sysTicks;
5291 tv1.tv_usec = tv2.tv_usec;
5292 tv1.tv_sec = tv2.tv_sec;
5294 cnt = newTicks - oldTicks;
5296 while(err_in_usec >= MT_TICK_CNT)
5299 err_in_usec -= MT_TICK_CNT;
5301 if( cnt >= MT_MAX_TICK_CNT_VAL)
5302 cnt = MT_MIN_TICK_CNT_VAL;
5303 /* call the common timer tick handler */
5304 for (i = 0; i < cnt; i++)
5306 /* mt008.301: cmPrcTmr is guarded with a lock */
5307 /* lock the timer table */
5308 if (SLock(&osCp.tmrTblLock) != ROK)
5310 #if (ERRCLASS & ERRCLS_DEBUG)
5311 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5315 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5316 /* unlock the timer table */
5317 SUnlock(&osCp.tmrTblLock);
5321 /* mt009.21: addition */
5322 return ( (Void *) NULLP);
5323 /* will not reach here */
5331 * Desc: Process timer event. Called from the common timer
5332 * code when a timeout occurs.
5343 PTR tCb, /* control block */
5344 S16 evnt /* event */
5353 #ifndef TENB_RTLIN_CHANGES
5356 /* mt028.201: modification: multiple procs support related changes */
5357 #ifdef SS_MULTIPLE_PROCS
5359 #endif /* SS_MULTIPLE_PROCS */
5360 #ifdef RGL_SPECIFIC_CHANGES
5361 #ifdef MSPD_MLOG_NEW
5362 uint32_t t = GetTIMETICK();
5368 /* get the timer entry */
5369 tEnt = (SsTmrEntry *) tCb;
5372 /* if the timer was deleted, this will be NULL, so drop it */
5378 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5381 /* Hmmmm, the timer might have been deleted while we've been
5382 * working at getting here, so we just skip this.
5384 if (tEnt->used == FALSE)
5390 /* Set up and send a timer message to the destination tasks'
5393 #ifndef SS_MULTICORE_SUPPORT
5394 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5396 #ifdef RGL_SPECIFIC_CHANGES
5397 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5399 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5404 #if (ERRCLASS & ERRCLS_DEBUG)
5405 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5411 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5412 mInfo->eventInfo.event = SS_EVNT_TIMER;
5413 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5415 mInfo->pst.dstEnt = tEnt->ownerEnt;
5416 mInfo->pst.dstInst = tEnt->ownerInst;
5417 mInfo->pst.srcEnt = tEnt->ownerEnt;
5418 mInfo->pst.srcInst = tEnt->ownerInst;
5419 /* mt028.201: modification: multiple procs support related changes */
5420 #ifndef SS_MULTIPLE_PROCS
5421 mInfo->pst.dstProcId = SFndProcId();
5422 mInfo->pst.srcProcId = SFndProcId();
5423 #else /* SS_MULTIPLE_PROCS */
5424 mInfo->pst.dstProcId = tEnt->ownerProc;
5425 mInfo->pst.srcProcId = tEnt->ownerProc;
5426 #endif /* SS_MULTIPLE_PROCS */
5427 mInfo->pst.selector = SEL_LC_NEW;
5428 #ifndef SS_MULTICORE_SUPPORT
5429 mInfo->pst.region = DFLT_REGION;
5432 mInfo->pst.pool = DFLT_POOL;
5433 mInfo->pst.prior = PRIOR0;
5434 mInfo->pst.route = RTESPEC;
5435 mInfo->pst.event = 0;
5438 #ifndef TENB_RTLIN_CHANGES
5439 /* get a semaphore for the TAPA task table */
5440 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5445 #if (ERRCLASS & ERRCLS_DEBUG)
5446 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5454 /* find the owner TAPA task */
5455 /* mt028.201: modification: multiple procs support related changes */
5456 #ifdef SS_MULTIPLE_PROCS
5457 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5458 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5459 #else /* SS_MULTIPLE_PROCS */
5460 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5461 #endif /* SS_MULTIPLE_PROCS */
5462 if (idx == SS_TSKNC)
5464 #ifndef TENB_RTLIN_CHANGES
5465 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5472 /* ensure that the TAPA task is hale and hearty */
5473 tTsk = &osCp.tTskTbl[idx];
5476 #ifndef TENB_RTLIN_CHANGES
5477 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5482 /* Klock work fix ccpu00148484 */
5483 /* write the timer message to the queue of the destination task */
5484 /* mt008.301 : check sTsk before putting into it's DQ */
5485 if (tTsk->sTsk == NULLP)
5487 #ifndef TENB_RTLIN_CHANGES
5488 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5492 #if (ERRCLASS & ERRCLS_DEBUG)
5493 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5494 "Could not write to demand queue");
5499 #ifdef SS_LOCKLESS_MEMORY
5500 mInfo->pst.region = tTsk->sTsk->region;
5501 mInfo->region = tTsk->sTsk->region;
5502 #endif /* SS_LOCKLESS_MEMORY */
5503 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5504 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5506 #ifndef TENB_RTLIN_CHANGES
5507 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5511 #if (ERRCLASS & ERRCLS_DEBUG)
5512 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5513 "Could not write to demand queue");
5518 /* Fix for ccpu00130657 */
5519 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5520 if (tTsk->sTsk->tskPrior == PRIOR0)
5523 WLS_WakeUp(mtGetWlsHdl());
5530 /* release the semaphore for the TAPA task table */
5531 #ifndef TENB_RTLIN_CHANGES
5532 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5536 /* restart the timer */
5537 arg.tq = osCp.dep.tmrTq;
5538 arg.tqCp = &osCp.dep.tmrTqCp;
5539 arg.timers = tEnt->dep.timers;
5540 arg.cb = (PTR) tEnt;
5544 arg.max = TMR_DEF_MAX;
5545 arg.wait = tEnt->interval;
5547 #ifdef RGL_SPECIFIC_CHANGES
5548 #ifdef MSPD_MLOG_NEW
5549 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5561 * Desc: This thread reads the console and hands over any
5562 * data read to a user function.
5564 * Ret: (thread function)
5571 static Void *mtConHdlr
5573 Ptr parm /* unused */
5580 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5586 /* check if we have a console input file handle */
5587 if (osCp.dep.conInFp == NULLP)
5593 fd = fileno(osCp.dep.conInFp);
5598 if ((read(fd, &data, 1)) != 1)
5604 /* call rdConQ, defined by the system service user */
5614 #ifdef SS_DRVR_SUPPORT
5617 * Fun: Interrupt service task handler
5619 * Desc: This is the interrupt service task handler. It blocks
5620 * on a pipe from which it reads an isFlag structure. The
5621 * structure indicates which interrupt service task is to
5622 * be executed. The thread identifies the task, calls the
5623 * isTsk function and sends itself a message to repeat
5624 * this operation until it receives a message to cease.
5633 /* mt009.21: addition */
5634 static Void *mtIsTskHdlr
5636 Ptr tskPtr /* pointer to task entry */
5639 #if (ERRCLASS & ERRCLS_DEBUG)
5646 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5651 switch (isFlag.action)
5654 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5656 /* call the interrupt service task activation function */
5657 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5659 /* send self a message to keep doing this */
5660 isFlag.action = MT_IS_RESET;
5662 #if (ERRCLASS & ERRCLS_DEBUG)
5663 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5664 if (ret != sizeof(isFlag))
5666 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5667 "write() to pipe failed");
5670 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5677 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5682 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5684 /* call the interrupt service task activation function */
5685 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5687 #if (ERRCLASS & ERRCLS_DEBUG)
5688 /* send self a message to do this again */
5689 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5691 if (ret != sizeof(isFlag))
5693 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5694 "write() to pipe failed");
5697 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5705 /* where did THIS come from?? */
5709 /* mt009.21: addition */
5710 return ( (Void *) NULLP);
5714 #endif /* SS_DRVR_SUPPORT */
5715 #endif /* L2_L3_SPLIT */
5717 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5721 * Fun: mtIntSigHndlr
5723 * Desc: Exit function, shuts down.
5732 Void mtIntSigHndlr(int arg)
5735 osCp.dep.sigEvnt=TRUE;
5738 #ifdef TENB_RTLIN_CHANGES
5746 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5751 * Desc: function, shuts down.
5760 Void mtExitClnup(void)
5766 SGetSysTime(&ticks);
5768 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5770 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5772 #ifdef SS_HISTOGRAM_SUPPORT
5776 osCp.dep.sigEvnt=FALSE;
5778 if (osCp.dep.fileOutFp)
5780 fclose(osCp.dep.fileOutFp);
5788 Void SIncrementTtiCount(Void)
5793 Ticks SGetTtiCount(Void)
5802 * Desc: This function displays a string to a given output
5807 * Notes: Buffer should be null terminated.
5809 * channel 0 is reserved for backwards compatibility
5817 S16 chan, /* channel */
5818 Txt *buf /* buffer */
5822 /* mt020.201 - Fixed typo */
5823 #if (ERRCLASS & ERRCLS_INT_PAR)
5826 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
5831 #ifndef XEON_SPECIFIC_CHANGES
5832 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5833 ssMemlog(buf, strlen(buf));
5838 /* mt012.301 :FIX for LOG RELATED ISSUE */
5846 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
5852 if (osCp.dep.fileOutFp)
5853 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
5854 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
5857 fflush(osCp.dep.fileOutFp);
5870 * Desc: function, shuts down.
5882 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
5883 a loop to overcome the child processes being killed upon exiting the
5885 #ifdef SS_LINUX /* this should have already been defined */
5886 /* mt010.301 removed flag SLES9_PLUS */
5887 /* wait forever for children */
5891 if(osCp.dep.sigEvnt==TRUE)
5898 pthread_exit(NULLP);
5904 * Fun: Set date and time
5906 * Desc: This function is used to set the calendar
5911 * Notes: Unimplemented
5918 REG1 DateTime *dt /* date and time */
5931 * Fun: Get date and time
5933 * Desc: This function is used to determine the calendar
5934 * date and time. This information may be used for
5935 * some management functions.
5947 REG1 DateTime *dt /* date and time */
5950 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
5953 struct timespec ptime;
5955 struct timeval ptime;
5962 #if (ERRCLASS & ERRCLS_INT_PAR)
5965 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
5974 localtime_r(&tt, &tme);
5977 clock_gettime(CLOCK_REALTIME, &ptime);
5979 gettimeofday(&ptime, NULL);
5981 localtime_r(&ptime.tv_sec, &tme);
5983 dt->month = (uint8_t) tme.tm_mon + 1;
5984 dt->day = (uint8_t) tme.tm_mday;
5985 dt->year = (uint8_t) tme.tm_year;
5986 dt->hour = (uint8_t) tme.tm_hour;
5987 dt->min = (uint8_t) tme.tm_min;
5988 dt->sec = (uint8_t) tme.tm_sec;
5991 #ifdef SS_DATETIME_USEC
5993 dt->usec = ptime.tv_nsec / 1000;
5995 dt->usec = ptime.tv_usec;
5997 #endif /*-- SS_DATETIME_USEC --*/
6003 * Get time from epoch in milliseconds
6005 * Fun: Get time from epoch in milliseconds
6007 * Desc: This function is used to get the time from epoch in milli seconds.
6008 * This information may be used for calculating a layer's activation function
6009 * execution time used for thread profiling.
6018 /* mt003.301 Modifications */
6021 EpcTime *et /* date and time */
6024 /* mt003.301 Modifications */
6025 static uint64_t now;
6026 uint64_t to_sec = 1000000;
6027 uint64_t to_nsec = 1000;
6029 struct timespec ptime;
6031 struct timeval ptime;
6036 #if (ERRCLASS & ERRCLS_INT_PAR)
6045 clock_gettime(CLOCK_REALTIME, &ptime);
6047 gettimeofday(&ptime, NULL);
6048 #endif /* SS_LINUX */
6050 now = (ptime.tv_sec * to_sec);
6053 now += (ptime.tv_nsec / to_nsec);
6054 #else /* SS_LINUX */
6055 now += (ptime.tv_usec);
6057 #endif /* SS_LINUX */
6058 now = (now / to_nsec);
6069 * Fun: Get system time
6071 * Desc: This function is used to determine the system time.
6075 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6082 Ticks *sysTime /* system time */
6087 #if (ERRCLASS & ERRCLS_INT_PAR)
6088 if (sysTime == NULLP)
6090 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6096 *sysTime = osCp.dep.sysTicks;
6102 /* mt021.201 - Addition of SGetRefTime function */
6105 * Fun: Get referenced time
6107 * Desc: This function is used to determine the time in seconds
6108 * and microseconds from a reference time. The reference
6109 * time is expressed in seconds from UTC EPOC, January 1,
6115 * Notes: Macros are defined for reference times:
6116 * SS_REFTIME_01_01_1970
6117 * SS_REFTIME_01_01_2002
6124 uint32_t refTime, /* reference time */
6131 struct timespec ptime;
6133 struct timeval ptime;
6138 clock_gettime(CLOCK_REALTIME, &ptime);
6140 gettimeofday(&ptime, NULL);
6143 #if (ERRCLASS & ERRCLS_INT_PAR)
6144 if (sec == NULLP || usec == NULLP)
6146 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6149 /* mt022.201 - Modification to fix compile warning */
6150 if (refTime > (uint32_t)(ptime.tv_sec))
6152 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6157 *sec = ptime.tv_sec - refTime;
6159 *usec = ptime.tv_nsec / 1000;
6161 *usec = ptime.tv_usec;
6171 * Fun: Get Random Number
6173 * Desc: Invoked by layer when a pseudorandom number is required.
6177 * Notes: Suggested approach uses shuffled Linear Congruential
6178 * Operators as described in Byte magazine October
6179 * 1984; "Generating and Testing Pseudorandom Numbers"
6186 Random *value /* random number */
6191 #if (ERRCLASS & ERRCLS_INT_PAR)
6194 /* mt011.21: addition */
6195 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6201 *value = (Random) rand_r(&osCp.dep.randSeed);
6212 * Desc: This function exits from a task.
6216 * Notes: Currently does nothing.
6231 * Fun: Exit Interrupt
6233 * Desc: This function exits from an interrupt.
6237 * Notes: Currently does nothing.
6252 * Fun: Hold Interrupt
6254 * Desc: This function prohibits interrupts from being enabled until
6255 * release interrupt. This function should be called when
6256 * interrupts are disabled and prior to any call to system
6257 * services either by entry to an interrupt service routine or
6258 * by explicit call to disable interrupt.
6262 * Notes: Currently does nothing
6277 * Fun: Release Interrupt
6279 * Desc: This function allows interrupts to be enabled.
6283 * Notes: Currently does nothing.
6300 * Desc: Enable interrupts
6302 * Ret: ROK on success
6305 * Notes: Currently does nothing.
6310 inline S16 SEnbInt(void)
6322 * Desc: Disable interrupts
6324 * Ret: ROK on success
6327 * Notes: Currently does nothing.
6332 inline S16 SDisInt(void)
6344 * Desc: This function gets the function address stored at the
6345 * specified interrupt vector.
6349 * Notes: Currently does nothing.
6356 VectNmb vectNmb, /* vector number */
6357 PIF *vectFnct /* vector function */
6374 * Desc: This function installs the specified function at the
6375 * specified interrupt vector.
6379 * Notes: Currently does nothing.
6386 VectNmb vectNmb, /* vector number */
6387 PIF vectFnct /* vector function */
6399 /* mt028.201: modification: multiple procs support related changes */
6400 #ifndef SS_MULTIPLE_PROCS
6406 * Desc: This function gets the current entity and instance.
6409 * RFAILED - failed, general (optional)
6411 * Notes: This function may be called by the OS or Layer 1
6419 Ent *ent, /* entity */
6420 Inst *inst /* instance */
6431 #if (ERRCLASS & ERRCLS_INT_PAR)
6432 /* check pointers */
6433 if (ent == NULLP || inst == NULLP)
6435 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6441 /* get the thread id */
6442 tId = pthread_self();
6445 /* find the system task in whose context we're running */
6447 ret = SLock(&osCp.sTskTblLock);
6452 for (i = 0; i < SS_MAX_STSKS; i++)
6454 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6456 sTsk = &osCp.sTskTbl[i];
6462 *ent = sTsk->dep.ent;
6463 *inst = sTsk->dep.inst;
6465 SUnlock(&osCp.sTskTblLock);
6468 return (ret == ROK ? ROK : RFAILED);
6476 * Desc: This function sets the current entity and instance.
6487 Ent ent, /* entity */
6488 Inst inst /* instance */
6499 #if (ERRCLASS & ERRCLS_INT_PAR)
6500 /* check entity and instance IDs */
6501 if (ent >= ENTNC || inst >= INSTNC)
6503 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6509 /* get the thread id */
6510 tId = pthread_self();
6513 /* find the system task in whose context we're running */
6515 ret = SLock(&osCp.sTskTblLock);
6520 for (i = 0; i < SS_MAX_STSKS; i++)
6522 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6524 sTsk = &osCp.sTskTbl[i];
6530 sTsk->dep.ent = ent;
6531 sTsk->dep.inst = inst;
6533 SUnlock(&osCp.sTskTblLock);
6536 return (ret == ROK ? ROK : RFAILED);
6539 #endif /* SS_MULTIPLE_PROCS */
6541 #ifdef SS_DRVR_SUPPORT
6547 * Desc: Set interrupt pending flag
6549 * Ret: ROK on success
6557 inline S16 SSetIntPend
6559 uint16_t id, /* driver task identifier */
6560 Bool flag /* flag */
6568 #if (ERRCLASS & ERRCLS_INT_PAR)
6569 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6571 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6578 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6580 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6588 #endif /* SS_DRVR_SUPPORT */
6591 #ifdef SS_LOCKLESS_MEMORY
6594 * Fun: SGlobMemInfoShow
6596 * Desc: This function displays the memory usage information
6597 * for the destined region. It will show the usage of
6598 * each configured bucket and the heap for the specified region.
6601 * RFAILED Region not registered
6606 S16 SGlobMemInfoShow(Void)
6610 CmMmGlobRegCb *globReg;
6613 globReg = osCp.globRegCb;
6615 sprintf(prntBuf, "--------------------------------------------------------------\n");
6616 SDisplay(0, prntBuf);
6617 sprintf(prntBuf, "Global Region Bucket Information\n");
6618 SDisplay(0, prntBuf);
6619 sprintf(prntBuf, "====================================================\n");
6620 SDisplay(0, prntBuf);
6621 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
6622 SDisplay(0, prntBuf);
6623 sprintf(prntBuf, "====================================================\n");
6624 SDisplay(0, prntBuf);
6627 for (idx = 0; idx < globReg->numBkts; idx++)
6629 #ifdef XEON_SPECIFIC_CHANGES
6630 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
6631 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6634 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
6635 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6637 sprintf(prntBuf, "%2u %12u %8u %9u\n",
6638 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6641 SDisplay(0, prntBuf);
6643 sprintf(prntBuf, "--------------------------------------------------------------\n");
6644 SDisplay(0, prntBuf);
6649 #endif /* SS_LOCKLESS_MEMORY */
6652 Bool IsMemoryThresholdHit(Region reg, Pool pool)
6654 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6656 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6659 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6660 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6667 /* mt022.201 - Addition of SRegInfoShow function */
6672 * Desc: This function displays the memory usage information
6673 * for the destined region. It will show the usage of
6674 * each configured bucket and the heap for the specified region.
6677 * RFAILED Region not registered
6679 * Notes: A Sample Output from the function
6680 * Bucket Memory: region 1
6681 * ====================================================
6682 * Bucket Number of Blks configured Size Allocated
6683 * ====================================================
6691 * Heap Memory: region 1
6694 * Heap Segmented blocks: 0
6710 #if (ERRCLASS & ERRCLS_INT_PAR)
6711 if (region > (SS_MAX_REGS-1) )
6713 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
6720 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
6721 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
6722 SDisplay(0, prntBuf);
6723 sprintf(prntBuf, "====================================================\n");
6724 SDisplay(0, prntBuf);
6725 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
6726 SDisplay(0, prntBuf);
6727 sprintf(prntBuf, "====================================================\n");
6728 SDisplay(0, prntBuf);
6732 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6734 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6736 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
6737 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6738 mtCMMRegCb[region]->bktTbl[idx].size,
6739 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6740 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6742 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
6743 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6744 mtCMMRegCb[region]->bktTbl[idx].size,
6745 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6746 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6749 /*mt009.301 Fixed 64BIT compilation warnings*/
6751 sprintf(prntBuf, "%2u %8u %5u %8u\n",
6752 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6753 mtCMMRegCb[region]->bktTbl[idx].size,
6754 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6756 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
6757 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6758 mtCMMRegCb[region]->bktTbl[idx].size,
6759 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6761 #endif /* not TENB_RTLIN_CHANGES */
6762 SDisplay(0, prntBuf);
6763 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
6764 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6765 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6767 sprintf(prntBuf, "\n---------------\n");
6768 SDisplay(0, prntBuf);
6769 sprintf(prntBuf, "Heap Memory: region %d\n", region);
6770 SDisplay(0, prntBuf);
6771 /*mt009.301 Fixed 64BIT compilation warnings*/
6773 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
6775 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
6777 SDisplay(0, prntBuf);
6778 /*mt009.301 Fixed 64BIT compilation warnings*/
6780 sprintf(prntBuf, "Heap Allocated: %u\n",
6781 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6783 sprintf(prntBuf, "Heap Allocated: %lu\n",
6784 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6786 SDisplay(0, prntBuf);
6787 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
6788 #if (ERRCLASS & ERRCLS_DEBUG)
6789 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
6790 mtCMMRegCb[region]->heapCb.numFragBlk);
6791 SDisplay(0, prntBuf);
6796 #ifdef XEON_SPECIFIC_CHANGES
6797 #define SSI_MAX_BKT_THRESHOLD 6
6798 #define SSI_MAX_REG_THRESHOLD 2
6799 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6800 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6801 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6803 static Void SInitMemThreshold
6810 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6812 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
6813 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
6814 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
6815 printf("\nREGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
6819 S16 SRegReachedMemThreshold
6826 uint8_t memStatus = 3;
6827 static uint8_t initFlag = 1;
6831 SInitMemThreshold(region, maxBkt);
6834 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6836 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
6841 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
6845 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
6853 /* mt033.201 - addition of API to return the memory statistical data */
6858 * Desc: This function returns the memory usage information
6859 * for the destined region. It will return the usage of
6860 * each configured bucket and the heap for the specified region.
6863 * RFAILED Region not registered
6873 SsMemDbgInfo *dbgInfo
6879 #if (ERRCLASS & ERRCLS_INT_PAR)
6880 if (region >= mtMemoCfg.numRegions )
6882 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
6887 dbgInfo->availmem = 0;
6889 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
6890 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
6892 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
6894 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
6896 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
6897 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
6898 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
6900 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
6901 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
6902 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6905 dbgInfo->region = region;
6907 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
6909 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
6910 mtCMMRegCb[region]->heapCb.avlSize);
6912 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
6914 #if (ERRCLASS & ERRCLS_DEBUG)
6915 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
6927 /* Send number of Region available */
6928 *numRegion = mtMemoCfg.numRegions;
6929 /* Send number of Pools available */
6930 *numPool = cfgRegInfo[0].numPools;
6935 /* mt033.201 - addition of APIs to print the memory statistical data
6936 * as defined by SSI enhancements
6938 #ifdef SSI_DEBUG_LEVEL1
6941 * Fun: SPrintRegMemStatusInfo
6943 * Desc: This function displays the memory usage information
6944 * for the destined region. It will show the total memory
6945 * used for static and dynamic memory if typeFlag is
6946 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
6947 * memory block allocated for a particular size if typeFlag
6948 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
6949 * calling SRegPrintMemStats.
6958 S16 SPrintRegMemStatusInfo
6966 uint32_t statMemSize;
6967 uint32_t dynMemSize;
6970 #if (ERRCLASS & ERRCLS_INT_PAR)
6971 if (region >= mtMemoCfg.numRegions )
6973 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
6978 /* initialize the counters*/
6982 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
6984 /* total static and dynamic memory allocated from all the buckets in region requested */
6985 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
6986 SDisplay(0, prntBuf);
6987 sprintf(prntBuf, "===========================================\n");
6988 SDisplay(0, prntBuf);
6989 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
6990 SDisplay(0, prntBuf);
6991 sprintf(prntBuf, "===========================================\n");
6992 SDisplay(0, prntBuf);
6993 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6995 /*mt009.301 Fixed 64BIT compilation warnings*/
6997 sprintf(prntBuf, "%2u %8u %8u\n", idx,
6998 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
6999 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7001 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7002 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7003 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7005 SDisplay(0, prntBuf);
7006 /* update the total count */
7007 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7008 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7011 /*mt009.301 Fixed 64BIT compilation warnings*/
7013 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7014 SDisplay(0, prntBuf);
7015 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7017 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7018 SDisplay(0, prntBuf);
7019 /*mt010.301 fix for compilation error*/
7020 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7022 SDisplay(0, prntBuf);
7024 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7025 SDisplay(0, prntBuf);
7026 /*mt009.301 Fixed 64BIT compilation warnings*/
7028 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7029 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7031 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7032 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7034 SDisplay(0, prntBuf);
7036 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7038 /* Bucket Memory allocation Statistics */
7039 return (SPrintRegMemStats(region));
7044 sprintf(prntBuf, "\n Invalid choice \n");
7045 SDisplay(0, prntBuf);
7053 * Fun: SPrintRegMemStats
7055 * Desc: This function displays the memory usage information for
7056 * the destined region. It will show the number of memory
7057 * block allocated for a particular size from the hash list.
7066 static S16 SPrintRegMemStats(Region region)
7068 CmMmHashListCp *hashListCp;
7074 hashListCp = &mtCMMRegCb[region]->hashListCp;
7076 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7077 SDisplay(0, prntBuf);
7078 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7079 hashListCp->numOfbins, hashListCp->numOfEntries);
7080 SDisplay(0, prntBuf);
7081 sprintf(prntBuf, "===================================\n");
7082 SDisplay(0, prntBuf);
7083 sprintf(prntBuf, "Block Size Total number of requests\n");
7084 SDisplay(0, prntBuf);
7085 sprintf(prntBuf, "===================================\n");
7086 SDisplay(0, prntBuf);
7088 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7089 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7091 if (hashListCp->hashList[idx].numAttempts)
7094 /*mt009.301 Fixed 64BIT compilation warnings*/
7096 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7097 hashListCp->hashList[idx].numAttempts);
7099 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7100 hashListCp->hashList[idx].numAttempts);
7102 SDisplay(0, prntBuf);
7106 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7107 SDisplay(0, prntBuf);
7108 sprintf(prntBuf, "=================================================\n");
7109 SDisplay(0, prntBuf);
7110 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7111 SDisplay(0, prntBuf);
7112 sprintf(prntBuf, "=================================================\n");
7113 SDisplay(0, prntBuf);
7115 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7116 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7118 /*mt009.301 Fixed 64BIT compilation warnings*/
7120 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7121 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7122 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7124 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7125 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7126 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7128 SDisplay(0, prntBuf);
7130 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7131 SDisplay(0, prntBuf);
7132 /*mt009.301 Fixed 64BIT compilation warnings*/
7134 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7135 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7136 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7138 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7139 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7140 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7142 SDisplay(0, prntBuf);
7143 sprintf(prntBuf, "\n");
7144 SDisplay(0, prntBuf);
7151 * Fun: SRegMemErrHdlr
7153 * Desc: This function handles the errors returned from the memory
7154 * related functions. Customers are suggested to modify this
7155 * API according to their specific requirement.
7174 if (errCode == RDBLFREE)
7176 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7177 SDisplay(0, prntBuf);
7179 else if (errCode == RTRAMPLINGNOK)
7181 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7182 SDisplay(0, prntBuf);
7190 * Fun: SPrintRegMemProfile
7192 * Desc: This function displays the memory profile information
7193 * for the destined region. This function prints for:
7194 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7195 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7204 S16 SPrintRegMemProfile
7211 CmMmBlkHdr *curBktBlk;
7213 Size offsetToNxtBlk;
7221 #if (ERRCLASS & ERRCLS_INT_PAR)
7222 if (region >= mtMemoCfg.numRegions )
7224 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7229 regCb = mtCMMRegCb[region];
7231 /* memory profile */
7232 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7233 SDisplay(0, prntBuf);
7235 /* bucket profile */
7236 sprintf(prntBuf, "\nBucket Profile\n");
7237 SDisplay(0, prntBuf);
7239 for (idx = 0; idx < regCb->numBkts; idx++)
7242 /*mt009.301 Fixed 64BIT compilation warnings*/
7244 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7245 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7247 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7248 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7250 SDisplay(0, prntBuf);
7252 sprintf(prntBuf, "==========================================================================\n");
7253 SDisplay(0, prntBuf);
7254 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7255 SDisplay(0, prntBuf);
7256 sprintf(prntBuf, "==========================================================================\n");
7257 SDisplay(0, prntBuf);
7259 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7261 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7262 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7263 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7265 /*mt009.301 Fixed 64BIT compilation warnings*/
7267 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7269 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7271 SDisplay(0, prntBuf);
7272 /* check if it is a sane block, elxe jump to next block */
7273 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7275 sprintf(prntBuf, " Trampled \n");
7276 SDisplay(0, prntBuf);
7281 if (CMM_IS_STATIC(curBktBlk->memFlags))
7283 /*mt009.301 Fixed 64BIT compilation warnings*/
7285 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7287 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7289 SDisplay(0, prntBuf);
7291 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7293 /*mt009.301 Fixed 64BIT compilation warnings*/
7295 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7297 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7299 SDisplay(0, prntBuf);
7301 else if (CMM_IS_FREE(curBktBlk->memFlags))
7303 /*mt009.301 Fixed 64BIT compilation warnings*/
7305 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7307 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7309 SDisplay(0, prntBuf);
7313 sprintf(prntBuf, " Trampled \n");
7314 SDisplay(0, prntBuf);
7320 sprintf(prntBuf, "\nHeap Profile\n");
7321 SDisplay(0, prntBuf);
7323 /* point to heapCb */
7324 heapCb = &(regCb->heapCb);
7326 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7327 SDisplay(0, prntBuf);
7328 sprintf(prntBuf, "==========================================================================\n");
7329 SDisplay(0, prntBuf);
7330 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7331 SDisplay(0, prntBuf);
7332 sprintf(prntBuf, "==========================================================================\n");
7333 SDisplay(0, prntBuf);
7335 /* traverse the entire heap to output the heap profile */
7336 hdrSize = sizeof(CmHEntry);
7337 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7338 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7340 /*mt009.301 Fixed 64BIT compilation warnings*/
7342 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7344 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7346 SDisplay(0, prntBuf);
7348 /* check if it is a sane block, elxe jump to next block */
7349 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7351 sprintf(prntBuf, " Trampled \n");
7352 SDisplay(0, prntBuf);
7354 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7355 SDisplay(0, prntBuf);
7358 * To go to next block in the heap we do not have any offset value
7359 * other than curHBlk->size. As the block is already trampled
7360 * we cannot rely on this size. So it is better to stop here unless there
7361 * exists any other mechanism(?) to know the offset to next block.
7366 /*mt009.301 Fixed 64BIT compilation warnings*/
7368 sprintf(prntBuf, " %8u", curHBlk->size);
7370 sprintf(prntBuf, " %8lu", curHBlk->size);
7372 SDisplay(0, prntBuf);
7374 if (CMM_IS_STATIC(curHBlk->memFlags))
7376 /*mt009.301 Fixed 64BIT compilation warnings*/
7378 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7380 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7382 SDisplay(0, prntBuf);
7384 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7386 /*mt009.301 Fixed 64BIT compilation warnings*/
7388 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7390 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7392 SDisplay(0, prntBuf);
7394 else if (CMM_IS_FREE(curHBlk->memFlags))
7396 /*mt009.301 Fixed 64BIT compilation warnings*/
7398 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7400 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7402 SDisplay(0, prntBuf);
7406 sprintf(prntBuf, " Trampled \n");
7407 SDisplay(0, prntBuf);
7409 /* goto next block in the heap */
7410 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7416 #endif /* SSI_DEBUG_LEVEL1 */
7418 /*-- mt035.201 : Added new API for timestamp --*/
7421 * Fun: Get TimeStamp
7423 * Desc: This function is used to Get TimeStamp in micro seconds
7440 struct timespec ptime;
7442 struct timeval ptime;
7451 clock_gettime(CLOCK_REALTIME, &ptime);
7453 gettimeofday(&ptime, NULL);
7456 /* Obtain the time of day, and convert it to a tm struct. --*/
7457 ptm = localtime (&ptime.tv_sec);
7458 /* Klock work fix ccpu00148484 */
7461 /* Format the date and time, down to a single second. --*/
7462 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7465 /* Compute microseconds. --*/
7467 microseconds = ptime.tv_nsec / 1000;
7469 microseconds = ptime.tv_usec;
7472 /* Print the formatted time, in seconds, followed by a decimal point
7473 and the microseconds. --*/
7474 /*mt009.301 Fixed 64BIT compilation warnings*/
7476 sprintf(ts, "%s.%03d", time_string, microseconds);
7478 sprintf(ts, "%s.%03ld", time_string, microseconds);
7484 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7487 * Fun: Get SGetSystemTsk
7489 * Desc: This function is used to Get sytem task id
7498 uint32_t SGetSystemTsk(Void)
7501 return (pthread_self());
7503 } /* end of SGetSystemTsk */
7505 #ifdef SS_MULTICORE_SUPPORT
7508 * Fun: Add Timer thread into system task table
7510 * Desc: This function is used to add the system task
7511 * associated with Timer thread.
7520 static SsSTskEntry* ssdAddTmrSTsk(Void)
7526 /* lock the system task table */
7527 ret = SLock(&osCp.sTskTblLock);
7531 #if (ERRCLASS & ERRCLS_DEBUG)
7532 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7533 "Could not lock system task table");
7539 /* check count of system tasks */
7540 if (osCp.numSTsks == SS_MAX_STSKS)
7543 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7545 #if (ERRCLASS & ERRCLS_DEBUG)
7546 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7547 "Could not give the Semaphore");
7552 #if (ERRCLASS & ERRCLS_ADD_RES)
7553 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7560 /* initialize the system task entry with the information we have */
7561 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7563 /* store the system task priority */
7564 sTsk->tskPrior = SS_NORM_TSK_PRI;
7566 /* initialize the demand queue */
7567 if (ssInitDmndQ(&sTsk->dQ) != ROK)
7570 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7572 #if (ERRCLASS & ERRCLS_DEBUG)
7573 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7574 "Could not give the Semaphore");
7579 #if (ERRCLASS & ERRCLS_DEBUG)
7580 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7581 "Could not initialize demand queue");
7587 /* initialize the system task entry lock */
7588 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7590 ssDestroyDmndQ(&sTsk->dQ);
7592 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7594 #if (ERRCLASS & ERRCLS_DEBUG)
7595 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7596 "Could not give the Semaphore");
7601 #if (ERRCLASS & ERRCLS_DEBUG)
7602 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
7603 "Could not initialize system task entry lock");
7610 /* success, update the table */
7611 sTsk->tskId = osCp.nxtSTskEntry;
7613 sTsk->termPend = FALSE;
7614 osCp.nxtSTskEntry = sTsk->nxt;
7617 /* unlock the system task table */
7619 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7621 #if (ERRCLASS & ERRCLS_DEBUG)
7622 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
7623 "Could not give the Semaphore");
7630 #endif /* SS_MULTICORE_SUPPORT */
7631 /* mt003.301 Readwrite lock and recursive mutex additions */
7632 #ifdef SS_LOCK_SUPPORT
7635 * Fun: ssdInitLockNew
7637 * Desc: This function is used to initialise lock/mutex
7646 S16 ssdInitLockNew(SLockInfo *lockId,uint8_t lockType)
7649 #ifdef SS_REC_LOCK_SUPPORT
7650 pthread_mutexattr_t attr;
7651 #endif /* SS_REC_LOCK_SUPPORT */
7652 Txt prntBuf[PRNTSZE];
7658 #ifdef SS_RDWR_LOCK_SUPPORT
7661 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
7663 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
7664 SDisplay(0, prntBuf);
7669 #endif /* SS_RDWR_LOCK_SUPPORT */
7670 #ifdef SS_REC_LOCK_SUPPORT
7673 retVal = pthread_mutexattr_init(&attr);
7677 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
7682 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
7684 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
7688 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
7689 pthread_mutexattr_destroy(&attr);
7693 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
7696 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
7697 pthread_mutexattr_destroy(&attr);
7703 #endif /* SS_REC_LOCK_SUPPORT */
7706 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
7707 SDisplay(0, prntBuf);
7717 * Desc: This function is used to aquire the read write lock
7726 S16 ssdLockNew(SLockInfo *lockId,uint8_t lockType)
7729 Txt prntBuf[PRNTSZE];
7735 #ifdef SS_RDWR_LOCK_SUPPORT
7738 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
7740 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7741 SDisplay(0, prntBuf);
7748 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
7750 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
7751 SDisplay(0, prntBuf);
7758 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
7760 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7761 SDisplay(0, prntBuf);
7768 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
7770 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7771 SDisplay(0, prntBuf);
7776 #endif /* SS_RDWR_LOCK_SUPPORT */
7777 #ifdef SS_REC_LOCK_SUPPORT
7780 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
7782 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7783 SDisplay(0, prntBuf);
7788 #endif /* SS_REC_LOCK_SUPPORT */
7791 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
7792 SDisplay(0, prntBuf);
7805 * Desc: This function is used to Unlock the read write lock
7814 S16 ssdUnlockNew(SLockInfo *lockId,uint8_t lockType)
7817 Txt prntBuf[PRNTSZE];
7823 #ifdef SS_RDWR_LOCK_SUPPORT
7826 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
7828 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
7829 SDisplay(0, prntBuf);
7834 #endif /* SS_RDWR_LOCK_SUPPORT */
7835 #ifdef SS_REC_LOCK_SUPPORT
7838 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
7840 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7841 SDisplay(0, prntBuf);
7846 #endif /* SS_REC_LOCK_SUPPORT */
7849 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
7850 SDisplay(0, prntBuf);
7859 * Fun: ssdDestroyLockNew
7861 * Desc: This function is used to destroy the read write lock
7870 S16 ssdDestroyLockNew(SLockInfo *lockId,uint8_t lockType)
7872 Txt prntBuf[PRNTSZE];
7878 #ifdef SS_RDWR_LOCK_SUPPORT
7881 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
7883 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
7884 SDisplay(0, prntBuf);
7889 #endif /* SS_RDWR_LOCK_SUPPORT */
7890 #ifdef SS_REC_LOCK_SUPPORT
7893 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
7895 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
7896 SDisplay(0, prntBuf);
7901 #endif /* SS_REC_LOCK_SUPPORT */
7904 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
7905 SDisplay(0, prntBuf);
7911 #endif /* SS_LOCK_SUPPORT */
7913 /* mt005.301 : Cavium Changes */
7914 #ifdef SS_SEUM_CAVIUM
7918 * Fun: ssInitRcvWork
7920 * Desc: This is the initializtion function of receive
7924 * RFAILED - failed, general (optional)
7926 * Notes: Function to initialize the work queue packet
7927 * receiving thread. This creates the new thread to
7928 * receive the work and sets the affinity.
7933 S16 ssInitRcvWork(void)
7935 pthread_attr_t attr;
7939 /* set the required attributes */
7940 pthread_attr_init(&attr);
7941 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
7942 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
7943 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
7945 /* Create a new thread to receive the work queue messages */
7946 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
7948 pthread_attr_destroy(&attr);
7953 pthread_attr_destroy(&attr);
7957 }/* ssInitRcvWork */
7964 * Desc: This is the handler function of receive
7968 * RFAILED - failed, general (optional)
7970 * Notes:The handler function of the work queue receiver task.
7971 * This will be waiting for the work and after receiving
7972 * it, work will converted and posted to that entityt
7978 static void *workRcvTsk(Ptr ptr)
7981 cvmx_wqe_t *workPtr;
7982 Buffer *mBuf, *rcvdBuf;
7983 SsMsgInfo *minfoPtr;
7992 /* get the work if its avilable */
7993 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
7995 if ( workPtr == NULLP )
7997 /* If there is no work then sleep for 10 usec */
7999 ts.tv_nsec = 500000;
8001 nanosleep(&ts, NULLP);
8005 switch(workPtr->tag)
8007 /* Switch over according to the tag value */
8008 case SS_CVMX_MBUF_TAG:
8010 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8012 /* Convert the physical address to Pointers */
8013 ret = SConvPhyPtr(&rcvdBuf);
8016 /* mt011.301: Cavium 32 bit changes */
8017 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8021 /* Copy the buffer to this region */
8022 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8025 /* mt011.301: Cavium 32 bit changes */
8026 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8030 /* mt011.301: Cavium 32 bit changes */
8031 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8033 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8035 /* Get the post strucutre and Post the message */
8036 if ( minfoPtr != NULLP)
8038 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8040 (Void)SPstTsk(&pst, mBuf);
8042 /* Free the buffer allocated if it cannot be sent */
8051 /* Invalid tag value, drop the work */
8052 /* mt011.301: Cavium 32 bit changes */
8053 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8062 #endif /* SS_SEUM_CAVIUM */
8064 #ifdef TENB_RTLIN_CHANGES
8065 S16 SInitLock(SLockId *l, uint8_t t)
8068 pthread_mutexattr_t prior;
8069 pthread_mutexattr_init(&prior);
8070 #ifndef RGL_SPECIFIC_CHANGES
8071 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8073 r = pthread_mutex_init(l, &prior);
8074 pthread_mutexattr_destroy(&prior);
8078 #ifdef SS_THR_REG_MAP
8081 * Fun: ssRegMainThread
8083 * Desc: This function is used to add the memory region
8084 * mapping for the main thread.
8086 * Ret: VOID (Always successful)
8094 Void ssRegMainThread(Void)
8097 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8099 printf("\nnot able to get different Id for main thread\n");
8102 /* Here the default region is added as we dont have any region associated with
8103 * Main thread. The thread should not perform any allocation except
8104 * the initial configuratin
8106 #ifdef XEON_SPECIFIC_CHANGES
8107 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8109 SS_GET_THREAD_MEM_REGION() =
8116 * Fun: ssCheckAndAddMemoryRegionMap
8118 * Desc: This function is used to add the memory region
8119 * mapping for the provided sTsk associated thread.
8120 * If the threadId can be placed in the thread memory
8121 * region mapping table and returns success if it is able
8122 * to place. If not, it keeps the thread ID in the static
8123 * local array and increments the count. Once thread Id
8124 * is successfully placed in the thread memory region mapping
8125 * table, pthread_cancel is sent for all the previous threads
8126 * which are failed to place in table.
8128 * Ret: TRUE - Thread ID successfully placed in thread memory region
8130 * FALSE - If thread Id is not placed in thread memory region
8133 * Notes:mapping tablemapping tablng tablee
8138 S32 ssCheckAndAddMemoryRegionMap
8140 pthread_t threadId, /* Thread Id of system task */
8141 Region region /* Region associated with thread */
8144 static uint32_t createdThreads;
8145 static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8149 /* Here 0xFF is considered as invalid region and if the mapping table
8150 * contains 0xFF, that mapping entry is free
8152 if(SS_INVALID_THREAD_REG_MAP !=
8153 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8155 /* Klock work fix ccpu00148484 */
8156 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8158 printf("\nfailed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8159 printf("\nNot able to get the different thread ID, exiting\n");
8162 createdThreadIds[createdThreads++] = threadId;
8165 /* If we found free mapping table entry, place the region and send pthread_cancel
8166 * for all the thread Ids which are created before this
8168 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8169 #ifdef XEON_SPECIFIC_CHANGES
8170 printf("\nThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8171 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8172 SS_MAX_THREAD_REGION_MAP), region);
8174 for(indx = 0; indx < createdThreads; indx++)
8176 #ifdef XEON_SPECIFIC_CHANGES
8177 printf("\nSending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8179 pthread_cancel(createdThreadIds[indx]);
8185 } /* ssCheckAndAddMemoryRegionMap */
8189 * Fun: ssCheckAndDelMemoryRegionMap
8191 * Desc: This function is used to add the memory region
8192 * mapping for the provided sTsk associated thread.
8193 * If the threadId can be placed in the thread memory
8194 * region mapping table and returns success if it is able
8195 * to place. If not, it keeps the thread ID in the static
8196 * local array and increments the count. Once thread Id
8197 * is successfully placed in the thread memory region mapping
8198 * table, pthread_cancel is sent for all the previous threads
8199 * which are failed to place in table.
8201 * Ret: TRUE - Thread ID successfully placed in thread memory region
8203 * FALSE - If thread Id is not placed in thread memory region
8206 * Notes:mapping tablemapping tablng tablee
8211 S32 ssCheckAndDelMemoryRegionMap
8213 pthread_t threadId /* Thread Id of system task */
8218 /* Raghu To-Do Check with team, is it necessary to acquire lock
8219 * as del and add may go parallel */
8220 /* Here 0xFF is considered as invalid region and if the mapping table
8221 * contains 0xFF, that mapping entry is free
8223 if(SS_INVALID_THREAD_REG_MAP ==
8224 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8227 printf("\nInvalid Thread ID (%ld)\n", (uint32_t)threadId);
8229 printf("\nInvalid Thread ID (%d)\n", (uint32_t)threadId);
8233 /* If we found free mapping table entry, place the region and send pthread_cancel
8234 * for all the thread Ids which are created before this
8236 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8240 } /* ssCheckAndAddMemoryRegionMap */
8244 #ifdef SS_TSKLOG_ENABLE
8249 * Desc: This function will return current time through input parameter.
8252 * RFAILED - failed, general (optional)
8260 volatile uint32_t *startTime,
8264 #ifdef MSPD_MLOG_NEW
8265 *startTime = GetTIMETICK();
8274 * Desc: This function will return current time through input parameter.
8275 * and take the difference of start time provided as input parameter
8279 * RFAILED - failed, general (optional)
8287 volatile uint32_t startTime,
8291 /*uint32_t stopTime;*/
8294 case PID_MAC_HARQ_IND:
8295 case PID_SCH_TTI_IND:
8297 case PID_MAC_DAT_IND:
8298 case PID_MAC_SF_ALLOC_REQ:
8299 case PID_MAC_STA_RSP:
8300 case PID_MAC_DL_SCHD:
8301 case PID_MAC_DL_CQI_IND:
8302 case PID_MAC_UL_CQI_IND:
8303 case PID_MAC_UL_SCHD:
8304 case PID_MAC_TTI_IND:
8305 case PID_CL_RCV_PHY_MSG:
8306 case PID_CL_HARQ_STA_IND:
8307 case PID_MAC_AM_HARQ_RLS:
8308 case PID_CL_DL_BATCH_PROC:
8309 case PID_CL_DLM_PRC_TTI_IND:
8310 case PID_CRC_IND_REAL:
8311 case PID_CRC_IND_DUMMY:
8312 case PID_TTI_LATENCY:
8313 case PID_RECPREQ_PROC:
8316 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8318 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8321 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8330 volatile uint32_t * startTime,
8340 volatile uint32_t startTime,
8347 #endif /*#ifdef SS_TSKLOG_ENABLE */
8348 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8350 * This primitive is used to calculate the CPU Utilization per Core
8355 * @return Void - function is always success
8357 Void UpdateSocCpuInfo
8359 CmCpuStatsInfo *cpuInfo,
8364 S8 mipsStr[MIPS_STRING_LEN];
8371 /* Open the file which holds the MIPS available value */
8372 mipsFd = fopen(MIPS_FILE, "r");
8379 /* Get the free mips available value from the file */
8380 if(NULLP == fgets(mipsStr, 24, mipsFd))
8382 printf("\nfgets to get the free mips available failed\n");
8387 strtok(mipsStr, " ");
8389 strPart = strtok(NULLP, " ");
8391 if(idx == CM_L2_CPU_UTIL)
8393 if(strPart != NULLP)
8395 l2FreeCpu = atoi(strPart);
8396 l2CpuUsed = 100 - l2FreeCpu;
8397 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8398 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
8399 cpuInfo->cpuUtil[0].numSamples++;
8402 if(idx == CM_L3_CPU_UTIL)
8404 strPart = strtok(NULLP, " ");
8405 if(strPart != NULLP)
8407 l3FreeCpu = atoi(strPart);
8408 l3CpuUsed = 100 - l3FreeCpu;
8409 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8410 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
8411 cpuInfo->cpuUtil[0].numSamples++;
8414 if(idx == CM_L2_CPU_UTIL)
8416 cpuInfo->numCores = CM_NUM_L2_CORES ;
8418 else if(idx == CM_L3_CPU_UTIL)
8420 cpuInfo->numCores = CM_NUM_L3_CORES ;
8426 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8427 #ifdef SS_MULTICORE_SUPPORT
8430 * Fun: Add Timer thread into system task table
8432 * Desc: This function is used to add the system task
8433 * associated with Timer thread.
8442 static SsSTskEntry* ssdReAddTmrSTsk(
8450 /* lock the system task table */
8451 ret = SLock(&osCp.sTskTblLock);
8455 #if (ERRCLASS & ERRCLS_DEBUG)
8456 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8457 "Could not lock system task table");
8463 /* initialize the system task entry with the information we have */
8464 sTsk = &osCp.sTskTbl[idx];
8469 SDestroyLock(&sTsk->lock);
8470 ssDestroyDmndQ(&sTsk->dQ);
8473 /* store the system task priority */
8474 sTsk->tskPrior = SS_NORM_TSK_PRI;
8476 /* initialize the demand queue */
8477 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8480 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8482 #if (ERRCLASS & ERRCLS_DEBUG)
8483 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8484 "Could not give the Semaphore");
8489 #if (ERRCLASS & ERRCLS_DEBUG)
8490 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8491 "Could not initialize demand queue");
8497 /* initialize the system task entry lock */
8498 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8500 ssDestroyDmndQ(&sTsk->dQ);
8502 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8504 #if (ERRCLASS & ERRCLS_DEBUG)
8505 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8506 "Could not give the Semaphore");
8511 #if (ERRCLASS & ERRCLS_DEBUG)
8512 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8513 "Could not initialize system task entry lock");
8520 /* success, update the table */
8521 sTsk->tskId = idx + 1;
8523 sTsk->termPend = FALSE;
8525 /* unlock the system task table */
8527 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8529 #if (ERRCLASS & ERRCLS_DEBUG)
8530 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8531 "Could not give the Semaphore");
8538 #endif /* SS_MULTICORE_SUPPORT */
8543 * Fun: Initialize timer table
8545 * Desc: This function initializes MTSS-specific information
8546 * in the timer table.
8555 S16 ssdReInitTmr(void)
8557 pthread_attr_t attr;
8558 struct sched_param param_sched;
8559 #ifndef XEON_SPECIFIC_CHANGES
8562 #ifdef SS_MULTICORE_SUPPORT
8564 #endif /* SS_MULTICORE_SUPPORT */
8565 #ifdef SS_THR_REG_MAP
8566 uint32_t threadCreated = FALSE;
8567 #endif /* SS_THR_REG_MAP */
8570 #ifndef XEON_SPECIFIC_CHANGES
8571 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
8574 #if (ERRCLASS & ERRCLS_DEBUG)
8575 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8576 "Could not give the Semaphore");
8582 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
8583 /* mt010.21: addition */
8585 #ifdef SS_MULTICORE_SUPPORT
8586 sTsk = ssdReAddTmrSTsk(0);
8591 #endif /* SS_MULTICORE_SUPPORT */
8592 /* create the timer handler thread */
8594 pthread_attr_init(&attr);
8595 /* mt021.201 - Addition to set stack size */
8596 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
8597 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8598 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8599 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
8600 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
8601 pthread_attr_setschedparam(&attr, ¶m_sched);
8604 #ifdef SS_THR_REG_MAP
8605 /* When the thread is created, we check for the memory mapping table if
8606 * threadId can be placed in thread memory map table. If it is not able to place
8607 * threadId is stored in tmporary array. Once thread is created successful,
8608 * thread_cancel is sent for each thread which are created before. All the
8609 * threads are made to wait on sema which is cancel point for thread.
8611 while(threadCreated == FALSE)
8614 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
8616 /* mt020.201 - Addition for destroying thread attribute object attr */
8617 pthread_attr_destroy(&attr);
8622 #ifdef SS_THR_REG_MAP
8623 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
8626 #endif /* SS_THR_REG_MAP */
8627 #ifdef SS_MEM_WL_DEBUG
8628 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
8631 /* mt020.201 - Addition for destroying thread attribute object attr */
8632 pthread_attr_destroy(&attr);
8633 sem_post(&osCp.dep.ssStarted);
8637 /**********************************************************************
8639 **********************************************************************/