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 */
820 #ifdef XEON_MULTIPLE_CELL_CHANGES
821 /* Read the WLS parameters from the file and copy into global control block */
822 if(smWrReadWlsConfigParams() != ROK)
824 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
826 } /* end of if statement */
832 #endif /* INTEL_WLS */
836 /* mt003.301 Modifications */
839 printf("\n SInit failed, SSI could not start \n");
840 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
844 /*mt010.301 cleanup part exposed to user*/
855 * Desc: This function is the entry point for the final binary. It
856 * calls SInit() in the common code. It can be replaced by a
857 * user function if required (SInit() must still be called).
859 * Ret: none on success
870 int argc, /* argument count */
871 char **argv /* argument vector */
874 int ssMain(argc, argv)
875 int argc; /* argument count */
876 char **argv; /* argument vector */
893 * initialization functions
898 * Fun: Initialize OS control point
900 * Desc: This function initializes MTSS-specific information
901 * in the OS control point.
919 struct sigaction act;
921 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
927 /*mt014.301 : 4GMX release related changes*/
931 /* mt005.301 : Cavium changes */
932 #ifdef SS_SEUM_CAVIUM
933 /* set group mask for the core */
934 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
935 #endif /* SS_SEUM_CAVIUM */
937 osCp.dep.sysTicks = 0;
939 /* mt020.201 - Addition for no command line available */
941 /* parse command line */
943 /* mt003.301 Additions */
944 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
946 printf("\n File Based Memory configuration failed \n");
951 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
952 #ifndef SS_LOCKLESS_MEMORY
953 #ifdef SS_MULTICORE_SUPPORT
954 if(memConfigured == FALSE)
960 /* initialize the started semaphore */
961 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
966 /* mt028.201 added compile time flag to allow not to mask signals */
968 /* mask all signals in the main thread */
970 sigdelset(&set, SIGINT);
971 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
972 sigdelset(&set, SIGSEGV);
973 sigdelset(&set, SIGUSR2);
974 sigdelset(&set, SIGILL);
975 #ifdef XEON_SPECIFIC_CHANGES
976 sigdelset(&set, SIGABRT);
977 sigdelset(&set, SIGTERM);
978 sigdelset(&set, SIGHUP);
981 pthread_sigmask(SIG_SETMASK, &set, NULLP);
982 #endif /* UNMASK_SIG */
984 /* install a SIGINT handler to shutdown */
985 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
987 /*Initialize SIGSEGV Signal */
988 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
990 memset(&sa, 0, sizeof(struct sigaction));
991 sigemptyset(&sa.sa_mask);
992 sa.sa_sigaction = signal_segv;
993 sa.sa_flags = SA_SIGINFO;
994 #ifndef XEON_SPECIFIC_CHANGES
995 sigaction(SIGSEGV, &sa, NULL);
997 memset(&sa, 0, sizeof(struct sigaction));
998 sigemptyset(&sa.sa_mask);
999 sa.sa_sigaction = signal_segv;
1000 sa.sa_flags = SA_SIGINFO;
1002 sigaction(SIGILL, &sa, NULL);
1004 if(sigaction(SIGILL, &sa, NULL) != 0)
1006 printf("Failed to process sigaction for the SIGILL\n");
1009 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1011 printf("Failed to process sigaction for the SIGSEGV\n");
1014 if(sigaction(SIGABRT, &sa, NULL) != 0)
1016 printf("Failed to process sigaction for the SIGABRT\n");
1019 if(sigaction(SIGTERM, &sa, NULL) != 0)
1021 printf("Failed to process sigaction for the SIGTERM\n");
1024 if(sigaction(SIGHUP, &sa, NULL) != 0)
1026 printf("Failed to process sigaction for the SIGHUP\n");
1031 signal (SIGSEGV, mtSigSegvHndlr);
1032 signal (SIGKILL, mtSigSegvHndlr);
1033 signal (SIGUSR2, mtSigUsr2Hndlr);
1038 signal (SIGINT, mtStopHndlr);
1041 act.sa_handler = mtIntSigHndlr;
1042 sigfillset(&act.sa_mask);
1044 if (sigaction(SIGINT, &act, NULLP) != 0)
1050 /* mt040.201 initialise random seed */
1051 osCp.dep.randSeed = time(NULLP);
1059 * Fun: De-initialize OS control point
1061 * Desc: This function reverses the initialization in ssdInitGen().
1082 sem_destroy(&osCp.dep.ssStarted);
1087 #ifdef SS_LOCKLESS_MEMORY
1091 * Fun: ssPutDynMemBlkSet
1093 * Desc: Returns the set of dynamic Blocks into the global region
1096 * Ret: ROK - successful,
1097 * RFAILED - unsuccessful.
1105 S16 ssPutDynMemBlkSet
1107 U8 bktIdx, /* Index to bucket list */
1108 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1109 added to global region */
1112 S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1113 U8 bktIdx; /* Index to bucket list */
1114 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1115 added to global region */
1118 CmMmGlobRegCb *globReg;
1119 CmMmGlobalBktCb *bktCb;
1123 globReg = osCp.globRegCb;
1125 #if (ERRCLASS & ERRCLS_INT_PAR)
1126 if(bktIdx >= globReg->numBkts)
1130 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1132 bktCb = &(globReg->bktTbl[bktIdx]);
1134 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1136 blkPtr = dynMemSetElem->nextBktPtr;
1137 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1138 free((Void *)blkPtr);
1141 dynMemSetElem->nextBktPtr = NULLP;
1142 dynMemSetElem->numFreeBlks = 0;
1149 * Fun: ssGetDynMemBlkSet
1151 * Desc: Gets the set of dynamic memory blocks from the global region
1154 * Ret: ROK - successful,
1155 * RFAILED - unsuccessful.
1163 S16 ssGetDynMemBlkSet
1165 U8 bktIdx, /* Index to bucket list */
1166 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1167 with new set values */
1170 S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1171 U8 bktIdx; /* Index to bucket list */
1172 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1173 with new set values */
1177 CmMmGlobRegCb *globReg;
1178 CmMmGlobalBktCb *bktCb;
1183 globReg = osCp.globRegCb;
1185 #if (ERRCLASS & ERRCLS_INT_PAR)
1186 if(bktIdx >= globReg->numBkts)
1190 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1192 bktCb = &(globReg->bktTbl[bktIdx]);
1193 basePtr = &(dynMemSetElem->nextBktPtr);
1195 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1197 blkPtr = (Data *)malloc(bktCb->size);
1199 basePtr = (CmMmEntry **)blkPtr;
1202 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1206 } /* ssGetDynMemBlkSet */
1211 * Fun: ssPutDynMemBlkSet
1213 * Desc: Returns the set of dynamic Blocks into the global region
1216 * Ret: ROK - successful,
1217 * RFAILED - unsuccessful.
1225 S16 ssPutDynMemBlkSet
1227 U8 bktIdx, /* Index to bucket list */
1228 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1229 added to global region */
1230 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1233 S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1234 U8 bktIdx; /* Index to bucket list */
1235 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1236 added to global region */
1237 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1240 CmMmGlobRegCb *globReg;
1241 CmMmGlobalBktCb *bktCb;
1243 CmMmBlkSetElement *globMemNode;
1246 TRC1(ssPutDynMemBlkSet);
1248 globReg = osCp.globRegCb;
1250 #if (ERRCLASS & ERRCLS_INT_PAR)
1251 if(bktIdx >= globReg->numBkts)
1255 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1257 bktCb = &(globReg->bktTbl[bktIdx]);
1259 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1260 try lock is used as it is not required to block as it will be taken
1261 in the next go else it will be blocked for lock as we have to get the
1264 SLock(&(bktCb->bucketLock));
1270 /* Get a free node from the free node linked list */
1271 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1272 if(lstNode == NULLP)
1274 SUnlock(&(bktCb->bucketLock));
1278 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1280 /* Copy the content of the received element information on to free node
1281 * and add it to valid linked list */
1282 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1283 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1284 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1285 dynMemSetElem->numFreeBlks = 0;
1286 dynMemSetElem->nextBktPtr = NULLP;
1288 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1290 SUnlock(&(bktCb->bucketLock));
1298 * Fun: ssGetDynMemBlkSet
1300 * Desc: Gets the set of dynamic memory blocks from the global region
1303 * Ret: ROK - successful,
1304 * RFAILED - unsuccessful.
1306 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1313 S16 ssGetDynMemBlkSet
1315 U8 bktIdx, /* Index to bucket list */
1316 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1317 with new set values */
1318 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1321 S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1322 U8 bktIdx; /* Index to bucket list */
1323 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1324 with new set values */
1325 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1328 CmMmGlobRegCb *globReg;
1329 CmMmGlobalBktCb *bktCb;
1331 CmMmBlkSetElement *globMemNode;
1334 TRC1(ssGetDynMemBlkSet);
1336 globReg = osCp.globRegCb;
1338 #if (ERRCLASS & ERRCLS_INT_PAR)
1339 if(bktIdx >= globReg->numBkts)
1343 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1345 bktCb = &(globReg->bktTbl[bktIdx]);
1347 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1348 try lock is used as it is not required to block as it will be taken
1349 in the next go else it will be blocked for lock as we have to get the
1352 SLock(&(bktCb->bucketLock));
1357 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1359 if(lstNode == NULLP)
1361 SUnlock(&(bktCb->bucketLock));
1365 /* Delete the node from the valid linked list and copy the values of the
1366 * elements of structrues into pointer */
1367 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1368 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1369 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1370 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1372 /* Add this node to the free node linked list */
1373 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1375 SUnlock(&(bktCb->bucketLock));
1379 } /* ssGetDynMemBlkSet */
1382 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1384 PRIVATE U32 memoryCheckCounter;
1387 U32 isMemThreshReached(
1391 U32 isMemThreshReached(reg)
1395 CmMmGlobRegCb *globReg;
1396 CmMmGlobalBktCb *bktCb;
1398 TRC3(isMemThreshReached)
1400 globReg = osCp.globRegCb;
1402 #if (ERRCLASS & ERRCLS_INT_PAR)
1403 if(bktIdx >= globReg->numBkts)
1407 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1409 bktCb = &(globReg->bktTbl[bktIdx]);
1411 if(gDynMemAlrm[bktIdx])
1413 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1414 SLock(&(bktCb->bucketLock));
1415 if(bktCb->listValidBktSet.count > 25)
1417 gDynMemAlrm[bktIdx] = FALSE;
1418 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1420 SUnlock(&(bktCb->bucketLock));
1426 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1428 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1429 SLock(&(bktCb->bucketLock));
1430 if(bktCb->listValidBktSet.count < 15 )
1431 gDynMemAlrm[bktIdx] = TRUE;
1432 memoryCheckCounter = 0;
1433 SUnlock(&(bktCb->bucketLock));
1439 #endif /* USE_MALLOC */
1440 #endif /* SS_LOCKLESS_MEMORY */
1442 #ifdef SS_USE_ICC_MEMORY
1445 * Fun: Initialize region/pool tables
1447 * Desc: This function initializes MTSS-specific information
1448 * in the region/pool tables and configures the common
1449 * memory manager for use.
1464 Void * ssGetIccHdl()
1468 CmMmDynRegCb *dynRegCb;
1470 /* Klock work fix ccpu00148484 */
1471 if(!(region < SS_MAX_REGS))
1476 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1478 return (dynRegCb->iccHdl);
1480 #endif /* SS_USE_ICC_MEMORY */
1482 #ifdef T2K_MEM_LEAK_DBG
1483 extern RegionMemLeakInfo regMemLeakInfo;
1484 #endif /* T2K_MEM_LEAK_DBG */
1488 S16 SPartitionWlsMemory()
1493 U64 pageSize[1], hugePageSize;
1496 long int pageSize[1], hugePageSize;
1499 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1501 U8 *regMemStrtAddr = (U8 *)osCp.wls.allocAddr;
1503 gethugepagesizes(pageSize,1);
1504 hugePageSize = pageSize[0];
1505 for (i = 0; i < 1; i++)
1507 mtRegMemSz[i].startAddr = regMemStrtAddr;
1508 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1510 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1511 reqdSz = numHugePg * hugePageSize;
1512 regMemStrtAddr += reqdSz;
1513 #ifdef T2K_MEM_LEAK_DBG
1514 /* Since wls is region 0 */
1515 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1516 regMemLeakInfo.numActvRegions++;
1517 #endif /* T2K_MEM_LEAK_DBG */
1519 //Store last region addr for validation
1520 mtRegMemSz[i].startAddr = regMemStrtAddr;
1524 #ifdef SS_MEM_WL_DEBUG
1525 Void SChkAddrValid(int type, int region, PTR ptr)
1527 char *tryPtr = NULL;
1528 if(type == 0) //Global
1530 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1531 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1533 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1539 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1541 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1547 #endif /* SS_MEM_WL_DEBUG */
1549 S16 SPartitionStaticMemory(U8 *startAddr)
1554 U8 *regMemStrtAddr = (U8 *)startAddr;
1557 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1558 for (i = 1; i < mtMemoCfg.numRegions; i++)
1560 mtRegMemSz[i].startAddr = regMemStrtAddr;
1561 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1562 regMemStrtAddr += reqdSz;
1563 #ifdef T2K_MEM_LEAK_DBG
1564 { /* Since region 1 onwards are used for non wls */
1565 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1566 regMemLeakInfo.numActvRegions++;
1568 #endif /* T2K_MEM_LEAK_DBG */
1572 S16 SAllocateWlsMem()
1580 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1581 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1583 for (i = 0; i < 1; i++)
1585 /* allocate space for the region */
1586 region = &mtMemoCfg.region[i];
1587 reqdMemSz += region->heapsize;
1588 mtRegMemSz[i].reqdSz += region->heapsize;
1590 for (j = 0; j < region->numBkts; j++)
1592 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1593 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1596 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1597 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1599 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1601 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1603 SPartitionWlsMemory();
1606 S16 SAllocateStaticMem()
1615 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1617 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1618 for (i = 1; i < mtMemoCfg.numRegions; i++)
1620 /* allocate space for the region */
1621 region = &mtMemoCfg.region[i];
1622 reqdMemSz += region->heapsize;
1623 mtRegMemSz[i].reqdSz += region->heapsize;
1625 for (j = 0; j < region->numBkts; j++)
1627 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1628 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1632 startAddr = malloc(reqdMemSz + (1024 * 10));
1634 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1636 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1638 SPartitionStaticMemory(startAddr);
1641 #endif /* INTEL_WLS */
1647 * Fun: Initialize region/pool tables
1649 * Desc: This function initializes MTSS-specific information
1650 * in the region/pool tables and configures the common
1651 * memory manager for use.
1669 /* mt018.201 - added local variable */
1674 Txt errMsg[256] = {'\0'};
1675 #ifdef SS_LOCKLESS_MEMORY
1676 CmMmDynRegCb *dynRegCb;
1677 #ifdef SS_USE_ICC_MEMORY
1679 CmMmGlobRegCb *globReg;
1682 #endif /* SS_LOCKLESS_MEMORY */
1686 /* Use the default SSI memory manager if the ICC memory manager is not
1687 * avilable. If ICC memory manager is avilable, it will be used for
1688 * all sharable memory allocation and de-allocation */
1689 #ifdef SS_LOCKLESS_MEMORY
1690 #ifdef SS_USE_ICC_MEMORY
1691 #ifndef YS_PHY_3_8_2
1693 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1695 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1696 if(dynRegCb == NULLP)
1700 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1702 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1704 dynRegCb->region = i;
1705 cmMmDynRegInit(dynRegCb);
1706 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1709 /* ysIccHdl = dynRegCb->iccHdl; */
1712 /* Initialize the global region first */
1713 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1715 if(osCp.globRegCb == NULLP)
1720 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1722 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1724 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1726 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1728 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1730 if(globReg->bktTbl[i].startAddr == NULLP)
1734 globReg->bktTbl[i].poolId = i;
1735 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1736 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1737 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1740 globReg->numBkts = mtGlobMemoCfg.numBkts;
1741 cmMmGlobRegInit(globReg);
1743 /* Initialize the dynamic task regions and sanity check for the theshold
1745 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1747 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1748 if(dynRegCb == NULLP)
1752 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1754 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1755 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1756 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1757 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1759 #ifdef XEON_SPECIFIC_CHANGES
1764 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1765 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1766 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1767 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1768 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1770 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1773 dynRegCb->region = i;
1774 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1775 cmMmDynRegInit(dynRegCb);
1777 #endif /* SS_USE_ICC_MEMORY */
1778 #endif /* SS_LOCKLESS_MEMORY */
1780 #ifdef T2K_MEM_LEAK_DBG
1782 /* Initailize mem leak tool memorys for debguing */
1783 regMemLeakInfo.numActvRegions=0;
1784 for(reg=0; reg <SS_MAX_REGS; reg++)
1786 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1787 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1788 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1789 regMemLeakInfo.regStartAddr[reg] = 0;
1792 regMemLeakInfo.regStartAddr[reg] = 0;
1793 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1795 printf("\n mutex init failed\n");
1801 /* Now allocate WLS memory */
1803 SAllocateStaticMem();
1805 /* mt018.201 - CMM Initialization */
1806 for (i = 0; i < mtMemoCfg.numRegions; i++)
1808 /* allocate space for the region control block */
1809 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1810 #ifdef TENB_RTLIN_CHANGES
1811 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1813 if (mtCMMRegCb[i] == NULLP)
1815 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1816 for the Region:%d control block\n",i);
1818 for (k = 0; k < i; k++)
1820 cmMmRegDeInit(mtCMMRegCb[k]);
1821 free(mtCMMRegCfg[k]->vAddr);
1822 free(mtCMMRegCb[k]);
1823 free(mtCMMRegCfg[k]);
1828 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1829 #ifdef TENB_RTLIN_CHANGES
1830 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1832 if (mtCMMRegCfg[i] == NULLP)
1834 for (k = 0; k < i; k++)
1836 cmMmRegDeInit(mtCMMRegCb[k]);
1837 free(mtCMMRegCfg[k]->vAddr);
1838 free(mtCMMRegCb[k]);
1839 free(mtCMMRegCfg[k]);
1841 free(mtCMMRegCb[i]);
1846 /* allocate space for the region */
1847 region = &mtMemoCfg.region[i];
1848 mtCMMRegCfg[i]->size = region->heapsize;
1849 for (j = 0; j < region->numBkts; j++)
1851 /* mt033.201 - addition for including the header size while computing the total size */
1852 #ifdef SSI_DEBUG_LEVEL1
1853 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1854 (region->bkt[j].numBlks);
1856 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1857 #endif /* SSI_DEBUG_LEVEL1 */
1860 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1862 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1865 #ifdef XEON_SPECIFIC_CHANGES
1866 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1867 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1869 #ifdef TENB_RTLIN_CHANGES
1870 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1873 if (mtCMMRegCfg[i]->vAddr == NULLP)
1875 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1876 for the Region:%d \n",i);
1878 for (k = 0; k < i; k++)
1880 cmMmRegDeInit(mtCMMRegCb[k]);
1881 free(mtCMMRegCfg[k]->vAddr);
1882 free(mtCMMRegCb[k]);
1883 free(mtCMMRegCfg[k]);
1885 free(mtCMMRegCb[i]);
1886 free(mtCMMRegCfg[i]);
1891 /* set up the CMM configuration structure */
1892 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1893 mtCMMRegCfg[i]->chFlag = 0;
1894 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1895 mtCMMRegCfg[i]->numBkts = region->numBkts;
1897 for (j = 0; j < region->numBkts; j++)
1899 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1900 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1903 /* initialize the CMM */
1904 #ifdef SS_LOCKLESS_MEMORY
1905 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1907 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1908 #endif /* SS_LOCKLESS_MEMORY */
1910 for (k = 0; k < i; k++)
1912 cmMmRegDeInit(mtCMMRegCb[k]);
1913 free(mtCMMRegCfg[k]->vAddr);
1914 free(mtCMMRegCb[k]);
1915 free(mtCMMRegCfg[k]);
1917 free(mtCMMRegCfg[i]->vAddr);
1918 free(mtCMMRegCb[i]);
1919 free(mtCMMRegCfg[i]);
1924 /* initialize the STREAMS module */
1925 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1926 if (region->regionId == 0)
1928 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
1930 for (k = 0; k < i; k++)
1932 cmMmRegDeInit(mtCMMRegCb[k]);
1933 free(mtCMMRegCfg[k]->vAddr);
1934 free(mtCMMRegCb[k]);
1935 free(mtCMMRegCfg[k]);
1937 cmMmRegDeInit(mtCMMRegCb[i]);
1938 free(mtCMMRegCfg[i]->vAddr);
1939 free(mtCMMRegCb[i]);
1940 free(mtCMMRegCfg[i]);
1945 /* mt001.301 : Additions */
1946 #ifdef SS_MEM_LEAK_STS
1948 #endif /* SS_MEM_LEAK_STS */
1957 * Fun: De-initialize region/pool tables
1959 * Desc: This function reverses the initialization in ssdInitMem().
1977 /* mt018.201 - added local variables */
1981 /* mt008.301 Additions */
1982 #ifdef SS_MEM_LEAK_STS
1983 cmDeinitMemLeakMdl();
1984 #endif /* SS_MEM_LEAK_STS */
1986 for (i = 0; i < mtMemoCfg.numRegions; i++)
1988 cmMmRegDeInit(mtCMMRegCb[i]);
1989 free(mtCMMRegCfg[i]->vAddr);
1990 free(mtCMMRegCb[i]);
1991 free(mtCMMRegCfg[i]);
2000 * Fun: Initialize task table
2002 * Desc: This function initializes MTSS-specific information
2003 * in the task table.
2021 /* mt001.301 : Additions */
2022 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2023 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2025 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2030 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2031 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2032 /* initialize system task information */
2033 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2035 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2037 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2044 * Fun: Deinitialize task table
2046 * Desc: This function reverses the initialization perfomed in
2071 #ifdef SS_DRVR_SUPPORT
2074 * Fun: Initialize driver task table
2076 * Desc: This function initializes MTSS-specific information
2077 * in the driver task table.
2097 pthread_attr_t attr;
2103 /* initialize the dependent portion of the driver task entries */
2104 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2106 osCp.drvrTskTbl[i].dep.flag = FALSE;
2110 /* create pipe for communication between SSetIntPend() and
2111 * the isTskHdlr thread.
2113 if (pipe(osCp.dep.isFildes) != 0)
2119 /* create the isTskHdlr thread */
2120 pthread_attr_init(&attr);
2121 /* mt021.201 - Addition to set stack size */
2122 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2123 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2124 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2125 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2127 /* mt020.201 - Addition for destroying thread attribute object attr */
2128 pthread_attr_destroy(&attr);
2134 /*mt014.301 : 4GMX release related changes*/
2135 #ifdef SS_4GMX_UCORE
2143 /* mt020.201 - Addition for destroying thread attribute object attr */
2144 pthread_attr_destroy(&attr);
2153 * Fun: Deinitialize driver information
2155 * Desc: This function reverses the initialization performed in
2171 Void ssdDeinitDrvr()
2174 TRC0(ssdDeinitDrvr);
2175 /* mt008.301: Terminate the Driver Task on exit */
2176 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2179 TL_Close(AppContext.hUAII);
2180 if (clusterMode == RADIO_CLUSTER_MODE)
2182 TL_Close(AppContext.hUAII_second);
2188 #endif /* SS_DRVR_SUPPORT */
2193 * Fun: Initialize timer table
2195 * Desc: This function initializes MTSS-specific information
2196 * in the timer table.
2214 pthread_attr_t attr;
2215 struct sched_param param_sched;
2216 /* mt010.21: addition */
2218 #ifdef SS_MULTICORE_SUPPORT
2220 #endif /* SS_MULTICORE_SUPPORT */
2221 #ifdef SS_THR_REG_MAP
2222 U32 threadCreated = FALSE;
2223 #endif /* SS_THR_REG_MAP */
2228 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2229 /* mt010.21: addition */
2230 osCp.dep.tmrTqCp.nxtEnt = 0;
2231 for (i=0; i< SS_MAX_TMRS; i++)
2233 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2236 #ifdef SS_MULTICORE_SUPPORT
2237 sTsk = ssdAddTmrSTsk();
2242 #endif /* SS_MULTICORE_SUPPORT */
2243 /* create the timer handler thread */
2244 pthread_attr_init(&attr);
2245 /* mt021.201 - Addition to set stack size */
2246 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2247 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2248 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2249 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2250 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2251 pthread_attr_setschedparam(&attr, ¶m_sched);
2254 #ifdef SS_THR_REG_MAP
2255 /* When the thread is created, we check for the memory mapping table if
2256 * threadId can be placed in thread memory map table. If it is not able to place
2257 * threadId is stored in tmporary array. Once thread is created successful,
2258 * thread_cancel is sent for each thread which are created before. All the
2259 * threads are made to wait on sema which is cancel point for thread.
2261 while(threadCreated == FALSE)
2264 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2266 /* mt020.201 - Addition for destroying thread attribute object attr */
2267 pthread_attr_destroy(&attr);
2272 #ifdef SS_THR_REG_MAP
2273 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2276 #endif /* SS_THR_REG_MAP */
2277 #ifdef SS_MEM_WL_DEBUG
2278 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2281 /* mt020.201 - Addition for destroying thread attribute object attr */
2282 pthread_attr_destroy(&attr);
2291 * Fun: Deinitialize timer table
2293 * Desc: This function reverses the initialization performed in
2312 #ifdef SS_MULTICORE_SUPPORT
2315 #endif /* SS_MULTICORE_SUPPORT */
2319 #ifdef SS_MULTICORE_SUPPORT
2320 ret = SLock(&osCp.sTskTblLock);
2324 #if (ERRCLASS & ERRCLS_DEBUG)
2325 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2326 "Could not lock system task table");
2330 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2331 /* clean up the system task entry */
2335 SDestroyLock(&sTsk->lock);
2336 ssDestroyDmndQ(&sTsk->dQ);
2339 /* make this entry available in the system task table */
2340 sTsk->nxt = osCp.nxtSTskEntry;
2341 osCp.nxtSTskEntry = 0;
2345 /* unlock the system task table */
2346 SUnlock(&osCp.sTskTblLock);
2348 #endif /* SS_MULTICORE_SUPPORT */
2349 /* mt008.301: Terminate the timer thread on exit */
2350 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2360 * Desc: Pre-tst() initialization.
2378 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2382 pthread_attr_t attr;
2385 #endif /* CONSTDIO */
2390 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2396 osCp.dep.conInFp = (FILE *) stdin;
2397 osCp.dep.conOutFp = (FILE *) stdout;
2398 /* added compile time flag CONRD: mt017.21 */
2402 /* disable canonical input processing */
2403 fd = fileno(osCp.dep.conInFp);
2404 if ((tcgetattr(fd, &tio)) != 0)
2406 printf("Error: disable canonical input processing\n");
2410 tio.c_lflag &= ~ICANON;
2411 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2412 tio.c_cc[VTIME] = 0;
2413 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2415 printf("Error: while tcsetattr() processing\n");
2419 #endif /* CONSTDIO */
2422 /* set up the input fd to block when no data is available */
2423 fd = fileno(osCp.dep.conInFp);
2424 flags = fcntl(fd, F_GETFL, &flags);
2425 flags &= ~O_NONBLOCK;
2426 if (fcntl(fd, F_SETFL, flags) == -1)
2428 printf("Error: while fcntl processing\n");
2433 /* create the console handler thread */
2434 pthread_attr_init(&attr);
2435 /* mt021.201 - Addition to set stack size */
2436 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2437 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2438 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2441 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2443 /* mt020.201 - Addition for destroying thread attribute object attr */
2444 pthread_attr_destroy(&attr);
2446 printf("Error: Logging Thread creation failed \n");
2450 /* mt020.201 - Addition for destroying thread attribute object attr */
2451 pthread_attr_destroy(&attr);
2465 * Desc: This function reverses the initialization performed in
2475 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2485 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2489 /* mt008.301: Terminate the console reader on exit */
2490 while(pthread_cancel(osCp.dep.conHdlrTID));
2496 /* mt001.301 : Additions */
2506 S16 ssdInitWatchDog(port)
2511 Txt prntBuf[PRNTSZE];
2514 #ifdef SS_WATCHDOG_IPV6
2515 struct sockaddr_in6 tmpaddr;
2517 struct sockaddr_in tmpaddr;
2518 #endif /* SS_WATCHDOG_IPV6 */
2519 #ifdef SS_MULTIPLE_PROCS
2520 ProcId procId = SS_WD_WDPROC;
2521 if (SAddProcIdLst(1, &procId) != ROK)
2525 #endif /* SS_MULTIPLE_PROCS */
2527 TRC0(ssdInitWatchDog);
2529 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2531 /* Create a watch dog system task */
2532 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2534 /* Create a watch dog reveiver system task */
2535 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2537 /* Register and attach watch dog TAPA task */
2538 #ifdef SS_MULTIPLE_PROCS
2539 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2540 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2542 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2543 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2544 #endif /* SS_MULTIPLE_PROCS */
2545 /* Register and attach watch dog receiver TAPA task */
2546 #ifdef SS_MULTIPLE_PROCS
2547 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2548 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2550 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2551 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2552 #endif /* SS_MULTIPLE_PROCS */
2554 #ifndef SS_MULTIPLE_PROCS
2555 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2556 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2558 osCp.wdCp.watchDgPst.srcProcId = procId;
2559 osCp.wdCp.watchDgPst.dstProcId = procId;
2560 #endif /* SS_MULTIPLE_PROCS */
2562 /* Initialise the pst structure */
2563 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2564 /* Initialize the watch dog timer resolution default is 1 sec */
2566 cmInitTimers(osCp.wdCp.watchDgTmr, (U8)1);
2567 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2568 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2569 for(idx = 0; idx < 1; idx++)
2571 osCp.wdCp.watchDgTs[idx].first = NULLP;
2572 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2574 #ifdef SS_MULTIPLE_PROCS
2575 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2577 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2578 #endif /* SS_MULTIPLE_PROCS */
2580 /* Create the watch dog receiver socket */
2581 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2582 if(osCp.wdCp.globWd.sock == -1)
2584 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2588 #ifdef SS_WATCHDOG_IPV6
2589 tmpaddr.sin6_len = sizeof(tmpadDr);
2590 tmpaddr.sin6_family = AF_INET6;
2591 tmpaddr.sin6_addr = in6addr_any;
2592 tmpaddr.sin6_port = htons(port);
2594 tmpaddr.sin_family = AF_INET;
2595 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2596 tmpaddr.sin_port = htons(port);
2597 #endif /* SS_WATCHDOG_IPV6 */
2599 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2602 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2606 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2610 #ifndef SS_MULTIPLE_PROCS
2611 pst.srcProcId = SFndProcId();
2612 pst.dstProcId = SFndProcId();
2614 pst.srcProcId = procId;
2615 pst.dstProcId = procId;
2616 #endif /* SS_MULTIPLE_PROCS */
2617 pst.event = EVTSSHRTBTREQ;
2618 ssdInitWatchDgPst(&pst);
2619 SPstTsk(&pst, mBuf);
2625 S16 ssdInitWatchDgPst
2630 S16 ssdInitWatchDgPst(pst)
2634 TRC1(ssInitWatchDgPst);
2636 pst->selector = SS_LOOSE_COUPLING;
2638 pst->region = DFLT_REGION; /* region */
2639 pst->pool = DFLT_POOL; /* pool */
2641 pst->prior = PRIOR0; /* priority */
2642 pst->route = RTESPEC; /* route */
2644 pst->dstEnt = ENTHB; /* destination entity */
2646 pst->srcEnt = ENTDW; /* source entity */
2652 #ifdef SS_MULTIPLE_PROCS
2654 S16 ssdWatchDgActvTmr
2661 S16 ssdWatchDgActvTmr(proc, ent, inst)
2665 S16 ssdWatchDgActvTmr
2670 S16 ssdWatchDgActvTmr()
2672 #endif /* SS_MULTIPLE_PROCS */
2674 TRC3(ssWatchDgActvTmr);
2676 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2682 Void ssdWatchDgTmrEvt
2684 PTR cb, /* control block */
2685 S16 event /* timer number */
2688 Void ssdWatchDgTmrEvt(cb, event)
2689 PTR cb; /* control block */
2690 S16 event; /* timer number */
2693 /* mt003.301 Fixed warings */
2697 Txt prntBuf[PRNTSZE];
2701 TRC2(ssWatchDgTmrEvt);
2707 SPrint("Timer Heartbeat Request Expired");
2709 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2714 SLock(&osCp.wdCp.wdLock);
2715 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2717 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2719 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2721 if(osCp.wdCp.globWd.callback != 0)
2723 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2727 SUnlock(&osCp.wdCp.wdLock);
2729 if(!osCp.wdCp.globWd.watchdogStop)
2731 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2732 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2743 Void ssdStartWatchDgTmr
2750 Void ssdStartWatchDgTmr(cb, event, wait)
2760 Txt prntBuf[PRNTSZE];
2764 TRC2(ssStartWatchDgTmr)
2765 /* mt003.301 Modifications */
2768 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2769 if(event == SS_TMR_HRTBT)
2771 SPrint("\nSTART SS_TMR_HRTBT");
2778 SLock(&osCp.wdCp.wdLock);
2779 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2781 osCp.wdCp.globWd.wdsta[i].status = 0;
2783 SUnlock(&osCp.wdCp.wdLock);
2785 arg.tq = osCp.wdCp.watchDgTs;
2786 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2787 arg.timers = osCp.wdCp.watchDgTmr;
2788 arg.cb = (PTR)NULLP;
2790 arg.wait = osCp.wdCp.globWd.timeout = wait;
2799 Void ssdStopWatchDgTmr
2805 Void ssdStopWatchDgTmr(cb, event)
2813 Txt prntBuf[PRNTSZE];
2817 TRC2(ssStopWatchDgTmr)
2818 /* mt003.301 Modifications */
2821 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2822 if(event == SS_TMR_HRTBT)
2824 SPrint("STOP SS_TMR_HRTBT");
2828 SLock(&osCp.wdCp.wdLock);
2829 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2831 osCp.wdCp.globWd.wdsta[i].status = 0;
2833 SUnlock(&osCp.wdCp.wdLock);
2836 arg.tq = osCp.wdCp.watchDgTs;
2837 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2838 arg.timers = osCp.wdCp.watchDgTmr;
2839 arg.cb = (PTR)NULLP;
2856 S16 ssdSndHrtBtMsg(restart, type)
2864 Txt prntBuf[PRNTSZE];
2866 struct sockaddr_in tmpaddr;
2867 char hbMsg[SS_WD_HB_MSG_SIZE];
2871 TRC2(ssdSndHrtBtReq)
2875 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2879 /* Pack the message */
2880 strcpy(hbMsg, "<HB>REQ</HB>");
2882 /* Send the heartbeat messages to all the configured nodes */
2883 SLock(&osCp.wdCp.wdLock);
2884 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2886 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2891 /* Identify the destination node */
2892 #ifdef SS_WATCHDOG_IPV6
2893 tmpaddr.sin6_len = sizeof(tmpaddr);
2894 tmpaddr.sin6_family = AF_INET6;
2895 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2896 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2898 tmpaddr.sin_family = AF_INET;
2899 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2900 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2901 #endif /* SS_WATCHDOG_IPV6 */
2903 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2907 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2908 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2915 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2920 SUnlock(&osCp.wdCp.wdLock);
2925 #endif /* SS_WATCHDOG */
2929 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2935 * Desc: This function gets command line options.
2945 PRIVATE Void mtGetOpts
2950 PRIVATE Void mtGetOpts()
2958 FILE *memOpt; /* memory options file pointer */
2961 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2967 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2969 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2975 #ifdef SS_LOCKLESS_MEMORY
2991 osCp.dep.fileOutFp = (FILE *)NULLP;
2993 /* initialize memOpt */
2994 memOpt = (FILE *) NULLP;
3001 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
3006 /* mt001.301 : Additions */
3007 #ifdef SS_MEM_LEAK_STS
3009 cmMemOpenMemLkFile(msOptArg);
3013 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3016 fileBasedMemCfg = TRUE;
3017 memOpt = fopen(msOptArg, "r");
3019 /* if file does not exist or could not be opened then use the
3020 * default memory configuration as defined in mt_ss.h
3022 if (memOpt == (FILE *) NULLP)
3024 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3025 be opened, using default mem configuration\n", msOptArg);
3030 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3032 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3038 case 0: /*** INPUT: Number of regions ***/
3039 sscanf(line, "%ld", (long *) &numReg);
3040 mtMemoCfg.numRegions = numReg;
3041 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3043 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3049 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3050 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3051 if(numBkts > MT_MAX_BKTS)
3053 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3057 if(numPools > SS_MAX_POOLS_PER_REG)
3059 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3064 * Delay updation from local variable to global
3065 * structure of number of regions and heap data to
3066 * counter error conditions present above.
3068 for(idx = 0; idx < cfgNumRegs; idx++)
3070 mtMemoCfg.region[idx].numBkts = numBkts;
3071 cfgRegInfo[idx].region = idx;
3072 cfgRegInfo[idx].numPools = numPools;
3074 * Initialize the pool info as static type with size zero
3076 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3078 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3079 cfgRegInfo[idx].pools[poolIdx].size = 0;
3084 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3085 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3087 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3089 if(bktIdx >= numBkts)
3091 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3096 mtBktInfo[bktIdx].blkSize = bktSz;
3098 if(bktUpdtCnt == numBkts)
3100 i++; /*done reading bkt info, start reading individual region info*/
3104 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3105 sscanf(line,"%ld",(long *) ®Id);
3106 if(regId >= mtMemoCfg.numRegions)
3108 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3109 #ifndef XEON_SPECIFIC_CHANGES
3114 mtMemoCfg.region[regId].regionId = regId;
3117 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3118 if(bktUpdtCnt < numBkts)
3120 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3121 if(bktIdx >= numBkts)
3123 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3128 if(bktIdx < MT_MAX_BKTS)
3130 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3131 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3132 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3133 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3136 if(bktUpdtCnt == numBkts)
3143 case 5: /* INPUT: Heapsize ***/
3144 sscanf(line, "%ld", (long *) &heapSz);
3145 mtMemoCfg.region[regId].heapsize = heapSz;
3147 if(regUpdtCnt != mtMemoCfg.numRegions)
3156 #ifdef SS_LOCKLESS_MEMORY
3158 sscanf(line, "%ld", (long *) &numBkts);
3159 mtGlobMemoCfg.numBkts = numBkts;
3160 #ifndef XEON_SPECIFIC_CHANGES
3161 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3164 #ifdef XEON_SPECIFIC_CHANGES
3165 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3166 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3167 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3169 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3172 mtDynMemoCfg.region[idx].regionId = idx;
3173 mtDynMemoCfg.region[idx].numBkts = numBkts;
3181 if(bktUpdtCnt < numBkts)
3183 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3184 (long *) &bktSz, (long *) &bktNum,
3185 (long *) &bktSetSize, (long *) &bktRelThr,
3186 (long *) &bktAqurThr);
3187 /* Klock work fix ccpu00148484 */
3188 if(bktIdx < SS_MAX_POOLS_PER_REG)
3190 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3191 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3192 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3193 #ifdef XEON_SPECIFIC_CHANGES
3194 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3195 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3196 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3198 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3200 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3206 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3208 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3209 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3210 #ifdef XEON_SPECIFIC_CHANGES
3211 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3212 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3213 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3219 #ifdef XEON_SPECIFIC_CHANGES
3220 if(bktUpdtCnt == numBkts)
3226 case 8: /* INPUT: Global Heapsize ***/
3227 sscanf(line, "%ld", (long *) &heapSz);
3228 mtGlobMemoCfg.heapSize = heapSz;
3229 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3237 memConfigured = FALSE;
3241 memConfigured = TRUE;
3249 /* mt028.201: modification: multiple procs support related changes */
3250 #ifndef SS_MULTIPLE_PROCS
3253 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3255 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3258 #else /* SS_MULTIPLE_PROCS */
3262 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3264 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3266 SAddProcIdLst(1, &procId);
3269 #endif /* SS_MULTIPLE_PROCS */
3273 osCp.configFilePath = msOptArg;
3297 * Desc: Get options from command line
3299 * Ret: option - success
3301 * EOF - end of options
3303 * Notes: Handles command lines like the following
3306 * then command line should look like this...
3307 * -a foo -b foo1 -c -d foo
3311 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3316 * nloops = atoi(msArgv[msOptInd]);
3319 * state1 = atoi(msArgv[msOptInd]);
3332 int argc, /* argument count */
3333 char **argv, /* argument value */
3334 char *opts /* options */
3337 S16 SGetOpt(argc, argv, opts)
3338 int argc; /* argument count */
3339 char **argv; /* argument value */
3340 char *opts; /* options */
3343 /* mt020.201 - Removed for no command line */
3352 /* mt020.201 - Addition for no command line */
3364 /*mt013.301 : Changes as per coding standards*/
3365 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3371 if (!strcmp(argv[msOptInd], "--"))
3376 else if (argv[msOptInd][0] != '-')
3384 c = argv[msOptInd][sp];
3385 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3387 if (argv[msOptInd][++sp] == '\0')
3398 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3401 if (++msOptInd >= (S16) argc)
3406 else msOptArg = argv[msOptInd++];
3413 if (argv[msOptInd][++sp] == '\0')
3425 #endif /* NOCMDLINE */
3433 * Desc: This function starts system services execution; the
3434 * permanent tasks are started and the system enters a
3459 /* mt025.201 - Modification for adding lock to timer handler */
3460 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3462 sem_post(&osCp.dep.ssStarted);
3471 * indirect interface functions to system services service user
3477 * Fun: ssdAttachTTsk
3479 * Desc: This function sends the initial tick message to a TAPA
3480 * task if the task is a permanent task.
3492 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3495 S16 ssdAttachTTsk(tTsk)
3496 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3504 TRC0(ssdAttachTTsk);
3507 if (tTsk->tskType == SS_TSK_PERMANENT)
3509 /* Send a permanent tick message to this task, to start
3512 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3515 #if (ERRCLASS & ERRCLS_DEBUG)
3516 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3521 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3522 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3524 /* set up post structure */
3525 /* mt028.201: modification: multiple procs support related changes */
3526 #ifndef SS_MULTIPLE_PROCS
3527 mInfo->pst.dstProcId = SFndProcId();
3528 mInfo->pst.srcProcId = SFndProcId();
3529 #else /* SS_MULTIPLE_PROCS */
3530 mInfo->pst.dstProcId = tTsk->proc;
3531 mInfo->pst.srcProcId = tTsk->proc;
3532 #endif /* SS_MULTIPLE_PROCS */
3533 mInfo->pst.selector = SEL_LC_NEW;
3534 mInfo->pst.region = DFLT_REGION;
3535 mInfo->pst.pool = DFLT_POOL;
3536 mInfo->pst.prior = PRIOR3;
3537 mInfo->pst.route = RTESPEC;
3538 mInfo->pst.event = 0;
3539 mInfo->pst.dstEnt = tTsk->ent;
3540 mInfo->pst.dstInst = tTsk->inst;
3541 mInfo->pst.srcEnt = tTsk->ent;
3542 mInfo->pst.srcInst = tTsk->inst;
3544 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3545 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3551 #if (ERRCLASS & ERRCLS_DEBUG)
3552 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3553 "Could not write to demand queue");
3566 * Fun: ssdDetachTTsk
3568 * Desc: Does nothing.
3580 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3583 S16 ssdDetachTTsk(tTsk)
3584 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3587 TRC0(ssdDetachTTsk);
3596 * Fun: ssdCreateSTsk
3598 * Desc: This function creates a system task. A thread is started
3599 * on the system task handler function defined later.
3611 SsSTskEntry *sTsk /* pointer to system task entry */
3614 S16 ssdCreateSTsk(sTsk)
3615 SsSTskEntry *sTsk; /* pointer to system task entry */
3619 pthread_attr_t attr;
3620 /* struct sched_param param_sched;*/
3622 #ifdef SS_THR_REG_MAP
3623 U32 threadCreated = FALSE;
3626 TRC0(ssdCreateSTsk);
3629 #ifdef SS_SINGLE_THREADED
3630 /* mt001.301 : Additions */
3632 #ifdef SS_MULTICORE_SUPPORT
3633 if (osCp.numSTsks > 1)
3635 if (osCp.numSTsks > 0)
3636 #endif /* SS_MULTICORE_SUPPORT */
3638 #ifdef SS_MULTICORE_SUPPORT
3639 if (osCp.numSTsks > 3)
3641 if (osCp.numSTsks > 2)
3642 #endif /* SS_MULTICORE_SUPPORT */
3643 #endif /* SS_WATCHDOG */
3650 /* set the current executing entity and instance IDs to
3651 * 'not configured'. create the lock to access them.
3653 sTsk->dep.ent = ENTNC;
3654 sTsk->dep.inst = INSTNC;
3657 /* create the thread */
3658 pthread_attr_init(&attr);
3659 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3661 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3662 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3663 if (sTsk->tskPrior == 0)
3665 printf("Creating RT thread #######################\n");
3666 #ifdef SS_THR_REG_MAP
3667 /* When the thread is created, we check for the memory mapping table if
3668 * threadId can be placed in thread memory map table. If it is not able to place
3669 * threadId is stored in tmporary array. Once thread is created successful,
3670 * thread_cancel is sent for each thread which are created before. All the
3671 * threads are made to wait on sema which is cancel point for thread.
3673 while(threadCreated == FALSE)
3676 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3679 DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3680 pthread_attr_destroy(&attr);
3682 #if (ERRCLASS & ERRCLS_DEBUG)
3683 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3688 #ifdef SS_THR_REG_MAP
3689 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3697 #ifdef SS_THR_REG_MAP
3698 /* When the thread is created, we check for the memory mapping table if
3699 * threadId can be placed in thread memory map table. If it is not able to place
3700 * threadId is stored in tmporary array. Once thread is created successful,
3701 * thread_cancel is sent for each thread which are created before. All the
3702 * threads are made to wait on sema which is cancel point for thread.
3704 while(threadCreated == FALSE)
3707 ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3711 /* mt020.201 - Addition for destroying thread attribute object attr */
3712 pthread_attr_destroy(&attr);
3714 #if (ERRCLASS & ERRCLS_DEBUG)
3715 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3720 #ifdef SS_THR_REG_MAP
3721 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3728 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3729 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3731 static U32 stLwpId = 3;
3732 sTsk->dep.lwpId = ++stLwpId;
3734 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3736 /* mt020.201 - Addition for destroying thread attribute object attr */
3737 pthread_attr_destroy(&attr);
3747 pthread_attr_t* attr,
3748 void *(*start_routine) (void *),
3752 int SCreatePThread(tid, attr, start_routine, arg)
3754 pthread_attr_t* attr;
3755 void *(*start_routine) (void *);
3760 #ifdef SS_THR_REG_MAP
3761 U32 threadCreated = FALSE;
3764 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3765 /* Klock work fix ccpu00148484 */
3766 if(threadArg == NULLP)
3770 threadArg->argument = arg;
3771 threadArg->start_routine = start_routine;
3773 TRC0(SCreatePThread);
3775 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3777 #ifdef SS_THR_REG_MAP
3778 /* When the thread is created, we check for the memory mapping table if
3779 * threadId can be placed in thread memory map table. If it is not able to place
3780 * threadId is stored in tmporary array. Once thread is created successful,
3781 * thread_cancel is sent for each thread which are created before. All the
3782 * threads are made to wait on sema which is cancel point for thread.
3784 while(threadCreated == FALSE)
3787 /*pthreadCreateHdlr */
3788 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3793 #ifdef SS_THR_REG_MAP
3794 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3805 * Fun: Set Pthread Attributes
3807 * Desc: This function is used to set various explicit
3808 * pthread attributes like, priority scheduling,etc
3819 PRIVATE S16 ssdSetPthreadAttr
3822 pthread_attr_t *attr
3825 PRIVATE S16 ssdSetPthreadAttr(sTsk, attr)
3827 pthread_attr_t *attr
3830 struct sched_param param;
3832 TRC0 (ssdSetPthreadAttr)
3834 SMemSet(¶m, 0, sizeof(param));
3836 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3837 param.sched_priority = 100 - 1 - tskPrior;
3839 param.sched_priority = 100 - 10 - tskPrior;
3842 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3843 /* TODO:: This can be avoided by reducing the priority
3844 * of iccserv thread in l1_master.sh*/
3846 if (clusterMode == RADIO_CLUSTER_MODE)
3848 if(tskPrior == PRIOR1)
3850 param.sched_priority = 91;
3857 printf("Set priority %u\n", param.sched_priority);
3859 /* Set Scheduler to explicit, without this non of the below
3860 pthread attr works */
3861 #ifdef TENB_RTLIN_CHANGES
3862 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3865 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3866 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3867 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3868 #ifdef TENB_RTLIN_CHANGES
3869 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3871 pthread_attr_setschedparam(attr, ¶m);
3875 } /* ssdSetPthreadAttr */
3877 /************* multi-core support **************/
3878 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3879 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3883 * Fun: Get the current core/cpu affinity for a thread/lwp
3885 * Desc: This function is used to get the current processor/core
3886 * affinity for a a system task (thread/lwp). It sets the
3887 * affinity based on the mode supplied by the caller.
3890 * RFAILED - failed, general (optional)
3900 SSTskId *tskId, /* filled in with system task ID */
3901 U32 *coreId /* the core/processor id to which the affinity is set */
3904 S16 ssdGetAffinity(tskId, coreId)
3905 SSTskId *tskId; /* filled in with system task ID */
3906 U32 *coreId; /* the core/processor id to which the affinity is set */
3917 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3923 TRC0(ssdGetAffinity);
3925 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3927 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3929 tId = osCp.sTskTbl[tskInd].dep.tId;
3934 /* if tskId is not found in the tskTbl */
3935 if (tskInd == SS_MAX_STSKS)
3937 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3942 /* initialize the cpu mask */
3945 /* set thread affinity for linux */
3946 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3948 #if (ERRCLASS & ERRCLS_DEBUG)
3949 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3952 } /* end if pthread_setaffinity fails */
3954 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3956 if (CPU_ISSET (cpuInd, & cpuSet))
3965 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3967 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3969 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3974 /* if tskId is not found in the tskTbl */
3975 if (tskInd == SS_MAX_STSKS)
3977 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3981 /* set thread affinity for Solaris */
3982 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3984 #if (ERRCLASS & ERRCLS_DEBUG)
3985 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3988 } /* end if processor_bind fails */
3991 #endif /* SS_LINUX */
3995 } /* ssdGetAffinity */
4000 * Fun: Set the core/cpu affinity for a thread/lwp
4002 * Desc: This function is used to set processor/core affinity for a
4003 * a system task (thread/lwp). It sets the affinity based on the
4004 * mode supplied by the caller.
4007 * RFAILED - failed, general (optional)
4017 SSTskId *tskId, /* filled in with system task ID */
4018 U32 coreId /* the core/processor id to which the affinity has to be set */
4021 S16 ssdSetAffinity(tskId, coreId)
4022 SSTskId *tskId; /* filled in with system task ID */
4023 U32 coreId; /* the core/processor id to which the affinity has to be set */
4032 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4039 TRC0(ssdSetAffinity)
4042 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4044 /* Here tskId can not be used as index as the task may be terminated if
4045 there is a TERM even for that tsk, thus breaking the task Id numbering
4047 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4049 tId = osCp.sTskTbl[tskInd].dep.tId;
4054 /* if tskId is not found in the tskTbl */
4055 if (tskInd == SS_MAX_STSKS)
4057 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4061 /* initialize the cpu mask */
4064 /* set the cpu mask */
4065 CPU_SET(coreId, &cpuSet);
4067 /* set thread affinity for linux */
4068 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4070 #if (ERRCLASS & ERRCLS_DEBUG)
4071 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4074 } /* end if pthread_setaffinity fails */
4078 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4080 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4081 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4083 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4088 /* if tskId is not found in the tskTbl */
4089 if (tskInd == SS_MAX_STSKS)
4091 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4095 /* set thread affinity for Solaris */
4096 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4098 #if (ERRCLASS & ERRCLS_DEBUG)
4099 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4102 } /* end if processor_bind fails */
4105 #endif /* SS_LINUX */
4107 } /* ssdSetAffinity */
4109 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4110 /************ end multi-core support *************/
4115 * Fun: ssdDestroySTsk
4117 * Desc: This function destroys a system task. A terminate
4118 * event message is sent to the thread function.
4130 SsSTskEntry *sTsk /* pointer to system task entry */
4133 S16 ssdDestroySTsk(sTsk)
4134 SsSTskEntry *sTsk; /* pointer to system task entry */
4141 TRC0(ssdDestroySTsk);
4144 /* we send a message to this system task to tell it to die */
4145 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4148 #if (ERRCLASS & ERRCLASS_DEBUG)
4149 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4155 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4156 mInfo->eventInfo.event = SS_EVNT_TERM;
4158 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4162 #if (ERRCLASS & ERRCLASS_DEBUG)
4163 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4164 "Could not write to demand queue");
4174 /* mt023.201 - Added SThreadYield function to yield CPU
4178 * Desc: This function defers thread execution to any other ready
4201 /* mt024.201 - seperated Linux and other UNIX implementations
4207 /* Set sleep value to 0 to yield CPU */
4211 return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4213 #else /* other UNICes */
4215 return (sleep(0) == 0 ? ROK : RFAILED);
4217 #endif /* SS_LINUX */
4224 * Fun: Register timer
4226 * Desc: This function is used to register a timer
4227 * function for the service user. System services
4228 * will invoke the timer activation function
4229 * passed to it at the specified intervals.
4233 * Notes: Timing is handled by the common timers. The
4234 * ticks are handled by a thread that uses
4235 * nanosleep() and thus timing precision will not
4244 SsTmrEntry *tmr /* pointer to timer entry */
4248 SsTmrEntry *tmr; /* pointer to timer entry */
4257 /* initialize common timers */
4258 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4261 /* start the timer */
4262 arg.tq = osCp.dep.tmrTq;
4263 arg.tqCp = &osCp.dep.tmrTqCp;
4264 arg.timers = tmr->dep.timers;
4269 arg.max = TMR_DEF_MAX;
4270 arg.wait = tmr->interval;
4280 * Fun: Deregister timer
4282 * Desc: This function is used to deregister a timer function.
4294 SsTmrEntry *tmr /* pointer to timer entry */
4297 S16 ssdDeregTmr(tmr)
4298 SsTmrEntry *tmr; /* pointer to timer entry */
4307 /* stop the timer */
4308 arg.tq = osCp.dep.tmrTq;
4309 arg.tqCp = &osCp.dep.tmrTqCp;
4310 arg.timers = tmr->dep.timers;
4315 arg.max = TMR_DEF_MAX;
4316 arg.wait = tmr->interval;
4326 * Fun: Critical error
4328 * Desc: This function is called when a critical error occurs.
4340 Seq seq, /* sequence number */
4341 Reason reason /* reset reason */
4344 S16 ssdError(seq, reason)
4345 Seq seq; /* sequence number */
4346 Reason reason; /* reset reason */
4357 /* get calling task ID */
4358 tId = pthread_self();
4361 /* set up the message to display */
4362 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4363 "reason = %d\n\n", (U8)tId, seq, reason);
4367 /* delete all system tasks */
4368 for (i = 0; i < SS_MAX_STSKS; i++)
4370 if (osCp.sTskTbl[i].used
4371 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4373 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4379 pthread_exit(NULLP);
4382 /* won't reach here */
4391 * Desc: This function is called to log an error.
4403 Ent ent, /* Calling layer's entity id */
4404 Inst inst, /* Calling layer's instance id */
4405 ProcId procId, /* Calling layer's processor id */
4406 Txt *file, /* file name where error occured */
4407 S32 line, /* line in file where error occured */
4408 ErrCls errCls, /* error class */
4409 ErrCode errCode, /* layer unique error code */
4410 ErrVal errVal, /* error value */
4411 Txt *errDesc /* description of error */
4414 Void ssdLogError(ent, inst, procId, file, line,
4415 errCls, errCode, errVal, errDesc)
4416 Ent ent; /* Calling layer's entity id */
4417 Inst inst; /* Calling layer's instance id */
4418 ProcId procId; /* Calling layer's processor id */
4419 Txt *file; /* file name where error occured */
4420 S32 line; /* line in file where error occured */
4421 ErrCls errCls; /* error class */
4422 ErrCode errCode; /* layer unique error code */
4423 ErrVal errVal; /* error value */
4424 Txt *errDesc; /* description of error */
4438 /* get calling task ID */
4440 tId = pthread_self();
4446 case ERRCLS_ADD_RES:
4447 errClsMsg = "ERRCLS_ADD_RES";
4450 case ERRCLS_INT_PAR:
4451 errClsMsg = "ERRCLS_INT_PAR";
4455 errClsMsg = "ERRCLS_DEBUG";
4458 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4460 errClsMsg = "ERRCLS_FTHA";
4464 errClsMsg = "INVALID ERROR CLASS!";
4469 /*mt009.301 Fixed 64BIT compilation warnings*/
4472 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4473 "file: %s line: %03d errcode: %05d errcls: %s\n"
4474 "errval: %05d errdesc: %s\n",
4475 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4478 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4479 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4480 "errval: %05ld errdesc: %s\n",
4481 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4483 SDisplay(0, errBuf);
4484 /* mt001.301 : Additions */
4485 #ifdef SS_LOGGER_SUPPORT
4487 #endif /* SS_LOGGER_SUPPORT */
4491 /* debug errors halt the system */
4492 if (errCls == ERRCLS_DEBUG)
4494 /* mt001.301 : Additions */
4495 #ifdef SS_LOGGER_SUPPORT
4497 #endif /* SS_LOGGER_SUPPORT */
4498 /* delete all system tasks */
4499 for (i = 0; i < SS_MAX_STSKS; i++)
4501 if (osCp.sTskTbl[i].used
4502 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4504 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4510 pthread_exit(NULLP);
4522 * Fun: Register driver task
4524 * Desc: This function is called to register the handlers for a
4537 SsDrvrTskEntry *drvrTsk /* driver task entry */
4540 S16 ssdRegDrvrTsk(drvrTsk)
4541 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4544 TRC0(ssdRegDrvrTsk);
4549 /* mt001.30 : Additions */
4552 * Fun: Deregister driver task
4554 * Desc: This function is called to deregister the handlers for a
4567 SsDrvrTskEntry *drvrTsk /* driver task entry */
4570 S16 ssdDeregDrvrTsk(drvrTsk)
4571 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4574 TRC0(ssdDeregDrvrTsk);
4585 * mt003.301 Additions - SDeRegTTsk fix
4587 #ifdef SS_MULTIPLE_PROCS
4596 S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4601 #else /*SS_MULTIPLE_PROCS*/
4609 S16 ssdProcTTskTerm(tTsk, idx)
4613 #endif /*SS_MULTIPLE_PROCS*/
4615 #ifdef SS_MULTIPLE_PROCS
4624 TRC0(ssdProcTTskTerm);
4629 /* We check the sTsk element; if it is not NULLP, the
4630 * task is attached. So we have to detach it before
4631 * deregistering the task.
4633 ret = SLock(&osCp.sTskTblLock);
4636 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4639 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4642 #if (ERRCLASS & ERRCLS_DEBUG)
4643 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4645 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4647 #if (ERRCLASS & ERRCLS_DEBUG)
4648 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4656 #ifdef SS_MULTIPLE_PROCS
4658 if (tTsk->initTsk != NULLP)
4661 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4664 &(osCp.tTskTbl[idx].xxCb));
4666 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4669 &(osCp.tTskTbl[idx].xxCb));
4670 #endif /* USE_MEMCAL */
4672 #endif /* SS_MULTIPLE_PROCS */
4674 if (tTsk->sTsk != NULLP)
4678 sTsk->dep.ent = ent;
4679 sTsk->dep.inst = inst;
4681 for (n = 0; n < SS_MAX_TTSKS; n++)
4683 if (sTsk->tTsks[n] == idx)
4685 sTsk->tTsks[n] = SS_INVALID_IDX;
4691 /* call the implementation to detach the task */
4692 ssdDetachTTsk(tTsk);
4694 sTsk->dep.ent = ENTNC;
4695 sTsk->dep.inst = INSTNC;
4698 /* Now we empty the entry for this task and update the table
4701 #ifdef SS_MULTIPLE_PROCS
4702 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4703 #else /* SS_MULTIPLE_PROCS */
4704 osCp.tTskIds[ent][inst] = SS_TSKNC;
4705 #endif /* SS_MULTIPLE_PROCS */
4708 #ifdef SS_MULTIPLE_PROCS
4709 tTsk->proc = PROCNC;
4710 #endif /* SS_MULTIPLE_PROCS */
4712 tTsk->inst = INSTNC;
4713 tTsk->tskType = TTUND;
4714 tTsk->initTsk = NULLP;
4715 tTsk->actvTsk = NULLP;
4718 tTsk->nxt = osCp.nxtTTskEntry;
4719 osCp.nxtTTskEntry = idx;
4722 #ifdef SS_MULTIPLE_PROCS
4723 /* mark the control block for this task as invalid */
4724 osCp.tTskTbl[idx].xxCb = NULLP;
4727 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4728 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4730 #if (ERRCLASS & ERRCLS_DEBUG)
4731 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4738 //#ifndef SPLIT_RLC_DL_TASK
4739 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4740 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4741 EXTERN Void ysMtTskHdlr(Void);
4742 EXTERN Void ysMtPollPhyMsg(U8 region);
4743 EXTERN Void ysMtRcvPhyMsg(Void);
4745 Void *mtTskHdlrT2kL2
4747 Ptr tskPtr /* pointer to task entry */
4750 Void *mtTskHdlrT2kL2(tskPtr)
4751 Ptr tskPtr; /* pointer to task entry */
4757 /* wait for SS to come up */
4758 /* It is required to block on this semaphore before starting actual processing of
4759 the thread becasue the creator of this thread might want to cance it without
4760 doing any processing. When this semaphore is released, means the creator gives
4761 the go ahead for actual processing and we should never come back to this point */
4762 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4771 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4772 * (processes L1 msgs) */
4778 EXTERN Void ysMtTskHdlr(Void);
4779 EXTERN Void YsPhyRecvMsg();
4781 Void *mtTskHdlrT2kL2
4783 Ptr tskPtr /* pointer to task entry */
4786 Void *mtTskHdlrT2kL2(tskPtr)
4787 Ptr tskPtr; /* pointer to task entry */
4793 /* get out the system task entry from the parameter */
4794 sTsk = (SsSTskEntry *) tskPtr;
4796 /* wait for SS to come up */
4797 /* It is required to block on this semaphore before starting actual processing of
4798 the thread becasue the creator of this thread might want to cance it without
4799 doing any processing. When this semaphore is released, means the creator gives
4800 the go ahead for actual processing and we should never come back to this point */
4801 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4804 #ifndef RGL_SPECIFIC_CHANGES
4812 #ifdef V5GTF_SPECIFIC_CHANGES
4815 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4816 * (processes L1 msgs) */
4818 /* get a message from the demand queue */
4820 #ifdef RLC_MAC_DAT_REQ_RBUF
4821 rgDlDatReqBatchProc();
4824 ret = mtTskHdlMsg(sTsk);
4827 /* exit the for loop here */
4830 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4837 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4841 void *pthreadCreateHdlr
4846 void *pthreadCreateHdlr(pthreadCreateArg)
4851 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4852 /* mt038.201 changed how sem_wait is called */
4853 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4856 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4864 * Desc: This is the system task handler function. It blocks on
4865 * the system task's demand queue. On receiving a message,
4866 * it identifies the target TAPA task, verifies that the
4867 * TAPA task belongs to this system task and if so, calls
4868 * the activation function of that TAPA task with the
4869 * received message. The task activation function or the
4870 * timer activation function may be called.
4872 * Ret: (thread function)
4882 Ptr tskPtr /* pointer to task entry */
4885 Void *mtTskHdlr(tskPtr)
4886 Ptr tskPtr; /* pointer to task entry */
4892 /* get out the system task entry from the parameter */
4893 sTsk = (SsSTskEntry *) tskPtr;
4896 /* wait for SS to come up */
4898 /* mt038.201 changed how sem_wait is called */
4899 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4901 #ifdef XEON_SPECIFIC_CHANGES
4902 printf("\n**********MT Task Handler********\n");
4906 #ifndef ODU_TEST_STUB
4911 /* Wait for a message from the demand queue */
4912 #ifdef SS_CDMNDQ_SUPPORT
4913 ret = ssCDmndQWait(&sTsk->dQ);
4915 ret = ssDmndQWait(&sTsk->dQ);
4920 ret = mtTskHdlMsg(sTsk);
4935 * Desc: This is the system task handler function. It blocks on
4936 * the system task's demand queue. On receiving a message,
4937 * it identifies the target TAPA task, verifies that the
4938 * TAPA task belongs to this system task and if so, calls
4939 * the activation function of that TAPA task with the
4940 * received message. The task activation function or the
4941 * timer activation function may be called.
4943 * Ret: (thread function)
4956 S16 mtTskHdlMsg(sTsk)
4970 /* mt028.201: modification: multiple procs support related changes */
4971 #ifndef SS_MULTIPLE_PROCS
4973 PAIFTMRS16 tmrActvFnMt = NULLP;
4975 /* mt015.301 Initialized the timer activation functions with NULLP */
4976 PFS16 tmrActvFn = NULLP;
4978 PAIFTMRS16 tmrActvFn;
4980 #endif /* SS_MULTIPLE_PROCS */
4981 /* mt003.301 Modifications */
4982 #ifdef SS_THREAD_PROFILE
4984 #endif /* SS_THREAD_PROFILE */
4987 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4990 /* nothing to receive */
4994 /* if we can't lock this system task entry, return the message */
4995 ret = SLock(&sTsk->lock);
4999 #if (ERRCLASS & ERRCLS_DEBUG)
5000 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
5001 "Could not lock system task entry");
5011 mBuf2 = mBuf->b_next;
5013 /* find out what kind of message this is */
5014 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5015 #ifdef SS_MEM_WL_DEBUG
5016 mtTskBuffer1 = mBuf2;
5018 mtTskBuffer2 = mBuf2->b_next;
5020 if(mInfo == 0x5050505)
5024 cmAnalyseBtInfo((PTR) mBuf,4);
5026 printf("\n In trouble .... \n");
5028 else if (mInfo == 0x2020202)
5031 cmAnalyseBtInfo((PTR) mBuf,1);
5032 printf("\n In trouble .... \n");
5034 #endif /* SS_MEM_WL_DEBUG */
5035 switch (mInfo->eventInfo.event)
5037 /* this is a termination event, we die */
5039 /* release the message */
5042 /* Unlock the system task entry and lock the system
5043 * task table to clean our entry up.
5045 SUnlock(&sTsk->lock);
5047 ret = SLock(&osCp.sTskTblLock);
5051 #if (ERRCLASS & ERRCLS_DEBUG)
5052 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5053 "Could not lock system task table");
5055 /* what to do here? */
5059 /* clean up the system task entry */
5062 /* mt003.301 Modifications - SDeRegTTsk */
5063 /* sTsk->numTTsks = 0; */
5064 SDestroyLock(&sTsk->lock);
5065 ssDestroyDmndQ(&sTsk->dQ);
5067 /* lock for current executing TAPA task ID */
5069 /* make this entry available in the system task table */
5070 sTsk->nxt = osCp.nxtSTskEntry;
5071 for (i = 0; i < SS_MAX_STSKS; i++)
5073 if (sTsk == &osCp.sTskTbl[i])
5075 osCp.nxtSTskEntry = i;
5082 /* unlock the system task table */
5083 SUnlock(&osCp.sTskTblLock);
5088 /* this is a data message or a permanent task keep-alive message */
5090 case SS_EVNT_PERMTICK:
5091 /* message to a task. find the destination task */
5092 /* mt028.201: modification: multiple procs support related changes */
5093 #ifdef SS_MULTIPLE_PROCS
5094 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5096 if (procIdIdx == SS_INV_PROCID_IDX)
5102 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5103 #else /* SS_MULTIPLE_PROCS */
5104 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5105 #endif /* SS_MULTIPLE_PROCS */
5107 /* verify that it hasn't been deregistered */
5108 if (idx == SS_TSKNC)
5114 /* verify that this system task is still running it */
5115 tTsk = &osCp.tTskTbl[idx];
5116 if (tTsk->sTsk != sTsk)
5122 /* set the current executing TAPA task ID */
5123 sTsk->dep.ent = mInfo->pst.dstEnt;
5124 sTsk->dep.inst = mInfo->pst.dstInst;
5126 /* copy the Pst structure into a local duplicate */
5127 for (i = 0; i < (S16) sizeof(Pst); i++)
5128 *(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
5130 /* Give the message to the task activation function. If
5131 * its a normal data message, we pass it, if this is a
5132 * keep-alive message for a permanent task then we pass
5133 * NULLP in place of the message to the task activation
5136 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5138 #ifndef RGL_SPECIFIC_CHANGES
5139 #ifdef SS_TSKLOG_ENABLE
5140 U32 t = MacGetTick();
5143 /* mt003.301 Modifications */
5144 #if SS_THREAD_PROFILE
5145 tTsk->curEvent = nPst.event;
5147 #endif /* SS_THREAD_PROFILE */
5148 tTsk->actvTsk(&nPst, mBuf);
5149 #ifndef RGL_SPECIFIC_CHANGES
5150 #ifdef SS_TSKLOG_ENABLE
5151 SStopTask(t,PID_SSI_TSK);
5154 #if SS_THREAD_PROFILE
5156 tTsk->curEvtTime = (U32)(et2 - et1);
5157 tTsk->totTime += (U64)tTsk->curEvtTime;
5158 #endif /* SS_THREAD_PROFILE */
5162 #if (ERRCLASS & ERRCLS_DEBUG)
5163 /* this message should only come to a permanent task */
5164 if (tTsk->tskType != SS_TSK_PERMANENT)
5166 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5170 tTsk->actvTsk(&nPst, NULLP);
5172 /* We need to re-send this message back to ourselves so
5173 * the permanent task continues to run.
5175 /* Check if this task got deregistered or detached
5176 * by the activation function; if so, there's nothing
5177 * more to do here, otherwise go ahead.
5180 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5182 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5183 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5187 /* failure here is a real problem */
5190 #if (ERRCLASS & ERRCLS_DEBUG)
5191 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5192 "Could not write to demand queue");
5198 /* unset the current executing TAPA task ID */
5199 sTsk->dep.ent = ENTNC;
5200 sTsk->dep.inst = INSTNC;
5205 /* timer event. find the timer entry */
5206 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5208 /* lock the timer table, coz we're going to peek in it */
5209 ret = SLock(&osCp.tmrTblLock);
5213 #if (ERRCLASS & ERRCLS_DEBUG)
5214 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5215 "Could not lock timer table");
5221 /* Verify that this timer entry is still around and that it
5222 * belongs to our task.
5224 if (osCp.tmrTbl[idx].used == FALSE
5225 /* mt028.201: modification: multiple procs support related changes */
5226 #ifdef SS_MULTIPLE_PROCS
5227 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5228 #endif /* SS_MULTIPLE_PROCS */
5229 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5230 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5232 SUnlock(&osCp.tmrTblLock);
5237 /* mt005.21: addition */
5238 /* set the current executing TAPA task ID */
5239 sTsk->dep.ent = mInfo->pst.dstEnt;
5240 sTsk->dep.inst = mInfo->pst.dstInst;
5242 #ifndef SS_MULTIPLE_PROCS
5244 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5245 tmrActvFnMt = NULLP;
5246 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5248 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5254 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5257 /* unlock the timer table */
5258 SUnlock(&osCp.tmrTblLock);
5260 /* activate the timer function */
5261 /* mt028.201: modification: multiple procs support related changes */
5262 #ifndef SS_MULTIPLE_PROCS
5266 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5267 osCp.tmrTbl[idx].ownerInst);
5275 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5276 osCp.tmrTbl[idx].ownerInst);
5277 #endif /* SS_MULTIPLE_PROCS */
5279 /*mt005.21: addition */
5280 /* unset the current executing TAPA task ID */
5281 sTsk->dep.ent = ENTNC;
5282 sTsk->dep.inst = INSTNC;
5285 /* return the message buffer */
5289 * mt003.301 - SDeRegTTsk fix
5291 case SS_EVNT_TTSK_TERM:
5292 #ifdef SS_MULTIPLE_PROCS
5293 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5295 if (procIdIdx == SS_INV_PROCID_IDX)
5301 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5302 #else /* SS_MULTIPLE_PROCS */
5303 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5304 #endif /* SS_MULTIPLE_PROCS */
5306 /* verify that it hasn't been deregistered */
5307 if (idx == SS_TSKNC)
5313 /* verify that this system task is still running it */
5314 tTsk = &osCp.tTskTbl[idx];
5315 if (tTsk->sTsk != sTsk)
5320 #ifdef SS_MULTIPLE_PROCS
5321 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5323 ssdProcTTskTerm(tTsk, idx);
5329 #if (ERRCLASS & ERRCLS_DEBUG)
5330 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5337 } while (mBuf != NULLP);
5340 /* unlock the system task entry */
5341 SUnlock(&sTsk->lock);
5344 /* yield for other threads */
5345 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5354 * Fun: mtTmrHdlrPublic
5357 Void mtTmrHdlrPublic
5361 Void mtTmrHdlrPublic()
5364 if (SLock(&osCp.tmrTblLock) != ROK)
5366 #if (ERRCLASS & ERRCLS_DEBUG)
5367 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5371 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5372 /* unlock the timer table */
5373 SUnlock(&osCp.tmrTblLock);
5381 * Desc: The timer handler thread function. Counts time
5382 * and invokes the common timer function on each
5385 * Ret: (thread function)
5392 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5394 PRIVATE Void *mtTmrHdlr
5396 void *parm /* unused */
5399 /* mt009.21: addition */
5400 PRIVATE Void *mtTmrHdlr(parm)
5401 void *parm; /* unused */
5404 /*mt004.301-addede new region*/
5405 /* mt010.301 Removed SS_FAP portion and
5406 * enabled oroginal code in function mtTmrHdlr */
5410 U32 i, cnt, oldTicks, newTicks;
5411 struct timeval tv1,tv2;
5412 /* mt038.201 added return */
5414 /* mt039.201 changes for nanosleep */
5415 struct timespec tsN;
5416 PRIVATE U32 err_in_usec;
5418 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5423 /* mt027.201 - Modification for SRegCfgTmr support */
5424 /* check SS_TICKS_SEC */
5425 if (SS_1MS < SS_TICKS_SEC)
5427 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5430 /* mt025.201 - Addition to stop timer handler till task registration is done */
5431 /* wait for SS to come up */
5432 /* mt038.201 changed how sem_wait is called */
5433 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5436 /* mt027.201 - Modification for SRegCfgTmr support */
5437 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5439 ts.tv_nsec = (MT_TICK_CNT * 1000);
5440 /* mt039.201 changes for nanosleep */
5446 if (gettimeofday(&tv1, NULL) == -1)
5448 #if (ERRCLASS & ERRCLS_DEBUG)
5449 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5450 "Error in clock_gettime");
5460 #ifndef STUB_TTI_HANDLING_5GTF
5461 printf("Returning from mtTmrHdlr()\n");
5466 /* mt039.201 changes for nanosleep */
5467 /* sleep for MT_TICK_CNT milli seconds */
5468 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5469 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5471 ts.tv_nsec = tsN.tv_nsec;
5476 if (gettimeofday(&tv2,NULL) == -1)
5478 #if (ERRCLASS & ERRCLS_DEBUG)
5479 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5480 "Error in clock_gettime");
5484 /*mt013.301 : changed check while calculating timer to fix
5485 * diffrence between MTSS time and real unix time
5487 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5489 time_int = (tv2.tv_usec - tv1.tv_usec);
5491 else if (tv2.tv_sec > tv1.tv_sec)
5493 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5495 else /* ts2 < ts1, this will not happen in normal scenario */
5497 /* to make sure cnt = 1 */
5499 time_int = MT_TICK_CNT;
5502 oldTicks = osCp.dep.sysTicks;
5503 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5504 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5505 newTicks = osCp.dep.sysTicks;
5506 tv1.tv_usec = tv2.tv_usec;
5507 tv1.tv_sec = tv2.tv_sec;
5509 cnt = newTicks - oldTicks;
5511 while(err_in_usec >= MT_TICK_CNT)
5514 err_in_usec -= MT_TICK_CNT;
5516 if( cnt >= MT_MAX_TICK_CNT_VAL)
5517 cnt = MT_MIN_TICK_CNT_VAL;
5518 /* call the common timer tick handler */
5519 for (i = 0; i < cnt; i++)
5521 /* mt008.301: cmPrcTmr is guarded with a lock */
5522 /* lock the timer table */
5523 if (SLock(&osCp.tmrTblLock) != ROK)
5525 #if (ERRCLASS & ERRCLS_DEBUG)
5526 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5530 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5531 /* unlock the timer table */
5532 SUnlock(&osCp.tmrTblLock);
5536 /* mt009.21: addition */
5537 return ( (Void *) NULLP);
5538 /* will not reach here */
5546 * Desc: Process timer event. Called from the common timer
5547 * code when a timeout occurs.
5559 PTR tCb, /* control block */
5560 S16 evnt /* event */
5563 Void mtTimeout(tCb, evnt)
5564 PTR tCb; /* control block */
5565 S16 evnt; /* event */
5574 #ifndef TENB_RTLIN_CHANGES
5577 /* mt028.201: modification: multiple procs support related changes */
5578 #ifdef SS_MULTIPLE_PROCS
5580 #endif /* SS_MULTIPLE_PROCS */
5581 #ifdef RGL_SPECIFIC_CHANGES
5582 #ifdef MSPD_MLOG_NEW
5583 U32 t = GetTIMETICK();
5590 /* get the timer entry */
5591 tEnt = (SsTmrEntry *) tCb;
5594 /* if the timer was deleted, this will be NULL, so drop it */
5600 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5603 /* Hmmmm, the timer might have been deleted while we've been
5604 * working at getting here, so we just skip this.
5606 if (tEnt->used == FALSE)
5612 /* Set up and send a timer message to the destination tasks'
5615 #ifndef SS_MULTICORE_SUPPORT
5616 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5618 #ifdef RGL_SPECIFIC_CHANGES
5619 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5621 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5626 #if (ERRCLASS & ERRCLS_DEBUG)
5627 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5633 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5634 mInfo->eventInfo.event = SS_EVNT_TIMER;
5635 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5637 mInfo->pst.dstEnt = tEnt->ownerEnt;
5638 mInfo->pst.dstInst = tEnt->ownerInst;
5639 mInfo->pst.srcEnt = tEnt->ownerEnt;
5640 mInfo->pst.srcInst = tEnt->ownerInst;
5641 /* mt028.201: modification: multiple procs support related changes */
5642 #ifndef SS_MULTIPLE_PROCS
5643 mInfo->pst.dstProcId = SFndProcId();
5644 mInfo->pst.srcProcId = SFndProcId();
5645 #else /* SS_MULTIPLE_PROCS */
5646 mInfo->pst.dstProcId = tEnt->ownerProc;
5647 mInfo->pst.srcProcId = tEnt->ownerProc;
5648 #endif /* SS_MULTIPLE_PROCS */
5649 mInfo->pst.selector = SEL_LC_NEW;
5650 #ifndef SS_MULTICORE_SUPPORT
5651 mInfo->pst.region = DFLT_REGION;
5654 mInfo->pst.pool = DFLT_POOL;
5655 mInfo->pst.prior = PRIOR0;
5656 mInfo->pst.route = RTESPEC;
5657 mInfo->pst.event = 0;
5660 #ifndef TENB_RTLIN_CHANGES
5661 /* get a semaphore for the TAPA task table */
5662 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5667 #if (ERRCLASS & ERRCLS_DEBUG)
5668 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5676 /* find the owner TAPA task */
5677 /* mt028.201: modification: multiple procs support related changes */
5678 #ifdef SS_MULTIPLE_PROCS
5679 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5680 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5681 #else /* SS_MULTIPLE_PROCS */
5682 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5683 #endif /* SS_MULTIPLE_PROCS */
5684 if (idx == SS_TSKNC)
5686 #ifndef TENB_RTLIN_CHANGES
5687 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5694 /* ensure that the TAPA task is hale and hearty */
5695 tTsk = &osCp.tTskTbl[idx];
5698 #ifndef TENB_RTLIN_CHANGES
5699 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5704 /* Klock work fix ccpu00148484 */
5705 /* write the timer message to the queue of the destination task */
5706 /* mt008.301 : check sTsk before putting into it's DQ */
5707 if (tTsk->sTsk == NULLP)
5709 #ifndef TENB_RTLIN_CHANGES
5710 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5714 #if (ERRCLASS & ERRCLS_DEBUG)
5715 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5716 "Could not write to demand queue");
5721 #ifdef SS_LOCKLESS_MEMORY
5722 mInfo->pst.region = tTsk->sTsk->region;
5723 mInfo->region = tTsk->sTsk->region;
5724 #endif /* SS_LOCKLESS_MEMORY */
5725 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5726 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5728 #ifndef TENB_RTLIN_CHANGES
5729 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5733 #if (ERRCLASS & ERRCLS_DEBUG)
5734 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5735 "Could not write to demand queue");
5740 /* Fix for ccpu00130657 */
5741 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5742 if (tTsk->sTsk->tskPrior == PRIOR0)
5745 WLS_WakeUp(mtGetWlsHdl());
5752 /* release the semaphore for the TAPA task table */
5753 #ifndef TENB_RTLIN_CHANGES
5754 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5758 /* restart the timer */
5759 arg.tq = osCp.dep.tmrTq;
5760 arg.tqCp = &osCp.dep.tmrTqCp;
5761 arg.timers = tEnt->dep.timers;
5762 arg.cb = (PTR) tEnt;
5766 arg.max = TMR_DEF_MAX;
5767 arg.wait = tEnt->interval;
5769 #ifdef RGL_SPECIFIC_CHANGES
5770 #ifdef MSPD_MLOG_NEW
5771 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5783 * Desc: This thread reads the console and hands over any
5784 * data read to a user function.
5786 * Ret: (thread function)
5794 PRIVATE Void *mtConHdlr
5796 Ptr parm /* unused */
5799 /* mt009.21: addition */
5800 PRIVATE Void *mtConHdlr(parm)
5801 Ptr parm; /* unused */
5808 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5814 /* check if we have a console input file handle */
5815 if (osCp.dep.conInFp == NULLP)
5821 fd = fileno(osCp.dep.conInFp);
5826 if ((read(fd, &data, 1)) != 1)
5832 /* call rdConQ, defined by the system service user */
5842 #ifdef SS_DRVR_SUPPORT
5845 * Fun: Interrupt service task handler
5847 * Desc: This is the interrupt service task handler. It blocks
5848 * on a pipe from which it reads an isFlag structure. The
5849 * structure indicates which interrupt service task is to
5850 * be executed. The thread identifies the task, calls the
5851 * isTsk function and sends itself a message to repeat
5852 * this operation until it receives a message to cease.
5862 /* mt009.21: addition */
5863 PRIVATE Void *mtIsTskHdlr
5865 Ptr tskPtr /* pointer to task entry */
5868 /* mt009.21: addition */
5869 PRIVATE Void *mtIsTskHdlr(tskPtr)
5870 Ptr tskPtr; /* pointer to task entry */
5873 #if (ERRCLASS & ERRCLS_DEBUG)
5884 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5889 switch (isFlag.action)
5892 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5894 /* call the interrupt service task activation function */
5895 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5897 /* send self a message to keep doing this */
5898 isFlag.action = MT_IS_RESET;
5900 #if (ERRCLASS & ERRCLS_DEBUG)
5901 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5902 if (ret != sizeof(isFlag))
5904 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5905 "write() to pipe failed");
5908 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5915 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5920 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5922 /* call the interrupt service task activation function */
5923 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5925 #if (ERRCLASS & ERRCLS_DEBUG)
5926 /* send self a message to do this again */
5927 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5929 if (ret != sizeof(isFlag))
5931 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5932 "write() to pipe failed");
5935 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5943 /* where did THIS come from?? */
5947 /* mt009.21: addition */
5948 return ( (Void *) NULLP);
5952 #endif /* SS_DRVR_SUPPORT */
5953 #endif /* L2_L3_SPLIT */
5955 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5959 * Fun: mtIntSigHndlr
5961 * Desc: Exit function, shuts down.
5976 Void mtIntSigHndlr(arg)
5981 TRC0(mtIntSigHndlr);
5983 osCp.dep.sigEvnt=TRUE;
5986 #ifdef TENB_RTLIN_CHANGES
5994 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5999 * Desc: function, shuts down.
6023 SGetSysTime(&ticks);
6025 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
6027 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
6029 #ifdef SS_HISTOGRAM_SUPPORT
6033 osCp.dep.sigEvnt=FALSE;
6035 if (osCp.dep.fileOutFp)
6037 fclose(osCp.dep.fileOutFp);
6045 Void SIncrementTtiCount(Void)
6050 Ticks SGetTtiCount(Void)
6059 * Desc: This function displays a string to a given output
6064 * Notes: Buffer should be null terminated.
6066 * channel 0 is reserved for backwards compatibility
6075 S16 chan, /* channel */
6076 Txt *buf /* buffer */
6079 S16 SDisplay(chan, buf)
6080 S16 chan; /* channel */
6081 Txt *buf; /* buffer */
6086 /* mt020.201 - Fixed typo */
6087 #if (ERRCLASS & ERRCLS_INT_PAR)
6090 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6095 #ifndef XEON_SPECIFIC_CHANGES
6096 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6097 ssMemlog(buf, strlen(buf));
6102 /* mt012.301 :FIX for LOG RELATED ISSUE */
6110 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6116 if (osCp.dep.fileOutFp)
6117 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6118 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6121 fflush(osCp.dep.fileOutFp);
6134 * Desc: function, shuts down.
6154 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6155 a loop to overcome the child processes being killed upon exiting the
6157 #ifdef SS_LINUX /* this should have already been defined */
6158 /* mt010.301 removed flag SLES9_PLUS */
6159 /* wait forever for children */
6163 if(osCp.dep.sigEvnt==TRUE)
6170 pthread_exit(NULLP);
6176 * Fun: Set date and time
6178 * Desc: This function is used to set the calendar
6183 * Notes: Unimplemented
6191 REG1 DateTime *dt /* date and time */
6194 S16 SSetDateTime(dt)
6195 REG1 DateTime *dt; /* date and time */
6210 * Fun: Get date and time
6212 * Desc: This function is used to determine the calendar
6213 * date and time. This information may be used for
6214 * some management functions.
6227 REG1 DateTime *dt /* date and time */
6230 S16 SGetDateTime(dt)
6231 REG1 DateTime *dt; /* date and time */
6234 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6237 struct timespec ptime;
6239 struct timeval ptime;
6248 #if (ERRCLASS & ERRCLS_INT_PAR)
6251 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6260 localtime_r(&tt, &tme);
6263 clock_gettime(CLOCK_REALTIME, &ptime);
6265 gettimeofday(&ptime, NULL);
6267 localtime_r(&ptime.tv_sec, &tme);
6269 dt->month = (U8) tme.tm_mon + 1;
6270 dt->day = (U8) tme.tm_mday;
6271 dt->year = (U8) tme.tm_year;
6272 dt->hour = (U8) tme.tm_hour;
6273 dt->min = (U8) tme.tm_min;
6274 dt->sec = (U8) tme.tm_sec;
6277 #ifdef SS_DATETIME_USEC
6279 dt->usec = ptime.tv_nsec / 1000;
6281 dt->usec = ptime.tv_usec;
6283 #endif /*-- SS_DATETIME_USEC --*/
6289 * Get time from epoch in milliseconds
6291 * Fun: Get time from epoch in milliseconds
6293 * Desc: This function is used to get the time from epoch in milli seconds.
6294 * This information may be used for calculating a layer's activation function
6295 * execution time used for thread profiling.
6304 /* mt003.301 Modifications */
6308 EpcTime *et /* date and time */
6312 EpcTime *et; /* date and time */
6315 /* mt003.301 Modifications */
6317 U64 to_sec = 1000000;
6320 struct timespec ptime;
6322 struct timeval ptime;
6328 #if (ERRCLASS & ERRCLS_INT_PAR)
6337 clock_gettime(CLOCK_REALTIME, &ptime);
6339 gettimeofday(&ptime, NULL);
6340 #endif /* SS_LINUX */
6342 now = (ptime.tv_sec * to_sec);
6345 now += (ptime.tv_nsec / to_nsec);
6346 #else /* SS_LINUX */
6347 now += (ptime.tv_usec);
6349 #endif /* SS_LINUX */
6350 now = (now / to_nsec);
6361 * Fun: Get system time
6363 * Desc: This function is used to determine the system time.
6367 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6375 Ticks *sysTime /* system time */
6378 S16 SGetSysTime(sysTime)
6379 Ticks *sysTime; /* system time */
6385 #if (ERRCLASS & ERRCLS_INT_PAR)
6386 if (sysTime == NULLP)
6388 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6394 *sysTime = osCp.dep.sysTicks;
6400 /* mt021.201 - Addition of SGetRefTime function */
6403 * Fun: Get referenced time
6405 * Desc: This function is used to determine the time in seconds
6406 * and microseconds from a reference time. The reference
6407 * time is expressed in seconds from UTC EPOC, January 1,
6413 * Notes: Macros are defined for reference times:
6414 * SS_REFTIME_01_01_1970
6415 * SS_REFTIME_01_01_2002
6423 U32 refTime, /* reference time */
6428 S16 SGetRefTime(refTime, sec, usec)
6429 U32 refTime; /* reference time */
6436 struct timespec ptime;
6438 struct timeval ptime;
6444 clock_gettime(CLOCK_REALTIME, &ptime);
6446 gettimeofday(&ptime, NULL);
6449 #if (ERRCLASS & ERRCLS_INT_PAR)
6450 if (sec == NULLP || usec == NULLP)
6452 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6455 /* mt022.201 - Modification to fix compile warning */
6456 if (refTime > (U32)(ptime.tv_sec))
6458 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6463 *sec = ptime.tv_sec - refTime;
6465 *usec = ptime.tv_nsec / 1000;
6467 *usec = ptime.tv_usec;
6477 * Fun: Get Random Number
6479 * Desc: Invoked by layer when a pseudorandom number is required.
6483 * Notes: Suggested approach uses shuffled Linear Congruential
6484 * Operators as described in Byte magazine October
6485 * 1984; "Generating and Testing Pseudorandom Numbers"
6493 Random *value /* random number */
6497 Random *value; /* random number */
6503 #if (ERRCLASS & ERRCLS_INT_PAR)
6506 /* mt011.21: addition */
6507 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6513 *value = (Random) rand_r(&osCp.dep.randSeed);
6524 * Desc: This function exits from a task.
6528 * Notes: Currently does nothing.
6551 * Fun: Exit Interrupt
6553 * Desc: This function exits from an interrupt.
6557 * Notes: Currently does nothing.
6580 * Fun: Hold Interrupt
6582 * Desc: This function prohibits interrupts from being enabled until
6583 * release interrupt. This function should be called when
6584 * interrupts are disabled and prior to any call to system
6585 * services either by entry to an interrupt service routine or
6586 * by explicit call to disable interrupt.
6590 * Notes: Currently does nothing
6613 * Fun: Release Interrupt
6615 * Desc: This function allows interrupts to be enabled.
6619 * Notes: Currently does nothing.
6644 * Desc: Enable interrupts
6646 * Ret: ROK on success
6649 * Notes: Currently does nothing.
6660 INLINE S16 SEnbInt()
6674 * Desc: Disable interrupts
6676 * Ret: ROK on success
6679 * Notes: Currently does nothing.
6690 INLINE S16 SDisInt()
6704 * Desc: This function gets the function address stored at the
6705 * specified interrupt vector.
6709 * Notes: Currently does nothing.
6717 VectNmb vectNmb, /* vector number */
6718 PIF *vectFnct /* vector function */
6721 S16 SGetVect(vectNmb, vectFnct)
6722 VectNmb vectNmb; /* vector number */
6723 PIF *vectFnct; /* vector function */
6741 * Desc: This function installs the specified function at the
6742 * specified interrupt vector.
6746 * Notes: Currently does nothing.
6754 VectNmb vectNmb, /* vector number */
6755 PIF vectFnct /* vector function */
6758 S16 SPutVect(vectNmb, vectFnct)
6759 VectNmb vectNmb; /* vector number */
6760 PIF vectFnct; /* vector function */
6773 /* mt028.201: modification: multiple procs support related changes */
6774 #ifndef SS_MULTIPLE_PROCS
6780 * Desc: This function gets the current entity and instance.
6783 * RFAILED - failed, general (optional)
6785 * Notes: This function may be called by the OS or Layer 1
6794 Ent *ent, /* entity */
6795 Inst *inst /* instance */
6798 S16 SGetEntInst(ent, inst)
6799 Ent *ent; /* entity */
6800 Inst *inst; /* instance */
6812 #if (ERRCLASS & ERRCLS_INT_PAR)
6813 /* check pointers */
6814 if (ent == NULLP || inst == NULLP)
6816 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6822 /* get the thread id */
6823 tId = pthread_self();
6826 /* find the system task in whose context we're running */
6828 ret = SLock(&osCp.sTskTblLock);
6833 for (i = 0; i < SS_MAX_STSKS; i++)
6835 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6837 sTsk = &osCp.sTskTbl[i];
6843 *ent = sTsk->dep.ent;
6844 *inst = sTsk->dep.inst;
6846 SUnlock(&osCp.sTskTblLock);
6849 return (ret == ROK ? ROK : RFAILED);
6857 * Desc: This function sets the current entity and instance.
6869 Ent ent, /* entity */
6870 Inst inst /* instance */
6873 S16 SSetEntInst(ent, inst)
6874 Ent ent; /* entity */
6875 Inst inst; /* instance */
6887 #if (ERRCLASS & ERRCLS_INT_PAR)
6888 /* check entity and instance IDs */
6889 if (ent >= ENTNC || inst >= INSTNC)
6891 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6897 /* get the thread id */
6898 tId = pthread_self();
6901 /* find the system task in whose context we're running */
6903 ret = SLock(&osCp.sTskTblLock);
6908 for (i = 0; i < SS_MAX_STSKS; i++)
6910 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6912 sTsk = &osCp.sTskTbl[i];
6918 sTsk->dep.ent = ent;
6919 sTsk->dep.inst = inst;
6921 SUnlock(&osCp.sTskTblLock);
6924 return (ret == ROK ? ROK : RFAILED);
6927 #endif /* SS_MULTIPLE_PROCS */
6929 #ifdef SS_DRVR_SUPPORT
6935 * Desc: Set interrupt pending flag
6937 * Ret: ROK on success
6946 INLINE S16 SSetIntPend
6948 U16 id, /* driver task identifier */
6949 Bool flag /* flag */
6952 INLINE S16 SSetIntPend(id, flag)
6953 U16 id; /* driver task identifier */
6954 Bool flag; /* flag */
6963 #if (ERRCLASS & ERRCLS_INT_PAR)
6964 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6966 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6973 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6975 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6983 #endif /* SS_DRVR_SUPPORT */
6986 #ifdef SS_LOCKLESS_MEMORY
6989 * Fun: SGlobMemInfoShow
6991 * Desc: This function displays the memory usage information
6992 * for the destined region. It will show the usage of
6993 * each configured bucket and the heap for the specified region.
6996 * RFAILED Region not registered
7002 S16 SGlobMemInfoShow
7007 S16 SGlobMemInfoShow()
7012 CmMmGlobRegCb *globReg;
7014 TRC1(SGlobMemInfoShow);
7016 globReg = osCp.globRegCb;
7018 sprintf(prntBuf, "--------------------------------------------------------------\n");
7019 SDisplay(0, prntBuf);
7020 sprintf(prntBuf, "Global Region Bucket Information\n");
7021 SDisplay(0, prntBuf);
7022 sprintf(prntBuf, "====================================================\n");
7023 SDisplay(0, prntBuf);
7024 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
7025 SDisplay(0, prntBuf);
7026 sprintf(prntBuf, "====================================================\n");
7027 SDisplay(0, prntBuf);
7030 for (idx = 0; idx < globReg->numBkts; idx++)
7032 #ifdef XEON_SPECIFIC_CHANGES
7033 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
7034 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7037 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
7038 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7040 sprintf(prntBuf, "%2u %12u %8u %9u\n",
7041 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7044 SDisplay(0, prntBuf);
7046 sprintf(prntBuf, "--------------------------------------------------------------\n");
7047 SDisplay(0, prntBuf);
7052 #endif /* SS_LOCKLESS_MEMORY */
7055 Bool IsMemoryThresholdHit(Region reg, Pool pool)
7057 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
7059 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
7062 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
7063 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
7070 /* mt022.201 - Addition of SRegInfoShow function */
7075 * Desc: This function displays the memory usage information
7076 * for the destined region. It will show the usage of
7077 * each configured bucket and the heap for the specified region.
7080 * RFAILED Region not registered
7082 * Notes: A Sample Output from the function
7083 * Bucket Memory: region 1
7084 * ====================================================
7085 * Bucket Number of Blks configured Size Allocated
7086 * ====================================================
7094 * Heap Memory: region 1
7097 * Heap Segmented blocks: 0
7110 S16 SRegInfoShow(region, availmem)
7120 #if (ERRCLASS & ERRCLS_INT_PAR)
7121 if (region > (SS_MAX_REGS-1) )
7123 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7130 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7131 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7132 SDisplay(0, prntBuf);
7133 sprintf(prntBuf, "====================================================\n");
7134 SDisplay(0, prntBuf);
7135 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7136 SDisplay(0, prntBuf);
7137 sprintf(prntBuf, "====================================================\n");
7138 SDisplay(0, prntBuf);
7142 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7144 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7146 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7147 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7148 mtCMMRegCb[region]->bktTbl[idx].size,
7149 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7150 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7152 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7153 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7154 mtCMMRegCb[region]->bktTbl[idx].size,
7155 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7156 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7159 /*mt009.301 Fixed 64BIT compilation warnings*/
7161 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7162 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7163 mtCMMRegCb[region]->bktTbl[idx].size,
7164 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7166 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7167 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7168 mtCMMRegCb[region]->bktTbl[idx].size,
7169 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7171 #endif /* not TENB_RTLIN_CHANGES */
7172 SDisplay(0, prntBuf);
7173 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7174 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7175 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7177 sprintf(prntBuf, "\n---------------\n");
7178 SDisplay(0, prntBuf);
7179 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7180 SDisplay(0, prntBuf);
7181 /*mt009.301 Fixed 64BIT compilation warnings*/
7183 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7185 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7187 SDisplay(0, prntBuf);
7188 /*mt009.301 Fixed 64BIT compilation warnings*/
7190 sprintf(prntBuf, "Heap Allocated: %u\n",
7191 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7193 sprintf(prntBuf, "Heap Allocated: %lu\n",
7194 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7196 SDisplay(0, prntBuf);
7197 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7198 #if (ERRCLASS & ERRCLS_DEBUG)
7199 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7200 mtCMMRegCb[region]->heapCb.numFragBlk);
7201 SDisplay(0, prntBuf);
7206 #ifdef XEON_SPECIFIC_CHANGES
7207 #define SSI_MAX_BKT_THRESHOLD 6
7208 #define SSI_MAX_REG_THRESHOLD 2
7209 U32 SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7210 U32 SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7211 U32 SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7214 PRIVATE Void SInitMemThreshold
7220 PRIVATE Void SInitMemThreshold(region, maxBkt)
7226 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7228 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7229 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7230 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7231 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7236 S16 SRegReachedMemThreshold
7242 S16 SRegReachedMemThreshold(region, maxBkt)
7249 PRIVATE U8 initFlag = 1;
7253 SInitMemThreshold(region, maxBkt);
7256 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7258 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7263 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7267 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7275 /* mt033.201 - addition of API to return the memory statistical data */
7280 * Desc: This function returns the memory usage information
7281 * for the destined region. It will return the usage of
7282 * each configured bucket and the heap for the specified region.
7285 * RFAILED Region not registered
7296 SsMemDbgInfo *dbgInfo
7299 S16 SGetRegInfo(region, dbgInfo)
7301 SsMemDbgInfo *dbgInfo;
7308 #if (ERRCLASS & ERRCLS_INT_PAR)
7309 if (region >= mtMemoCfg.numRegions )
7311 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7316 dbgInfo->availmem = 0;
7318 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7319 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7321 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7323 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7325 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7326 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7327 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7329 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7330 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7331 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7334 dbgInfo->region = region;
7336 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7338 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7339 mtCMMRegCb[region]->heapCb.avlSize);
7341 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7343 #if (ERRCLASS & ERRCLS_DEBUG)
7344 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7357 S16 SGetRegPoolInfo(numRegion, numPool)
7362 /* Send number of Region available */
7363 *numRegion = mtMemoCfg.numRegions;
7364 /* Send number of Pools available */
7365 *numPool = cfgRegInfo[0].numPools;
7370 /* mt033.201 - addition of APIs to print the memory statistical data
7371 * as defined by SSI enhancements
7373 #ifdef SSI_DEBUG_LEVEL1
7376 * Fun: SPrintRegMemStatusInfo
7378 * Desc: This function displays the memory usage information
7379 * for the destined region. It will show the total memory
7380 * used for static and dynamic memory if typeFlag is
7381 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7382 * memory block allocated for a particular size if typeFlag
7383 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7384 * calling SRegPrintMemStats.
7394 S16 SPrintRegMemStatusInfo
7400 S16 SPrintRegMemStatusInfo(region, typeFlag)
7410 TRC1(SPrintRegMemStatusInfo);
7412 #if (ERRCLASS & ERRCLS_INT_PAR)
7413 if (region >= mtMemoCfg.numRegions )
7415 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7420 /* initialize the counters*/
7424 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7426 /* total static and dynamic memory allocated from all the buckets in region requested */
7427 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7428 SDisplay(0, prntBuf);
7429 sprintf(prntBuf, "===========================================\n");
7430 SDisplay(0, prntBuf);
7431 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7432 SDisplay(0, prntBuf);
7433 sprintf(prntBuf, "===========================================\n");
7434 SDisplay(0, prntBuf);
7435 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7437 /*mt009.301 Fixed 64BIT compilation warnings*/
7439 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7440 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7441 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7443 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7444 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7445 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7447 SDisplay(0, prntBuf);
7448 /* update the total count */
7449 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7450 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7453 /*mt009.301 Fixed 64BIT compilation warnings*/
7455 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7456 SDisplay(0, prntBuf);
7457 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7459 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7460 SDisplay(0, prntBuf);
7461 /*mt010.301 fix for compilation error*/
7462 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7464 SDisplay(0, prntBuf);
7466 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7467 SDisplay(0, prntBuf);
7468 /*mt009.301 Fixed 64BIT compilation warnings*/
7470 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7471 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7473 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7474 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7476 SDisplay(0, prntBuf);
7478 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7480 /* Bucket Memory allocation Statistics */
7481 return (SPrintRegMemStats(region));
7486 sprintf(prntBuf, "\n Invalid choice \n");
7487 SDisplay(0, prntBuf);
7495 * Fun: SPrintRegMemStats
7497 * Desc: This function displays the memory usage information for
7498 * the destined region. It will show the number of memory
7499 * block allocated for a particular size from the hash list.
7509 PRIVATE S16 SPrintRegMemStats
7514 PRIVATE S16 SPrintRegMemStats(region)
7518 CmMmHashListCp *hashListCp;
7523 TRC1(SPrintRegMemStats);
7525 hashListCp = &mtCMMRegCb[region]->hashListCp;
7527 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7528 SDisplay(0, prntBuf);
7529 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7530 hashListCp->numOfbins, hashListCp->numOfEntries);
7531 SDisplay(0, prntBuf);
7532 sprintf(prntBuf, "===================================\n");
7533 SDisplay(0, prntBuf);
7534 sprintf(prntBuf, "Block Size Total number of requests\n");
7535 SDisplay(0, prntBuf);
7536 sprintf(prntBuf, "===================================\n");
7537 SDisplay(0, prntBuf);
7539 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7540 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7542 if (hashListCp->hashList[idx].numAttempts)
7545 /*mt009.301 Fixed 64BIT compilation warnings*/
7547 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7548 hashListCp->hashList[idx].numAttempts);
7550 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7551 hashListCp->hashList[idx].numAttempts);
7553 SDisplay(0, prntBuf);
7557 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7558 SDisplay(0, prntBuf);
7559 sprintf(prntBuf, "=================================================\n");
7560 SDisplay(0, prntBuf);
7561 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7562 SDisplay(0, prntBuf);
7563 sprintf(prntBuf, "=================================================\n");
7564 SDisplay(0, prntBuf);
7566 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7567 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7569 /*mt009.301 Fixed 64BIT compilation warnings*/
7571 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7572 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7573 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7575 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7576 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7577 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7579 SDisplay(0, prntBuf);
7581 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7582 SDisplay(0, prntBuf);
7583 /*mt009.301 Fixed 64BIT compilation warnings*/
7585 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7586 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7587 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7589 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7590 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7591 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7593 SDisplay(0, prntBuf);
7594 sprintf(prntBuf, "\n");
7595 SDisplay(0, prntBuf);
7602 * Fun: SRegMemErrHdlr
7604 * Desc: This function handles the errors returned from the memory
7605 * related functions. Customers are suggested to modify this
7606 * API according to their specific requirement.
7623 Void SRegMemErrHdlr(region, ptr, errCode)
7631 TRC1(SRegMemErrHdlr);
7633 if (errCode == RDBLFREE)
7635 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7636 SDisplay(0, prntBuf);
7638 else if (errCode == RTRAMPLINGNOK)
7640 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7641 SDisplay(0, prntBuf);
7649 * Fun: SPrintRegMemProfile
7651 * Desc: This function displays the memory profile information
7652 * for the destined region. This function prints for:
7653 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7654 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7664 S16 SPrintRegMemProfile
7669 S16 SPrintRegMemProfile(region)
7675 CmMmBlkHdr *curBktBlk;
7677 Size offsetToNxtBlk;
7684 TRC1(SPrintRegMemProfile);
7686 #if (ERRCLASS & ERRCLS_INT_PAR)
7687 if (region >= mtMemoCfg.numRegions )
7689 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7694 regCb = mtCMMRegCb[region];
7696 /* memory profile */
7697 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7698 SDisplay(0, prntBuf);
7700 /* bucket profile */
7701 sprintf(prntBuf, "\nBucket Profile\n");
7702 SDisplay(0, prntBuf);
7704 for (idx = 0; idx < regCb->numBkts; idx++)
7707 /*mt009.301 Fixed 64BIT compilation warnings*/
7709 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7710 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7712 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7713 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7715 SDisplay(0, prntBuf);
7717 sprintf(prntBuf, "==========================================================================\n");
7718 SDisplay(0, prntBuf);
7719 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7720 SDisplay(0, prntBuf);
7721 sprintf(prntBuf, "==========================================================================\n");
7722 SDisplay(0, prntBuf);
7724 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7726 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7727 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7728 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7730 /*mt009.301 Fixed 64BIT compilation warnings*/
7732 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7734 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7736 SDisplay(0, prntBuf);
7737 /* check if it is a sane block, elxe jump to next block */
7738 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7740 sprintf(prntBuf, " Trampled \n");
7741 SDisplay(0, prntBuf);
7746 if (CMM_IS_STATIC(curBktBlk->memFlags))
7748 /*mt009.301 Fixed 64BIT compilation warnings*/
7750 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7752 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7754 SDisplay(0, prntBuf);
7756 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7758 /*mt009.301 Fixed 64BIT compilation warnings*/
7760 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7762 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7764 SDisplay(0, prntBuf);
7766 else if (CMM_IS_FREE(curBktBlk->memFlags))
7768 /*mt009.301 Fixed 64BIT compilation warnings*/
7770 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7772 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7774 SDisplay(0, prntBuf);
7778 sprintf(prntBuf, " Trampled \n");
7779 SDisplay(0, prntBuf);
7785 sprintf(prntBuf, "\nHeap Profile\n");
7786 SDisplay(0, prntBuf);
7788 /* point to heapCb */
7789 heapCb = &(regCb->heapCb);
7791 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7792 SDisplay(0, prntBuf);
7793 sprintf(prntBuf, "==========================================================================\n");
7794 SDisplay(0, prntBuf);
7795 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7796 SDisplay(0, prntBuf);
7797 sprintf(prntBuf, "==========================================================================\n");
7798 SDisplay(0, prntBuf);
7800 /* traverse the entire heap to output the heap profile */
7801 hdrSize = sizeof(CmHEntry);
7802 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7803 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7805 /*mt009.301 Fixed 64BIT compilation warnings*/
7807 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7809 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7811 SDisplay(0, prntBuf);
7813 /* check if it is a sane block, elxe jump to next block */
7814 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7816 sprintf(prntBuf, " Trampled \n");
7817 SDisplay(0, prntBuf);
7819 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7820 SDisplay(0, prntBuf);
7823 * To go to next block in the heap we do not have any offset value
7824 * other than curHBlk->size. As the block is already trampled
7825 * we cannot rely on this size. So it is better to stop here unless there
7826 * exists any other mechanism(?) to know the offset to next block.
7831 /*mt009.301 Fixed 64BIT compilation warnings*/
7833 sprintf(prntBuf, " %8u", curHBlk->size);
7835 sprintf(prntBuf, " %8lu", curHBlk->size);
7837 SDisplay(0, prntBuf);
7839 if (CMM_IS_STATIC(curHBlk->memFlags))
7841 /*mt009.301 Fixed 64BIT compilation warnings*/
7843 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7845 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7847 SDisplay(0, prntBuf);
7849 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7851 /*mt009.301 Fixed 64BIT compilation warnings*/
7853 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7855 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7857 SDisplay(0, prntBuf);
7859 else if (CMM_IS_FREE(curHBlk->memFlags))
7861 /*mt009.301 Fixed 64BIT compilation warnings*/
7863 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7865 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7867 SDisplay(0, prntBuf);
7871 sprintf(prntBuf, " Trampled \n");
7872 SDisplay(0, prntBuf);
7874 /* goto next block in the heap */
7875 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7881 #endif /* SSI_DEBUG_LEVEL1 */
7883 /*-- mt035.201 : Added new API for timestamp --*/
7886 * Fun: Get TimeStamp
7888 * Desc: This function is used to Get TimeStamp in micro seconds
7904 S16 SGetTimeStamp(ts)
7910 struct timespec ptime;
7912 struct timeval ptime;
7919 TRC1(SGetTimeStamp);
7922 clock_gettime(CLOCK_REALTIME, &ptime);
7924 gettimeofday(&ptime, NULL);
7927 /* Obtain the time of day, and convert it to a tm struct. --*/
7928 ptm = localtime (&ptime.tv_sec);
7929 /* Klock work fix ccpu00148484 */
7932 /* Format the date and time, down to a single second. --*/
7933 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7936 /* Compute microseconds. --*/
7938 microseconds = ptime.tv_nsec / 1000;
7940 microseconds = ptime.tv_usec;
7943 /* Print the formatted time, in seconds, followed by a decimal point
7944 and the microseconds. --*/
7945 /*mt009.301 Fixed 64BIT compilation warnings*/
7947 sprintf(ts, "%s.%03d", time_string, microseconds);
7949 sprintf(ts, "%s.%03ld", time_string, microseconds);
7955 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7958 * Fun: Get SGetSystemTsk
7960 * Desc: This function is used to Get sytem task id
7978 TRC1(SGetSystemTskS);
7980 return (pthread_self());
7982 } /* end of SGetSystemTsk */
7984 #ifdef SS_MULTICORE_SUPPORT
7987 * Fun: Add Timer thread into system task table
7989 * Desc: This function is used to add the system task
7990 * associated with Timer thread.
8000 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void)
8002 PRIVATE SsSTskEntry* ssdAddTmrSTsk()
8008 TRC1(ssdAddTmrSTsk);
8010 /* lock the system task table */
8011 ret = SLock(&osCp.sTskTblLock);
8015 #if (ERRCLASS & ERRCLS_DEBUG)
8016 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8017 "Could not lock system task table");
8023 /* check count of system tasks */
8024 if (osCp.numSTsks == SS_MAX_STSKS)
8027 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8029 #if (ERRCLASS & ERRCLS_DEBUG)
8030 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
8031 "Could not give the Semaphore");
8036 #if (ERRCLASS & ERRCLS_ADD_RES)
8037 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
8044 /* initialize the system task entry with the information we have */
8045 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
8047 /* store the system task priority */
8048 sTsk->tskPrior = SS_NORM_TSK_PRI;
8050 /* initialize the demand queue */
8051 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8054 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8056 #if (ERRCLASS & ERRCLS_DEBUG)
8057 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8058 "Could not give the Semaphore");
8063 #if (ERRCLASS & ERRCLS_DEBUG)
8064 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8065 "Could not initialize demand queue");
8071 /* initialize the system task entry lock */
8072 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8074 ssDestroyDmndQ(&sTsk->dQ);
8076 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8078 #if (ERRCLASS & ERRCLS_DEBUG)
8079 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8080 "Could not give the Semaphore");
8085 #if (ERRCLASS & ERRCLS_DEBUG)
8086 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8087 "Could not initialize system task entry lock");
8094 /* success, update the table */
8095 sTsk->tskId = osCp.nxtSTskEntry;
8097 sTsk->termPend = FALSE;
8098 osCp.nxtSTskEntry = sTsk->nxt;
8101 /* unlock the system task table */
8103 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8105 #if (ERRCLASS & ERRCLS_DEBUG)
8106 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8107 "Could not give the Semaphore");
8114 #endif /* SS_MULTICORE_SUPPORT */
8115 /* mt003.301 Readwrite lock and recursive mutex additions */
8116 #ifdef SS_LOCK_SUPPORT
8119 * Fun: ssdInitLockNew
8121 * Desc: This function is used to initialise lock/mutex
8137 S16 ssdInitLockNew(lockId, lockType)
8143 #ifdef SS_REC_LOCK_SUPPORT
8144 pthread_mutexattr_t attr;
8145 #endif /* SS_REC_LOCK_SUPPORT */
8146 Txt prntBuf[PRNTSZE];
8149 TRC1(ssdInitLockNew);
8153 #ifdef SS_RDWR_LOCK_SUPPORT
8156 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8158 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8159 SDisplay(0, prntBuf);
8164 #endif /* SS_RDWR_LOCK_SUPPORT */
8165 #ifdef SS_REC_LOCK_SUPPORT
8168 retVal = pthread_mutexattr_init(&attr);
8172 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8177 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8179 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8183 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8184 pthread_mutexattr_destroy(&attr);
8188 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8191 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8192 pthread_mutexattr_destroy(&attr);
8198 #endif /* SS_REC_LOCK_SUPPORT */
8201 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8202 SDisplay(0, prntBuf);
8212 * Desc: This function is used to aquire the read write lock
8228 S16 ssdLockNew(lockId, lockType)
8234 Txt prntBuf[PRNTSZE];
8241 #ifdef SS_RDWR_LOCK_SUPPORT
8244 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8246 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8247 SDisplay(0, prntBuf);
8254 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8256 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8257 SDisplay(0, prntBuf);
8264 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8266 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8267 SDisplay(0, prntBuf);
8274 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8276 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8277 SDisplay(0, prntBuf);
8282 #endif /* SS_RDWR_LOCK_SUPPORT */
8283 #ifdef SS_REC_LOCK_SUPPORT
8286 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8288 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8289 SDisplay(0, prntBuf);
8294 #endif /* SS_REC_LOCK_SUPPORT */
8297 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8298 SDisplay(0, prntBuf);
8311 * Desc: This function is used to Unlock the read write lock
8327 S16 ssdUnlockNew(lockId, lockType)
8333 Txt prntBuf[PRNTSZE];
8340 #ifdef SS_RDWR_LOCK_SUPPORT
8343 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8345 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8346 SDisplay(0, prntBuf);
8351 #endif /* SS_RDWR_LOCK_SUPPORT */
8352 #ifdef SS_REC_LOCK_SUPPORT
8355 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8357 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8358 SDisplay(0, prntBuf);
8363 #endif /* SS_REC_LOCK_SUPPORT */
8366 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8367 SDisplay(0, prntBuf);
8376 * Fun: ssdDestroyLockNew
8378 * Desc: This function is used to destroy the read write lock
8388 S16 ssdDestroyLockNew
8394 S16 ssdDestroyLockNew(lockId, lockType)
8399 Txt prntBuf[PRNTSZE];
8402 TRC1(ssdDestroyLockNew);
8406 #ifdef SS_RDWR_LOCK_SUPPORT
8409 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8411 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8412 SDisplay(0, prntBuf);
8417 #endif /* SS_RDWR_LOCK_SUPPORT */
8418 #ifdef SS_REC_LOCK_SUPPORT
8421 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8423 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8424 SDisplay(0, prntBuf);
8429 #endif /* SS_REC_LOCK_SUPPORT */
8432 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8433 SDisplay(0, prntBuf);
8439 #endif /* SS_LOCK_SUPPORT */
8441 /* mt005.301 : Cavium Changes */
8442 #ifdef SS_SEUM_CAVIUM
8446 * Fun: ssInitRcvWork
8448 * Desc: This is the initializtion function of receive
8452 * RFAILED - failed, general (optional)
8454 * Notes: Function to initialize the work queue packet
8455 * receiving thread. This creates the new thread to
8456 * receive the work and sets the affinity.
8470 pthread_attr_t attr;
8473 TRC1(ssInitRcvWork);
8475 /* set the required attributes */
8476 pthread_attr_init(&attr);
8477 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8478 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8479 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8481 /* Create a new thread to receive the work queue messages */
8482 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8484 pthread_attr_destroy(&attr);
8489 pthread_attr_destroy(&attr);
8493 }/* ssInitRcvWork */
8500 * Desc: This is the handler function of receive
8504 * RFAILED - failed, general (optional)
8506 * Notes:The handler function of the work queue receiver task.
8507 * This will be waiting for the work and after receiving
8508 * it, work will converted and posted to that entityt
8515 PRIVATE void *workRcvTsk
8520 PRIVATE void *workRcvTsk (ptr)
8525 cvmx_wqe_t *workPtr;
8526 Buffer *mBuf, *rcvdBuf;
8527 SsMsgInfo *minfoPtr;
8537 /* get the work if its avilable */
8538 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8540 if ( workPtr == NULLP )
8542 /* If there is no work then sleep for 10 usec */
8544 ts.tv_nsec = 500000;
8546 nanosleep(&ts, NULLP);
8550 switch(workPtr->tag)
8552 /* Switch over according to the tag value */
8553 case SS_CVMX_MBUF_TAG:
8555 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8557 /* Convert the physical address to Pointers */
8558 ret = SConvPhyPtr(&rcvdBuf);
8561 /* mt011.301: Cavium 32 bit changes */
8562 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8566 /* Copy the buffer to this region */
8567 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8570 /* mt011.301: Cavium 32 bit changes */
8571 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8575 /* mt011.301: Cavium 32 bit changes */
8576 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8578 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8580 /* Get the post strucutre and Post the message */
8581 if ( minfoPtr != NULLP)
8583 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8585 (Void)SPstTsk(&pst, mBuf);
8587 /* Free the buffer allocated if it cannot be sent */
8596 /* Invalid tag value, drop the work */
8597 /* mt011.301: Cavium 32 bit changes */
8598 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8607 #endif /* SS_SEUM_CAVIUM */
8609 #ifdef TENB_RTLIN_CHANGES
8610 S16 SInitLock(SLockId *l, U8 t)
8613 pthread_mutexattr_t prior;
8614 pthread_mutexattr_init(&prior);
8615 #ifndef RGL_SPECIFIC_CHANGES
8616 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8618 r = pthread_mutex_init(l, &prior);
8619 pthread_mutexattr_destroy(&prior);
8623 #ifdef SS_THR_REG_MAP
8626 * Fun: ssRegMainThread
8628 * Desc: This function is used to add the memory region
8629 * mapping for the main thread.
8631 * Ret: VOID (Always successful)
8639 Void ssRegMainThread(Void)
8642 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8644 printf("not able to get different Id for main thread\n");
8647 /* Here the default region is added as we dont have any region associated with
8648 * Main thread. The thread should not perform any allocation except
8649 * the initial configuratin
8651 #ifdef XEON_SPECIFIC_CHANGES
8652 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8654 SS_GET_THREAD_MEM_REGION() =
8661 * Fun: ssCheckAndAddMemoryRegionMap
8663 * Desc: This function is used to add the memory region
8664 * mapping for the provided sTsk associated thread.
8665 * If the threadId can be placed in the thread memory
8666 * region mapping table and returns success if it is able
8667 * to place. If not, it keeps the thread ID in the static
8668 * local array and increments the count. Once thread Id
8669 * is successfully placed in the thread memory region mapping
8670 * table, pthread_cancel is sent for all the previous threads
8671 * which are failed to place in table.
8673 * Ret: TRUE - Thread ID successfully placed in thread memory region
8675 * FALSE - If thread Id is not placed in thread memory region
8678 * Notes:mapping tablemapping tablng tablee
8683 S32 ssCheckAndAddMemoryRegionMap
8685 pthread_t threadId, /* Thread Id of system task */
8686 Region region /* Region associated with thread */
8689 PRIVATE U32 createdThreads;
8690 PRIVATE pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8693 TRC1(ssCheckAndAddMemoryRegionMap);
8695 /* Here 0xFF is considered as invalid region and if the mapping table
8696 * contains 0xFF, that mapping entry is free
8698 if(SS_INVALID_THREAD_REG_MAP !=
8699 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8701 /* Klock work fix ccpu00148484 */
8702 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8704 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8705 printf("Not able to get the different thread ID, exiting\n");
8708 createdThreadIds[createdThreads++] = threadId;
8711 /* If we found free mapping table entry, place the region and send pthread_cancel
8712 * for all the thread Ids which are created before this
8714 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8715 #ifdef XEON_SPECIFIC_CHANGES
8716 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8717 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8718 SS_MAX_THREAD_REGION_MAP), region);
8720 for(indx = 0; indx < createdThreads; indx++)
8722 #ifdef XEON_SPECIFIC_CHANGES
8723 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8725 pthread_cancel(createdThreadIds[indx]);
8731 } /* ssCheckAndAddMemoryRegionMap */
8735 * Fun: ssCheckAndDelMemoryRegionMap
8737 * Desc: This function is used to add the memory region
8738 * mapping for the provided sTsk associated thread.
8739 * If the threadId can be placed in the thread memory
8740 * region mapping table and returns success if it is able
8741 * to place. If not, it keeps the thread ID in the static
8742 * local array and increments the count. Once thread Id
8743 * is successfully placed in the thread memory region mapping
8744 * table, pthread_cancel is sent for all the previous threads
8745 * which are failed to place in table.
8747 * Ret: TRUE - Thread ID successfully placed in thread memory region
8749 * FALSE - If thread Id is not placed in thread memory region
8752 * Notes:mapping tablemapping tablng tablee
8757 S32 ssCheckAndDelMemoryRegionMap
8759 pthread_t threadId /* Thread Id of system task */
8763 TRC1(ssCheckAndDelMemoryRegionMap);
8765 /* Raghu To-Do Check with team, is it necessary to acquire lock
8766 * as del and add may go parallel */
8767 /* Here 0xFF is considered as invalid region and if the mapping table
8768 * contains 0xFF, that mapping entry is free
8770 if(SS_INVALID_THREAD_REG_MAP ==
8771 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8774 printf("Invalid Thread ID (%ld)\n", (U32)threadId);
8776 printf("Invalid Thread ID (%d)\n", (U32)threadId);
8780 /* If we found free mapping table entry, place the region and send pthread_cancel
8781 * for all the thread Ids which are created before this
8783 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8787 } /* ssCheckAndAddMemoryRegionMap */
8791 #ifdef SS_TSKLOG_ENABLE
8796 * Desc: This function will return current time through input parameter.
8799 * RFAILED - failed, general (optional)
8808 VOLATILE U32 *startTime,
8812 S16 SStartTask(startTime, taskId)
8813 VOLATILE U32 *startTime;
8817 #ifdef MSPD_MLOG_NEW
8818 *startTime = GetTIMETICK();
8827 * Desc: This function will return current time through input parameter.
8828 * and take the difference of start time provided as input parameter
8832 * RFAILED - failed, general (optional)
8841 VOLATILE U32 startTime,
8845 S16 SStopTask(startTime, taskId)
8846 VOLATILE U32 startTime;
8853 case PID_MAC_HARQ_IND:
8854 case PID_SCH_TTI_IND:
8856 case PID_MAC_DAT_IND:
8857 case PID_MAC_SF_ALLOC_REQ:
8858 case PID_MAC_STA_RSP:
8859 case PID_MAC_DL_SCHD:
8860 case PID_MAC_DL_CQI_IND:
8861 case PID_MAC_UL_CQI_IND:
8862 case PID_MAC_UL_SCHD:
8863 case PID_MAC_TTI_IND:
8864 case PID_CL_RCV_PHY_MSG:
8865 case PID_CL_HARQ_STA_IND:
8866 case PID_MAC_AM_HARQ_RLS:
8867 case PID_CL_DL_BATCH_PROC:
8868 case PID_CL_DLM_PRC_TTI_IND:
8869 case PID_CRC_IND_REAL:
8870 case PID_CRC_IND_DUMMY:
8871 case PID_TTI_LATENCY:
8872 case PID_RECPREQ_PROC:
8875 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8877 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8880 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8890 VOLATILE U32 * startTime,
8894 S16 SStartTask(startTime, taskId)
8895 VOLATILE U32 * startTime;
8906 VOLATILE U32 startTime,
8910 S16 SStopTask(startTime, taskId)
8911 VOLATILE U32 startTime;
8918 #endif /*#ifdef SS_TSKLOG_ENABLE */
8919 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8921 * This primitive is used to calculate the CPU Utilization per Core
8926 * @return Void - function is always success
8929 Void UpdateSocCpuInfo
8931 CmCpuStatsInfo *cpuInfo,
8935 Void UpdateSocCpuInfo(*cpuInfo, idx)
8936 CmCpuStatsInfo *cpuInfo;
8941 S8 mipsStr[MIPS_STRING_LEN];
8948 /* Open the file which holds the MIPS available value */
8949 mipsFd = fopen(MIPS_FILE, "r");
8956 /* Get the free mips available value from the file */
8957 if(NULLP == fgets(mipsStr, 24, mipsFd))
8959 printf("fgets to get the free mips available failed\n");
8964 strtok(mipsStr, " ");
8966 strPart = strtok(NULLP, " ");
8968 if(idx == CM_L2_CPU_UTIL)
8970 if(strPart != NULLP)
8972 l2FreeCpu = atoi(strPart);
8973 l2CpuUsed = 100 - l2FreeCpu;
8974 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8975 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);;
8976 cpuInfo->cpuUtil[0].numSamples++;
8979 if(idx == CM_L3_CPU_UTIL)
8981 strPart = strtok(NULLP, " ");
8982 if(strPart != NULLP)
8984 l3FreeCpu = atoi(strPart);
8985 l3CpuUsed = 100 - l3FreeCpu;
8986 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8987 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);;
8988 cpuInfo->cpuUtil[0].numSamples++;
8991 if(idx == CM_L2_CPU_UTIL)
8993 cpuInfo->numCores = CM_NUM_L2_CORES ;
8995 else if(idx == CM_L3_CPU_UTIL)
8997 cpuInfo->numCores = CM_NUM_L3_CORES ;
9003 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
9004 #ifdef SS_MULTICORE_SUPPORT
9007 * Fun: Add Timer thread into system task table
9009 * Desc: This function is used to add the system task
9010 * associated with Timer thread.
9020 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(
9024 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(idx)
9031 TRC1(ssdReAddTmrSTsk);
9033 /* lock the system task table */
9034 ret = SLock(&osCp.sTskTblLock);
9038 #if (ERRCLASS & ERRCLS_DEBUG)
9039 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
9040 "Could not lock system task table");
9046 /* initialize the system task entry with the information we have */
9047 sTsk = &osCp.sTskTbl[idx];
9052 SDestroyLock(&sTsk->lock);
9053 ssDestroyDmndQ(&sTsk->dQ);
9056 /* store the system task priority */
9057 sTsk->tskPrior = SS_NORM_TSK_PRI;
9059 /* initialize the demand queue */
9060 if (ssInitDmndQ(&sTsk->dQ) != ROK)
9063 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9065 #if (ERRCLASS & ERRCLS_DEBUG)
9066 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
9067 "Could not give the Semaphore");
9072 #if (ERRCLASS & ERRCLS_DEBUG)
9073 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
9074 "Could not initialize demand queue");
9080 /* initialize the system task entry lock */
9081 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
9083 ssDestroyDmndQ(&sTsk->dQ);
9085 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9087 #if (ERRCLASS & ERRCLS_DEBUG)
9088 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
9089 "Could not give the Semaphore");
9094 #if (ERRCLASS & ERRCLS_DEBUG)
9095 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9096 "Could not initialize system task entry lock");
9103 /* success, update the table */
9104 sTsk->tskId = idx + 1;
9106 sTsk->termPend = FALSE;
9108 /* unlock the system task table */
9110 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9112 #if (ERRCLASS & ERRCLS_DEBUG)
9113 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9114 "Could not give the Semaphore");
9121 #endif /* SS_MULTICORE_SUPPORT */
9126 * Fun: Initialize timer table
9128 * Desc: This function initializes MTSS-specific information
9129 * in the timer table.
9147 pthread_attr_t attr;
9148 struct sched_param param_sched;
9149 #ifndef XEON_SPECIFIC_CHANGES
9152 #ifdef SS_MULTICORE_SUPPORT
9154 #endif /* SS_MULTICORE_SUPPORT */
9155 #ifdef SS_THR_REG_MAP
9156 U32 threadCreated = FALSE;
9157 #endif /* SS_THR_REG_MAP */
9161 #ifndef XEON_SPECIFIC_CHANGES
9162 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9165 #if (ERRCLASS & ERRCLS_DEBUG)
9166 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9167 "Could not give the Semaphore");
9173 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9174 /* mt010.21: addition */
9176 #ifdef SS_MULTICORE_SUPPORT
9177 sTsk = ssdReAddTmrSTsk(0);
9182 #endif /* SS_MULTICORE_SUPPORT */
9183 /* create the timer handler thread */
9185 pthread_attr_init(&attr);
9186 /* mt021.201 - Addition to set stack size */
9187 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9188 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9189 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9190 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9191 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9192 pthread_attr_setschedparam(&attr, ¶m_sched);
9195 #ifdef SS_THR_REG_MAP
9196 /* When the thread is created, we check for the memory mapping table if
9197 * threadId can be placed in thread memory map table. If it is not able to place
9198 * threadId is stored in tmporary array. Once thread is created successful,
9199 * thread_cancel is sent for each thread which are created before. All the
9200 * threads are made to wait on sema which is cancel point for thread.
9202 while(threadCreated == FALSE)
9205 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9207 /* mt020.201 - Addition for destroying thread attribute object attr */
9208 pthread_attr_destroy(&attr);
9213 #ifdef SS_THR_REG_MAP
9214 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9217 #endif /* SS_THR_REG_MAP */
9218 #ifdef SS_MEM_WL_DEBUG
9219 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9222 /* mt020.201 - Addition for destroying thread attribute object attr */
9223 pthread_attr_destroy(&attr);
9224 sem_post(&osCp.dep.ssStarted);
9228 /**********************************************************************
9230 **********************************************************************/