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 /* header/extern include files (.x) */
107 #include "gen.x" /* general layer */
108 #include "ssi.x" /* system services */
110 #include "cm5.x" /* common timers */
112 #include "mt_ss.x" /* MTSS specific */
113 #ifdef SS_LOCKLESS_MEMORY
114 #include "mt_ss_wl.x" /* MTSS specific */
115 #endif /* SS_LOCKLESS_MEMORY */
117 #include "ss_queue.x" /* queues */
118 #include "ss_task.x" /* tasking */
119 #include "ss_timer.x" /* timers */
120 #include "ss_strm.x" /* STREAMS */
121 #include "ss_msg.x" /* messaging */
122 #include "ss_mem.x" /* memory management interface */
123 #include "ss_drvr.x" /* driver tasks */
124 #include "ss_gen.x" /* general */
125 #ifdef SS_LOCKLESS_MEMORY
126 #include "cm_llist.x"
128 #include "cm_mem_wl.x" /* common memory manager */
130 #include "cm_mem.x" /* common memory manager */
131 #endif /* SS_LOCKLESS_MEMORY */
132 #include "cm_lte.x" /* common memory manager */
133 /* mt001.301 : Additions */
134 #ifdef SS_LOGGER_SUPPORT
136 #endif /* SS_LOGGER_SUPPORT */
138 /*mt005.301: Cavium Changes */
139 #ifdef SS_SEUM_CAVIUM
140 /* cvmx includes files */
141 #include "cvmx-config.h"
143 #include "cvmx-pow.h"
144 #include "cvmx-tim.h"
145 #include "cvmx-fpa.h"
146 #include "cvmx-helper-fpa.h"
147 #include "cvmx-malloc.h"
148 #endif /* SS_SEUM_CAVIUM */
151 #include "mt_plat_t33.h"
152 #include "mt_plat_t33.x"
153 #include "sys/syscall.h"
156 #if defined(RGL_SPECIFIC_CHANGES) || defined(INTEL_WLS)
158 #include <hugetlbfs.h>
162 EXTERN void LwrMacRecvPhyMsg();
165 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
166 EXTERN S16 rgBatchProc (Void);
168 #ifdef RLC_MAC_DAT_REQ_RBUF
169 EXTERN S16 rgDlDatReqBatchProc ARGS((
172 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
173 EXTERN S16 rgBatchProc ARGS((
177 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
178 /* general purpose debug zone */
179 char my_buffer2[4096 * 4] = { 0 };
180 char my_buffer[4096] = { 0 };
181 int my_buffer_idx = 0;
185 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
187 struct sigcontext my_uc_mcontext = { 0 };
192 #include <ucontext.h>
196 #define SIGSEGV_STACK_GENERIC
197 #define REGFORMAT "%x\n"
199 #ifdef XEON_SPECIFIC_CHANGES
200 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
203 void dump_external(void);
206 PRIVATE Void mtDelSigals
211 PRIVATE Void mtDelSignals()
216 memset(&sa, 0, sizeof(struct sigaction));
217 sigemptyset(&sa.sa_mask);
218 sa.sa_handler = SIG_DFL;
219 sigaction(SIGSEGV, &sa, NULL);
221 memset(&sa, 0, sizeof(struct sigaction));
222 sigemptyset(&sa.sa_mask);
223 sa.sa_handler = SIG_DFL;
224 sigaction(SIGILL, &sa, NULL);
228 static void signal_segv(int signum, siginfo_t * info, void *ptr)
230 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
233 ucontext_t *ucontext = (ucontext_t *) ptr;
234 #ifdef XEON_SPECIFIC_CHANGES
236 int *p32 = (int *) 0x2fff0000;
241 printf("segv ooops @ %p\n", info->si_addr);
244 printf("Segmentation Fault!\n");
245 printf("info.si_signo = %d\n", signum);
246 printf("info.si_errno = %d\n", info->si_errno);
247 printf("info.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
248 printf("info.si_addr = %p\n", info->si_addr);
250 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
253 #ifndef RGL_SPECIFIC_CHANGES
254 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
255 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
256 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
257 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
258 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
259 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
260 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
261 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
262 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
263 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
264 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
265 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
266 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
267 printf("reg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
268 printf("reg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
269 printf("reg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
270 printf("reg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
273 printf("Stack trace (non-dedicated):\n");
275 sz = backtrace(buffer, 50);
276 strings = backtrace_symbols(buffer, sz);
277 for (i = 0; i < sz; ++i)
278 printf("%s\n", strings[i]);
280 printf("End of stack trace.");
282 #ifdef XEON_SPECIFIC_CHANGES
287 /* Lets first print our debug information */
288 printf("Before dumping our Debug info\n");
290 printf("After dumping our Debug info\n");
292 /* Disable the signal and make the enodeb to dump. This will make
293 * eNB to generate the core with dumping the ccpu log
300 /* End printing debug information */
305 /*** TBD: IMPORTANT ***
306 *** The following definition is temporary. This must be removed
307 *** when all products have been updated with latest ssi.h file OR
308 *** all ssi.h files have been updated to contain this definitions
310 /* New error class for FTHA added */
312 #define ERRCLS_FTHA 0x8
313 #endif /* ERRCLS_FTHA */
315 typedef struct _SPThreadCreateArg
317 void *argument; /* argument that is to be passed to the actual pthread */
318 void *(*start_routine) (void *); /* function from which pthread starts */
321 void *pthreadCreateHdlr(void* arg);
323 #ifdef SS_LOCKLESS_MEMORY
324 Buffer *mtTskBuffer1;
325 Buffer *mtTskBuffer2;
327 EXTERN pthread_t tmpRegTidMap[20];
328 EXTERN U8 stopBtInfo;
329 EXTERN S16 SGlobMemInfoShow(void);
330 #endif /* SS_LOCKLESS_MEMORY */
333 EXTERN APP_CONTEXT AppContext;
334 EXTERN S32 clusterMode;
337 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
338 EXTERN unsigned int tlPost(void *handle);
341 /* forward references */
342 /* mt003.301 Modifications - Moved to ss_gen.x */
343 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
344 Void *mtTskHdlrT2kL2 ARGS((Void*));
345 void mtSigSegvHndlr ARGS((void));
346 void mtSigUsr2Hndlr ARGS((void));
349 PRIVATE S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
350 PRIVATE Void *mtTskHdlr ARGS((void *));
351 PRIVATE S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
353 PRIVATE Void *mtTmrHdlr ARGS((void *));
354 PRIVATE Void mtTimeout ARGS((PTR tCb, S16 evnt));
356 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
357 PRIVATE Void mtIntSigHndlr ARGS((int));
358 PRIVATE Void mtExitClnup ARGS((void));
361 PRIVATE Void *mtConHdlr ARGS((void *));
365 #ifdef SS_DRVR_SUPPORT
366 PRIVATE Void *mtIsTskHdlr ARGS((void *));
370 /* mt020.201 - Addition for no command line available */
372 PRIVATE Void mtGetOpts ARGS((void));
373 /* mt003.301 Additions - File Based task registration made
374 * common for both MULTICORE and NON-MULTICORE
376 PRIVATE Bool fileBasedMemCfg = FALSE;
379 /* mt033.201 - addition of local function to print the statistics such as
380 * (size vs. numAttempts) and (allocations vs. deallocations)
382 #ifdef SSI_DEBUG_LEVEL1
383 PRIVATE S16 SPrintRegMemStats ARGS((Region region));
384 #endif /* SSI_DEBUG_LEVEL1 */
386 #ifdef SS_MULTICORE_SUPPORT
387 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void);
388 PRIVATE SsSTskEntry* ssdReAddTmrSTsk ARGS((U8 idx));
389 #ifndef SS_LOCKLESS_MEMORY
390 #ifndef RGL_SPECIFIC_CHANGES
391 PRIVATE S16 ssdInitMemInfo ARGS((void));
396 /* mt005.301: Cavium changes */
397 #ifdef SS_SEUM_CAVIUM
398 PRIVATE Void *workRcvTsk ARGS((void *));
399 #endif /* SS_SEUM_CAVIUM */
401 #ifdef SS_THR_REG_MAP
402 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
404 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
405 #endif /* SS_THR_REG_MAP */
407 /* type declarations */
409 #ifdef SS_DRVR_SUPPORT
410 typedef struct mtIsFlag
420 /* public variable declarations */
422 Cntr cfgNumRegs = SS_MAX_REGS;
423 /* Set memory configuration as false.
424 * Set to true if memory configuration through file is successfull.
426 Bool memConfigured = FALSE;
427 /* mt022.201 - Modification for shared memory relay region and memcal tool */
428 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
431 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
433 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
434 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
435 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
436 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
437 { SS_POOL_STATIC, 0 }
443 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
445 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
446 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
447 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
448 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
449 { SS_POOL_STATIC, 0 }
452 #endif /* INTEL_WLS */
454 #ifdef SS_LOCKLESS_MEMORY
457 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
459 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
460 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
461 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
462 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
463 { SS_POOL_STATIC, 0 }
467 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
469 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
470 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
471 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
472 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
473 { SS_POOL_STATIC, 0 }
477 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
479 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
480 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
481 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
482 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
483 { SS_POOL_STATIC, 0 }
487 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
489 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
490 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
491 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
492 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
493 { SS_POOL_STATIC, 0 }
496 #endif /* SS_LOCKLESS_MEMORY */
498 /* mt003.301 Modifications - File Based task registration made
499 * common for both MULTICORE and NON-MULTICORE
502 #ifdef SS_LOCKLESS_MEMORY
503 MtDynMemCfg mtDynMemoCfg =
505 SS_MAX_REGS, /* number of regions */
508 SS_DFLT_REGION, /* region id */
509 MT_MAX_BKTS, /* number of buckets */
511 /* block size, no. of blocks, Upper threshold, lower threshold */
512 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
513 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
514 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
515 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
519 SS_DFLT_REGION + 1, /* region id */
520 MT_MAX_BKTS, /* number of buckets */
522 /* block size, no. of blocks, Upper threshold, lower threshold */
523 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
524 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
525 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
526 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
530 SS_DFLT_REGION + 2, /* region id */
531 MT_MAX_BKTS, /* number of buckets */
533 /* block size, no. of blocks, Upper threshold, lower threshold */
534 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
535 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
536 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
537 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
541 SS_DFLT_REGION + 3, /* region id */
542 MT_MAX_BKTS, /* number of buckets */
544 /* block size, no. of blocks, Upper threshold, lower threshold */
545 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
546 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
547 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
548 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
552 SS_DFLT_REGION + 4, /* region id */
553 MT_MAX_BKTS, /* number of buckets */
555 /* block size, no. of blocks, Upper threshold, lower threshold */
556 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
557 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
558 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
559 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
562 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
565 SS_DFLT_REGION + 4, /* region id */
566 MT_MAX_BKTS, /* number of buckets */
568 /* block size, no. of blocks, Upper threshold, lower threshold */
569 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
570 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
571 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
572 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
580 MtGlobMemCfg mtGlobMemoCfg =
582 MT_MAX_BKTS, /* number of buckets */
585 /* block size, no. of blocks, Upper threshold, lower threshold */
586 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
587 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
588 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
589 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
591 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
592 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
593 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
594 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
598 #endif /* SS_LOCKLESS_MEMORY */
600 /* mt022.201 - Modification for memory calculator tool */
601 /* mt018.201 - added memory configuration matrix */
605 SS_MAX_REGS - 1, /* number of regions */
607 #ifndef XEON_SPECIFIC_CHANGES
608 SS_MAX_REGS, /* number of regions */
615 SS_DFLT_REGION, /* region id */
616 MT_MAX_BKTS, /* number of buckets */
617 MT_HEAP_SIZE, /* heap size */
619 #ifndef XEON_SPECIFIC_CHANGES
620 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
621 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
622 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
623 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
625 {256, 491520}, /* 60 pages of 2M*/
626 {512, 12288}, /* 3 pages of 2M */
627 {2048, 99328}, /* 97 Pages of 2M */
628 {8192, 75008}, /* 293 Pages of 2M */
629 {16384, 4096} /* 32 pages of 2M */
634 #ifndef SS_LOCKLESS_MEMORY
636 SS_DFLT_REGION + 1, /* region id */
637 MT_MAX_BKTS, /* number of buckets */
638 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
640 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
641 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
642 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
643 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
651 #endif /* SS_LOCKLESS_MEMORY */
652 #endif /* INTEL_WLS */
653 #ifdef SS_LOCKLESS_MEMORY
655 SS_DFLT_REGION + 1, /* region id */
656 MT_MAX_BKTS, /* number of buckets */
657 MT_HEAP_SIZE, /* heap size */
659 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
660 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
661 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
662 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
666 SS_DFLT_REGION + 2, /* region id */
667 MT_MAX_BKTS, /* number of buckets */
668 MT_HEAP_SIZE, /* heap size */
670 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
671 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
672 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
673 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
677 SS_DFLT_REGION + 3, /* region id */
678 MT_MAX_BKTS, /* number of buckets */
679 MT_HEAP_SIZE, /* heap size */
681 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
682 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
683 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
684 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
688 SS_DFLT_REGION + 4, /* region id */
689 MT_MAX_BKTS, /* number of buckets */
690 MT_HEAP_SIZE, /* heap size */
692 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
693 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
694 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
695 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
699 #endif /* SS_LOCKLESS_MEMORY */
703 /* mt003.301 Modifications - File Based task registration made
704 * common for both MULTICORE and NON-MULTICORE
705 * bucket info, as different regions may request for different no.
708 MtBktCfg mtBktInfo[MT_MAX_BKTS];
709 S16 msArgc; /* argc */
710 Txt **msArgv; /* argv */
711 S16 msOptInd; /* SGetOpt vars */
712 S8 *msOptArg; /* SGetOpt vars */
716 typedef struct _MtRegMemSz
722 PRIVATE MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
726 /* private variable declarations */
727 /* mt018.201 - change mtCMMRegCfg as array of pointers */
728 PRIVATE CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
729 PRIVATE CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
730 /* mt003.301 - Fixed compilation warnings */
731 /*mt004.301-addede new veriable for FAP*/
732 /*mt010.301 - removed veriable defined for FA*/
738 void mtSetNtlHdl(unsigned int hdl)
743 unsigned int mtGetNtlHdl()
745 return(osCp.ntl.hdl);
752 return (osCp.wls.intf);
755 #ifdef XEON_MULTIPLE_CELL_CHANGES
756 EXTERN S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
757 EXTERN S16 smWrReadWlsConfigParams (Void);
760 PRIVATE int SOpenWlsIntf()
763 #define WLS_DEVICE_NAME "/dev/wls"
765 #ifdef XEON_SPECIFIC_CHANGES
766 #ifdef XEON_MULTIPLE_CELL_CHANGES
767 hdl = WLS_Open(gWrWlsDeviceName, 1);
769 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
772 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, (512 *1024 * 1024));
779 printf("Could not open WLS Interface \n");
794 * Desc: This function is the entry point for the final binary. It
795 * calls SInit() in the common code. It can be replaced by a
796 * user function if required (SInit() must still be called).
798 * Ret: none on success
809 int argc, /* argument count */
810 char **argv /* argument vector */
814 int argc; /* argument count */
815 char **argv; /* argument vector */
819 #ifdef XEON_MULTIPLE_CELL_CHANGES
820 /* Read the WLS parameters from the file and copy into global control block */
821 if(smWrReadWlsConfigParams() != ROK)
823 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
825 } /* end of if statement */
831 #endif /* INTEL_WLS */
835 /* mt003.301 Modifications */
838 printf("\n SInit failed, SSI could not start \n");
839 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
843 /*mt010.301 cleanup part exposed to user*/
854 * Desc: This function is the entry point for the final binary. It
855 * calls SInit() in the common code. It can be replaced by a
856 * user function if required (SInit() must still be called).
858 * Ret: none on success
869 int argc, /* argument count */
870 char **argv /* argument vector */
873 int ssMain(argc, argv)
874 int argc; /* argument count */
875 char **argv; /* argument vector */
891 * initialization functions
896 * Fun: Initialize OS control point
898 * Desc: This function initializes MTSS-specific information
899 * in the OS control point.
917 struct sigaction act;
919 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
924 /*mt014.301 : 4GMX release related changes*/
928 /* mt005.301 : Cavium changes */
929 #ifdef SS_SEUM_CAVIUM
930 /* set group mask for the core */
931 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
932 #endif /* SS_SEUM_CAVIUM */
934 osCp.dep.sysTicks = 0;
936 /* mt020.201 - Addition for no command line available */
938 /* parse command line */
940 /* mt003.301 Additions */
941 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
943 printf("\n File Based Memory configuration failed \n");
948 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
949 #ifndef SS_LOCKLESS_MEMORY
950 #ifdef SS_MULTICORE_SUPPORT
951 if(memConfigured == FALSE)
957 /* initialize the started semaphore */
958 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
963 /* mt028.201 added compile time flag to allow not to mask signals */
965 /* mask all signals in the main thread */
967 sigdelset(&set, SIGINT);
968 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
969 sigdelset(&set, SIGSEGV);
970 sigdelset(&set, SIGUSR2);
971 sigdelset(&set, SIGILL);
972 #ifdef XEON_SPECIFIC_CHANGES
973 sigdelset(&set, SIGABRT);
974 sigdelset(&set, SIGTERM);
975 sigdelset(&set, SIGHUP);
978 pthread_sigmask(SIG_SETMASK, &set, NULLP);
979 #endif /* UNMASK_SIG */
981 /* install a SIGINT handler to shutdown */
982 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
984 /*Initialize SIGSEGV Signal */
985 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
987 memset(&sa, 0, sizeof(struct sigaction));
988 sigemptyset(&sa.sa_mask);
989 sa.sa_sigaction = signal_segv;
990 sa.sa_flags = SA_SIGINFO;
991 #ifndef XEON_SPECIFIC_CHANGES
992 sigaction(SIGSEGV, &sa, NULL);
994 memset(&sa, 0, sizeof(struct sigaction));
995 sigemptyset(&sa.sa_mask);
996 sa.sa_sigaction = signal_segv;
997 sa.sa_flags = SA_SIGINFO;
999 sigaction(SIGILL, &sa, NULL);
1001 if(sigaction(SIGILL, &sa, NULL) != 0)
1003 printf("Failed to process sigaction for the SIGILL\n");
1006 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1008 printf("Failed to process sigaction for the SIGSEGV\n");
1011 if(sigaction(SIGABRT, &sa, NULL) != 0)
1013 printf("Failed to process sigaction for the SIGABRT\n");
1016 if(sigaction(SIGTERM, &sa, NULL) != 0)
1018 printf("Failed to process sigaction for the SIGTERM\n");
1021 if(sigaction(SIGHUP, &sa, NULL) != 0)
1023 printf("Failed to process sigaction for the SIGHUP\n");
1028 signal (SIGSEGV, mtSigSegvHndlr);
1029 signal (SIGKILL, mtSigSegvHndlr);
1030 signal (SIGUSR2, mtSigUsr2Hndlr);
1035 signal (SIGINT, mtStopHndlr);
1038 act.sa_handler = mtIntSigHndlr;
1039 sigfillset(&act.sa_mask);
1041 if (sigaction(SIGINT, &act, NULLP) != 0)
1047 /* mt040.201 initialise random seed */
1048 osCp.dep.randSeed = time(NULLP);
1056 * Fun: De-initialize OS control point
1058 * Desc: This function reverses the initialization in ssdInitGen().
1078 sem_destroy(&osCp.dep.ssStarted);
1083 #ifdef SS_LOCKLESS_MEMORY
1087 * Fun: ssPutDynMemBlkSet
1089 * Desc: Returns the set of dynamic Blocks into the global region
1092 * Ret: ROK - successful,
1093 * RFAILED - unsuccessful.
1101 S16 ssPutDynMemBlkSet
1103 U8 bktIdx, /* Index to bucket list */
1104 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1105 added to global region */
1108 S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1109 U8 bktIdx; /* Index to bucket list */
1110 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1111 added to global region */
1114 CmMmGlobRegCb *globReg;
1115 CmMmGlobalBktCb *bktCb;
1119 globReg = osCp.globRegCb;
1121 #if (ERRCLASS & ERRCLS_INT_PAR)
1122 if(bktIdx >= globReg->numBkts)
1126 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1128 bktCb = &(globReg->bktTbl[bktIdx]);
1130 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1132 blkPtr = dynMemSetElem->nextBktPtr;
1133 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1134 free((Void *)blkPtr);
1137 dynMemSetElem->nextBktPtr = NULLP;
1138 dynMemSetElem->numFreeBlks = 0;
1145 * Fun: ssGetDynMemBlkSet
1147 * Desc: Gets the set of dynamic memory blocks from the global region
1150 * Ret: ROK - successful,
1151 * RFAILED - unsuccessful.
1159 S16 ssGetDynMemBlkSet
1161 U8 bktIdx, /* Index to bucket list */
1162 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1163 with new set values */
1166 S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1167 U8 bktIdx; /* Index to bucket list */
1168 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1169 with new set values */
1173 CmMmGlobRegCb *globReg;
1174 CmMmGlobalBktCb *bktCb;
1179 globReg = osCp.globRegCb;
1181 #if (ERRCLASS & ERRCLS_INT_PAR)
1182 if(bktIdx >= globReg->numBkts)
1186 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1188 bktCb = &(globReg->bktTbl[bktIdx]);
1189 basePtr = &(dynMemSetElem->nextBktPtr);
1191 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1193 blkPtr = (Data *)malloc(bktCb->size);
1195 basePtr = (CmMmEntry **)blkPtr;
1198 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1202 } /* ssGetDynMemBlkSet */
1207 * Fun: ssPutDynMemBlkSet
1209 * Desc: Returns the set of dynamic Blocks into the global region
1212 * Ret: ROK - successful,
1213 * RFAILED - unsuccessful.
1221 S16 ssPutDynMemBlkSet
1223 U8 bktIdx, /* Index to bucket list */
1224 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1225 added to global region */
1226 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1229 S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1230 U8 bktIdx; /* Index to bucket list */
1231 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1232 added to global region */
1233 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1236 CmMmGlobRegCb *globReg;
1237 CmMmGlobalBktCb *bktCb;
1239 CmMmBlkSetElement *globMemNode;
1243 globReg = osCp.globRegCb;
1245 #if (ERRCLASS & ERRCLS_INT_PAR)
1246 if(bktIdx >= globReg->numBkts)
1250 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1252 bktCb = &(globReg->bktTbl[bktIdx]);
1254 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1255 try lock is used as it is not required to block as it will be taken
1256 in the next go else it will be blocked for lock as we have to get the
1259 SLock(&(bktCb->bucketLock));
1265 /* Get a free node from the free node linked list */
1266 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1267 if(lstNode == NULLP)
1269 SUnlock(&(bktCb->bucketLock));
1273 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1275 /* Copy the content of the received element information on to free node
1276 * and add it to valid linked list */
1277 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1278 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1279 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1280 dynMemSetElem->numFreeBlks = 0;
1281 dynMemSetElem->nextBktPtr = NULLP;
1283 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1285 SUnlock(&(bktCb->bucketLock));
1293 * Fun: ssGetDynMemBlkSet
1295 * Desc: Gets the set of dynamic memory blocks from the global region
1298 * Ret: ROK - successful,
1299 * RFAILED - unsuccessful.
1301 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1308 S16 ssGetDynMemBlkSet
1310 U8 bktIdx, /* Index to bucket list */
1311 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1312 with new set values */
1313 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1316 S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1317 U8 bktIdx; /* Index to bucket list */
1318 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1319 with new set values */
1320 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1323 CmMmGlobRegCb *globReg;
1324 CmMmGlobalBktCb *bktCb;
1326 CmMmBlkSetElement *globMemNode;
1330 globReg = osCp.globRegCb;
1332 #if (ERRCLASS & ERRCLS_INT_PAR)
1333 if(bktIdx >= globReg->numBkts)
1337 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1339 bktCb = &(globReg->bktTbl[bktIdx]);
1341 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1342 try lock is used as it is not required to block as it will be taken
1343 in the next go else it will be blocked for lock as we have to get the
1346 SLock(&(bktCb->bucketLock));
1351 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1353 if(lstNode == NULLP)
1355 SUnlock(&(bktCb->bucketLock));
1359 /* Delete the node from the valid linked list and copy the values of the
1360 * elements of structrues into pointer */
1361 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1362 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1363 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1364 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1366 /* Add this node to the free node linked list */
1367 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1369 SUnlock(&(bktCb->bucketLock));
1373 } /* ssGetDynMemBlkSet */
1376 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1378 PRIVATE U32 memoryCheckCounter;
1381 U32 isMemThreshReached(
1385 U32 isMemThreshReached(reg)
1389 CmMmGlobRegCb *globReg;
1390 CmMmGlobalBktCb *bktCb;
1393 globReg = osCp.globRegCb;
1395 #if (ERRCLASS & ERRCLS_INT_PAR)
1396 if(bktIdx >= globReg->numBkts)
1400 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1402 bktCb = &(globReg->bktTbl[bktIdx]);
1404 if(gDynMemAlrm[bktIdx])
1406 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1407 SLock(&(bktCb->bucketLock));
1408 if(bktCb->listValidBktSet.count > 25)
1410 gDynMemAlrm[bktIdx] = FALSE;
1411 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1413 SUnlock(&(bktCb->bucketLock));
1419 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1421 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1422 SLock(&(bktCb->bucketLock));
1423 if(bktCb->listValidBktSet.count < 15 )
1424 gDynMemAlrm[bktIdx] = TRUE;
1425 memoryCheckCounter = 0;
1426 SUnlock(&(bktCb->bucketLock));
1432 #endif /* USE_MALLOC */
1433 #endif /* SS_LOCKLESS_MEMORY */
1435 #ifdef SS_USE_ICC_MEMORY
1438 * Fun: Initialize region/pool tables
1440 * Desc: This function initializes MTSS-specific information
1441 * in the region/pool tables and configures the common
1442 * memory manager for use.
1457 Void * ssGetIccHdl()
1461 CmMmDynRegCb *dynRegCb;
1463 /* Klock work fix ccpu00148484 */
1464 if(!(region < SS_MAX_REGS))
1469 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1471 return (dynRegCb->iccHdl);
1473 #endif /* SS_USE_ICC_MEMORY */
1475 #ifdef T2K_MEM_LEAK_DBG
1476 extern RegionMemLeakInfo regMemLeakInfo;
1477 #endif /* T2K_MEM_LEAK_DBG */
1481 S16 SPartitionWlsMemory()
1486 U64 pageSize[1], hugePageSize;
1489 long int pageSize[1], hugePageSize;
1492 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1494 U8 *regMemStrtAddr = (U8 *)osCp.wls.allocAddr;
1496 gethugepagesizes(pageSize,1);
1497 hugePageSize = pageSize[0];
1498 for (i = 0; i < 1; i++)
1500 mtRegMemSz[i].startAddr = regMemStrtAddr;
1501 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1503 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1504 reqdSz = numHugePg * hugePageSize;
1505 regMemStrtAddr += reqdSz;
1506 #ifdef T2K_MEM_LEAK_DBG
1507 /* Since wls is region 0 */
1508 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1509 regMemLeakInfo.numActvRegions++;
1510 #endif /* T2K_MEM_LEAK_DBG */
1512 //Store last region addr for validation
1513 mtRegMemSz[i].startAddr = regMemStrtAddr;
1517 #ifdef SS_MEM_WL_DEBUG
1518 Void SChkAddrValid(int type, int region, PTR ptr)
1520 char *tryPtr = NULL;
1521 if(type == 0) //Global
1523 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1524 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1526 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1532 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1534 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1540 #endif /* SS_MEM_WL_DEBUG */
1542 S16 SPartitionStaticMemory(U8 *startAddr)
1547 U8 *regMemStrtAddr = (U8 *)startAddr;
1550 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1551 for (i = 1; i < mtMemoCfg.numRegions; i++)
1553 mtRegMemSz[i].startAddr = regMemStrtAddr;
1554 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1555 regMemStrtAddr += reqdSz;
1556 #ifdef T2K_MEM_LEAK_DBG
1557 { /* Since region 1 onwards are used for non wls */
1558 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1559 regMemLeakInfo.numActvRegions++;
1561 #endif /* T2K_MEM_LEAK_DBG */
1565 S16 SAllocateWlsMem()
1573 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1574 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1576 for (i = 0; i < 1; i++)
1578 /* allocate space for the region */
1579 region = &mtMemoCfg.region[i];
1580 reqdMemSz += region->heapsize;
1581 mtRegMemSz[i].reqdSz += region->heapsize;
1583 for (j = 0; j < region->numBkts; j++)
1585 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1586 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1589 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1590 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1592 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1594 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1596 SPartitionWlsMemory();
1599 S16 SAllocateStaticMem()
1608 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1610 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1611 for (i = 1; i < mtMemoCfg.numRegions; i++)
1613 /* allocate space for the region */
1614 region = &mtMemoCfg.region[i];
1615 reqdMemSz += region->heapsize;
1616 mtRegMemSz[i].reqdSz += region->heapsize;
1618 for (j = 0; j < region->numBkts; j++)
1620 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1621 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1625 startAddr = malloc(reqdMemSz + (1024 * 10));
1627 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1629 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1631 SPartitionStaticMemory(startAddr);
1634 #endif /* INTEL_WLS */
1640 * Fun: Initialize region/pool tables
1642 * Desc: This function initializes MTSS-specific information
1643 * in the region/pool tables and configures the common
1644 * memory manager for use.
1662 /* mt018.201 - added local variable */
1667 Txt errMsg[256] = {'\0'};
1668 #ifdef SS_LOCKLESS_MEMORY
1669 CmMmDynRegCb *dynRegCb;
1670 #ifdef SS_USE_ICC_MEMORY
1672 CmMmGlobRegCb *globReg;
1675 #endif /* SS_LOCKLESS_MEMORY */
1678 /* Use the default SSI memory manager if the ICC memory manager is not
1679 * avilable. If ICC memory manager is avilable, it will be used for
1680 * all sharable memory allocation and de-allocation */
1681 #ifdef SS_LOCKLESS_MEMORY
1682 #ifdef SS_USE_ICC_MEMORY
1683 #ifndef YS_PHY_3_8_2
1685 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1687 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1688 if(dynRegCb == NULLP)
1692 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1694 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1696 dynRegCb->region = i;
1697 cmMmDynRegInit(dynRegCb);
1698 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1701 /* ysIccHdl = dynRegCb->iccHdl; */
1704 /* Initialize the global region first */
1705 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1707 if(osCp.globRegCb == NULLP)
1712 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1714 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1716 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1718 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1720 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1722 if(globReg->bktTbl[i].startAddr == NULLP)
1726 globReg->bktTbl[i].poolId = i;
1727 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1728 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1729 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1732 globReg->numBkts = mtGlobMemoCfg.numBkts;
1733 cmMmGlobRegInit(globReg);
1735 /* Initialize the dynamic task regions and sanity check for the theshold
1737 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1739 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1740 if(dynRegCb == NULLP)
1744 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1746 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1747 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1748 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1749 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1751 #ifdef XEON_SPECIFIC_CHANGES
1756 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1757 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1758 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1759 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1760 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1762 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1765 dynRegCb->region = i;
1766 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1767 cmMmDynRegInit(dynRegCb);
1769 #endif /* SS_USE_ICC_MEMORY */
1770 #endif /* SS_LOCKLESS_MEMORY */
1772 #ifdef T2K_MEM_LEAK_DBG
1774 /* Initailize mem leak tool memorys for debguing */
1775 regMemLeakInfo.numActvRegions=0;
1776 for(reg=0; reg <SS_MAX_REGS; reg++)
1778 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1779 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1780 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1781 regMemLeakInfo.regStartAddr[reg] = 0;
1784 regMemLeakInfo.regStartAddr[reg] = 0;
1785 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1787 printf("\n mutex init failed\n");
1793 /* Now allocate WLS memory */
1795 SAllocateStaticMem();
1797 /* mt018.201 - CMM Initialization */
1798 for (i = 0; i < mtMemoCfg.numRegions; i++)
1800 /* allocate space for the region control block */
1801 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1802 #ifdef TENB_RTLIN_CHANGES
1803 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1805 if (mtCMMRegCb[i] == NULLP)
1807 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1808 for the Region:%d control block\n",i);
1810 for (k = 0; k < i; k++)
1812 cmMmRegDeInit(mtCMMRegCb[k]);
1813 free(mtCMMRegCfg[k]->vAddr);
1814 free(mtCMMRegCb[k]);
1815 free(mtCMMRegCfg[k]);
1820 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1821 #ifdef TENB_RTLIN_CHANGES
1822 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1824 if (mtCMMRegCfg[i] == NULLP)
1826 for (k = 0; k < i; k++)
1828 cmMmRegDeInit(mtCMMRegCb[k]);
1829 free(mtCMMRegCfg[k]->vAddr);
1830 free(mtCMMRegCb[k]);
1831 free(mtCMMRegCfg[k]);
1833 free(mtCMMRegCb[i]);
1838 /* allocate space for the region */
1839 region = &mtMemoCfg.region[i];
1840 mtCMMRegCfg[i]->size = region->heapsize;
1841 for (j = 0; j < region->numBkts; j++)
1843 /* mt033.201 - addition for including the header size while computing the total size */
1844 #ifdef SSI_DEBUG_LEVEL1
1845 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1846 (region->bkt[j].numBlks);
1848 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1849 #endif /* SSI_DEBUG_LEVEL1 */
1852 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1854 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1857 #ifdef XEON_SPECIFIC_CHANGES
1858 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1859 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1861 #ifdef TENB_RTLIN_CHANGES
1862 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1865 if (mtCMMRegCfg[i]->vAddr == NULLP)
1867 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1868 for the Region:%d \n",i);
1870 for (k = 0; k < i; k++)
1872 cmMmRegDeInit(mtCMMRegCb[k]);
1873 free(mtCMMRegCfg[k]->vAddr);
1874 free(mtCMMRegCb[k]);
1875 free(mtCMMRegCfg[k]);
1877 free(mtCMMRegCb[i]);
1878 free(mtCMMRegCfg[i]);
1883 /* set up the CMM configuration structure */
1884 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1885 mtCMMRegCfg[i]->chFlag = 0;
1886 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1887 mtCMMRegCfg[i]->numBkts = region->numBkts;
1889 for (j = 0; j < region->numBkts; j++)
1891 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1892 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1895 /* initialize the CMM */
1896 #ifdef SS_LOCKLESS_MEMORY
1897 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1899 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1900 #endif /* SS_LOCKLESS_MEMORY */
1902 for (k = 0; k < i; k++)
1904 cmMmRegDeInit(mtCMMRegCb[k]);
1905 free(mtCMMRegCfg[k]->vAddr);
1906 free(mtCMMRegCb[k]);
1907 free(mtCMMRegCfg[k]);
1909 free(mtCMMRegCfg[i]->vAddr);
1910 free(mtCMMRegCb[i]);
1911 free(mtCMMRegCfg[i]);
1916 /* initialize the STREAMS module */
1917 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1918 if (region->regionId == 0)
1920 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
1922 for (k = 0; k < i; k++)
1924 cmMmRegDeInit(mtCMMRegCb[k]);
1925 free(mtCMMRegCfg[k]->vAddr);
1926 free(mtCMMRegCb[k]);
1927 free(mtCMMRegCfg[k]);
1929 cmMmRegDeInit(mtCMMRegCb[i]);
1930 free(mtCMMRegCfg[i]->vAddr);
1931 free(mtCMMRegCb[i]);
1932 free(mtCMMRegCfg[i]);
1937 /* mt001.301 : Additions */
1938 #ifdef SS_MEM_LEAK_STS
1940 #endif /* SS_MEM_LEAK_STS */
1949 * Fun: De-initialize region/pool tables
1951 * Desc: This function reverses the initialization in ssdInitMem().
1969 /* mt018.201 - added local variables */
1972 /* mt008.301 Additions */
1973 #ifdef SS_MEM_LEAK_STS
1974 cmDeinitMemLeakMdl();
1975 #endif /* SS_MEM_LEAK_STS */
1977 for (i = 0; i < mtMemoCfg.numRegions; i++)
1979 cmMmRegDeInit(mtCMMRegCb[i]);
1980 free(mtCMMRegCfg[i]->vAddr);
1981 free(mtCMMRegCb[i]);
1982 free(mtCMMRegCfg[i]);
1991 * Fun: Initialize task table
1993 * Desc: This function initializes MTSS-specific information
1994 * in the task table.
2012 /* mt001.301 : Additions */
2013 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2014 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2016 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2020 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2021 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2022 /* initialize system task information */
2023 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2025 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2027 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2034 * Fun: Deinitialize task table
2036 * Desc: This function reverses the initialization perfomed in
2060 #ifdef SS_DRVR_SUPPORT
2063 * Fun: Initialize driver task table
2065 * Desc: This function initializes MTSS-specific information
2066 * in the driver task table.
2086 pthread_attr_t attr;
2091 /* initialize the dependent portion of the driver task entries */
2092 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2094 osCp.drvrTskTbl[i].dep.flag = FALSE;
2098 /* create pipe for communication between SSetIntPend() and
2099 * the isTskHdlr thread.
2101 if (pipe(osCp.dep.isFildes) != 0)
2107 /* create the isTskHdlr thread */
2108 pthread_attr_init(&attr);
2109 /* mt021.201 - Addition to set stack size */
2110 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2111 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2112 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2113 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2115 /* mt020.201 - Addition for destroying thread attribute object attr */
2116 pthread_attr_destroy(&attr);
2122 /*mt014.301 : 4GMX release related changes*/
2123 #ifdef SS_4GMX_UCORE
2131 /* mt020.201 - Addition for destroying thread attribute object attr */
2132 pthread_attr_destroy(&attr);
2141 * Fun: Deinitialize driver information
2143 * Desc: This function reverses the initialization performed in
2159 Void ssdDeinitDrvr()
2162 /* mt008.301: Terminate the Driver Task on exit */
2163 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2166 TL_Close(AppContext.hUAII);
2167 if (clusterMode == RADIO_CLUSTER_MODE)
2169 TL_Close(AppContext.hUAII_second);
2175 #endif /* SS_DRVR_SUPPORT */
2180 * Fun: Initialize timer table
2182 * Desc: This function initializes MTSS-specific information
2183 * in the timer table.
2201 pthread_attr_t attr;
2202 struct sched_param param_sched;
2203 /* mt010.21: addition */
2205 #ifdef SS_MULTICORE_SUPPORT
2207 #endif /* SS_MULTICORE_SUPPORT */
2208 #ifdef SS_THR_REG_MAP
2209 U32 threadCreated = FALSE;
2210 #endif /* SS_THR_REG_MAP */
2214 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2215 /* mt010.21: addition */
2216 osCp.dep.tmrTqCp.nxtEnt = 0;
2217 for (i=0; i< SS_MAX_TMRS; i++)
2219 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2222 #ifdef SS_MULTICORE_SUPPORT
2223 sTsk = ssdAddTmrSTsk();
2228 #endif /* SS_MULTICORE_SUPPORT */
2229 /* create the timer handler thread */
2230 pthread_attr_init(&attr);
2231 /* mt021.201 - Addition to set stack size */
2232 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2233 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2234 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2235 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2236 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2237 pthread_attr_setschedparam(&attr, ¶m_sched);
2240 #ifdef SS_THR_REG_MAP
2241 /* When the thread is created, we check for the memory mapping table if
2242 * threadId can be placed in thread memory map table. If it is not able to place
2243 * threadId is stored in tmporary array. Once thread is created successful,
2244 * thread_cancel is sent for each thread which are created before. All the
2245 * threads are made to wait on sema which is cancel point for thread.
2247 while(threadCreated == FALSE)
2250 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2252 /* mt020.201 - Addition for destroying thread attribute object attr */
2253 pthread_attr_destroy(&attr);
2258 #ifdef SS_THR_REG_MAP
2259 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2262 #endif /* SS_THR_REG_MAP */
2263 #ifdef SS_MEM_WL_DEBUG
2264 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2267 /* mt020.201 - Addition for destroying thread attribute object attr */
2268 pthread_attr_destroy(&attr);
2277 * Fun: Deinitialize timer table
2279 * Desc: This function reverses the initialization performed in
2298 #ifdef SS_MULTICORE_SUPPORT
2301 #endif /* SS_MULTICORE_SUPPORT */
2304 #ifdef SS_MULTICORE_SUPPORT
2305 ret = SLock(&osCp.sTskTblLock);
2309 #if (ERRCLASS & ERRCLS_DEBUG)
2310 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2311 "Could not lock system task table");
2315 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2316 /* clean up the system task entry */
2320 SDestroyLock(&sTsk->lock);
2321 ssDestroyDmndQ(&sTsk->dQ);
2324 /* make this entry available in the system task table */
2325 sTsk->nxt = osCp.nxtSTskEntry;
2326 osCp.nxtSTskEntry = 0;
2330 /* unlock the system task table */
2331 SUnlock(&osCp.sTskTblLock);
2333 #endif /* SS_MULTICORE_SUPPORT */
2334 /* mt008.301: Terminate the timer thread on exit */
2335 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2345 * Desc: Pre-tst() initialization.
2363 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2367 pthread_attr_t attr;
2370 #endif /* CONSTDIO */
2375 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2380 osCp.dep.conInFp = (FILE *) stdin;
2381 osCp.dep.conOutFp = (FILE *) stdout;
2382 /* added compile time flag CONRD: mt017.21 */
2386 /* disable canonical input processing */
2387 fd = fileno(osCp.dep.conInFp);
2388 if ((tcgetattr(fd, &tio)) != 0)
2390 printf("Error: disable canonical input processing\n");
2394 tio.c_lflag &= ~ICANON;
2395 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2396 tio.c_cc[VTIME] = 0;
2397 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2399 printf("Error: while tcsetattr() processing\n");
2403 #endif /* CONSTDIO */
2406 /* set up the input fd to block when no data is available */
2407 fd = fileno(osCp.dep.conInFp);
2408 flags = fcntl(fd, F_GETFL, &flags);
2409 flags &= ~O_NONBLOCK;
2410 if (fcntl(fd, F_SETFL, flags) == -1)
2412 printf("Error: while fcntl processing\n");
2417 /* create the console handler thread */
2418 pthread_attr_init(&attr);
2419 /* mt021.201 - Addition to set stack size */
2420 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2421 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2422 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2425 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2427 /* mt020.201 - Addition for destroying thread attribute object attr */
2428 pthread_attr_destroy(&attr);
2430 printf("Error: Logging Thread creation failed \n");
2434 /* mt020.201 - Addition for destroying thread attribute object attr */
2435 pthread_attr_destroy(&attr);
2449 * Desc: This function reverses the initialization performed in
2459 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2469 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2472 /* mt008.301: Terminate the console reader on exit */
2473 while(pthread_cancel(osCp.dep.conHdlrTID));
2479 /* mt001.301 : Additions */
2489 S16 ssdInitWatchDog(port)
2494 Txt prntBuf[PRNTSZE];
2497 #ifdef SS_WATCHDOG_IPV6
2498 struct sockaddr_in6 tmpaddr;
2500 struct sockaddr_in tmpaddr;
2501 #endif /* SS_WATCHDOG_IPV6 */
2502 #ifdef SS_MULTIPLE_PROCS
2503 ProcId procId = SS_WD_WDPROC;
2504 if (SAddProcIdLst(1, &procId) != ROK)
2508 #endif /* SS_MULTIPLE_PROCS */
2511 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2513 /* Create a watch dog system task */
2514 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2516 /* Create a watch dog reveiver system task */
2517 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2519 /* Register and attach watch dog TAPA task */
2520 #ifdef SS_MULTIPLE_PROCS
2521 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2522 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2524 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2525 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2526 #endif /* SS_MULTIPLE_PROCS */
2527 /* Register and attach watch dog receiver TAPA task */
2528 #ifdef SS_MULTIPLE_PROCS
2529 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2530 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2532 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2533 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2534 #endif /* SS_MULTIPLE_PROCS */
2536 #ifndef SS_MULTIPLE_PROCS
2537 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2538 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2540 osCp.wdCp.watchDgPst.srcProcId = procId;
2541 osCp.wdCp.watchDgPst.dstProcId = procId;
2542 #endif /* SS_MULTIPLE_PROCS */
2544 /* Initialise the pst structure */
2545 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2546 /* Initialize the watch dog timer resolution default is 1 sec */
2548 cmInitTimers(osCp.wdCp.watchDgTmr, (U8)1);
2549 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2550 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2551 for(idx = 0; idx < 1; idx++)
2553 osCp.wdCp.watchDgTs[idx].first = NULLP;
2554 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2556 #ifdef SS_MULTIPLE_PROCS
2557 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2559 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2560 #endif /* SS_MULTIPLE_PROCS */
2562 /* Create the watch dog receiver socket */
2563 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2564 if(osCp.wdCp.globWd.sock == -1)
2566 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2570 #ifdef SS_WATCHDOG_IPV6
2571 tmpaddr.sin6_len = sizeof(tmpadDr);
2572 tmpaddr.sin6_family = AF_INET6;
2573 tmpaddr.sin6_addr = in6addr_any;
2574 tmpaddr.sin6_port = htons(port);
2576 tmpaddr.sin_family = AF_INET;
2577 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2578 tmpaddr.sin_port = htons(port);
2579 #endif /* SS_WATCHDOG_IPV6 */
2581 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2584 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2588 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2592 #ifndef SS_MULTIPLE_PROCS
2593 pst.srcProcId = SFndProcId();
2594 pst.dstProcId = SFndProcId();
2596 pst.srcProcId = procId;
2597 pst.dstProcId = procId;
2598 #endif /* SS_MULTIPLE_PROCS */
2599 pst.event = EVTSSHRTBTREQ;
2600 ssdInitWatchDgPst(&pst);
2601 SPstTsk(&pst, mBuf);
2607 S16 ssdInitWatchDgPst
2612 S16 ssdInitWatchDgPst(pst)
2617 pst->selector = SS_LOOSE_COUPLING;
2619 pst->region = DFLT_REGION; /* region */
2620 pst->pool = DFLT_POOL; /* pool */
2622 pst->prior = PRIOR0; /* priority */
2623 pst->route = RTESPEC; /* route */
2625 pst->dstEnt = ENTHB; /* destination entity */
2627 pst->srcEnt = ENTDW; /* source entity */
2633 #ifdef SS_MULTIPLE_PROCS
2635 S16 ssdWatchDgActvTmr
2642 S16 ssdWatchDgActvTmr(proc, ent, inst)
2646 S16 ssdWatchDgActvTmr
2651 S16 ssdWatchDgActvTmr()
2653 #endif /* SS_MULTIPLE_PROCS */
2656 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2662 Void ssdWatchDgTmrEvt
2664 PTR cb, /* control block */
2665 S16 event /* timer number */
2668 Void ssdWatchDgTmrEvt(cb, event)
2669 PTR cb; /* control block */
2670 S16 event; /* timer number */
2673 /* mt003.301 Fixed warings */
2677 Txt prntBuf[PRNTSZE];
2686 SPrint("Timer Heartbeat Request Expired");
2688 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2693 SLock(&osCp.wdCp.wdLock);
2694 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2696 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2698 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2700 if(osCp.wdCp.globWd.callback != 0)
2702 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2706 SUnlock(&osCp.wdCp.wdLock);
2708 if(!osCp.wdCp.globWd.watchdogStop)
2710 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2711 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2722 Void ssdStartWatchDgTmr
2729 Void ssdStartWatchDgTmr(cb, event, wait)
2739 Txt prntBuf[PRNTSZE];
2743 /* mt003.301 Modifications */
2746 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2747 if(event == SS_TMR_HRTBT)
2749 SPrint("\nSTART SS_TMR_HRTBT");
2756 SLock(&osCp.wdCp.wdLock);
2757 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2759 osCp.wdCp.globWd.wdsta[i].status = 0;
2761 SUnlock(&osCp.wdCp.wdLock);
2763 arg.tq = osCp.wdCp.watchDgTs;
2764 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2765 arg.timers = osCp.wdCp.watchDgTmr;
2766 arg.cb = (PTR)NULLP;
2768 arg.wait = osCp.wdCp.globWd.timeout = wait;
2777 Void ssdStopWatchDgTmr
2783 Void ssdStopWatchDgTmr(cb, event)
2791 Txt prntBuf[PRNTSZE];
2795 /* mt003.301 Modifications */
2798 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2799 if(event == SS_TMR_HRTBT)
2801 SPrint("STOP SS_TMR_HRTBT");
2805 SLock(&osCp.wdCp.wdLock);
2806 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2808 osCp.wdCp.globWd.wdsta[i].status = 0;
2810 SUnlock(&osCp.wdCp.wdLock);
2813 arg.tq = osCp.wdCp.watchDgTs;
2814 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2815 arg.timers = osCp.wdCp.watchDgTmr;
2816 arg.cb = (PTR)NULLP;
2833 S16 ssdSndHrtBtMsg(restart, type)
2841 Txt prntBuf[PRNTSZE];
2843 struct sockaddr_in tmpaddr;
2844 char hbMsg[SS_WD_HB_MSG_SIZE];
2851 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2855 /* Pack the message */
2856 strcpy(hbMsg, "<HB>REQ</HB>");
2858 /* Send the heartbeat messages to all the configured nodes */
2859 SLock(&osCp.wdCp.wdLock);
2860 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2862 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2867 /* Identify the destination node */
2868 #ifdef SS_WATCHDOG_IPV6
2869 tmpaddr.sin6_len = sizeof(tmpaddr);
2870 tmpaddr.sin6_family = AF_INET6;
2871 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2872 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2874 tmpaddr.sin_family = AF_INET;
2875 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2876 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2877 #endif /* SS_WATCHDOG_IPV6 */
2879 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2883 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2884 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2891 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2896 SUnlock(&osCp.wdCp.wdLock);
2901 #endif /* SS_WATCHDOG */
2905 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2911 * Desc: This function gets command line options.
2921 PRIVATE Void mtGetOpts
2926 PRIVATE Void mtGetOpts()
2934 FILE *memOpt; /* memory options file pointer */
2937 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2943 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2945 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2951 #ifdef SS_LOCKLESS_MEMORY
2966 osCp.dep.fileOutFp = (FILE *)NULLP;
2968 /* initialize memOpt */
2969 memOpt = (FILE *) NULLP;
2976 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2981 /* mt001.301 : Additions */
2982 #ifdef SS_MEM_LEAK_STS
2984 cmMemOpenMemLkFile(msOptArg);
2988 osCp.dep.fileOutFp = fopen(msOptArg, "w");
2991 fileBasedMemCfg = TRUE;
2992 memOpt = fopen(msOptArg, "r");
2994 /* if file does not exist or could not be opened then use the
2995 * default memory configuration as defined in mt_ss.h
2997 if (memOpt == (FILE *) NULLP)
2999 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3000 be opened, using default mem configuration\n", msOptArg);
3005 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3007 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3013 case 0: /*** INPUT: Number of regions ***/
3014 sscanf(line, "%ld", (long *) &numReg);
3015 mtMemoCfg.numRegions = numReg;
3016 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3018 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3024 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3025 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3026 if(numBkts > MT_MAX_BKTS)
3028 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3032 if(numPools > SS_MAX_POOLS_PER_REG)
3034 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3039 * Delay updation from local variable to global
3040 * structure of number of regions and heap data to
3041 * counter error conditions present above.
3043 for(idx = 0; idx < cfgNumRegs; idx++)
3045 mtMemoCfg.region[idx].numBkts = numBkts;
3046 cfgRegInfo[idx].region = idx;
3047 cfgRegInfo[idx].numPools = numPools;
3049 * Initialize the pool info as static type with size zero
3051 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3053 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3054 cfgRegInfo[idx].pools[poolIdx].size = 0;
3059 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3060 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3062 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3064 if(bktIdx >= numBkts)
3066 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3071 mtBktInfo[bktIdx].blkSize = bktSz;
3073 if(bktUpdtCnt == numBkts)
3075 i++; /*done reading bkt info, start reading individual region info*/
3079 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3080 sscanf(line,"%ld",(long *) ®Id);
3081 if(regId >= mtMemoCfg.numRegions)
3083 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3084 #ifndef XEON_SPECIFIC_CHANGES
3089 mtMemoCfg.region[regId].regionId = regId;
3092 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3093 if(bktUpdtCnt < numBkts)
3095 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3096 if(bktIdx >= numBkts)
3098 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3103 if(bktIdx < MT_MAX_BKTS)
3105 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3106 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3107 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3108 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3111 if(bktUpdtCnt == numBkts)
3118 case 5: /* INPUT: Heapsize ***/
3119 sscanf(line, "%ld", (long *) &heapSz);
3120 mtMemoCfg.region[regId].heapsize = heapSz;
3122 if(regUpdtCnt != mtMemoCfg.numRegions)
3131 #ifdef SS_LOCKLESS_MEMORY
3133 sscanf(line, "%ld", (long *) &numBkts);
3134 mtGlobMemoCfg.numBkts = numBkts;
3135 #ifndef XEON_SPECIFIC_CHANGES
3136 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3139 #ifdef XEON_SPECIFIC_CHANGES
3140 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3141 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3142 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3144 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3147 mtDynMemoCfg.region[idx].regionId = idx;
3148 mtDynMemoCfg.region[idx].numBkts = numBkts;
3156 if(bktUpdtCnt < numBkts)
3158 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3159 (long *) &bktSz, (long *) &bktNum,
3160 (long *) &bktSetSize, (long *) &bktRelThr,
3161 (long *) &bktAqurThr);
3162 /* Klock work fix ccpu00148484 */
3163 if(bktIdx < SS_MAX_POOLS_PER_REG)
3165 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3166 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3167 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3168 #ifdef XEON_SPECIFIC_CHANGES
3169 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3170 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3171 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3173 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3175 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3181 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3183 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3184 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3185 #ifdef XEON_SPECIFIC_CHANGES
3186 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3187 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3188 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3194 #ifdef XEON_SPECIFIC_CHANGES
3195 if(bktUpdtCnt == numBkts)
3201 case 8: /* INPUT: Global Heapsize ***/
3202 sscanf(line, "%ld", (long *) &heapSz);
3203 mtGlobMemoCfg.heapSize = heapSz;
3204 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3212 memConfigured = FALSE;
3216 memConfigured = TRUE;
3224 /* mt028.201: modification: multiple procs support related changes */
3225 #ifndef SS_MULTIPLE_PROCS
3228 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3230 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3233 #else /* SS_MULTIPLE_PROCS */
3237 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3239 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3241 SAddProcIdLst(1, &procId);
3244 #endif /* SS_MULTIPLE_PROCS */
3248 osCp.configFilePath = msOptArg;
3272 * Desc: Get options from command line
3274 * Ret: option - success
3276 * EOF - end of options
3278 * Notes: Handles command lines like the following
3281 * then command line should look like this...
3282 * -a foo -b foo1 -c -d foo
3286 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3291 * nloops = atoi(msArgv[msOptInd]);
3294 * state1 = atoi(msArgv[msOptInd]);
3307 int argc, /* argument count */
3308 char **argv, /* argument value */
3309 char *opts /* options */
3312 S16 SGetOpt(argc, argv, opts)
3313 int argc; /* argument count */
3314 char **argv; /* argument value */
3315 char *opts; /* options */
3318 /* mt020.201 - Removed for no command line */
3326 /* mt020.201 - Addition for no command line */
3338 /*mt013.301 : Changes as per coding standards*/
3339 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3345 if (!strcmp(argv[msOptInd], "--"))
3350 else if (argv[msOptInd][0] != '-')
3358 c = argv[msOptInd][sp];
3359 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3361 if (argv[msOptInd][++sp] == '\0')
3372 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3375 if (++msOptInd >= (S16) argc)
3380 else msOptArg = argv[msOptInd++];
3387 if (argv[msOptInd][++sp] == '\0')
3399 #endif /* NOCMDLINE */
3407 * Desc: This function starts system services execution; the
3408 * permanent tasks are started and the system enters a
3432 /* mt025.201 - Modification for adding lock to timer handler */
3433 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3435 sem_post(&osCp.dep.ssStarted);
3444 * indirect interface functions to system services service user
3450 * Fun: ssdAttachTTsk
3452 * Desc: This function sends the initial tick message to a TAPA
3453 * task if the task is a permanent task.
3465 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3468 S16 ssdAttachTTsk(tTsk)
3469 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3476 if (tTsk->tskType == SS_TSK_PERMANENT)
3478 /* Send a permanent tick message to this task, to start
3481 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3484 #if (ERRCLASS & ERRCLS_DEBUG)
3485 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3490 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3491 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3493 /* set up post structure */
3494 /* mt028.201: modification: multiple procs support related changes */
3495 #ifndef SS_MULTIPLE_PROCS
3496 mInfo->pst.dstProcId = SFndProcId();
3497 mInfo->pst.srcProcId = SFndProcId();
3498 #else /* SS_MULTIPLE_PROCS */
3499 mInfo->pst.dstProcId = tTsk->proc;
3500 mInfo->pst.srcProcId = tTsk->proc;
3501 #endif /* SS_MULTIPLE_PROCS */
3502 mInfo->pst.selector = SEL_LC_NEW;
3503 mInfo->pst.region = DFLT_REGION;
3504 mInfo->pst.pool = DFLT_POOL;
3505 mInfo->pst.prior = PRIOR3;
3506 mInfo->pst.route = RTESPEC;
3507 mInfo->pst.event = 0;
3508 mInfo->pst.dstEnt = tTsk->ent;
3509 mInfo->pst.dstInst = tTsk->inst;
3510 mInfo->pst.srcEnt = tTsk->ent;
3511 mInfo->pst.srcInst = tTsk->inst;
3513 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3514 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3520 #if (ERRCLASS & ERRCLS_DEBUG)
3521 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3522 "Could not write to demand queue");
3535 * Fun: ssdDetachTTsk
3537 * Desc: Does nothing.
3549 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3552 S16 ssdDetachTTsk(tTsk)
3553 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3563 * Fun: ssdCreateSTsk
3565 * Desc: This function creates a system task. A thread is started
3566 * on the system task handler function defined later.
3578 SsSTskEntry *sTsk /* pointer to system task entry */
3581 S16 ssdCreateSTsk(sTsk)
3582 SsSTskEntry *sTsk; /* pointer to system task entry */
3586 pthread_attr_t attr;
3587 /* struct sched_param param_sched;*/
3589 #ifdef SS_THR_REG_MAP
3590 U32 threadCreated = FALSE;
3595 #ifdef SS_SINGLE_THREADED
3596 /* mt001.301 : Additions */
3598 #ifdef SS_MULTICORE_SUPPORT
3599 if (osCp.numSTsks > 1)
3601 if (osCp.numSTsks > 0)
3602 #endif /* SS_MULTICORE_SUPPORT */
3604 #ifdef SS_MULTICORE_SUPPORT
3605 if (osCp.numSTsks > 3)
3607 if (osCp.numSTsks > 2)
3608 #endif /* SS_MULTICORE_SUPPORT */
3609 #endif /* SS_WATCHDOG */
3616 /* set the current executing entity and instance IDs to
3617 * 'not configured'. create the lock to access them.
3619 sTsk->dep.ent = ENTNC;
3620 sTsk->dep.inst = INSTNC;
3623 /* create the thread */
3624 pthread_attr_init(&attr);
3625 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3627 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3628 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3629 if (sTsk->tskPrior == 0)
3631 printf("Creating RT thread #######################\n");
3632 #ifdef SS_THR_REG_MAP
3633 /* When the thread is created, we check for the memory mapping table if
3634 * threadId can be placed in thread memory map table. If it is not able to place
3635 * threadId is stored in tmporary array. Once thread is created successful,
3636 * thread_cancel is sent for each thread which are created before. All the
3637 * threads are made to wait on sema which is cancel point for thread.
3639 while(threadCreated == FALSE)
3642 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3645 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3646 pthread_attr_destroy(&attr);
3648 #if (ERRCLASS & ERRCLS_DEBUG)
3649 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3654 #ifdef SS_THR_REG_MAP
3655 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3663 #ifdef SS_THR_REG_MAP
3664 /* When the thread is created, we check for the memory mapping table if
3665 * threadId can be placed in thread memory map table. If it is not able to place
3666 * threadId is stored in tmporary array. Once thread is created successful,
3667 * thread_cancel is sent for each thread which are created before. All the
3668 * threads are made to wait on sema which is cancel point for thread.
3670 while(threadCreated == FALSE)
3673 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3677 /* mt020.201 - Addition for destroying thread attribute object attr */
3678 pthread_attr_destroy(&attr);
3680 #if (ERRCLASS & ERRCLS_DEBUG)
3681 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3686 #ifdef SS_THR_REG_MAP
3687 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3694 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3695 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3697 static U32 stLwpId = 3;
3698 sTsk->dep.lwpId = ++stLwpId;
3700 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3702 /* mt020.201 - Addition for destroying thread attribute object attr */
3703 pthread_attr_destroy(&attr);
3713 pthread_attr_t* attr,
3714 void *(*start_routine) (void *),
3718 int SCreatePThread(tid, attr, start_routine, arg)
3720 pthread_attr_t* attr;
3721 void *(*start_routine) (void *);
3726 #ifdef SS_THR_REG_MAP
3727 U32 threadCreated = FALSE;
3730 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3731 /* Klock work fix ccpu00148484 */
3732 if(threadArg == NULLP)
3736 threadArg->argument = arg;
3737 threadArg->start_routine = start_routine;
3740 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3742 #ifdef SS_THR_REG_MAP
3743 /* When the thread is created, we check for the memory mapping table if
3744 * threadId can be placed in thread memory map table. If it is not able to place
3745 * threadId is stored in tmporary array. Once thread is created successful,
3746 * thread_cancel is sent for each thread which are created before. All the
3747 * threads are made to wait on sema which is cancel point for thread.
3749 while(threadCreated == FALSE)
3752 /*pthreadCreateHdlr */
3753 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3758 #ifdef SS_THR_REG_MAP
3759 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3770 * Fun: Set Pthread Attributes
3772 * Desc: This function is used to set various explicit
3773 * pthread attributes like, priority scheduling,etc
3784 PRIVATE S16 ssdSetPthreadAttr
3787 pthread_attr_t *attr
3790 PRIVATE S16 ssdSetPthreadAttr(sTsk, attr)
3792 pthread_attr_t *attr
3795 struct sched_param param;
3798 SMemSet(¶m, 0, sizeof(param));
3800 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3801 param.sched_priority = 100 - 1 - tskPrior;
3803 param.sched_priority = 100 - 10 - tskPrior;
3806 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3807 /* TODO:: This can be avoided by reducing the priority
3808 * of iccserv thread in l1_master.sh*/
3810 if (clusterMode == RADIO_CLUSTER_MODE)
3812 if(tskPrior == PRIOR1)
3814 param.sched_priority = 91;
3821 printf("Set priority %u\n", param.sched_priority);
3823 /* Set Scheduler to explicit, without this non of the below
3824 pthread attr works */
3825 #ifdef TENB_RTLIN_CHANGES
3826 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3829 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3830 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3831 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3832 #ifdef TENB_RTLIN_CHANGES
3833 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3835 pthread_attr_setschedparam(attr, ¶m);
3839 } /* ssdSetPthreadAttr */
3841 /************* multi-core support **************/
3842 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3843 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3847 * Fun: Get the current core/cpu affinity for a thread/lwp
3849 * Desc: This function is used to get the current processor/core
3850 * affinity for a a system task (thread/lwp). It sets the
3851 * affinity based on the mode supplied by the caller.
3854 * RFAILED - failed, general (optional)
3864 SSTskId *tskId, /* filled in with system task ID */
3865 U32 *coreId /* the core/processor id to which the affinity is set */
3868 S16 ssdGetAffinity(tskId, coreId)
3869 SSTskId *tskId; /* filled in with system task ID */
3870 U32 *coreId; /* the core/processor id to which the affinity is set */
3881 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3888 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3890 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3892 tId = osCp.sTskTbl[tskInd].dep.tId;
3897 /* if tskId is not found in the tskTbl */
3898 if (tskInd == SS_MAX_STSKS)
3900 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3905 /* initialize the cpu mask */
3908 /* set thread affinity for linux */
3909 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3911 #if (ERRCLASS & ERRCLS_DEBUG)
3912 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3915 } /* end if pthread_setaffinity fails */
3917 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3919 if (CPU_ISSET (cpuInd, & cpuSet))
3928 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3930 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3932 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3937 /* if tskId is not found in the tskTbl */
3938 if (tskInd == SS_MAX_STSKS)
3940 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3944 /* set thread affinity for Solaris */
3945 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3947 #if (ERRCLASS & ERRCLS_DEBUG)
3948 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3951 } /* end if processor_bind fails */
3954 #endif /* SS_LINUX */
3958 } /* ssdGetAffinity */
3963 * Fun: Set the core/cpu affinity for a thread/lwp
3965 * Desc: This function is used to set processor/core affinity for a
3966 * a system task (thread/lwp). It sets the affinity based on the
3967 * mode supplied by the caller.
3970 * RFAILED - failed, general (optional)
3980 SSTskId *tskId, /* filled in with system task ID */
3981 U32 coreId /* the core/processor id to which the affinity has to be set */
3984 S16 ssdSetAffinity(tskId, coreId)
3985 SSTskId *tskId; /* filled in with system task ID */
3986 U32 coreId; /* the core/processor id to which the affinity has to be set */
3995 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4004 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4006 /* Here tskId can not be used as index as the task may be terminated if
4007 there is a TERM even for that tsk, thus breaking the task Id numbering
4009 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4011 tId = osCp.sTskTbl[tskInd].dep.tId;
4016 /* if tskId is not found in the tskTbl */
4017 if (tskInd == SS_MAX_STSKS)
4019 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4023 /* initialize the cpu mask */
4026 /* set the cpu mask */
4027 CPU_SET(coreId, &cpuSet);
4029 /* set thread affinity for linux */
4030 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4032 #if (ERRCLASS & ERRCLS_DEBUG)
4033 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4036 } /* end if pthread_setaffinity fails */
4040 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4042 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4043 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4045 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4050 /* if tskId is not found in the tskTbl */
4051 if (tskInd == SS_MAX_STSKS)
4053 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4057 /* set thread affinity for Solaris */
4058 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4060 #if (ERRCLASS & ERRCLS_DEBUG)
4061 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4064 } /* end if processor_bind fails */
4067 #endif /* SS_LINUX */
4069 } /* ssdSetAffinity */
4071 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4072 /************ end multi-core support *************/
4077 * Fun: ssdDestroySTsk
4079 * Desc: This function destroys a system task. A terminate
4080 * event message is sent to the thread function.
4092 SsSTskEntry *sTsk /* pointer to system task entry */
4095 S16 ssdDestroySTsk(sTsk)
4096 SsSTskEntry *sTsk; /* pointer to system task entry */
4105 /* we send a message to this system task to tell it to die */
4106 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4109 #if (ERRCLASS & ERRCLASS_DEBUG)
4110 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4116 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4117 mInfo->eventInfo.event = SS_EVNT_TERM;
4119 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4123 #if (ERRCLASS & ERRCLASS_DEBUG)
4124 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4125 "Could not write to demand queue");
4135 /* mt023.201 - Added SThreadYield function to yield CPU
4139 * Desc: This function defers thread execution to any other ready
4161 /* mt024.201 - seperated Linux and other UNIX implementations
4167 /* Set sleep value to 0 to yield CPU */
4171 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4173 #else /* other UNICes */
4175 return (sleep(0) == 0 ? ROK : RFAILED);
4177 #endif /* SS_LINUX */
4184 * Fun: Register timer
4186 * Desc: This function is used to register a timer
4187 * function for the service user. System services
4188 * will invoke the timer activation function
4189 * passed to it at the specified intervals.
4193 * Notes: Timing is handled by the common timers. The
4194 * ticks are handled by a thread that uses
4195 * nanosleep() and thus timing precision will not
4204 SsTmrEntry *tmr /* pointer to timer entry */
4208 SsTmrEntry *tmr; /* pointer to timer entry */
4216 /* initialize common timers */
4217 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4220 /* start the timer */
4221 arg.tq = osCp.dep.tmrTq;
4222 arg.tqCp = &osCp.dep.tmrTqCp;
4223 arg.timers = tmr->dep.timers;
4228 arg.max = TMR_DEF_MAX;
4229 arg.wait = tmr->interval;
4239 * Fun: Deregister timer
4241 * Desc: This function is used to deregister a timer function.
4253 SsTmrEntry *tmr /* pointer to timer entry */
4256 S16 ssdDeregTmr(tmr)
4257 SsTmrEntry *tmr; /* pointer to timer entry */
4265 /* stop the timer */
4266 arg.tq = osCp.dep.tmrTq;
4267 arg.tqCp = &osCp.dep.tmrTqCp;
4268 arg.timers = tmr->dep.timers;
4273 arg.max = TMR_DEF_MAX;
4274 arg.wait = tmr->interval;
4284 * Fun: Critical error
4286 * Desc: This function is called when a critical error occurs.
4298 Seq seq, /* sequence number */
4299 Reason reason /* reset reason */
4302 S16 ssdError(seq, reason)
4303 Seq seq; /* sequence number */
4304 Reason reason; /* reset reason */
4314 /* get calling task ID */
4315 tId = pthread_self();
4318 /* set up the message to display */
4319 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4320 "reason = %d\n\n", (U8)tId, seq, reason);
4324 /* delete all system tasks */
4325 for (i = 0; i < SS_MAX_STSKS; i++)
4327 if (osCp.sTskTbl[i].used
4328 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4330 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4336 pthread_exit(NULLP);
4339 /* won't reach here */
4348 * Desc: This function is called to log an error.
4360 Ent ent, /* Calling layer's entity id */
4361 Inst inst, /* Calling layer's instance id */
4362 ProcId procId, /* Calling layer's processor id */
4363 Txt *file, /* file name where error occured */
4364 S32 line, /* line in file where error occured */
4365 ErrCls errCls, /* error class */
4366 ErrCode errCode, /* layer unique error code */
4367 ErrVal errVal, /* error value */
4368 Txt *errDesc /* description of error */
4371 Void ssdLogError(ent, inst, procId, file, line,
4372 errCls, errCode, errVal, errDesc)
4373 Ent ent; /* Calling layer's entity id */
4374 Inst inst; /* Calling layer's instance id */
4375 ProcId procId; /* Calling layer's processor id */
4376 Txt *file; /* file name where error occured */
4377 S32 line; /* line in file where error occured */
4378 ErrCls errCls; /* error class */
4379 ErrCode errCode; /* layer unique error code */
4380 ErrVal errVal; /* error value */
4381 Txt *errDesc; /* description of error */
4394 /* get calling task ID */
4396 tId = pthread_self();
4402 case ERRCLS_ADD_RES:
4403 errClsMsg = "ERRCLS_ADD_RES";
4406 case ERRCLS_INT_PAR:
4407 errClsMsg = "ERRCLS_INT_PAR";
4411 errClsMsg = "ERRCLS_DEBUG";
4414 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4416 errClsMsg = "ERRCLS_FTHA";
4420 errClsMsg = "INVALID ERROR CLASS!";
4425 /*mt009.301 Fixed 64BIT compilation warnings*/
4428 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4429 "file: %s line: %03d errcode: %05d errcls: %s\n"
4430 "errval: %05d errdesc: %s\n",
4431 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4434 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4435 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4436 "errval: %05ld errdesc: %s\n",
4437 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4439 SDisplay(0, errBuf);
4440 /* mt001.301 : Additions */
4441 #ifdef SS_LOGGER_SUPPORT
4443 #endif /* SS_LOGGER_SUPPORT */
4447 /* debug errors halt the system */
4448 if (errCls == ERRCLS_DEBUG)
4450 /* mt001.301 : Additions */
4451 #ifdef SS_LOGGER_SUPPORT
4453 #endif /* SS_LOGGER_SUPPORT */
4454 /* delete all system tasks */
4455 for (i = 0; i < SS_MAX_STSKS; i++)
4457 if (osCp.sTskTbl[i].used
4458 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4460 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4466 pthread_exit(NULLP);
4478 * Fun: Register driver task
4480 * Desc: This function is called to register the handlers for a
4493 SsDrvrTskEntry *drvrTsk /* driver task entry */
4496 S16 ssdRegDrvrTsk(drvrTsk)
4497 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4504 /* mt001.30 : Additions */
4507 * Fun: Deregister driver task
4509 * Desc: This function is called to deregister the handlers for a
4522 SsDrvrTskEntry *drvrTsk /* driver task entry */
4525 S16 ssdDeregDrvrTsk(drvrTsk)
4526 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4539 * mt003.301 Additions - SDeRegTTsk fix
4541 #ifdef SS_MULTIPLE_PROCS
4550 S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4555 #else /*SS_MULTIPLE_PROCS*/
4563 S16 ssdProcTTskTerm(tTsk, idx)
4567 #endif /*SS_MULTIPLE_PROCS*/
4569 #ifdef SS_MULTIPLE_PROCS
4582 /* We check the sTsk element; if it is not NULLP, the
4583 * task is attached. So we have to detach it before
4584 * deregistering the task.
4586 ret = SLock(&osCp.sTskTblLock);
4589 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4592 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4595 #if (ERRCLASS & ERRCLS_DEBUG)
4596 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4598 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4600 #if (ERRCLASS & ERRCLS_DEBUG)
4601 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4609 #ifdef SS_MULTIPLE_PROCS
4611 if (tTsk->initTsk != NULLP)
4614 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4617 &(osCp.tTskTbl[idx].xxCb));
4619 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4622 &(osCp.tTskTbl[idx].xxCb));
4623 #endif /* USE_MEMCAL */
4625 #endif /* SS_MULTIPLE_PROCS */
4627 if (tTsk->sTsk != NULLP)
4631 sTsk->dep.ent = ent;
4632 sTsk->dep.inst = inst;
4634 for (n = 0; n < SS_MAX_TTSKS; n++)
4636 if (sTsk->tTsks[n] == idx)
4638 sTsk->tTsks[n] = SS_INVALID_IDX;
4644 /* call the implementation to detach the task */
4645 ssdDetachTTsk(tTsk);
4647 sTsk->dep.ent = ENTNC;
4648 sTsk->dep.inst = INSTNC;
4651 /* Now we empty the entry for this task and update the table
4654 #ifdef SS_MULTIPLE_PROCS
4655 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4656 #else /* SS_MULTIPLE_PROCS */
4657 osCp.tTskIds[ent][inst] = SS_TSKNC;
4658 #endif /* SS_MULTIPLE_PROCS */
4661 #ifdef SS_MULTIPLE_PROCS
4662 tTsk->proc = PROCNC;
4663 #endif /* SS_MULTIPLE_PROCS */
4665 tTsk->inst = INSTNC;
4666 tTsk->tskType = TTUND;
4667 tTsk->initTsk = NULLP;
4668 tTsk->actvTsk = NULLP;
4671 tTsk->nxt = osCp.nxtTTskEntry;
4672 osCp.nxtTTskEntry = idx;
4675 #ifdef SS_MULTIPLE_PROCS
4676 /* mark the control block for this task as invalid */
4677 osCp.tTskTbl[idx].xxCb = NULLP;
4680 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4681 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4683 #if (ERRCLASS & ERRCLS_DEBUG)
4684 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4691 //#ifndef SPLIT_RLC_DL_TASK
4692 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4693 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4694 EXTERN Void ysMtTskHdlr(Void);
4695 EXTERN Void ysMtPollPhyMsg(U8 region);
4696 EXTERN Void ysMtRcvPhyMsg(Void);
4698 Void *mtTskHdlrT2kL2
4700 Ptr tskPtr /* pointer to task entry */
4703 Void *mtTskHdlrT2kL2(tskPtr)
4704 Ptr tskPtr; /* pointer to task entry */
4710 /* wait for SS to come up */
4711 /* It is required to block on this semaphore before starting actual processing of
4712 the thread becasue the creator of this thread might want to cance it without
4713 doing any processing. When this semaphore is released, means the creator gives
4714 the go ahead for actual processing and we should never come back to this point */
4715 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4724 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4725 * (processes L1 msgs) */
4731 EXTERN Void ysMtTskHdlr(Void);
4732 EXTERN Void YsPhyRecvMsg();
4734 Void *mtTskHdlrT2kL2
4736 Ptr tskPtr /* pointer to task entry */
4739 Void *mtTskHdlrT2kL2(tskPtr)
4740 Ptr tskPtr; /* pointer to task entry */
4746 /* get out the system task entry from the parameter */
4747 sTsk = (SsSTskEntry *) tskPtr;
4749 /* wait for SS to come up */
4750 /* It is required to block on this semaphore before starting actual processing of
4751 the thread becasue the creator of this thread might want to cance it without
4752 doing any processing. When this semaphore is released, means the creator gives
4753 the go ahead for actual processing and we should never come back to this point */
4754 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4757 #ifndef RGL_SPECIFIC_CHANGES
4765 #ifdef V5GTF_SPECIFIC_CHANGES
4768 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4769 * (processes L1 msgs) */
4771 /* get a message from the demand queue */
4773 #ifdef RLC_MAC_DAT_REQ_RBUF
4774 rgDlDatReqBatchProc();
4777 ret = mtTskHdlMsg(sTsk);
4780 /* exit the for loop here */
4783 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4790 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4794 void *pthreadCreateHdlr
4799 void *pthreadCreateHdlr(pthreadCreateArg)
4804 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4805 /* mt038.201 changed how sem_wait is called */
4806 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4809 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4817 * Desc: This is the system task handler function. It blocks on
4818 * the system task's demand queue. On receiving a message,
4819 * it identifies the target TAPA task, verifies that the
4820 * TAPA task belongs to this system task and if so, calls
4821 * the activation function of that TAPA task with the
4822 * received message. The task activation function or the
4823 * timer activation function may be called.
4825 * Ret: (thread function)
4835 Ptr tskPtr /* pointer to task entry */
4838 Void *mtTskHdlr(tskPtr)
4839 Ptr tskPtr; /* pointer to task entry */
4845 /* get out the system task entry from the parameter */
4846 sTsk = (SsSTskEntry *) tskPtr;
4849 /* wait for SS to come up */
4851 /* mt038.201 changed how sem_wait is called */
4852 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4854 #ifdef XEON_SPECIFIC_CHANGES
4855 printf("\n**********MT Task Handler********\n");
4859 #ifndef ODU_TEST_STUB
4864 /* Wait for a message from the demand queue */
4865 #ifdef SS_CDMNDQ_SUPPORT
4866 ret = ssCDmndQWait(&sTsk->dQ);
4868 ret = ssDmndQWait(&sTsk->dQ);
4873 ret = mtTskHdlMsg(sTsk);
4888 * Desc: This is the system task handler function. It blocks on
4889 * the system task's demand queue. On receiving a message,
4890 * it identifies the target TAPA task, verifies that the
4891 * TAPA task belongs to this system task and if so, calls
4892 * the activation function of that TAPA task with the
4893 * received message. The task activation function or the
4894 * timer activation function may be called.
4896 * Ret: (thread function)
4909 S16 mtTskHdlMsg(sTsk)
4923 /* mt028.201: modification: multiple procs support related changes */
4924 #ifndef SS_MULTIPLE_PROCS
4926 PAIFTMRS16 tmrActvFnMt = NULLP;
4928 /* mt015.301 Initialized the timer activation functions with NULLP */
4929 PFS16 tmrActvFn = NULLP;
4931 PAIFTMRS16 tmrActvFn;
4933 #endif /* SS_MULTIPLE_PROCS */
4934 /* mt003.301 Modifications */
4935 #ifdef SS_THREAD_PROFILE
4937 #endif /* SS_THREAD_PROFILE */
4940 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4943 /* nothing to receive */
4947 /* if we can't lock this system task entry, return the message */
4948 ret = SLock(&sTsk->lock);
4952 #if (ERRCLASS & ERRCLS_DEBUG)
4953 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4954 "Could not lock system task entry");
4964 mBuf2 = mBuf->b_next;
4966 /* find out what kind of message this is */
4967 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4968 #ifdef SS_MEM_WL_DEBUG
4969 mtTskBuffer1 = mBuf2;
4971 mtTskBuffer2 = mBuf2->b_next;
4973 if(mInfo == 0x5050505)
4977 cmAnalyseBtInfo((PTR) mBuf,4);
4979 printf("\n In trouble .... \n");
4981 else if (mInfo == 0x2020202)
4984 cmAnalyseBtInfo((PTR) mBuf,1);
4985 printf("\n In trouble .... \n");
4987 #endif /* SS_MEM_WL_DEBUG */
4988 switch (mInfo->eventInfo.event)
4990 /* this is a termination event, we die */
4992 /* release the message */
4995 /* Unlock the system task entry and lock the system
4996 * task table to clean our entry up.
4998 SUnlock(&sTsk->lock);
5000 ret = SLock(&osCp.sTskTblLock);
5004 #if (ERRCLASS & ERRCLS_DEBUG)
5005 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5006 "Could not lock system task table");
5008 /* what to do here? */
5012 /* clean up the system task entry */
5015 /* mt003.301 Modifications - SDeRegTTsk */
5016 /* sTsk->numTTsks = 0; */
5017 SDestroyLock(&sTsk->lock);
5018 ssDestroyDmndQ(&sTsk->dQ);
5020 /* lock for current executing TAPA task ID */
5022 /* make this entry available in the system task table */
5023 sTsk->nxt = osCp.nxtSTskEntry;
5024 for (i = 0; i < SS_MAX_STSKS; i++)
5026 if (sTsk == &osCp.sTskTbl[i])
5028 osCp.nxtSTskEntry = i;
5035 /* unlock the system task table */
5036 SUnlock(&osCp.sTskTblLock);
5041 /* this is a data message or a permanent task keep-alive message */
5043 case SS_EVNT_PERMTICK:
5044 /* message to a task. find the destination task */
5045 /* mt028.201: modification: multiple procs support related changes */
5046 #ifdef SS_MULTIPLE_PROCS
5047 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5049 if (procIdIdx == SS_INV_PROCID_IDX)
5055 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5056 #else /* SS_MULTIPLE_PROCS */
5057 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5058 #endif /* SS_MULTIPLE_PROCS */
5060 /* verify that it hasn't been deregistered */
5061 if (idx == SS_TSKNC)
5067 /* verify that this system task is still running it */
5068 tTsk = &osCp.tTskTbl[idx];
5069 if (tTsk->sTsk != sTsk)
5075 /* set the current executing TAPA task ID */
5076 sTsk->dep.ent = mInfo->pst.dstEnt;
5077 sTsk->dep.inst = mInfo->pst.dstInst;
5079 /* copy the Pst structure into a local duplicate */
5080 for (i = 0; i < (S16) sizeof(Pst); i++)
5081 *(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
5083 /* Give the message to the task activation function. If
5084 * its a normal data message, we pass it, if this is a
5085 * keep-alive message for a permanent task then we pass
5086 * NULLP in place of the message to the task activation
5089 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5091 #ifndef RGL_SPECIFIC_CHANGES
5092 #ifdef SS_TSKLOG_ENABLE
5093 U32 t = MacGetTick();
5096 /* mt003.301 Modifications */
5097 #if SS_THREAD_PROFILE
5098 tTsk->curEvent = nPst.event;
5100 #endif /* SS_THREAD_PROFILE */
5101 tTsk->actvTsk(&nPst, mBuf);
5102 #ifndef RGL_SPECIFIC_CHANGES
5103 #ifdef SS_TSKLOG_ENABLE
5104 SStopTask(t,PID_SSI_TSK);
5107 #if SS_THREAD_PROFILE
5109 tTsk->curEvtTime = (U32)(et2 - et1);
5110 tTsk->totTime += (U64)tTsk->curEvtTime;
5111 #endif /* SS_THREAD_PROFILE */
5115 #if (ERRCLASS & ERRCLS_DEBUG)
5116 /* this message should only come to a permanent task */
5117 if (tTsk->tskType != SS_TSK_PERMANENT)
5119 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5123 tTsk->actvTsk(&nPst, NULLP);
5125 /* We need to re-send this message back to ourselves so
5126 * the permanent task continues to run.
5128 /* Check if this task got deregistered or detached
5129 * by the activation function; if so, there's nothing
5130 * more to do here, otherwise go ahead.
5133 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5135 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5136 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5140 /* failure here is a real problem */
5143 #if (ERRCLASS & ERRCLS_DEBUG)
5144 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5145 "Could not write to demand queue");
5151 /* unset the current executing TAPA task ID */
5152 sTsk->dep.ent = ENTNC;
5153 sTsk->dep.inst = INSTNC;
5158 /* timer event. find the timer entry */
5159 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5161 /* lock the timer table, coz we're going to peek in it */
5162 ret = SLock(&osCp.tmrTblLock);
5166 #if (ERRCLASS & ERRCLS_DEBUG)
5167 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5168 "Could not lock timer table");
5174 /* Verify that this timer entry is still around and that it
5175 * belongs to our task.
5177 if (osCp.tmrTbl[idx].used == FALSE
5178 /* mt028.201: modification: multiple procs support related changes */
5179 #ifdef SS_MULTIPLE_PROCS
5180 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5181 #endif /* SS_MULTIPLE_PROCS */
5182 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5183 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5185 SUnlock(&osCp.tmrTblLock);
5190 /* mt005.21: addition */
5191 /* set the current executing TAPA task ID */
5192 sTsk->dep.ent = mInfo->pst.dstEnt;
5193 sTsk->dep.inst = mInfo->pst.dstInst;
5195 #ifndef SS_MULTIPLE_PROCS
5197 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5198 tmrActvFnMt = NULLP;
5199 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5201 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5207 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5210 /* unlock the timer table */
5211 SUnlock(&osCp.tmrTblLock);
5213 /* activate the timer function */
5214 /* mt028.201: modification: multiple procs support related changes */
5215 #ifndef SS_MULTIPLE_PROCS
5219 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5220 osCp.tmrTbl[idx].ownerInst);
5228 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5229 osCp.tmrTbl[idx].ownerInst);
5230 #endif /* SS_MULTIPLE_PROCS */
5232 /*mt005.21: addition */
5233 /* unset the current executing TAPA task ID */
5234 sTsk->dep.ent = ENTNC;
5235 sTsk->dep.inst = INSTNC;
5238 /* return the message buffer */
5242 * mt003.301 - SDeRegTTsk fix
5244 case SS_EVNT_TTSK_TERM:
5245 #ifdef SS_MULTIPLE_PROCS
5246 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5248 if (procIdIdx == SS_INV_PROCID_IDX)
5254 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5255 #else /* SS_MULTIPLE_PROCS */
5256 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5257 #endif /* SS_MULTIPLE_PROCS */
5259 /* verify that it hasn't been deregistered */
5260 if (idx == SS_TSKNC)
5266 /* verify that this system task is still running it */
5267 tTsk = &osCp.tTskTbl[idx];
5268 if (tTsk->sTsk != sTsk)
5273 #ifdef SS_MULTIPLE_PROCS
5274 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5276 ssdProcTTskTerm(tTsk, idx);
5282 #if (ERRCLASS & ERRCLS_DEBUG)
5283 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5290 } while (mBuf != NULLP);
5293 /* unlock the system task entry */
5294 SUnlock(&sTsk->lock);
5297 /* yield for other threads */
5298 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5307 * Fun: mtTmrHdlrPublic
5310 Void mtTmrHdlrPublic
5314 Void mtTmrHdlrPublic()
5317 if (SLock(&osCp.tmrTblLock) != ROK)
5319 #if (ERRCLASS & ERRCLS_DEBUG)
5320 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5324 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5325 /* unlock the timer table */
5326 SUnlock(&osCp.tmrTblLock);
5334 * Desc: The timer handler thread function. Counts time
5335 * and invokes the common timer function on each
5338 * Ret: (thread function)
5345 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5347 PRIVATE Void *mtTmrHdlr
5349 void *parm /* unused */
5352 /* mt009.21: addition */
5353 PRIVATE Void *mtTmrHdlr(parm)
5354 void *parm; /* unused */
5357 /*mt004.301-addede new region*/
5358 /* mt010.301 Removed SS_FAP portion and
5359 * enabled oroginal code in function mtTmrHdlr */
5363 U32 i, cnt, oldTicks, newTicks;
5364 struct timeval tv1,tv2;
5365 /* mt038.201 added return */
5367 /* mt039.201 changes for nanosleep */
5368 struct timespec tsN;
5369 PRIVATE U32 err_in_usec;
5371 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5376 /* mt027.201 - Modification for SRegCfgTmr support */
5377 /* check SS_TICKS_SEC */
5378 if (SS_1MS < SS_TICKS_SEC)
5380 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5383 /* mt025.201 - Addition to stop timer handler till task registration is done */
5384 /* wait for SS to come up */
5385 /* mt038.201 changed how sem_wait is called */
5386 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5389 /* mt027.201 - Modification for SRegCfgTmr support */
5390 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5392 ts.tv_nsec = (MT_TICK_CNT * 1000);
5393 /* mt039.201 changes for nanosleep */
5399 if (gettimeofday(&tv1, NULL) == -1)
5401 #if (ERRCLASS & ERRCLS_DEBUG)
5402 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5403 "Error in clock_gettime");
5413 #ifndef STUB_TTI_HANDLING_5GTF
5414 printf("Returning from mtTmrHdlr()\n");
5419 /* mt039.201 changes for nanosleep */
5420 /* sleep for MT_TICK_CNT milli seconds */
5421 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5422 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5424 ts.tv_nsec = tsN.tv_nsec;
5429 if (gettimeofday(&tv2,NULL) == -1)
5431 #if (ERRCLASS & ERRCLS_DEBUG)
5432 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5433 "Error in clock_gettime");
5437 /*mt013.301 : changed check while calculating timer to fix
5438 * diffrence between MTSS time and real unix time
5440 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5442 time_int = (tv2.tv_usec - tv1.tv_usec);
5444 else if (tv2.tv_sec > tv1.tv_sec)
5446 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5448 else /* ts2 < ts1, this will not happen in normal scenario */
5450 /* to make sure cnt = 1 */
5452 time_int = MT_TICK_CNT;
5455 oldTicks = osCp.dep.sysTicks;
5456 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5457 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5458 newTicks = osCp.dep.sysTicks;
5459 tv1.tv_usec = tv2.tv_usec;
5460 tv1.tv_sec = tv2.tv_sec;
5462 cnt = newTicks - oldTicks;
5464 while(err_in_usec >= MT_TICK_CNT)
5467 err_in_usec -= MT_TICK_CNT;
5469 if( cnt >= MT_MAX_TICK_CNT_VAL)
5470 cnt = MT_MIN_TICK_CNT_VAL;
5471 /* call the common timer tick handler */
5472 for (i = 0; i < cnt; i++)
5474 /* mt008.301: cmPrcTmr is guarded with a lock */
5475 /* lock the timer table */
5476 if (SLock(&osCp.tmrTblLock) != ROK)
5478 #if (ERRCLASS & ERRCLS_DEBUG)
5479 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5483 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5484 /* unlock the timer table */
5485 SUnlock(&osCp.tmrTblLock);
5489 /* mt009.21: addition */
5490 return ( (Void *) NULLP);
5491 /* will not reach here */
5499 * Desc: Process timer event. Called from the common timer
5500 * code when a timeout occurs.
5512 PTR tCb, /* control block */
5513 S16 evnt /* event */
5516 Void mtTimeout(tCb, evnt)
5517 PTR tCb; /* control block */
5518 S16 evnt; /* event */
5527 #ifndef TENB_RTLIN_CHANGES
5530 /* mt028.201: modification: multiple procs support related changes */
5531 #ifdef SS_MULTIPLE_PROCS
5533 #endif /* SS_MULTIPLE_PROCS */
5534 #ifdef RGL_SPECIFIC_CHANGES
5535 #ifdef MSPD_MLOG_NEW
5536 U32 t = GetTIMETICK();
5542 /* get the timer entry */
5543 tEnt = (SsTmrEntry *) tCb;
5546 /* if the timer was deleted, this will be NULL, so drop it */
5552 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5555 /* Hmmmm, the timer might have been deleted while we've been
5556 * working at getting here, so we just skip this.
5558 if (tEnt->used == FALSE)
5564 /* Set up and send a timer message to the destination tasks'
5567 #ifndef SS_MULTICORE_SUPPORT
5568 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5570 #ifdef RGL_SPECIFIC_CHANGES
5571 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5573 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5578 #if (ERRCLASS & ERRCLS_DEBUG)
5579 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5585 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5586 mInfo->eventInfo.event = SS_EVNT_TIMER;
5587 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5589 mInfo->pst.dstEnt = tEnt->ownerEnt;
5590 mInfo->pst.dstInst = tEnt->ownerInst;
5591 mInfo->pst.srcEnt = tEnt->ownerEnt;
5592 mInfo->pst.srcInst = tEnt->ownerInst;
5593 /* mt028.201: modification: multiple procs support related changes */
5594 #ifndef SS_MULTIPLE_PROCS
5595 mInfo->pst.dstProcId = SFndProcId();
5596 mInfo->pst.srcProcId = SFndProcId();
5597 #else /* SS_MULTIPLE_PROCS */
5598 mInfo->pst.dstProcId = tEnt->ownerProc;
5599 mInfo->pst.srcProcId = tEnt->ownerProc;
5600 #endif /* SS_MULTIPLE_PROCS */
5601 mInfo->pst.selector = SEL_LC_NEW;
5602 #ifndef SS_MULTICORE_SUPPORT
5603 mInfo->pst.region = DFLT_REGION;
5606 mInfo->pst.pool = DFLT_POOL;
5607 mInfo->pst.prior = PRIOR0;
5608 mInfo->pst.route = RTESPEC;
5609 mInfo->pst.event = 0;
5612 #ifndef TENB_RTLIN_CHANGES
5613 /* get a semaphore for the TAPA task table */
5614 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5619 #if (ERRCLASS & ERRCLS_DEBUG)
5620 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5628 /* find the owner TAPA task */
5629 /* mt028.201: modification: multiple procs support related changes */
5630 #ifdef SS_MULTIPLE_PROCS
5631 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5632 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5633 #else /* SS_MULTIPLE_PROCS */
5634 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5635 #endif /* SS_MULTIPLE_PROCS */
5636 if (idx == SS_TSKNC)
5638 #ifndef TENB_RTLIN_CHANGES
5639 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5646 /* ensure that the TAPA task is hale and hearty */
5647 tTsk = &osCp.tTskTbl[idx];
5650 #ifndef TENB_RTLIN_CHANGES
5651 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5656 /* Klock work fix ccpu00148484 */
5657 /* write the timer message to the queue of the destination task */
5658 /* mt008.301 : check sTsk before putting into it's DQ */
5659 if (tTsk->sTsk == NULLP)
5661 #ifndef TENB_RTLIN_CHANGES
5662 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5666 #if (ERRCLASS & ERRCLS_DEBUG)
5667 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5668 "Could not write to demand queue");
5673 #ifdef SS_LOCKLESS_MEMORY
5674 mInfo->pst.region = tTsk->sTsk->region;
5675 mInfo->region = tTsk->sTsk->region;
5676 #endif /* SS_LOCKLESS_MEMORY */
5677 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5678 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5680 #ifndef TENB_RTLIN_CHANGES
5681 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5685 #if (ERRCLASS & ERRCLS_DEBUG)
5686 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5687 "Could not write to demand queue");
5692 /* Fix for ccpu00130657 */
5693 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5694 if (tTsk->sTsk->tskPrior == PRIOR0)
5697 WLS_WakeUp(mtGetWlsHdl());
5704 /* release the semaphore for the TAPA task table */
5705 #ifndef TENB_RTLIN_CHANGES
5706 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5710 /* restart the timer */
5711 arg.tq = osCp.dep.tmrTq;
5712 arg.tqCp = &osCp.dep.tmrTqCp;
5713 arg.timers = tEnt->dep.timers;
5714 arg.cb = (PTR) tEnt;
5718 arg.max = TMR_DEF_MAX;
5719 arg.wait = tEnt->interval;
5721 #ifdef RGL_SPECIFIC_CHANGES
5722 #ifdef MSPD_MLOG_NEW
5723 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5735 * Desc: This thread reads the console and hands over any
5736 * data read to a user function.
5738 * Ret: (thread function)
5746 PRIVATE Void *mtConHdlr
5748 Ptr parm /* unused */
5751 /* mt009.21: addition */
5752 PRIVATE Void *mtConHdlr(parm)
5753 Ptr parm; /* unused */
5760 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5766 /* check if we have a console input file handle */
5767 if (osCp.dep.conInFp == NULLP)
5773 fd = fileno(osCp.dep.conInFp);
5778 if ((read(fd, &data, 1)) != 1)
5784 /* call rdConQ, defined by the system service user */
5794 #ifdef SS_DRVR_SUPPORT
5797 * Fun: Interrupt service task handler
5799 * Desc: This is the interrupt service task handler. It blocks
5800 * on a pipe from which it reads an isFlag structure. The
5801 * structure indicates which interrupt service task is to
5802 * be executed. The thread identifies the task, calls the
5803 * isTsk function and sends itself a message to repeat
5804 * this operation until it receives a message to cease.
5814 /* mt009.21: addition */
5815 PRIVATE Void *mtIsTskHdlr
5817 Ptr tskPtr /* pointer to task entry */
5820 /* mt009.21: addition */
5821 PRIVATE Void *mtIsTskHdlr(tskPtr)
5822 Ptr tskPtr; /* pointer to task entry */
5825 #if (ERRCLASS & ERRCLS_DEBUG)
5832 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5837 switch (isFlag.action)
5840 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5842 /* call the interrupt service task activation function */
5843 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5845 /* send self a message to keep doing this */
5846 isFlag.action = MT_IS_RESET;
5848 #if (ERRCLASS & ERRCLS_DEBUG)
5849 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5850 if (ret != sizeof(isFlag))
5852 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5853 "write() to pipe failed");
5856 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5863 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5868 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5870 /* call the interrupt service task activation function */
5871 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5873 #if (ERRCLASS & ERRCLS_DEBUG)
5874 /* send self a message to do this again */
5875 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5877 if (ret != sizeof(isFlag))
5879 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5880 "write() to pipe failed");
5883 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5891 /* where did THIS come from?? */
5895 /* mt009.21: addition */
5896 return ( (Void *) NULLP);
5900 #endif /* SS_DRVR_SUPPORT */
5901 #endif /* L2_L3_SPLIT */
5903 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5907 * Fun: mtIntSigHndlr
5909 * Desc: Exit function, shuts down.
5924 Void mtIntSigHndlr(arg)
5929 osCp.dep.sigEvnt=TRUE;
5932 #ifdef TENB_RTLIN_CHANGES
5940 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5945 * Desc: function, shuts down.
5967 SGetSysTime(&ticks);
5969 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5971 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5973 #ifdef SS_HISTOGRAM_SUPPORT
5977 osCp.dep.sigEvnt=FALSE;
5979 if (osCp.dep.fileOutFp)
5981 fclose(osCp.dep.fileOutFp);
5989 Void SIncrementTtiCount(Void)
5994 Ticks SGetTtiCount(Void)
6003 * Desc: This function displays a string to a given output
6008 * Notes: Buffer should be null terminated.
6010 * channel 0 is reserved for backwards compatibility
6019 S16 chan, /* channel */
6020 Txt *buf /* buffer */
6023 S16 SDisplay(chan, buf)
6024 S16 chan; /* channel */
6025 Txt *buf; /* buffer */
6029 /* mt020.201 - Fixed typo */
6030 #if (ERRCLASS & ERRCLS_INT_PAR)
6033 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6038 #ifndef XEON_SPECIFIC_CHANGES
6039 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6040 ssMemlog(buf, strlen(buf));
6045 /* mt012.301 :FIX for LOG RELATED ISSUE */
6053 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6059 if (osCp.dep.fileOutFp)
6060 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6061 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6064 fflush(osCp.dep.fileOutFp);
6077 * Desc: function, shuts down.
6096 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6097 a loop to overcome the child processes being killed upon exiting the
6099 #ifdef SS_LINUX /* this should have already been defined */
6100 /* mt010.301 removed flag SLES9_PLUS */
6101 /* wait forever for children */
6105 if(osCp.dep.sigEvnt==TRUE)
6112 pthread_exit(NULLP);
6118 * Fun: Set date and time
6120 * Desc: This function is used to set the calendar
6125 * Notes: Unimplemented
6133 REG1 DateTime *dt /* date and time */
6136 S16 SSetDateTime(dt)
6137 REG1 DateTime *dt; /* date and time */
6150 * Fun: Get date and time
6152 * Desc: This function is used to determine the calendar
6153 * date and time. This information may be used for
6154 * some management functions.
6167 REG1 DateTime *dt /* date and time */
6170 S16 SGetDateTime(dt)
6171 REG1 DateTime *dt; /* date and time */
6174 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6177 struct timespec ptime;
6179 struct timeval ptime;
6186 #if (ERRCLASS & ERRCLS_INT_PAR)
6189 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6198 localtime_r(&tt, &tme);
6201 clock_gettime(CLOCK_REALTIME, &ptime);
6203 gettimeofday(&ptime, NULL);
6205 localtime_r(&ptime.tv_sec, &tme);
6207 dt->month = (U8) tme.tm_mon + 1;
6208 dt->day = (U8) tme.tm_mday;
6209 dt->year = (U8) tme.tm_year;
6210 dt->hour = (U8) tme.tm_hour;
6211 dt->min = (U8) tme.tm_min;
6212 dt->sec = (U8) tme.tm_sec;
6215 #ifdef SS_DATETIME_USEC
6217 dt->usec = ptime.tv_nsec / 1000;
6219 dt->usec = ptime.tv_usec;
6221 #endif /*-- SS_DATETIME_USEC --*/
6227 * Get time from epoch in milliseconds
6229 * Fun: Get time from epoch in milliseconds
6231 * Desc: This function is used to get the time from epoch in milli seconds.
6232 * This information may be used for calculating a layer's activation function
6233 * execution time used for thread profiling.
6242 /* mt003.301 Modifications */
6246 EpcTime *et /* date and time */
6250 EpcTime *et; /* date and time */
6253 /* mt003.301 Modifications */
6255 U64 to_sec = 1000000;
6258 struct timespec ptime;
6260 struct timeval ptime;
6265 #if (ERRCLASS & ERRCLS_INT_PAR)
6274 clock_gettime(CLOCK_REALTIME, &ptime);
6276 gettimeofday(&ptime, NULL);
6277 #endif /* SS_LINUX */
6279 now = (ptime.tv_sec * to_sec);
6282 now += (ptime.tv_nsec / to_nsec);
6283 #else /* SS_LINUX */
6284 now += (ptime.tv_usec);
6286 #endif /* SS_LINUX */
6287 now = (now / to_nsec);
6298 * Fun: Get system time
6300 * Desc: This function is used to determine the system time.
6304 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6312 Ticks *sysTime /* system time */
6315 S16 SGetSysTime(sysTime)
6316 Ticks *sysTime; /* system time */
6321 #if (ERRCLASS & ERRCLS_INT_PAR)
6322 if (sysTime == NULLP)
6324 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6330 *sysTime = osCp.dep.sysTicks;
6336 /* mt021.201 - Addition of SGetRefTime function */
6339 * Fun: Get referenced time
6341 * Desc: This function is used to determine the time in seconds
6342 * and microseconds from a reference time. The reference
6343 * time is expressed in seconds from UTC EPOC, January 1,
6349 * Notes: Macros are defined for reference times:
6350 * SS_REFTIME_01_01_1970
6351 * SS_REFTIME_01_01_2002
6359 U32 refTime, /* reference time */
6364 S16 SGetRefTime(refTime, sec, usec)
6365 U32 refTime; /* reference time */
6372 struct timespec ptime;
6374 struct timeval ptime;
6379 clock_gettime(CLOCK_REALTIME, &ptime);
6381 gettimeofday(&ptime, NULL);
6384 #if (ERRCLASS & ERRCLS_INT_PAR)
6385 if (sec == NULLP || usec == NULLP)
6387 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6390 /* mt022.201 - Modification to fix compile warning */
6391 if (refTime > (U32)(ptime.tv_sec))
6393 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6398 *sec = ptime.tv_sec - refTime;
6400 *usec = ptime.tv_nsec / 1000;
6402 *usec = ptime.tv_usec;
6412 * Fun: Get Random Number
6414 * Desc: Invoked by layer when a pseudorandom number is required.
6418 * Notes: Suggested approach uses shuffled Linear Congruential
6419 * Operators as described in Byte magazine October
6420 * 1984; "Generating and Testing Pseudorandom Numbers"
6428 Random *value /* random number */
6432 Random *value; /* random number */
6437 #if (ERRCLASS & ERRCLS_INT_PAR)
6440 /* mt011.21: addition */
6441 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6447 *value = (Random) rand_r(&osCp.dep.randSeed);
6458 * Desc: This function exits from a task.
6462 * Notes: Currently does nothing.
6484 * Fun: Exit Interrupt
6486 * Desc: This function exits from an interrupt.
6490 * Notes: Currently does nothing.
6512 * Fun: Hold Interrupt
6514 * Desc: This function prohibits interrupts from being enabled until
6515 * release interrupt. This function should be called when
6516 * interrupts are disabled and prior to any call to system
6517 * services either by entry to an interrupt service routine or
6518 * by explicit call to disable interrupt.
6522 * Notes: Currently does nothing
6544 * Fun: Release Interrupt
6546 * Desc: This function allows interrupts to be enabled.
6550 * Notes: Currently does nothing.
6574 * Desc: Enable interrupts
6576 * Ret: ROK on success
6579 * Notes: Currently does nothing.
6590 INLINE S16 SEnbInt()
6603 * Desc: Disable interrupts
6605 * Ret: ROK on success
6608 * Notes: Currently does nothing.
6619 INLINE S16 SDisInt()
6632 * Desc: This function gets the function address stored at the
6633 * specified interrupt vector.
6637 * Notes: Currently does nothing.
6645 VectNmb vectNmb, /* vector number */
6646 PIF *vectFnct /* vector function */
6649 S16 SGetVect(vectNmb, vectFnct)
6650 VectNmb vectNmb; /* vector number */
6651 PIF *vectFnct; /* vector function */
6668 * Desc: This function installs the specified function at the
6669 * specified interrupt vector.
6673 * Notes: Currently does nothing.
6681 VectNmb vectNmb, /* vector number */
6682 PIF vectFnct /* vector function */
6685 S16 SPutVect(vectNmb, vectFnct)
6686 VectNmb vectNmb; /* vector number */
6687 PIF vectFnct; /* vector function */
6699 /* mt028.201: modification: multiple procs support related changes */
6700 #ifndef SS_MULTIPLE_PROCS
6706 * Desc: This function gets the current entity and instance.
6709 * RFAILED - failed, general (optional)
6711 * Notes: This function may be called by the OS or Layer 1
6720 Ent *ent, /* entity */
6721 Inst *inst /* instance */
6724 S16 SGetEntInst(ent, inst)
6725 Ent *ent; /* entity */
6726 Inst *inst; /* instance */
6737 #if (ERRCLASS & ERRCLS_INT_PAR)
6738 /* check pointers */
6739 if (ent == NULLP || inst == NULLP)
6741 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6747 /* get the thread id */
6748 tId = pthread_self();
6751 /* find the system task in whose context we're running */
6753 ret = SLock(&osCp.sTskTblLock);
6758 for (i = 0; i < SS_MAX_STSKS; i++)
6760 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6762 sTsk = &osCp.sTskTbl[i];
6768 *ent = sTsk->dep.ent;
6769 *inst = sTsk->dep.inst;
6771 SUnlock(&osCp.sTskTblLock);
6774 return (ret == ROK ? ROK : RFAILED);
6782 * Desc: This function sets the current entity and instance.
6794 Ent ent, /* entity */
6795 Inst inst /* instance */
6798 S16 SSetEntInst(ent, inst)
6799 Ent ent; /* entity */
6800 Inst inst; /* instance */
6811 #if (ERRCLASS & ERRCLS_INT_PAR)
6812 /* check entity and instance IDs */
6813 if (ent >= ENTNC || inst >= INSTNC)
6815 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6821 /* get the thread id */
6822 tId = pthread_self();
6825 /* find the system task in whose context we're running */
6827 ret = SLock(&osCp.sTskTblLock);
6832 for (i = 0; i < SS_MAX_STSKS; i++)
6834 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6836 sTsk = &osCp.sTskTbl[i];
6842 sTsk->dep.ent = ent;
6843 sTsk->dep.inst = inst;
6845 SUnlock(&osCp.sTskTblLock);
6848 return (ret == ROK ? ROK : RFAILED);
6851 #endif /* SS_MULTIPLE_PROCS */
6853 #ifdef SS_DRVR_SUPPORT
6859 * Desc: Set interrupt pending flag
6861 * Ret: ROK on success
6870 INLINE S16 SSetIntPend
6872 U16 id, /* driver task identifier */
6873 Bool flag /* flag */
6876 INLINE S16 SSetIntPend(id, flag)
6877 U16 id; /* driver task identifier */
6878 Bool flag; /* flag */
6886 #if (ERRCLASS & ERRCLS_INT_PAR)
6887 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6889 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6896 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6898 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6906 #endif /* SS_DRVR_SUPPORT */
6909 #ifdef SS_LOCKLESS_MEMORY
6912 * Fun: SGlobMemInfoShow
6914 * Desc: This function displays the memory usage information
6915 * for the destined region. It will show the usage of
6916 * each configured bucket and the heap for the specified region.
6919 * RFAILED Region not registered
6925 S16 SGlobMemInfoShow
6930 S16 SGlobMemInfoShow()
6935 CmMmGlobRegCb *globReg;
6938 globReg = osCp.globRegCb;
6940 sprintf(prntBuf, "--------------------------------------------------------------\n");
6941 SDisplay(0, prntBuf);
6942 sprintf(prntBuf, "Global Region Bucket Information\n");
6943 SDisplay(0, prntBuf);
6944 sprintf(prntBuf, "====================================================\n");
6945 SDisplay(0, prntBuf);
6946 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
6947 SDisplay(0, prntBuf);
6948 sprintf(prntBuf, "====================================================\n");
6949 SDisplay(0, prntBuf);
6952 for (idx = 0; idx < globReg->numBkts; idx++)
6954 #ifdef XEON_SPECIFIC_CHANGES
6955 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
6956 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6959 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
6960 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6962 sprintf(prntBuf, "%2u %12u %8u %9u\n",
6963 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6966 SDisplay(0, prntBuf);
6968 sprintf(prntBuf, "--------------------------------------------------------------\n");
6969 SDisplay(0, prntBuf);
6974 #endif /* SS_LOCKLESS_MEMORY */
6977 Bool IsMemoryThresholdHit(Region reg, Pool pool)
6979 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6981 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6984 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6985 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6992 /* mt022.201 - Addition of SRegInfoShow function */
6997 * Desc: This function displays the memory usage information
6998 * for the destined region. It will show the usage of
6999 * each configured bucket and the heap for the specified region.
7002 * RFAILED Region not registered
7004 * Notes: A Sample Output from the function
7005 * Bucket Memory: region 1
7006 * ====================================================
7007 * Bucket Number of Blks configured Size Allocated
7008 * ====================================================
7016 * Heap Memory: region 1
7019 * Heap Segmented blocks: 0
7032 S16 SRegInfoShow(region, availmem)
7041 #if (ERRCLASS & ERRCLS_INT_PAR)
7042 if (region > (SS_MAX_REGS-1) )
7044 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7051 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7052 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7053 SDisplay(0, prntBuf);
7054 sprintf(prntBuf, "====================================================\n");
7055 SDisplay(0, prntBuf);
7056 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7057 SDisplay(0, prntBuf);
7058 sprintf(prntBuf, "====================================================\n");
7059 SDisplay(0, prntBuf);
7063 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7065 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7067 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7068 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7069 mtCMMRegCb[region]->bktTbl[idx].size,
7070 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7071 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7073 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7074 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7075 mtCMMRegCb[region]->bktTbl[idx].size,
7076 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7077 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7080 /*mt009.301 Fixed 64BIT compilation warnings*/
7082 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7083 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7084 mtCMMRegCb[region]->bktTbl[idx].size,
7085 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7087 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7088 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7089 mtCMMRegCb[region]->bktTbl[idx].size,
7090 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7092 #endif /* not TENB_RTLIN_CHANGES */
7093 SDisplay(0, prntBuf);
7094 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7095 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7096 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7098 sprintf(prntBuf, "\n---------------\n");
7099 SDisplay(0, prntBuf);
7100 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7101 SDisplay(0, prntBuf);
7102 /*mt009.301 Fixed 64BIT compilation warnings*/
7104 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7106 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7108 SDisplay(0, prntBuf);
7109 /*mt009.301 Fixed 64BIT compilation warnings*/
7111 sprintf(prntBuf, "Heap Allocated: %u\n",
7112 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7114 sprintf(prntBuf, "Heap Allocated: %lu\n",
7115 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7117 SDisplay(0, prntBuf);
7118 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7119 #if (ERRCLASS & ERRCLS_DEBUG)
7120 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7121 mtCMMRegCb[region]->heapCb.numFragBlk);
7122 SDisplay(0, prntBuf);
7127 #ifdef XEON_SPECIFIC_CHANGES
7128 #define SSI_MAX_BKT_THRESHOLD 6
7129 #define SSI_MAX_REG_THRESHOLD 2
7130 U32 SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7131 U32 SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7132 U32 SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7135 PRIVATE Void SInitMemThreshold
7141 PRIVATE Void SInitMemThreshold(region, maxBkt)
7147 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7149 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7150 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7151 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7152 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7157 S16 SRegReachedMemThreshold
7163 S16 SRegReachedMemThreshold(region, maxBkt)
7170 PRIVATE U8 initFlag = 1;
7174 SInitMemThreshold(region, maxBkt);
7177 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7179 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7184 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7188 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7196 /* mt033.201 - addition of API to return the memory statistical data */
7201 * Desc: This function returns the memory usage information
7202 * for the destined region. It will return the usage of
7203 * each configured bucket and the heap for the specified region.
7206 * RFAILED Region not registered
7217 SsMemDbgInfo *dbgInfo
7220 S16 SGetRegInfo(region, dbgInfo)
7222 SsMemDbgInfo *dbgInfo;
7228 #if (ERRCLASS & ERRCLS_INT_PAR)
7229 if (region >= mtMemoCfg.numRegions )
7231 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7236 dbgInfo->availmem = 0;
7238 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7239 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7241 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7243 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7245 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7246 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7247 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7249 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7250 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7251 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7254 dbgInfo->region = region;
7256 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7258 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7259 mtCMMRegCb[region]->heapCb.avlSize);
7261 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7263 #if (ERRCLASS & ERRCLS_DEBUG)
7264 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7277 S16 SGetRegPoolInfo(numRegion, numPool)
7282 /* Send number of Region available */
7283 *numRegion = mtMemoCfg.numRegions;
7284 /* Send number of Pools available */
7285 *numPool = cfgRegInfo[0].numPools;
7290 /* mt033.201 - addition of APIs to print the memory statistical data
7291 * as defined by SSI enhancements
7293 #ifdef SSI_DEBUG_LEVEL1
7296 * Fun: SPrintRegMemStatusInfo
7298 * Desc: This function displays the memory usage information
7299 * for the destined region. It will show the total memory
7300 * used for static and dynamic memory if typeFlag is
7301 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7302 * memory block allocated for a particular size if typeFlag
7303 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7304 * calling SRegPrintMemStats.
7314 S16 SPrintRegMemStatusInfo
7320 S16 SPrintRegMemStatusInfo(region, typeFlag)
7331 #if (ERRCLASS & ERRCLS_INT_PAR)
7332 if (region >= mtMemoCfg.numRegions )
7334 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7339 /* initialize the counters*/
7343 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7345 /* total static and dynamic memory allocated from all the buckets in region requested */
7346 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7347 SDisplay(0, prntBuf);
7348 sprintf(prntBuf, "===========================================\n");
7349 SDisplay(0, prntBuf);
7350 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7351 SDisplay(0, prntBuf);
7352 sprintf(prntBuf, "===========================================\n");
7353 SDisplay(0, prntBuf);
7354 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7356 /*mt009.301 Fixed 64BIT compilation warnings*/
7358 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7359 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7360 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7362 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7363 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7364 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7366 SDisplay(0, prntBuf);
7367 /* update the total count */
7368 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7369 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7372 /*mt009.301 Fixed 64BIT compilation warnings*/
7374 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7375 SDisplay(0, prntBuf);
7376 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7378 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7379 SDisplay(0, prntBuf);
7380 /*mt010.301 fix for compilation error*/
7381 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7383 SDisplay(0, prntBuf);
7385 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7386 SDisplay(0, prntBuf);
7387 /*mt009.301 Fixed 64BIT compilation warnings*/
7389 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7390 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7392 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7393 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7395 SDisplay(0, prntBuf);
7397 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7399 /* Bucket Memory allocation Statistics */
7400 return (SPrintRegMemStats(region));
7405 sprintf(prntBuf, "\n Invalid choice \n");
7406 SDisplay(0, prntBuf);
7414 * Fun: SPrintRegMemStats
7416 * Desc: This function displays the memory usage information for
7417 * the destined region. It will show the number of memory
7418 * block allocated for a particular size from the hash list.
7428 PRIVATE S16 SPrintRegMemStats
7433 PRIVATE S16 SPrintRegMemStats(region)
7437 CmMmHashListCp *hashListCp;
7443 hashListCp = &mtCMMRegCb[region]->hashListCp;
7445 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7446 SDisplay(0, prntBuf);
7447 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7448 hashListCp->numOfbins, hashListCp->numOfEntries);
7449 SDisplay(0, prntBuf);
7450 sprintf(prntBuf, "===================================\n");
7451 SDisplay(0, prntBuf);
7452 sprintf(prntBuf, "Block Size Total number of requests\n");
7453 SDisplay(0, prntBuf);
7454 sprintf(prntBuf, "===================================\n");
7455 SDisplay(0, prntBuf);
7457 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7458 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7460 if (hashListCp->hashList[idx].numAttempts)
7463 /*mt009.301 Fixed 64BIT compilation warnings*/
7465 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7466 hashListCp->hashList[idx].numAttempts);
7468 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7469 hashListCp->hashList[idx].numAttempts);
7471 SDisplay(0, prntBuf);
7475 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7476 SDisplay(0, prntBuf);
7477 sprintf(prntBuf, "=================================================\n");
7478 SDisplay(0, prntBuf);
7479 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7480 SDisplay(0, prntBuf);
7481 sprintf(prntBuf, "=================================================\n");
7482 SDisplay(0, prntBuf);
7484 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7485 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7487 /*mt009.301 Fixed 64BIT compilation warnings*/
7489 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7490 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7491 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7493 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7494 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7495 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7497 SDisplay(0, prntBuf);
7499 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7500 SDisplay(0, prntBuf);
7501 /*mt009.301 Fixed 64BIT compilation warnings*/
7503 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7504 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7505 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7507 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7508 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7509 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7511 SDisplay(0, prntBuf);
7512 sprintf(prntBuf, "\n");
7513 SDisplay(0, prntBuf);
7520 * Fun: SRegMemErrHdlr
7522 * Desc: This function handles the errors returned from the memory
7523 * related functions. Customers are suggested to modify this
7524 * API according to their specific requirement.
7541 Void SRegMemErrHdlr(region, ptr, errCode)
7550 if (errCode == RDBLFREE)
7552 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7553 SDisplay(0, prntBuf);
7555 else if (errCode == RTRAMPLINGNOK)
7557 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7558 SDisplay(0, prntBuf);
7566 * Fun: SPrintRegMemProfile
7568 * Desc: This function displays the memory profile information
7569 * for the destined region. This function prints for:
7570 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7571 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7581 S16 SPrintRegMemProfile
7586 S16 SPrintRegMemProfile(region)
7592 CmMmBlkHdr *curBktBlk;
7594 Size offsetToNxtBlk;
7602 #if (ERRCLASS & ERRCLS_INT_PAR)
7603 if (region >= mtMemoCfg.numRegions )
7605 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7610 regCb = mtCMMRegCb[region];
7612 /* memory profile */
7613 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7614 SDisplay(0, prntBuf);
7616 /* bucket profile */
7617 sprintf(prntBuf, "\nBucket Profile\n");
7618 SDisplay(0, prntBuf);
7620 for (idx = 0; idx < regCb->numBkts; idx++)
7623 /*mt009.301 Fixed 64BIT compilation warnings*/
7625 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7626 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7628 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7629 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7631 SDisplay(0, prntBuf);
7633 sprintf(prntBuf, "==========================================================================\n");
7634 SDisplay(0, prntBuf);
7635 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7636 SDisplay(0, prntBuf);
7637 sprintf(prntBuf, "==========================================================================\n");
7638 SDisplay(0, prntBuf);
7640 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7642 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7643 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7644 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7646 /*mt009.301 Fixed 64BIT compilation warnings*/
7648 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7650 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7652 SDisplay(0, prntBuf);
7653 /* check if it is a sane block, elxe jump to next block */
7654 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7656 sprintf(prntBuf, " Trampled \n");
7657 SDisplay(0, prntBuf);
7662 if (CMM_IS_STATIC(curBktBlk->memFlags))
7664 /*mt009.301 Fixed 64BIT compilation warnings*/
7666 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7668 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7670 SDisplay(0, prntBuf);
7672 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7674 /*mt009.301 Fixed 64BIT compilation warnings*/
7676 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7678 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7680 SDisplay(0, prntBuf);
7682 else if (CMM_IS_FREE(curBktBlk->memFlags))
7684 /*mt009.301 Fixed 64BIT compilation warnings*/
7686 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7688 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7690 SDisplay(0, prntBuf);
7694 sprintf(prntBuf, " Trampled \n");
7695 SDisplay(0, prntBuf);
7701 sprintf(prntBuf, "\nHeap Profile\n");
7702 SDisplay(0, prntBuf);
7704 /* point to heapCb */
7705 heapCb = &(regCb->heapCb);
7707 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7708 SDisplay(0, prntBuf);
7709 sprintf(prntBuf, "==========================================================================\n");
7710 SDisplay(0, prntBuf);
7711 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7712 SDisplay(0, prntBuf);
7713 sprintf(prntBuf, "==========================================================================\n");
7714 SDisplay(0, prntBuf);
7716 /* traverse the entire heap to output the heap profile */
7717 hdrSize = sizeof(CmHEntry);
7718 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7719 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7721 /*mt009.301 Fixed 64BIT compilation warnings*/
7723 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7725 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7727 SDisplay(0, prntBuf);
7729 /* check if it is a sane block, elxe jump to next block */
7730 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7732 sprintf(prntBuf, " Trampled \n");
7733 SDisplay(0, prntBuf);
7735 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7736 SDisplay(0, prntBuf);
7739 * To go to next block in the heap we do not have any offset value
7740 * other than curHBlk->size. As the block is already trampled
7741 * we cannot rely on this size. So it is better to stop here unless there
7742 * exists any other mechanism(?) to know the offset to next block.
7747 /*mt009.301 Fixed 64BIT compilation warnings*/
7749 sprintf(prntBuf, " %8u", curHBlk->size);
7751 sprintf(prntBuf, " %8lu", curHBlk->size);
7753 SDisplay(0, prntBuf);
7755 if (CMM_IS_STATIC(curHBlk->memFlags))
7757 /*mt009.301 Fixed 64BIT compilation warnings*/
7759 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7761 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7763 SDisplay(0, prntBuf);
7765 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7767 /*mt009.301 Fixed 64BIT compilation warnings*/
7769 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7771 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7773 SDisplay(0, prntBuf);
7775 else if (CMM_IS_FREE(curHBlk->memFlags))
7777 /*mt009.301 Fixed 64BIT compilation warnings*/
7779 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7781 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7783 SDisplay(0, prntBuf);
7787 sprintf(prntBuf, " Trampled \n");
7788 SDisplay(0, prntBuf);
7790 /* goto next block in the heap */
7791 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7797 #endif /* SSI_DEBUG_LEVEL1 */
7799 /*-- mt035.201 : Added new API for timestamp --*/
7802 * Fun: Get TimeStamp
7804 * Desc: This function is used to Get TimeStamp in micro seconds
7820 S16 SGetTimeStamp(ts)
7826 struct timespec ptime;
7828 struct timeval ptime;
7837 clock_gettime(CLOCK_REALTIME, &ptime);
7839 gettimeofday(&ptime, NULL);
7842 /* Obtain the time of day, and convert it to a tm struct. --*/
7843 ptm = localtime (&ptime.tv_sec);
7844 /* Klock work fix ccpu00148484 */
7847 /* Format the date and time, down to a single second. --*/
7848 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7851 /* Compute microseconds. --*/
7853 microseconds = ptime.tv_nsec / 1000;
7855 microseconds = ptime.tv_usec;
7858 /* Print the formatted time, in seconds, followed by a decimal point
7859 and the microseconds. --*/
7860 /*mt009.301 Fixed 64BIT compilation warnings*/
7862 sprintf(ts, "%s.%03d", time_string, microseconds);
7864 sprintf(ts, "%s.%03ld", time_string, microseconds);
7870 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7873 * Fun: Get SGetSystemTsk
7875 * Desc: This function is used to Get sytem task id
7894 return (pthread_self());
7896 } /* end of SGetSystemTsk */
7898 #ifdef SS_MULTICORE_SUPPORT
7901 * Fun: Add Timer thread into system task table
7903 * Desc: This function is used to add the system task
7904 * associated with Timer thread.
7914 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void)
7916 PRIVATE SsSTskEntry* ssdAddTmrSTsk()
7923 /* lock the system task table */
7924 ret = SLock(&osCp.sTskTblLock);
7928 #if (ERRCLASS & ERRCLS_DEBUG)
7929 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7930 "Could not lock system task table");
7936 /* check count of system tasks */
7937 if (osCp.numSTsks == SS_MAX_STSKS)
7940 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7942 #if (ERRCLASS & ERRCLS_DEBUG)
7943 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7944 "Could not give the Semaphore");
7949 #if (ERRCLASS & ERRCLS_ADD_RES)
7950 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7957 /* initialize the system task entry with the information we have */
7958 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7960 /* store the system task priority */
7961 sTsk->tskPrior = SS_NORM_TSK_PRI;
7963 /* initialize the demand queue */
7964 if (ssInitDmndQ(&sTsk->dQ) != ROK)
7967 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7969 #if (ERRCLASS & ERRCLS_DEBUG)
7970 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7971 "Could not give the Semaphore");
7976 #if (ERRCLASS & ERRCLS_DEBUG)
7977 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7978 "Could not initialize demand queue");
7984 /* initialize the system task entry lock */
7985 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7987 ssDestroyDmndQ(&sTsk->dQ);
7989 if ( SUnlock(&osCp.sTskTblLock) != ROK)
7991 #if (ERRCLASS & ERRCLS_DEBUG)
7992 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7993 "Could not give the Semaphore");
7998 #if (ERRCLASS & ERRCLS_DEBUG)
7999 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8000 "Could not initialize system task entry lock");
8007 /* success, update the table */
8008 sTsk->tskId = osCp.nxtSTskEntry;
8010 sTsk->termPend = FALSE;
8011 osCp.nxtSTskEntry = sTsk->nxt;
8014 /* unlock the system task table */
8016 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8018 #if (ERRCLASS & ERRCLS_DEBUG)
8019 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8020 "Could not give the Semaphore");
8027 #endif /* SS_MULTICORE_SUPPORT */
8028 /* mt003.301 Readwrite lock and recursive mutex additions */
8029 #ifdef SS_LOCK_SUPPORT
8032 * Fun: ssdInitLockNew
8034 * Desc: This function is used to initialise lock/mutex
8050 S16 ssdInitLockNew(lockId, lockType)
8056 #ifdef SS_REC_LOCK_SUPPORT
8057 pthread_mutexattr_t attr;
8058 #endif /* SS_REC_LOCK_SUPPORT */
8059 Txt prntBuf[PRNTSZE];
8065 #ifdef SS_RDWR_LOCK_SUPPORT
8068 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8070 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8071 SDisplay(0, prntBuf);
8076 #endif /* SS_RDWR_LOCK_SUPPORT */
8077 #ifdef SS_REC_LOCK_SUPPORT
8080 retVal = pthread_mutexattr_init(&attr);
8084 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8089 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8091 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8095 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8096 pthread_mutexattr_destroy(&attr);
8100 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8103 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8104 pthread_mutexattr_destroy(&attr);
8110 #endif /* SS_REC_LOCK_SUPPORT */
8113 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8114 SDisplay(0, prntBuf);
8124 * Desc: This function is used to aquire the read write lock
8140 S16 ssdLockNew(lockId, lockType)
8146 Txt prntBuf[PRNTSZE];
8152 #ifdef SS_RDWR_LOCK_SUPPORT
8155 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8157 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8158 SDisplay(0, prntBuf);
8165 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8167 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8168 SDisplay(0, prntBuf);
8175 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8177 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8178 SDisplay(0, prntBuf);
8185 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8187 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8188 SDisplay(0, prntBuf);
8193 #endif /* SS_RDWR_LOCK_SUPPORT */
8194 #ifdef SS_REC_LOCK_SUPPORT
8197 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8199 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8200 SDisplay(0, prntBuf);
8205 #endif /* SS_REC_LOCK_SUPPORT */
8208 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8209 SDisplay(0, prntBuf);
8222 * Desc: This function is used to Unlock the read write lock
8238 S16 ssdUnlockNew(lockId, lockType)
8244 Txt prntBuf[PRNTSZE];
8250 #ifdef SS_RDWR_LOCK_SUPPORT
8253 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8255 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8256 SDisplay(0, prntBuf);
8261 #endif /* SS_RDWR_LOCK_SUPPORT */
8262 #ifdef SS_REC_LOCK_SUPPORT
8265 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8267 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8268 SDisplay(0, prntBuf);
8273 #endif /* SS_REC_LOCK_SUPPORT */
8276 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8277 SDisplay(0, prntBuf);
8286 * Fun: ssdDestroyLockNew
8288 * Desc: This function is used to destroy the read write lock
8298 S16 ssdDestroyLockNew
8304 S16 ssdDestroyLockNew(lockId, lockType)
8309 Txt prntBuf[PRNTSZE];
8315 #ifdef SS_RDWR_LOCK_SUPPORT
8318 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8320 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8321 SDisplay(0, prntBuf);
8326 #endif /* SS_RDWR_LOCK_SUPPORT */
8327 #ifdef SS_REC_LOCK_SUPPORT
8330 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8332 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8333 SDisplay(0, prntBuf);
8338 #endif /* SS_REC_LOCK_SUPPORT */
8341 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8342 SDisplay(0, prntBuf);
8348 #endif /* SS_LOCK_SUPPORT */
8350 /* mt005.301 : Cavium Changes */
8351 #ifdef SS_SEUM_CAVIUM
8355 * Fun: ssInitRcvWork
8357 * Desc: This is the initializtion function of receive
8361 * RFAILED - failed, general (optional)
8363 * Notes: Function to initialize the work queue packet
8364 * receiving thread. This creates the new thread to
8365 * receive the work and sets the affinity.
8379 pthread_attr_t attr;
8383 /* set the required attributes */
8384 pthread_attr_init(&attr);
8385 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8386 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8387 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8389 /* Create a new thread to receive the work queue messages */
8390 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8392 pthread_attr_destroy(&attr);
8397 pthread_attr_destroy(&attr);
8401 }/* ssInitRcvWork */
8408 * Desc: This is the handler function of receive
8412 * RFAILED - failed, general (optional)
8414 * Notes:The handler function of the work queue receiver task.
8415 * This will be waiting for the work and after receiving
8416 * it, work will converted and posted to that entityt
8423 PRIVATE void *workRcvTsk
8428 PRIVATE void *workRcvTsk (ptr)
8433 cvmx_wqe_t *workPtr;
8434 Buffer *mBuf, *rcvdBuf;
8435 SsMsgInfo *minfoPtr;
8444 /* get the work if its avilable */
8445 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8447 if ( workPtr == NULLP )
8449 /* If there is no work then sleep for 10 usec */
8451 ts.tv_nsec = 500000;
8453 nanosleep(&ts, NULLP);
8457 switch(workPtr->tag)
8459 /* Switch over according to the tag value */
8460 case SS_CVMX_MBUF_TAG:
8462 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8464 /* Convert the physical address to Pointers */
8465 ret = SConvPhyPtr(&rcvdBuf);
8468 /* mt011.301: Cavium 32 bit changes */
8469 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8473 /* Copy the buffer to this region */
8474 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8477 /* mt011.301: Cavium 32 bit changes */
8478 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8482 /* mt011.301: Cavium 32 bit changes */
8483 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8485 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8487 /* Get the post strucutre and Post the message */
8488 if ( minfoPtr != NULLP)
8490 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8492 (Void)SPstTsk(&pst, mBuf);
8494 /* Free the buffer allocated if it cannot be sent */
8503 /* Invalid tag value, drop the work */
8504 /* mt011.301: Cavium 32 bit changes */
8505 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8514 #endif /* SS_SEUM_CAVIUM */
8516 #ifdef TENB_RTLIN_CHANGES
8517 S16 SInitLock(SLockId *l, U8 t)
8520 pthread_mutexattr_t prior;
8521 pthread_mutexattr_init(&prior);
8522 #ifndef RGL_SPECIFIC_CHANGES
8523 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8525 r = pthread_mutex_init(l, &prior);
8526 pthread_mutexattr_destroy(&prior);
8530 #ifdef SS_THR_REG_MAP
8533 * Fun: ssRegMainThread
8535 * Desc: This function is used to add the memory region
8536 * mapping for the main thread.
8538 * Ret: VOID (Always successful)
8546 Void ssRegMainThread(Void)
8549 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8551 printf("not able to get different Id for main thread\n");
8554 /* Here the default region is added as we dont have any region associated with
8555 * Main thread. The thread should not perform any allocation except
8556 * the initial configuratin
8558 #ifdef XEON_SPECIFIC_CHANGES
8559 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8561 SS_GET_THREAD_MEM_REGION() =
8568 * Fun: ssCheckAndAddMemoryRegionMap
8570 * Desc: This function is used to add the memory region
8571 * mapping for the provided sTsk associated thread.
8572 * If the threadId can be placed in the thread memory
8573 * region mapping table and returns success if it is able
8574 * to place. If not, it keeps the thread ID in the static
8575 * local array and increments the count. Once thread Id
8576 * is successfully placed in the thread memory region mapping
8577 * table, pthread_cancel is sent for all the previous threads
8578 * which are failed to place in table.
8580 * Ret: TRUE - Thread ID successfully placed in thread memory region
8582 * FALSE - If thread Id is not placed in thread memory region
8585 * Notes:mapping tablemapping tablng tablee
8590 S32 ssCheckAndAddMemoryRegionMap
8592 pthread_t threadId, /* Thread Id of system task */
8593 Region region /* Region associated with thread */
8596 PRIVATE U32 createdThreads;
8597 PRIVATE pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8601 /* Here 0xFF is considered as invalid region and if the mapping table
8602 * contains 0xFF, that mapping entry is free
8604 if(SS_INVALID_THREAD_REG_MAP !=
8605 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8607 /* Klock work fix ccpu00148484 */
8608 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8610 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8611 printf("Not able to get the different thread ID, exiting\n");
8614 createdThreadIds[createdThreads++] = threadId;
8617 /* If we found free mapping table entry, place the region and send pthread_cancel
8618 * for all the thread Ids which are created before this
8620 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8621 #ifdef XEON_SPECIFIC_CHANGES
8622 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8623 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8624 SS_MAX_THREAD_REGION_MAP), region);
8626 for(indx = 0; indx < createdThreads; indx++)
8628 #ifdef XEON_SPECIFIC_CHANGES
8629 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8631 pthread_cancel(createdThreadIds[indx]);
8637 } /* ssCheckAndAddMemoryRegionMap */
8641 * Fun: ssCheckAndDelMemoryRegionMap
8643 * Desc: This function is used to add the memory region
8644 * mapping for the provided sTsk associated thread.
8645 * If the threadId can be placed in the thread memory
8646 * region mapping table and returns success if it is able
8647 * to place. If not, it keeps the thread ID in the static
8648 * local array and increments the count. Once thread Id
8649 * is successfully placed in the thread memory region mapping
8650 * table, pthread_cancel is sent for all the previous threads
8651 * which are failed to place in table.
8653 * Ret: TRUE - Thread ID successfully placed in thread memory region
8655 * FALSE - If thread Id is not placed in thread memory region
8658 * Notes:mapping tablemapping tablng tablee
8663 S32 ssCheckAndDelMemoryRegionMap
8665 pthread_t threadId /* Thread Id of system task */
8670 /* Raghu To-Do Check with team, is it necessary to acquire lock
8671 * as del and add may go parallel */
8672 /* Here 0xFF is considered as invalid region and if the mapping table
8673 * contains 0xFF, that mapping entry is free
8675 if(SS_INVALID_THREAD_REG_MAP ==
8676 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8679 printf("Invalid Thread ID (%ld)\n", (U32)threadId);
8681 printf("Invalid Thread ID (%d)\n", (U32)threadId);
8685 /* If we found free mapping table entry, place the region and send pthread_cancel
8686 * for all the thread Ids which are created before this
8688 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8692 } /* ssCheckAndAddMemoryRegionMap */
8696 #ifdef SS_TSKLOG_ENABLE
8701 * Desc: This function will return current time through input parameter.
8704 * RFAILED - failed, general (optional)
8713 VOLATILE U32 *startTime,
8717 S16 SStartTask(startTime, taskId)
8718 VOLATILE U32 *startTime;
8722 #ifdef MSPD_MLOG_NEW
8723 *startTime = GetTIMETICK();
8732 * Desc: This function will return current time through input parameter.
8733 * and take the difference of start time provided as input parameter
8737 * RFAILED - failed, general (optional)
8746 VOLATILE U32 startTime,
8750 S16 SStopTask(startTime, taskId)
8751 VOLATILE U32 startTime;
8758 case PID_MAC_HARQ_IND:
8759 case PID_SCH_TTI_IND:
8761 case PID_MAC_DAT_IND:
8762 case PID_MAC_SF_ALLOC_REQ:
8763 case PID_MAC_STA_RSP:
8764 case PID_MAC_DL_SCHD:
8765 case PID_MAC_DL_CQI_IND:
8766 case PID_MAC_UL_CQI_IND:
8767 case PID_MAC_UL_SCHD:
8768 case PID_MAC_TTI_IND:
8769 case PID_CL_RCV_PHY_MSG:
8770 case PID_CL_HARQ_STA_IND:
8771 case PID_MAC_AM_HARQ_RLS:
8772 case PID_CL_DL_BATCH_PROC:
8773 case PID_CL_DLM_PRC_TTI_IND:
8774 case PID_CRC_IND_REAL:
8775 case PID_CRC_IND_DUMMY:
8776 case PID_TTI_LATENCY:
8777 case PID_RECPREQ_PROC:
8780 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8782 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8785 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8795 VOLATILE U32 * startTime,
8799 S16 SStartTask(startTime, taskId)
8800 VOLATILE U32 * startTime;
8811 VOLATILE U32 startTime,
8815 S16 SStopTask(startTime, taskId)
8816 VOLATILE U32 startTime;
8823 #endif /*#ifdef SS_TSKLOG_ENABLE */
8824 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8826 * This primitive is used to calculate the CPU Utilization per Core
8831 * @return Void - function is always success
8834 Void UpdateSocCpuInfo
8836 CmCpuStatsInfo *cpuInfo,
8840 Void UpdateSocCpuInfo(*cpuInfo, idx)
8841 CmCpuStatsInfo *cpuInfo;
8846 S8 mipsStr[MIPS_STRING_LEN];
8853 /* Open the file which holds the MIPS available value */
8854 mipsFd = fopen(MIPS_FILE, "r");
8861 /* Get the free mips available value from the file */
8862 if(NULLP == fgets(mipsStr, 24, mipsFd))
8864 printf("fgets to get the free mips available failed\n");
8869 strtok(mipsStr, " ");
8871 strPart = strtok(NULLP, " ");
8873 if(idx == CM_L2_CPU_UTIL)
8875 if(strPart != NULLP)
8877 l2FreeCpu = atoi(strPart);
8878 l2CpuUsed = 100 - l2FreeCpu;
8879 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8880 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);;
8881 cpuInfo->cpuUtil[0].numSamples++;
8884 if(idx == CM_L3_CPU_UTIL)
8886 strPart = strtok(NULLP, " ");
8887 if(strPart != NULLP)
8889 l3FreeCpu = atoi(strPart);
8890 l3CpuUsed = 100 - l3FreeCpu;
8891 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8892 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);;
8893 cpuInfo->cpuUtil[0].numSamples++;
8896 if(idx == CM_L2_CPU_UTIL)
8898 cpuInfo->numCores = CM_NUM_L2_CORES ;
8900 else if(idx == CM_L3_CPU_UTIL)
8902 cpuInfo->numCores = CM_NUM_L3_CORES ;
8908 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8909 #ifdef SS_MULTICORE_SUPPORT
8912 * Fun: Add Timer thread into system task table
8914 * Desc: This function is used to add the system task
8915 * associated with Timer thread.
8925 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(
8929 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(idx)
8937 /* lock the system task table */
8938 ret = SLock(&osCp.sTskTblLock);
8942 #if (ERRCLASS & ERRCLS_DEBUG)
8943 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8944 "Could not lock system task table");
8950 /* initialize the system task entry with the information we have */
8951 sTsk = &osCp.sTskTbl[idx];
8956 SDestroyLock(&sTsk->lock);
8957 ssDestroyDmndQ(&sTsk->dQ);
8960 /* store the system task priority */
8961 sTsk->tskPrior = SS_NORM_TSK_PRI;
8963 /* initialize the demand queue */
8964 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8967 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8969 #if (ERRCLASS & ERRCLS_DEBUG)
8970 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8971 "Could not give the Semaphore");
8976 #if (ERRCLASS & ERRCLS_DEBUG)
8977 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8978 "Could not initialize demand queue");
8984 /* initialize the system task entry lock */
8985 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8987 ssDestroyDmndQ(&sTsk->dQ);
8989 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8991 #if (ERRCLASS & ERRCLS_DEBUG)
8992 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8993 "Could not give the Semaphore");
8998 #if (ERRCLASS & ERRCLS_DEBUG)
8999 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9000 "Could not initialize system task entry lock");
9007 /* success, update the table */
9008 sTsk->tskId = idx + 1;
9010 sTsk->termPend = FALSE;
9012 /* unlock the system task table */
9014 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9016 #if (ERRCLASS & ERRCLS_DEBUG)
9017 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9018 "Could not give the Semaphore");
9025 #endif /* SS_MULTICORE_SUPPORT */
9030 * Fun: Initialize timer table
9032 * Desc: This function initializes MTSS-specific information
9033 * in the timer table.
9051 pthread_attr_t attr;
9052 struct sched_param param_sched;
9053 #ifndef XEON_SPECIFIC_CHANGES
9056 #ifdef SS_MULTICORE_SUPPORT
9058 #endif /* SS_MULTICORE_SUPPORT */
9059 #ifdef SS_THR_REG_MAP
9060 U32 threadCreated = FALSE;
9061 #endif /* SS_THR_REG_MAP */
9064 #ifndef XEON_SPECIFIC_CHANGES
9065 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9068 #if (ERRCLASS & ERRCLS_DEBUG)
9069 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9070 "Could not give the Semaphore");
9076 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9077 /* mt010.21: addition */
9079 #ifdef SS_MULTICORE_SUPPORT
9080 sTsk = ssdReAddTmrSTsk(0);
9085 #endif /* SS_MULTICORE_SUPPORT */
9086 /* create the timer handler thread */
9088 pthread_attr_init(&attr);
9089 /* mt021.201 - Addition to set stack size */
9090 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9091 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9092 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9093 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9094 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9095 pthread_attr_setschedparam(&attr, ¶m_sched);
9098 #ifdef SS_THR_REG_MAP
9099 /* When the thread is created, we check for the memory mapping table if
9100 * threadId can be placed in thread memory map table. If it is not able to place
9101 * threadId is stored in tmporary array. Once thread is created successful,
9102 * thread_cancel is sent for each thread which are created before. All the
9103 * threads are made to wait on sema which is cancel point for thread.
9105 while(threadCreated == FALSE)
9108 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9110 /* mt020.201 - Addition for destroying thread attribute object attr */
9111 pthread_attr_destroy(&attr);
9116 #ifdef SS_THR_REG_MAP
9117 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9120 #endif /* SS_THR_REG_MAP */
9121 #ifdef SS_MEM_WL_DEBUG
9122 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9125 /* mt020.201 - Addition for destroying thread attribute object attr */
9126 pthread_attr_destroy(&attr);
9127 sem_post(&osCp.dep.ssStarted);
9131 /**********************************************************************
9133 **********************************************************************/