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 */
39 #include "envopt.h" /* environment options */
40 #include "envdep.h" /* environment dependent */
41 #include "envind.h" /* environment independent */
48 #include <sys/types.h>
53 /* mt003.301: included sys/time.h
54 * for both solaris and linux
57 /* mt008.21: addition */
62 /* header include files (.h) */
65 #include "gen.h" /* general layer */
66 #include "ssi.h" /* system services */
68 #include "cm5.h" /* common timers */
70 #include "mt_ss.h" /* MTSS specific */
71 #include "mt_err.h" /* MTSS error defines */
73 #include "ss_queue.h" /* queues */
74 #include "ss_task.h" /* tasking */
75 #include "ss_msg.h" /* messaging */
76 #include "ss_mem.h" /* memory management interface */
77 #include "ss_gen.h" /* general */
78 /* mt003.301 Additions - Task deregistration */
79 #include "ss_err.h" /* error */
80 #include "cm_mem.h" /* common memory manager */
81 #include "cm_lte.h" /* common lte param */
82 /* mt001.301 : Additions */
83 #ifdef SS_THREAD_PROFILE
86 #ifdef SS_LOCKLESS_MEMORY
91 /* multi-core support enhancement */
92 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
93 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
99 #include <sys/types.h>
100 #include <sys/processor.h>
101 #include <sys/procset.h>
103 #endif /* SS_LINUX */
104 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
105 /* mt001.301 : Additions */
107 #include <sys/types.h>
108 #include <sys/socket.h>
109 #include <netinet/in.h>
110 #include <arpa/inet.h>
111 #endif /* SS_WATCHDOG */
113 /* header/extern include files (.x) */
115 #include "gen.x" /* general layer */
116 #include "ssi.x" /* system services */
118 #include "cm5.x" /* common timers */
120 #include "mt_ss.x" /* MTSS specific */
121 #ifdef SS_LOCKLESS_MEMORY
122 #include "mt_ss_wl.x" /* MTSS specific */
123 #endif /* SS_LOCKLESS_MEMORY */
125 #include "ss_queue.x" /* queues */
126 #include "ss_task.x" /* tasking */
127 #include "ss_timer.x" /* timers */
128 #include "ss_strm.x" /* STREAMS */
129 #include "ss_msg.x" /* messaging */
130 #include "ss_mem.x" /* memory management interface */
131 #include "ss_drvr.x" /* driver tasks */
132 #include "ss_gen.x" /* general */
133 #ifdef SS_LOCKLESS_MEMORY
134 #include "cm_llist.x"
136 #include "cm_mem_wl.x" /* common memory manager */
138 #include "cm_mem.x" /* common memory manager */
139 #endif /* SS_LOCKLESS_MEMORY */
140 #include "cm_lte.x" /* common memory manager */
141 /* mt001.301 : Additions */
142 #ifdef SS_LOGGER_SUPPORT
144 #endif /* SS_LOGGER_SUPPORT */
146 /*mt005.301: Cavium Changes */
147 #ifdef SS_SEUM_CAVIUM
148 /* cvmx includes files */
149 #include "cvmx-config.h"
151 #include "cvmx-pow.h"
152 #include "cvmx-tim.h"
153 #include "cvmx-fpa.h"
154 #include "cvmx-helper-fpa.h"
155 #include "cvmx-malloc.h"
156 #endif /* SS_SEUM_CAVIUM */
159 #include "mt_plat_t33.h"
160 #include "mt_plat_t33.x"
161 #include "sys/syscall.h"
164 #ifdef RGL_SPECIFIC_CHANGES
166 #include <hugetlbfs.h>
169 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
170 EXTERN S16 rgBatchProc (Void);
172 #ifdef RLC_MAC_DAT_REQ_RBUF
173 EXTERN S16 rgDlDatReqBatchProc ARGS((
176 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
177 EXTERN S16 rgBatchProc ARGS((
181 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
182 /* general purpose debug zone */
183 char my_buffer2[4096 * 4] = { 0 };
184 char my_buffer[4096] = { 0 };
185 int my_buffer_idx = 0;
189 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
191 struct sigcontext my_uc_mcontext = { 0 };
196 #include <ucontext.h>
200 #define SIGSEGV_STACK_GENERIC
201 #define REGFORMAT "%x\n"
203 #ifdef XEON_SPECIFIC_CHANGES
204 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
207 void dump_external(void);
210 PRIVATE Void mtDelSigals
215 PRIVATE Void mtDelSignals()
220 memset(&sa, 0, sizeof(struct sigaction));
221 sigemptyset(&sa.sa_mask);
222 sa.sa_handler = SIG_DFL;
223 sigaction(SIGSEGV, &sa, NULL);
225 memset(&sa, 0, sizeof(struct sigaction));
226 sigemptyset(&sa.sa_mask);
227 sa.sa_handler = SIG_DFL;
228 sigaction(SIGILL, &sa, NULL);
232 static void signal_segv(int signum, siginfo_t * info, void *ptr)
234 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
237 ucontext_t *ucontext = (ucontext_t *) ptr;
238 #ifdef XEON_SPECIFIC_CHANGES
240 int *p32 = (int *) 0x2fff0000;
245 printf("segv ooops @ %p\n", info->si_addr);
248 printf("Segmentation Fault!\n");
249 printf("info.si_signo = %d\n", signum);
250 printf("info.si_errno = %d\n", info->si_errno);
251 printf("info.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
252 printf("info.si_addr = %p\n", info->si_addr);
254 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
257 #ifndef RGL_SPECIFIC_CHANGES
258 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
259 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
260 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
261 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
262 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
263 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
264 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
265 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
266 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
267 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
268 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
269 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
270 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
271 printf("reg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
272 printf("reg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
273 printf("reg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
274 printf("reg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
277 printf("Stack trace (non-dedicated):\n");
279 sz = backtrace(buffer, 50);
280 strings = backtrace_symbols(buffer, sz);
281 for (i = 0; i < sz; ++i)
282 printf("%s\n", strings[i]);
284 printf("End of stack trace.");
286 #ifdef XEON_SPECIFIC_CHANGES
291 /* Lets first print our debug information */
292 printf("Before dumping our Debug info\n");
294 printf("After dumping our Debug info\n");
296 /* Disable the signal and make the enodeb to dump. This will make
297 * eNB to generate the core with dumping the ccpu log
304 /* End printing debug information */
309 /*** TBD: IMPORTANT ***
310 *** The following definition is temporary. This must be removed
311 *** when all products have been updated with latest ssi.h file OR
312 *** all ssi.h files have been updated to contain this definitions
314 /* New error class for FTHA added */
316 #define ERRCLS_FTHA 0x8
317 #endif /* ERRCLS_FTHA */
319 typedef struct _SPThreadCreateArg
321 void *argument; /* argument that is to be passed to the actual pthread */
322 void *(*start_routine) (void *); /* function from which pthread starts */
325 PUBLIC void *pthreadCreateHdlr(void* arg);
327 #ifdef SS_LOCKLESS_MEMORY
328 PUBLIC Buffer *mtTskBuffer1;
329 PUBLIC Buffer *mtTskBuffer2;
331 EXTERN pthread_t tmpRegTidMap[20];
332 EXTERN U8 stopBtInfo;
333 EXTERN S16 SGlobMemInfoShow(void);
334 #endif /* SS_LOCKLESS_MEMORY */
337 EXTERN APP_CONTEXT AppContext;
338 EXTERN S32 clusterMode;
341 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
342 EXTERN unsigned int tlPost(void *handle);
345 /* forward references */
346 /* mt003.301 Modifications - Moved to ss_gen.x */
347 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
348 PUBLIC Void *mtTskHdlrT2kL2 ARGS((Void*));
349 PUBLIC void mtSigSegvHndlr ARGS((void));
350 PUBLIC void mtSigUsr2Hndlr ARGS((void));
353 PRIVATE S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
354 PRIVATE Void *mtTskHdlr ARGS((void *));
355 PRIVATE S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
357 PRIVATE Void *mtTmrHdlr ARGS((void *));
358 PRIVATE Void mtTimeout ARGS((PTR tCb, S16 evnt));
360 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
361 PRIVATE Void mtIntSigHndlr ARGS((int));
362 PRIVATE Void mtExitClnup ARGS((void));
365 PRIVATE Void *mtConHdlr ARGS((void *));
369 #ifdef SS_DRVR_SUPPORT
370 PRIVATE Void *mtIsTskHdlr ARGS((void *));
374 /* mt020.201 - Addition for no command line available */
376 PRIVATE Void mtGetOpts ARGS((void));
377 /* mt003.301 Additions - File Based task registration made
378 * common for both MULTICORE and NON-MULTICORE
380 PRIVATE Bool fileBasedMemCfg = FALSE;
383 /* mt033.201 - addition of local function to print the statistics such as
384 * (size vs. numAttempts) and (allocations vs. deallocations)
386 #ifdef SSI_DEBUG_LEVEL1
387 PRIVATE S16 SPrintRegMemStats ARGS((Region region));
388 #endif /* SSI_DEBUG_LEVEL1 */
390 #ifdef SS_MULTICORE_SUPPORT
391 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void);
392 PRIVATE SsSTskEntry* ssdReAddTmrSTsk ARGS((U8 idx));
393 #ifndef SS_LOCKLESS_MEMORY
394 #ifndef RGL_SPECIFIC_CHANGES
395 PRIVATE S16 ssdInitMemInfo ARGS((void));
400 /* mt005.301: Cavium changes */
401 #ifdef SS_SEUM_CAVIUM
402 PRIVATE Void *workRcvTsk ARGS((void *));
403 #endif /* SS_SEUM_CAVIUM */
405 #ifdef SS_THR_REG_MAP
406 PUBLIC S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
408 PUBLIC S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
409 #endif /* SS_THR_REG_MAP */
411 /* type declarations */
413 #ifdef SS_DRVR_SUPPORT
414 typedef struct mtIsFlag
424 /* public variable declarations */
426 PUBLIC Cntr cfgNumRegs = SS_MAX_REGS;
427 /* Set memory configuration as false.
428 * Set to true if memory configuration through file is successfull.
430 PUBLIC Bool memConfigured = FALSE;
431 /* mt022.201 - Modification for shared memory relay region and memcal tool */
432 PUBLIC SsRegCfg cfgRegInfo[SS_MAX_REGS] =
435 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
437 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
438 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
439 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
440 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
441 { SS_POOL_STATIC, 0 }
447 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
449 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
450 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
451 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
452 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
453 { SS_POOL_STATIC, 0 }
456 #endif /* INTEL_WLS */
458 #ifdef SS_LOCKLESS_MEMORY
461 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
463 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
464 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
465 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
466 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
467 { SS_POOL_STATIC, 0 }
471 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
473 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
474 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
475 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
476 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
477 { SS_POOL_STATIC, 0 }
481 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
483 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
484 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
485 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
486 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
487 { SS_POOL_STATIC, 0 }
490 #endif /* SS_LOCKLESS_MEMORY */
492 /* mt003.301 Modifications - File Based task registration made
493 * common for both MULTICORE and NON-MULTICORE
496 #ifdef SS_LOCKLESS_MEMORY
497 PUBLIC MtDynMemCfg mtDynMemoCfg =
499 SS_MAX_REGS, /* number of regions */
502 SS_DFLT_REGION, /* region id */
503 MT_MAX_BKTS, /* number of buckets */
505 /* block size, no. of blocks, Upper threshold, lower threshold */
506 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
507 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
508 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
509 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
513 SS_DFLT_REGION + 1, /* region id */
514 MT_MAX_BKTS, /* number of buckets */
516 /* block size, no. of blocks, Upper threshold, lower threshold */
517 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
518 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
519 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
520 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
524 SS_DFLT_REGION + 2, /* region id */
525 MT_MAX_BKTS, /* number of buckets */
527 /* block size, no. of blocks, Upper threshold, lower threshold */
528 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
529 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
530 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
531 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
535 SS_DFLT_REGION + 3, /* region id */
536 MT_MAX_BKTS, /* number of buckets */
538 /* block size, no. of blocks, Upper threshold, lower threshold */
539 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
540 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
541 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
542 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
545 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
548 SS_DFLT_REGION + 4, /* region id */
549 MT_MAX_BKTS, /* number of buckets */
551 /* block size, no. of blocks, Upper threshold, lower threshold */
552 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
553 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
554 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
555 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
563 PUBLIC MtGlobMemCfg mtGlobMemoCfg =
565 MT_MAX_BKTS, /* number of buckets */
568 /* block size, no. of blocks, Upper threshold, lower threshold */
569 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
570 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
571 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
572 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
574 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
575 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
576 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
577 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
581 #endif /* SS_LOCKLESS_MEMORY */
583 /* mt022.201 - Modification for memory calculator tool */
584 /* mt018.201 - added memory configuration matrix */
585 PUBLIC MtMemCfg mtMemoCfg =
588 SS_MAX_REGS - 1, /* number of regions */
590 #ifndef XEON_SPECIFIC_CHANGES
591 SS_MAX_REGS, /* number of regions */
598 SS_DFLT_REGION, /* region id */
599 MT_MAX_BKTS, /* number of buckets */
600 MT_HEAP_SIZE, /* heap size */
602 #ifndef XEON_SPECIFIC_CHANGES
603 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
604 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
605 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
606 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
614 #else /* Page boundary alignment */
615 {256, 491520}, /* 60 pages of 2M*/
616 {512, 12288}, /* 3 pages of 2M */
617 {2048, 99328}, /* 97 Pages of 2M */
618 {8192, 75008}, /* 293 Pages of 2M */
619 {16384, 4096} /* 32 pages of 2M */
625 #ifndef SS_LOCKLESS_MEMORY
627 SS_DFLT_REGION + 1, /* region id */
628 MT_MAX_BKTS, /* number of buckets */
629 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
631 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
632 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
633 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
634 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
642 #endif /* SS_LOCKLESS_MEMORY */
643 #endif /* INTEL_WLS */
644 #ifdef SS_LOCKLESS_MEMORY
646 SS_DFLT_REGION + 1, /* region id */
647 MT_MAX_BKTS, /* number of buckets */
648 MT_HEAP_SIZE, /* heap size */
650 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
651 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
652 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
653 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
657 SS_DFLT_REGION + 2, /* region id */
658 MT_MAX_BKTS, /* number of buckets */
659 MT_HEAP_SIZE, /* heap size */
661 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
662 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
663 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
664 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
668 SS_DFLT_REGION + 3, /* region id */
669 MT_MAX_BKTS, /* number of buckets */
670 MT_HEAP_SIZE, /* heap size */
672 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
673 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
674 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
675 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
678 #endif /* SS_LOCKLESS_MEMORY */
682 /* mt003.301 Modifications - File Based task registration made
683 * common for both MULTICORE and NON-MULTICORE
684 * bucket info, as different regions may request for different no.
687 PUBLIC MtBktCfg mtBktInfo[MT_MAX_BKTS];
688 PUBLIC S16 msArgc; /* argc */
689 PUBLIC Txt **msArgv; /* argv */
690 PUBLIC S16 msOptInd; /* SGetOpt vars */
691 PUBLIC S8 *msOptArg; /* SGetOpt vars */
695 typedef struct _MtRegMemSz
701 PRIVATE MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
705 /* private variable declarations */
706 /* mt018.201 - change mtCMMRegCfg as array of pointers */
707 PRIVATE CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
708 PRIVATE CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
709 /* mt003.301 - Fixed compilation warnings */
710 /*mt004.301-addede new veriable for FAP*/
711 /*mt010.301 - removed veriable defined for FA*/
717 void mtSetNtlHdl(unsigned int hdl)
722 unsigned int mtGetNtlHdl()
724 return(osCp.ntl.hdl);
731 RETVALUE(osCp.wls.intf);
734 #ifdef XEON_MULTIPLE_CELL_CHANGES
735 EXTERN S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
736 EXTERN S16 smWrReadWlsConfigParams (Void);
739 PRIVATE int SOpenWlsIntf()
742 #define WLS_DEVICE_NAME "/dev/wls"
744 #ifdef XEON_SPECIFIC_CHANGES
745 #ifdef XEON_MULTIPLE_CELL_CHANGES
746 hdl = WLS_Open(gWrWlsDeviceName, 1);
748 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
751 hdl = WLS_Open(WLS_DEVICE_NAME, 0);
758 printf("Could not open WLS Interface \n");
773 * Desc: This function is the entry point for the final binary. It
774 * calls SInit() in the common code. It can be replaced by a
775 * user function if required (SInit() must still be called).
777 * Ret: none on success
788 int argc, /* argument count */
789 char **argv /* argument vector */
792 PUBLIC int main(argc, argv)
793 int argc; /* argument count */
794 char **argv; /* argument vector */
799 #ifdef XEON_MULTIPLE_CELL_CHANGES
800 /* Read the WLS parameters from the file and copy into global control block */
801 if(smWrReadWlsConfigParams() != ROK)
803 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
805 } /* end of if statement */
811 #endif /* INTEL_WLS */
815 /* mt003.301 Modifications */
818 printf("\n SInit failed, SSI could not start \n");
819 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
823 /*mt010.301 cleanup part exposed to user*/
834 * Desc: This function is the entry point for the final binary. It
835 * calls SInit() in the common code. It can be replaced by a
836 * user function if required (SInit() must still be called).
838 * Ret: none on success
849 int argc, /* argument count */
850 char **argv /* argument vector */
853 PUBLIC int ssMain(argc, argv)
854 int argc; /* argument count */
855 char **argv; /* argument vector */
872 * initialization functions
877 * Fun: Initialize OS control point
879 * Desc: This function initializes MTSS-specific information
880 * in the OS control point.
890 PUBLIC S16 ssdInitGen
895 PUBLIC S16 ssdInitGen()
898 struct sigaction act;
900 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
906 /*mt014.301 : 4GMX release related changes*/
910 /* mt005.301 : Cavium changes */
911 #ifdef SS_SEUM_CAVIUM
912 /* set group mask for the core */
913 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
914 #endif /* SS_SEUM_CAVIUM */
916 osCp.dep.sysTicks = 0;
918 /* mt020.201 - Addition for no command line available */
920 /* parse command line */
922 /* mt003.301 Additions */
923 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
925 printf("\n File Based Memory configuration failed \n");
930 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
931 #ifndef SS_LOCKLESS_MEMORY
932 #ifdef SS_MULTICORE_SUPPORT
933 if(memConfigured == FALSE)
939 /* initialize the started semaphore */
940 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
945 /* mt028.201 added compile time flag to allow not to mask signals */
947 /* mask all signals in the main thread */
949 sigdelset(&set, SIGINT);
950 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
951 sigdelset(&set, SIGSEGV);
952 sigdelset(&set, SIGUSR2);
953 sigdelset(&set, SIGILL);
954 #ifdef XEON_SPECIFIC_CHANGES
955 sigdelset(&set, SIGABRT);
956 sigdelset(&set, SIGTERM);
957 sigdelset(&set, SIGHUP);
960 pthread_sigmask(SIG_SETMASK, &set, NULLP);
961 #endif /* UNMASK_SIG */
963 /* install a SIGINT handler to shutdown */
964 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
966 /*Initialize SIGSEGV Signal */
967 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
969 memset(&sa, 0, sizeof(struct sigaction));
970 sigemptyset(&sa.sa_mask);
971 sa.sa_sigaction = signal_segv;
972 sa.sa_flags = SA_SIGINFO;
973 #ifndef XEON_SPECIFIC_CHANGES
974 sigaction(SIGSEGV, &sa, NULL);
976 memset(&sa, 0, sizeof(struct sigaction));
977 sigemptyset(&sa.sa_mask);
978 sa.sa_sigaction = signal_segv;
979 sa.sa_flags = SA_SIGINFO;
981 sigaction(SIGILL, &sa, NULL);
983 if(sigaction(SIGILL, &sa, NULL) != 0)
985 printf("Failed to process sigaction for the SIGILL\n");
988 if(sigaction(SIGSEGV, &sa, NULL) != 0)
990 printf("Failed to process sigaction for the SIGSEGV\n");
993 if(sigaction(SIGABRT, &sa, NULL) != 0)
995 printf("Failed to process sigaction for the SIGABRT\n");
998 if(sigaction(SIGTERM, &sa, NULL) != 0)
1000 printf("Failed to process sigaction for the SIGTERM\n");
1003 if(sigaction(SIGHUP, &sa, NULL) != 0)
1005 printf("Failed to process sigaction for the SIGHUP\n");
1010 signal (SIGSEGV, mtSigSegvHndlr);
1011 signal (SIGKILL, mtSigSegvHndlr);
1012 signal (SIGUSR2, mtSigUsr2Hndlr);
1017 signal (SIGINT, mtStopHndlr);
1020 act.sa_handler = mtIntSigHndlr;
1021 sigfillset(&act.sa_mask);
1023 if (sigaction(SIGINT, &act, NULLP) != 0)
1029 /* mt040.201 initialise random seed */
1030 osCp.dep.randSeed = time(NULLP);
1038 * Fun: De-initialize OS control point
1040 * Desc: This function reverses the initialization in ssdInitGen().
1050 PUBLIC Void ssdDeinitGen
1055 PUBLIC Void ssdDeinitGen()
1061 sem_destroy(&osCp.dep.ssStarted);
1066 #ifdef SS_LOCKLESS_MEMORY
1070 * Fun: ssPutDynMemBlkSet
1072 * Desc: Returns the set of dynamic Blocks into the global region
1075 * Ret: ROK - successful,
1076 * RFAILED - unsuccessful.
1084 PUBLIC S16 ssPutDynMemBlkSet
1086 U8 bktIdx, /* Index to bucket list */
1087 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1088 added to global region */
1091 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1092 U8 bktIdx; /* Index to bucket list */
1093 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1094 added to global region */
1097 CmMmGlobRegCb *globReg;
1098 CmMmGlobalBktCb *bktCb;
1102 globReg = osCp.globRegCb;
1104 #if (ERRCLASS & ERRCLS_INT_PAR)
1105 if(bktIdx >= globReg->numBkts)
1109 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1111 bktCb = &(globReg->bktTbl[bktIdx]);
1113 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1115 blkPtr = dynMemSetElem->nextBktPtr;
1116 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1117 free((Void *)blkPtr);
1120 dynMemSetElem->nextBktPtr = NULLP;
1121 dynMemSetElem->numFreeBlks = 0;
1128 * Fun: ssGetDynMemBlkSet
1130 * Desc: Gets the set of dynamic memory blocks from the global region
1133 * Ret: ROK - successful,
1134 * RFAILED - unsuccessful.
1142 PUBLIC S16 ssGetDynMemBlkSet
1144 U8 bktIdx, /* Index to bucket list */
1145 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1146 with new set values */
1149 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1150 U8 bktIdx; /* Index to bucket list */
1151 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1152 with new set values */
1156 CmMmGlobRegCb *globReg;
1157 CmMmGlobalBktCb *bktCb;
1162 globReg = osCp.globRegCb;
1164 #if (ERRCLASS & ERRCLS_INT_PAR)
1165 if(bktIdx >= globReg->numBkts)
1169 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1171 bktCb = &(globReg->bktTbl[bktIdx]);
1172 basePtr = &(dynMemSetElem->nextBktPtr);
1174 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1176 blkPtr = (Data *)malloc(bktCb->size);
1178 basePtr = (CmMmEntry **)blkPtr;
1181 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1185 } /* ssGetDynMemBlkSet */
1190 * Fun: ssPutDynMemBlkSet
1192 * Desc: Returns the set of dynamic Blocks into the global region
1195 * Ret: ROK - successful,
1196 * RFAILED - unsuccessful.
1204 PUBLIC S16 ssPutDynMemBlkSet
1206 U8 bktIdx, /* Index to bucket list */
1207 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1208 added to global region */
1209 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1212 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1213 U8 bktIdx; /* Index to bucket list */
1214 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1215 added to global region */
1216 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1219 CmMmGlobRegCb *globReg;
1220 CmMmGlobalBktCb *bktCb;
1222 CmMmBlkSetElement *globMemNode;
1225 TRC1(ssPutDynMemBlkSet);
1227 globReg = osCp.globRegCb;
1229 #if (ERRCLASS & ERRCLS_INT_PAR)
1230 if(bktIdx >= globReg->numBkts)
1234 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1236 bktCb = &(globReg->bktTbl[bktIdx]);
1238 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1239 try lock is used as it is not required to block as it will be taken
1240 in the next go else it will be blocked for lock as we have to get the
1243 SLock(&(bktCb->bucketLock));
1249 /* Get a free node from the free node linked list */
1250 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1251 if(lstNode == NULLP)
1253 SUnlock(&(bktCb->bucketLock));
1257 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1259 /* Copy the content of the received element information on to free node
1260 * and add it to valid linked list */
1261 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1262 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1263 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1264 dynMemSetElem->numFreeBlks = 0;
1265 dynMemSetElem->nextBktPtr = NULLP;
1267 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1269 SUnlock(&(bktCb->bucketLock));
1277 * Fun: ssGetDynMemBlkSet
1279 * Desc: Gets the set of dynamic memory blocks from the global region
1282 * Ret: ROK - successful,
1283 * RFAILED - unsuccessful.
1285 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1292 PUBLIC S16 ssGetDynMemBlkSet
1294 U8 bktIdx, /* Index to bucket list */
1295 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1296 with new set values */
1297 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1300 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1301 U8 bktIdx; /* Index to bucket list */
1302 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1303 with new set values */
1304 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1307 CmMmGlobRegCb *globReg;
1308 CmMmGlobalBktCb *bktCb;
1310 CmMmBlkSetElement *globMemNode;
1313 TRC1(ssGetDynMemBlkSet);
1315 globReg = osCp.globRegCb;
1317 #if (ERRCLASS & ERRCLS_INT_PAR)
1318 if(bktIdx >= globReg->numBkts)
1322 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1324 bktCb = &(globReg->bktTbl[bktIdx]);
1326 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1327 try lock is used as it is not required to block as it will be taken
1328 in the next go else it will be blocked for lock as we have to get the
1331 SLock(&(bktCb->bucketLock));
1336 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1338 if(lstNode == NULLP)
1340 SUnlock(&(bktCb->bucketLock));
1344 /* Delete the node from the valid linked list and copy the values of the
1345 * elements of structrues into pointer */
1346 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1347 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1348 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1349 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1351 /* Add this node to the free node linked list */
1352 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1354 SUnlock(&(bktCb->bucketLock));
1358 } /* ssGetDynMemBlkSet */
1361 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1363 PRIVATE U32 memoryCheckCounter;
1366 PUBLIC U32 isMemThreshReached(
1370 PUBLIC U32 isMemThreshReached(reg)
1374 CmMmGlobRegCb *globReg;
1375 CmMmGlobalBktCb *bktCb;
1378 TRC3(isMemThreshReached)
1380 globReg = osCp.globRegCb;
1382 #if (ERRCLASS & ERRCLS_INT_PAR)
1383 if(bktIdx >= globReg->numBkts)
1387 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1389 bktCb = &(globReg->bktTbl[bktIdx]);
1391 if(gDynMemAlrm[bktIdx])
1393 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1394 SLock(&(bktCb->bucketLock));
1395 if(bktCb->listValidBktSet.count > 25)
1397 gDynMemAlrm[bktIdx] = FALSE;
1398 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1400 SUnlock(&(bktCb->bucketLock));
1406 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1408 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1409 SLock(&(bktCb->bucketLock));
1410 if(bktCb->listValidBktSet.count < 15 )
1411 gDynMemAlrm[bktIdx] = TRUE;
1412 memoryCheckCounter = 0;
1413 SUnlock(&(bktCb->bucketLock));
1419 #endif /* USE_MALLOC */
1420 #endif /* SS_LOCKLESS_MEMORY */
1422 #ifdef SS_USE_ICC_MEMORY
1425 * Fun: Initialize region/pool tables
1427 * Desc: This function initializes MTSS-specific information
1428 * in the region/pool tables and configures the common
1429 * memory manager for use.
1439 PUBLIC Void * ssGetIccHdl
1444 PUBLIC Void * ssGetIccHdl()
1448 CmMmDynRegCb *dynRegCb;
1450 /* Klock work fix ccpu00148484 */
1451 if(!(region < SS_MAX_REGS))
1456 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1458 RETVALUE(dynRegCb->iccHdl);
1460 #endif /* SS_USE_ICC_MEMORY */
1462 #ifdef T2K_MEM_LEAK_DBG
1463 extern RegionMemLeakInfo regMemLeakInfo;
1464 #endif /* T2K_MEM_LEAK_DBG */
1468 PUBLIC S16 SPartitionWlsMemory()
1473 U64 pageSize[1], hugePageSize;
1476 long int pageSize[1], hugePageSize;
1479 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1481 U8 *regMemStrtAddr = (U8 *)osCp.wls.allocAddr;
1483 gethugepagesizes(pageSize,1);
1484 hugePageSize = pageSize[0];
1485 for (i = 0; i < 1; i++)
1487 mtRegMemSz[i].startAddr = regMemStrtAddr;
1488 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1490 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1491 reqdSz = numHugePg * hugePageSize;
1492 regMemStrtAddr += reqdSz;
1493 #ifdef T2K_MEM_LEAK_DBG
1494 /* Since wls is region 0 */
1495 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1496 regMemLeakInfo.numActvRegions++;
1497 #endif /* T2K_MEM_LEAK_DBG */
1499 //Store last region addr for validation
1500 mtRegMemSz[i].startAddr = regMemStrtAddr;
1504 #ifdef SS_MEM_WL_DEBUG
1505 PUBLIC Void SChkAddrValid(int type, int region, PTR ptr)
1507 char *tryPtr = NULL;
1508 if(type == 0) //Global
1510 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1511 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1513 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1519 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1521 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1527 #endif /* SS_MEM_WL_DEBUG */
1529 PUBLIC S16 SPartitionStaticMemory(U8 *startAddr)
1534 U8 *regMemStrtAddr = (U8 *)startAddr;
1537 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1538 for (i = 1; i < mtMemoCfg.numRegions; i++)
1540 mtRegMemSz[i].startAddr = regMemStrtAddr;
1541 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1542 regMemStrtAddr += reqdSz;
1543 #ifdef T2K_MEM_LEAK_DBG
1544 { /* Since region 1 onwards are used for non wls */
1545 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1546 regMemLeakInfo.numActvRegions++;
1548 #endif /* T2K_MEM_LEAK_DBG */
1552 PUBLIC S16 SAllocateWlsMem()
1560 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1561 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1563 for (i = 0; i < 1; i++)
1565 /* allocate space for the region */
1566 region = &mtMemoCfg.region[i];
1567 reqdMemSz += region->heapsize;
1568 mtRegMemSz[i].reqdSz += region->heapsize;
1570 for (j = 0; j < region->numBkts; j++)
1572 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1573 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1576 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1577 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1579 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1581 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1583 SPartitionWlsMemory();
1586 PUBLIC S16 SAllocateStaticMem()
1595 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1597 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1598 for (i = 1; i < mtMemoCfg.numRegions; i++)
1600 /* allocate space for the region */
1601 region = &mtMemoCfg.region[i];
1602 reqdMemSz += region->heapsize;
1603 mtRegMemSz[i].reqdSz += region->heapsize;
1605 for (j = 0; j < region->numBkts; j++)
1607 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1608 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1612 startAddr = malloc(reqdMemSz + (1024 * 10));
1614 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1616 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1618 SPartitionStaticMemory(startAddr);
1621 #endif /* INTEL_WLS */
1627 * Fun: Initialize region/pool tables
1629 * Desc: This function initializes MTSS-specific information
1630 * in the region/pool tables and configures the common
1631 * memory manager for use.
1641 PUBLIC S16 ssdInitMem
1646 PUBLIC S16 ssdInitMem()
1649 /* mt018.201 - added local variable */
1654 Txt errMsg[256] = {'\0'};
1655 #ifdef SS_LOCKLESS_MEMORY
1656 CmMmDynRegCb *dynRegCb;
1657 #ifdef SS_USE_ICC_MEMORY
1659 CmMmGlobRegCb *globReg;
1662 #endif /* SS_LOCKLESS_MEMORY */
1666 /* Use the default SSI memory manager if the ICC memory manager is not
1667 * avilable. If ICC memory manager is avilable, it will be used for
1668 * all sharable memory allocation and de-allocation */
1669 #ifdef SS_LOCKLESS_MEMORY
1670 #ifdef SS_USE_ICC_MEMORY
1671 #ifndef YS_PHY_3_8_2
1673 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1675 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1676 if(dynRegCb == NULLP)
1680 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1682 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1684 dynRegCb->region = i;
1685 cmMmDynRegInit(dynRegCb);
1686 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1689 /* ysIccHdl = dynRegCb->iccHdl; */
1692 /* Initialize the global region first */
1693 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1695 if(osCp.globRegCb == NULLP)
1700 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1702 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1704 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1706 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1708 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1710 if(globReg->bktTbl[i].startAddr == NULLP)
1714 globReg->bktTbl[i].poolId = i;
1715 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1716 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1717 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1720 globReg->numBkts = mtGlobMemoCfg.numBkts;
1721 cmMmGlobRegInit(globReg);
1723 /* Initialize the dynamic task regions and sanity check for the theshold
1725 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1727 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1728 if(dynRegCb == NULLP)
1732 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1734 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1735 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1736 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1737 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1739 #ifdef XEON_SPECIFIC_CHANGES
1744 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1745 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1746 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1747 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1748 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1750 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1753 dynRegCb->region = i;
1754 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1755 cmMmDynRegInit(dynRegCb);
1757 #endif /* SS_USE_ICC_MEMORY */
1758 #endif /* SS_LOCKLESS_MEMORY */
1760 #ifdef T2K_MEM_LEAK_DBG
1762 /* Initailize mem leak tool memorys for debguing */
1763 regMemLeakInfo.numActvRegions=0;
1764 for(reg=0; reg <SS_MAX_REGS; reg++)
1766 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1767 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1768 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1769 regMemLeakInfo.regStartAddr[reg] = 0;
1772 regMemLeakInfo.regStartAddr[reg] = 0;
1773 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1775 printf("\n mutex init failed\n");
1781 /* Now allocate WLS memory */
1783 SAllocateStaticMem();
1785 /* mt018.201 - CMM Initialization */
1786 for (i = 0; i < mtMemoCfg.numRegions; i++)
1788 /* allocate space for the region control block */
1789 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1790 #ifdef TENB_RTLIN_CHANGES
1791 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1793 if (mtCMMRegCb[i] == NULLP)
1795 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1796 for the Region:%d control block\n",i);
1798 for (k = 0; k < i; k++)
1800 cmMmRegDeInit(mtCMMRegCb[k]);
1801 free(mtCMMRegCfg[k]->vAddr);
1802 free(mtCMMRegCb[k]);
1803 free(mtCMMRegCfg[k]);
1808 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1809 #ifdef TENB_RTLIN_CHANGES
1810 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1812 if (mtCMMRegCfg[i] == NULLP)
1814 for (k = 0; k < i; k++)
1816 cmMmRegDeInit(mtCMMRegCb[k]);
1817 free(mtCMMRegCfg[k]->vAddr);
1818 free(mtCMMRegCb[k]);
1819 free(mtCMMRegCfg[k]);
1821 free(mtCMMRegCb[i]);
1826 /* allocate space for the region */
1827 region = &mtMemoCfg.region[i];
1828 mtCMMRegCfg[i]->size = region->heapsize;
1829 for (j = 0; j < region->numBkts; j++)
1831 /* mt033.201 - addition for including the header size while computing the total size */
1832 #ifdef SSI_DEBUG_LEVEL1
1833 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1834 (region->bkt[j].numBlks);
1836 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1837 #endif /* SSI_DEBUG_LEVEL1 */
1840 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1842 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1845 #ifdef XEON_SPECIFIC_CHANGES
1846 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1847 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1849 #ifdef TENB_RTLIN_CHANGES
1850 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1853 if (mtCMMRegCfg[i]->vAddr == NULLP)
1855 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1856 for the Region:%d \n",i);
1858 for (k = 0; k < i; k++)
1860 cmMmRegDeInit(mtCMMRegCb[k]);
1861 free(mtCMMRegCfg[k]->vAddr);
1862 free(mtCMMRegCb[k]);
1863 free(mtCMMRegCfg[k]);
1865 free(mtCMMRegCb[i]);
1866 free(mtCMMRegCfg[i]);
1871 /* set up the CMM configuration structure */
1872 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1873 mtCMMRegCfg[i]->chFlag = 0;
1874 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1875 mtCMMRegCfg[i]->numBkts = region->numBkts;
1877 for (j = 0; j < region->numBkts; j++)
1879 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1880 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1883 /* initialize the CMM */
1884 #ifdef SS_LOCKLESS_MEMORY
1885 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1887 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1888 #endif /* SS_LOCKLESS_MEMORY */
1890 for (k = 0; k < i; k++)
1892 cmMmRegDeInit(mtCMMRegCb[k]);
1893 free(mtCMMRegCfg[k]->vAddr);
1894 free(mtCMMRegCb[k]);
1895 free(mtCMMRegCfg[k]);
1897 free(mtCMMRegCfg[i]->vAddr);
1898 free(mtCMMRegCb[i]);
1899 free(mtCMMRegCfg[i]);
1904 /* initialize the STREAMS module */
1905 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1906 if (region->regionId == 0)
1908 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
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 cmMmRegDeInit(mtCMMRegCb[i]);
1918 free(mtCMMRegCfg[i]->vAddr);
1919 free(mtCMMRegCb[i]);
1920 free(mtCMMRegCfg[i]);
1925 /* mt001.301 : Additions */
1926 #ifdef SS_MEM_LEAK_STS
1928 #endif /* SS_MEM_LEAK_STS */
1937 * Fun: De-initialize region/pool tables
1939 * Desc: This function reverses the initialization in ssdInitMem().
1949 PUBLIC Void ssdDeinitMem
1954 PUBLIC Void ssdDeinitMem()
1957 /* mt018.201 - added local variables */
1961 /* mt008.301 Additions */
1962 #ifdef SS_MEM_LEAK_STS
1963 cmDeinitMemLeakMdl();
1964 #endif /* SS_MEM_LEAK_STS */
1966 for (i = 0; i < mtMemoCfg.numRegions; i++)
1968 cmMmRegDeInit(mtCMMRegCb[i]);
1969 free(mtCMMRegCfg[i]->vAddr);
1970 free(mtCMMRegCb[i]);
1971 free(mtCMMRegCfg[i]);
1980 * Fun: Initialize task table
1982 * Desc: This function initializes MTSS-specific information
1983 * in the task table.
1993 PUBLIC S16 ssdInitTsk
1998 PUBLIC S16 ssdInitTsk()
2001 /* mt001.301 : Additions */
2002 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2003 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2005 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2010 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2011 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2012 /* initialize system task information */
2013 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2015 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2017 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2024 * Fun: Deinitialize task table
2026 * Desc: This function reverses the initialization perfomed in
2037 PUBLIC Void ssdDeinitTsk
2042 PUBLIC Void ssdDeinitTsk()
2051 #ifdef SS_DRVR_SUPPORT
2054 * Fun: Initialize driver task table
2056 * Desc: This function initializes MTSS-specific information
2057 * in the driver task table.
2067 PUBLIC S16 ssdInitDrvr
2072 PUBLIC S16 ssdInitDrvr()
2077 pthread_attr_t attr;
2083 /* initialize the dependent portion of the driver task entries */
2084 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2086 osCp.drvrTskTbl[i].dep.flag = FALSE;
2090 /* create pipe for communication between SSetIntPend() and
2091 * the isTskHdlr thread.
2093 if (pipe(osCp.dep.isFildes) != 0)
2099 /* create the isTskHdlr thread */
2100 pthread_attr_init(&attr);
2101 /* mt021.201 - Addition to set stack size */
2102 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2103 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2104 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2105 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2107 /* mt020.201 - Addition for destroying thread attribute object attr */
2108 pthread_attr_destroy(&attr);
2114 /*mt014.301 : 4GMX release related changes*/
2115 #ifdef SS_4GMX_UCORE
2123 /* mt020.201 - Addition for destroying thread attribute object attr */
2124 pthread_attr_destroy(&attr);
2133 * Fun: Deinitialize driver information
2135 * Desc: This function reverses the initialization performed in
2146 PUBLIC Void ssdDeinitDrvr
2151 PUBLIC Void ssdDeinitDrvr()
2154 TRC0(ssdDeinitDrvr);
2155 /* mt008.301: Terminate the Driver Task on exit */
2156 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2159 TL_Close(AppContext.hUAII);
2160 if (clusterMode == RADIO_CLUSTER_MODE)
2162 TL_Close(AppContext.hUAII_second);
2168 #endif /* SS_DRVR_SUPPORT */
2173 * Fun: Initialize timer table
2175 * Desc: This function initializes MTSS-specific information
2176 * in the timer table.
2186 PUBLIC S16 ssdInitTmr
2191 PUBLIC S16 ssdInitTmr()
2194 pthread_attr_t attr;
2195 struct sched_param param_sched;
2196 /* mt010.21: addition */
2198 #ifdef SS_MULTICORE_SUPPORT
2200 #endif /* SS_MULTICORE_SUPPORT */
2201 #ifdef SS_THR_REG_MAP
2202 U32 threadCreated = FALSE;
2203 #endif /* SS_THR_REG_MAP */
2208 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2209 /* mt010.21: addition */
2210 osCp.dep.tmrTqCp.nxtEnt = 0;
2211 for (i=0; i< SS_MAX_TMRS; i++)
2213 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2216 #ifdef SS_MULTICORE_SUPPORT
2217 sTsk = ssdAddTmrSTsk();
2222 #endif /* SS_MULTICORE_SUPPORT */
2223 /* create the timer handler thread */
2224 pthread_attr_init(&attr);
2225 /* mt021.201 - Addition to set stack size */
2226 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2227 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2228 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2229 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2230 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2231 pthread_attr_setschedparam(&attr, ¶m_sched);
2234 #ifdef SS_THR_REG_MAP
2235 /* When the thread is created, we check for the memory mapping table if
2236 * threadId can be placed in thread memory map table. If it is not able to place
2237 * threadId is stored in tmporary array. Once thread is created successful,
2238 * thread_cancel is sent for each thread which are created before. All the
2239 * threads are made to wait on sema which is cancel point for thread.
2241 while(threadCreated == FALSE)
2244 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2246 /* mt020.201 - Addition for destroying thread attribute object attr */
2247 pthread_attr_destroy(&attr);
2252 #ifdef SS_THR_REG_MAP
2253 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2256 #endif /* SS_THR_REG_MAP */
2257 #ifdef SS_MEM_WL_DEBUG
2258 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2261 /* mt020.201 - Addition for destroying thread attribute object attr */
2262 pthread_attr_destroy(&attr);
2271 * Fun: Deinitialize timer table
2273 * Desc: This function reverses the initialization performed in
2284 PUBLIC Void ssdDeinitTmr
2289 PUBLIC Void ssdDeinitTmr()
2292 #ifdef SS_MULTICORE_SUPPORT
2295 #endif /* SS_MULTICORE_SUPPORT */
2299 #ifdef SS_MULTICORE_SUPPORT
2300 ret = SLock(&osCp.sTskTblLock);
2304 #if (ERRCLASS & ERRCLS_DEBUG)
2305 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2306 "Could not lock system task table");
2310 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2311 /* clean up the system task entry */
2315 SDestroyLock(&sTsk->lock);
2316 ssDestroyDmndQ(&sTsk->dQ);
2319 /* make this entry available in the system task table */
2320 sTsk->nxt = osCp.nxtSTskEntry;
2321 osCp.nxtSTskEntry = 0;
2325 /* unlock the system task table */
2326 SUnlock(&osCp.sTskTblLock);
2328 #endif /* SS_MULTICORE_SUPPORT */
2329 /* mt008.301: Terminate the timer thread on exit */
2330 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2340 * Desc: Pre-tst() initialization.
2350 PUBLIC S16 ssdInitLog
2355 PUBLIC S16 ssdInitLog()
2358 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2362 pthread_attr_t attr;
2365 #endif /* CONSTDIO */
2370 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2376 osCp.dep.conInFp = (FILE *) stdin;
2377 osCp.dep.conOutFp = (FILE *) stdout;
2378 /* added compile time flag CONRD: mt017.21 */
2382 /* disable canonical input processing */
2383 fd = fileno(osCp.dep.conInFp);
2384 if ((tcgetattr(fd, &tio)) != 0)
2386 printf("Error: disable canonical input processing\n");
2390 tio.c_lflag &= ~ICANON;
2391 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2392 tio.c_cc[VTIME] = 0;
2393 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2395 printf("Error: while tcsetattr() processing\n");
2399 #endif /* CONSTDIO */
2402 /* set up the input fd to block when no data is available */
2403 fd = fileno(osCp.dep.conInFp);
2404 flags = fcntl(fd, F_GETFL, &flags);
2405 flags &= ~O_NONBLOCK;
2406 if (fcntl(fd, F_SETFL, flags) == -1)
2408 printf("Error: while fcntl processing\n");
2413 /* create the console handler thread */
2414 pthread_attr_init(&attr);
2415 /* mt021.201 - Addition to set stack size */
2416 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2417 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2418 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2421 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2423 /* mt020.201 - Addition for destroying thread attribute object attr */
2424 pthread_attr_destroy(&attr);
2426 printf("Error: Logging Thread creation failed \n");
2430 /* mt020.201 - Addition for destroying thread attribute object attr */
2431 pthread_attr_destroy(&attr);
2445 * Desc: This function reverses the initialization performed in
2455 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2457 PUBLIC Void ssdDeinitLog
2462 PUBLIC Void ssdDeinitLog()
2465 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2469 /* mt008.301: Terminate the console reader on exit */
2470 while(pthread_cancel(osCp.dep.conHdlrTID));
2476 /* mt001.301 : Additions */
2481 PUBLIC S16 ssdInitWatchDog
2486 PUBLIC S16 ssdInitWatchDog(port)
2491 Txt prntBuf[PRNTSZE];
2494 #ifdef SS_WATCHDOG_IPV6
2495 struct sockaddr_in6 tmpaddr;
2497 struct sockaddr_in tmpaddr;
2498 #endif /* SS_WATCHDOG_IPV6 */
2499 #ifdef SS_MULTIPLE_PROCS
2500 ProcId procId = SS_WD_WDPROC;
2501 if (SAddProcIdLst(1, &procId) != ROK)
2505 #endif /* SS_MULTIPLE_PROCS */
2507 TRC0(ssdInitWatchDog);
2509 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2511 /* Create a watch dog system task */
2512 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2514 /* Create a watch dog reveiver system task */
2515 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2517 /* Register and attach watch dog TAPA task */
2518 #ifdef SS_MULTIPLE_PROCS
2519 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2520 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2522 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2523 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2524 #endif /* SS_MULTIPLE_PROCS */
2525 /* Register and attach watch dog receiver TAPA task */
2526 #ifdef SS_MULTIPLE_PROCS
2527 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2528 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2530 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2531 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2532 #endif /* SS_MULTIPLE_PROCS */
2534 #ifndef SS_MULTIPLE_PROCS
2535 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2536 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2538 osCp.wdCp.watchDgPst.srcProcId = procId;
2539 osCp.wdCp.watchDgPst.dstProcId = procId;
2540 #endif /* SS_MULTIPLE_PROCS */
2542 /* Initialise the pst structure */
2543 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2544 /* Initialize the watch dog timer resolution default is 1 sec */
2546 cmInitTimers(osCp.wdCp.watchDgTmr, (U8)1);
2547 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2548 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2549 for(idx = 0; idx < 1; idx++)
2551 osCp.wdCp.watchDgTs[idx].first = NULLP;
2552 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2554 #ifdef SS_MULTIPLE_PROCS
2555 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2557 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2558 #endif /* SS_MULTIPLE_PROCS */
2560 /* Create the watch dog receiver socket */
2561 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2562 if(osCp.wdCp.globWd.sock == -1)
2564 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2568 #ifdef SS_WATCHDOG_IPV6
2569 tmpaddr.sin6_len = sizeof(tmpadDr);
2570 tmpaddr.sin6_family = AF_INET6;
2571 tmpaddr.sin6_addr = in6addr_any;
2572 tmpaddr.sin6_port = htons(port);
2574 tmpaddr.sin_family = AF_INET;
2575 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2576 tmpaddr.sin_port = htons(port);
2577 #endif /* SS_WATCHDOG_IPV6 */
2579 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2582 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2586 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2590 #ifndef SS_MULTIPLE_PROCS
2591 pst.srcProcId = SFndProcId();
2592 pst.dstProcId = SFndProcId();
2594 pst.srcProcId = procId;
2595 pst.dstProcId = procId;
2596 #endif /* SS_MULTIPLE_PROCS */
2597 pst.event = EVTSSHRTBTREQ;
2598 ssdInitWatchDgPst(&pst);
2599 SPstTsk(&pst, mBuf);
2605 PUBLIC S16 ssdInitWatchDgPst
2610 PUBLIC S16 ssdInitWatchDgPst(pst)
2614 TRC1(ssInitWatchDgPst);
2616 pst->selector = SS_LOOSE_COUPLING;
2618 pst->region = DFLT_REGION; /* region */
2619 pst->pool = DFLT_POOL; /* pool */
2621 pst->prior = PRIOR0; /* priority */
2622 pst->route = RTESPEC; /* route */
2624 pst->dstEnt = ENTHB; /* destination entity */
2626 pst->srcEnt = ENTDW; /* source entity */
2632 #ifdef SS_MULTIPLE_PROCS
2634 PUBLIC S16 ssdWatchDgActvTmr
2641 PUBLIC S16 ssdWatchDgActvTmr(proc, ent, inst)
2645 PUBLIC S16 ssdWatchDgActvTmr
2650 PUBLIC S16 ssdWatchDgActvTmr()
2652 #endif /* SS_MULTIPLE_PROCS */
2654 TRC3(ssWatchDgActvTmr);
2656 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2662 PUBLIC Void ssdWatchDgTmrEvt
2664 PTR cb, /* control block */
2665 S16 event /* timer number */
2668 PUBLIC Void ssdWatchDgTmrEvt(cb, event)
2669 PTR cb; /* control block */
2670 S16 event; /* timer number */
2673 /* mt003.301 Fixed warings */
2677 Txt prntBuf[PRNTSZE];
2681 TRC2(ssWatchDgTmrEvt);
2687 SPrint("Timer Heartbeat Request Expired");
2689 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2694 SLock(&osCp.wdCp.wdLock);
2695 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2697 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2699 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2701 if(osCp.wdCp.globWd.callback != 0)
2703 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2707 SUnlock(&osCp.wdCp.wdLock);
2709 if(!osCp.wdCp.globWd.watchdogStop)
2711 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2712 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2723 PUBLIC Void ssdStartWatchDgTmr
2730 PUBLIC Void ssdStartWatchDgTmr(cb, event, wait)
2740 Txt prntBuf[PRNTSZE];
2744 TRC2(ssStartWatchDgTmr)
2745 /* mt003.301 Modifications */
2748 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2749 if(event == SS_TMR_HRTBT)
2751 SPrint("\nSTART SS_TMR_HRTBT");
2758 SLock(&osCp.wdCp.wdLock);
2759 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2761 osCp.wdCp.globWd.wdsta[i].status = 0;
2763 SUnlock(&osCp.wdCp.wdLock);
2765 arg.tq = osCp.wdCp.watchDgTs;
2766 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2767 arg.timers = osCp.wdCp.watchDgTmr;
2768 arg.cb = (PTR)NULLP;
2770 arg.wait = osCp.wdCp.globWd.timeout = wait;
2779 PUBLIC Void ssdStopWatchDgTmr
2785 PUBLIC Void ssdStopWatchDgTmr(cb, event)
2793 Txt prntBuf[PRNTSZE];
2797 TRC2(ssStopWatchDgTmr)
2798 /* mt003.301 Modifications */
2801 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2802 if(event == SS_TMR_HRTBT)
2804 SPrint("STOP SS_TMR_HRTBT");
2808 SLock(&osCp.wdCp.wdLock);
2809 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2811 osCp.wdCp.globWd.wdsta[i].status = 0;
2813 SUnlock(&osCp.wdCp.wdLock);
2816 arg.tq = osCp.wdCp.watchDgTs;
2817 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2818 arg.timers = osCp.wdCp.watchDgTmr;
2819 arg.cb = (PTR)NULLP;
2830 PUBLIC S16 ssdSndHrtBtMsg
2836 PUBLIC S16 ssdSndHrtBtMsg(restart, type)
2844 Txt prntBuf[PRNTSZE];
2846 struct sockaddr_in tmpaddr;
2847 char hbMsg[SS_WD_HB_MSG_SIZE];
2851 TRC2(ssdSndHrtBtReq)
2855 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2859 /* Pack the message */
2860 strcpy(hbMsg, "<HB>REQ</HB>");
2862 /* Send the heartbeat messages to all the configured nodes */
2863 SLock(&osCp.wdCp.wdLock);
2864 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2866 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2871 /* Identify the destination node */
2872 #ifdef SS_WATCHDOG_IPV6
2873 tmpaddr.sin6_len = sizeof(tmpaddr);
2874 tmpaddr.sin6_family = AF_INET6;
2875 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2876 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2878 tmpaddr.sin_family = AF_INET;
2879 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2880 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2881 #endif /* SS_WATCHDOG_IPV6 */
2883 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2887 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2888 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2895 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2900 SUnlock(&osCp.wdCp.wdLock);
2905 #endif /* SS_WATCHDOG */
2909 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2915 * Desc: This function gets command line options.
2925 PRIVATE Void mtGetOpts
2930 PRIVATE Void mtGetOpts()
2938 FILE *memOpt; /* memory options file pointer */
2941 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2947 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2949 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2955 #ifdef SS_LOCKLESS_MEMORY
2971 osCp.dep.fileOutFp = (FILE *)NULLP;
2973 /* initialize memOpt */
2974 memOpt = (FILE *) NULLP;
2981 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2986 /* mt001.301 : Additions */
2987 #ifdef SS_MEM_LEAK_STS
2989 cmMemOpenMemLkFile(msOptArg);
2993 osCp.dep.fileOutFp = fopen(msOptArg, "w");
2996 fileBasedMemCfg = TRUE;
2997 memOpt = fopen(msOptArg, "r");
2999 /* if file does not exist or could not be opened then use the
3000 * default memory configuration as defined in mt_ss.h
3002 if (memOpt == (FILE *) NULLP)
3004 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3005 be opened, using default mem configuration\n", msOptArg);
3010 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3012 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3018 case 0: /*** INPUT: Number of regions ***/
3019 sscanf(line, "%ld", (long *) &numReg);
3020 mtMemoCfg.numRegions = numReg;
3021 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3023 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3029 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3030 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3031 if(numBkts > MT_MAX_BKTS)
3033 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3037 if(numPools > SS_MAX_POOLS_PER_REG)
3039 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3044 * Delay updation from local variable to global
3045 * structure of number of regions and heap data to
3046 * counter error conditions present above.
3048 for(idx = 0; idx < cfgNumRegs; idx++)
3050 mtMemoCfg.region[idx].numBkts = numBkts;
3051 cfgRegInfo[idx].region = idx;
3052 cfgRegInfo[idx].numPools = numPools;
3054 * Initialize the pool info as static type with size zero
3056 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3058 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3059 cfgRegInfo[idx].pools[poolIdx].size = 0;
3064 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3065 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3067 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3069 if(bktIdx >= numBkts)
3071 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3076 mtBktInfo[bktIdx].blkSize = bktSz;
3078 if(bktUpdtCnt == numBkts)
3080 i++; /*done reading bkt info, start reading individual region info*/
3084 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3085 sscanf(line,"%ld",(long *) ®Id);
3086 if(regId >= mtMemoCfg.numRegions)
3088 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3089 #ifndef XEON_SPECIFIC_CHANGES
3094 mtMemoCfg.region[regId].regionId = regId;
3097 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3098 if(bktUpdtCnt < numBkts)
3100 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3101 if(bktIdx >= numBkts)
3103 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3108 if(bktIdx < MT_MAX_BKTS)
3110 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3111 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3112 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3113 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3116 if(bktUpdtCnt == numBkts)
3123 case 5: /* INPUT: Heapsize ***/
3124 sscanf(line, "%ld", (long *) &heapSz);
3125 mtMemoCfg.region[regId].heapsize = heapSz;
3127 if(regUpdtCnt != mtMemoCfg.numRegions)
3136 #ifdef SS_LOCKLESS_MEMORY
3138 sscanf(line, "%ld", (long *) &numBkts);
3139 mtGlobMemoCfg.numBkts = numBkts;
3140 #ifndef XEON_SPECIFIC_CHANGES
3141 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3144 #ifdef XEON_SPECIFIC_CHANGES
3145 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3146 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3147 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3149 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3152 mtDynMemoCfg.region[idx].regionId = idx;
3153 mtDynMemoCfg.region[idx].numBkts = numBkts;
3161 if(bktUpdtCnt < numBkts)
3163 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3164 (long *) &bktSz, (long *) &bktNum,
3165 (long *) &bktSetSize, (long *) &bktRelThr,
3166 (long *) &bktAqurThr);
3167 /* Klock work fix ccpu00148484 */
3168 if(bktIdx < SS_MAX_POOLS_PER_REG)
3170 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3171 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3172 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3173 #ifdef XEON_SPECIFIC_CHANGES
3174 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3175 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3176 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3178 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3180 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3186 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3188 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3189 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3190 #ifdef XEON_SPECIFIC_CHANGES
3191 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3192 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3193 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3199 #ifdef XEON_SPECIFIC_CHANGES
3200 if(bktUpdtCnt == numBkts)
3206 case 8: /* INPUT: Global Heapsize ***/
3207 sscanf(line, "%ld", (long *) &heapSz);
3208 mtGlobMemoCfg.heapSize = heapSz;
3209 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3217 memConfigured = FALSE;
3221 memConfigured = TRUE;
3229 /* mt028.201: modification: multiple procs support related changes */
3230 #ifndef SS_MULTIPLE_PROCS
3233 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3235 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3238 #else /* SS_MULTIPLE_PROCS */
3242 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3244 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3246 SAddProcIdLst(1, &procId);
3249 #endif /* SS_MULTIPLE_PROCS */
3253 osCp.configFilePath = msOptArg;
3277 * Desc: Get options from command line
3279 * Ret: option - success
3281 * EOF - end of options
3283 * Notes: Handles command lines like the following
3286 * then command line should look like this...
3287 * -a foo -b foo1 -c -d foo
3291 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3296 * nloops = atoi(msArgv[msOptInd]);
3299 * state1 = atoi(msArgv[msOptInd]);
3312 int argc, /* argument count */
3313 char **argv, /* argument value */
3314 char *opts /* options */
3317 PUBLIC S16 SGetOpt(argc, argv, opts)
3318 int argc; /* argument count */
3319 char **argv; /* argument value */
3320 char *opts; /* options */
3323 /* mt020.201 - Removed for no command line */
3332 /* mt020.201 - Addition for no command line */
3344 /*mt013.301 : Changes as per coding standards*/
3345 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3351 if (!strcmp(argv[msOptInd], "--"))
3356 else if (argv[msOptInd][0] != '-')
3364 c = argv[msOptInd][sp];
3365 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3367 if (argv[msOptInd][++sp] == '\0')
3378 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3381 if (++msOptInd >= (S16) argc)
3386 else msOptArg = argv[msOptInd++];
3393 if (argv[msOptInd][++sp] == '\0')
3405 #endif /* NOCMDLINE */
3413 * Desc: This function starts system services execution; the
3414 * permanent tasks are started and the system enters a
3425 PUBLIC Void ssdStart
3430 PUBLIC Void ssdStart()
3439 /* mt025.201 - Modification for adding lock to timer handler */
3440 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3442 sem_post(&osCp.dep.ssStarted);
3451 * indirect interface functions to system services service user
3457 * Fun: ssdAttachTTsk
3459 * Desc: This function sends the initial tick message to a TAPA
3460 * task if the task is a permanent task.
3470 PUBLIC S16 ssdAttachTTsk
3472 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3475 PUBLIC S16 ssdAttachTTsk(tTsk)
3476 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3484 TRC0(ssdAttachTTsk);
3487 if (tTsk->tskType == SS_TSK_PERMANENT)
3489 /* Send a permanent tick message to this task, to start
3492 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3495 #if (ERRCLASS & ERRCLS_DEBUG)
3496 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3501 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3502 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3504 /* set up post structure */
3505 /* mt028.201: modification: multiple procs support related changes */
3506 #ifndef SS_MULTIPLE_PROCS
3507 mInfo->pst.dstProcId = SFndProcId();
3508 mInfo->pst.srcProcId = SFndProcId();
3509 #else /* SS_MULTIPLE_PROCS */
3510 mInfo->pst.dstProcId = tTsk->proc;
3511 mInfo->pst.srcProcId = tTsk->proc;
3512 #endif /* SS_MULTIPLE_PROCS */
3513 mInfo->pst.selector = SEL_LC_NEW;
3514 mInfo->pst.region = DFLT_REGION;
3515 mInfo->pst.pool = DFLT_POOL;
3516 mInfo->pst.prior = PRIOR3;
3517 mInfo->pst.route = RTESPEC;
3518 mInfo->pst.event = 0;
3519 mInfo->pst.dstEnt = tTsk->ent;
3520 mInfo->pst.dstInst = tTsk->inst;
3521 mInfo->pst.srcEnt = tTsk->ent;
3522 mInfo->pst.srcInst = tTsk->inst;
3524 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3525 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3531 #if (ERRCLASS & ERRCLS_DEBUG)
3532 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3533 "Could not write to demand queue");
3546 * Fun: ssdDetachTTsk
3548 * Desc: Does nothing.
3558 PUBLIC S16 ssdDetachTTsk
3560 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3563 PUBLIC S16 ssdDetachTTsk(tTsk)
3564 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3567 TRC0(ssdDetachTTsk);
3576 * Fun: ssdCreateSTsk
3578 * Desc: This function creates a system task. A thread is started
3579 * on the system task handler function defined later.
3589 PUBLIC S16 ssdCreateSTsk
3591 SsSTskEntry *sTsk /* pointer to system task entry */
3594 PUBLIC S16 ssdCreateSTsk(sTsk)
3595 SsSTskEntry *sTsk; /* pointer to system task entry */
3598 pthread_attr_t attr;
3599 /* struct sched_param param_sched;*/
3601 #ifdef SS_THR_REG_MAP
3602 U32 threadCreated = FALSE;
3605 TRC0(ssdCreateSTsk);
3608 #ifdef SS_SINGLE_THREADED
3609 /* mt001.301 : Additions */
3611 #ifdef SS_MULTICORE_SUPPORT
3612 if (osCp.numSTsks > 1)
3614 if (osCp.numSTsks > 0)
3615 #endif /* SS_MULTICORE_SUPPORT */
3617 #ifdef SS_MULTICORE_SUPPORT
3618 if (osCp.numSTsks > 3)
3620 if (osCp.numSTsks > 2)
3621 #endif /* SS_MULTICORE_SUPPORT */
3622 #endif /* SS_WATCHDOG */
3629 /* set the current executing entity and instance IDs to
3630 * 'not configured'. create the lock to access them.
3632 sTsk->dep.ent = ENTNC;
3633 sTsk->dep.inst = INSTNC;
3636 /* create the thread */
3637 pthread_attr_init(&attr);
3638 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3640 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3641 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3642 if (sTsk->tskPrior == 0)
3644 printf("Creating RT thread #######################\n");
3645 #ifdef SS_THR_REG_MAP
3646 /* When the thread is created, we check for the memory mapping table if
3647 * threadId can be placed in thread memory map table. If it is not able to place
3648 * threadId is stored in tmporary array. Once thread is created successful,
3649 * thread_cancel is sent for each thread which are created before. All the
3650 * threads are made to wait on sema which is cancel point for thread.
3652 while(threadCreated == FALSE)
3655 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlrT2kL2, (Ptr)sTsk)) != 0)
3658 pthread_attr_destroy(&attr);
3660 #if (ERRCLASS & ERRCLS_DEBUG)
3661 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3666 #ifdef SS_THR_REG_MAP
3667 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3675 #ifdef SS_THR_REG_MAP
3676 /* When the thread is created, we check for the memory mapping table if
3677 * threadId can be placed in thread memory map table. If it is not able to place
3678 * threadId is stored in tmporary array. Once thread is created successful,
3679 * thread_cancel is sent for each thread which are created before. All the
3680 * threads are made to wait on sema which is cancel point for thread.
3682 while(threadCreated == FALSE)
3685 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk)) != 0)
3688 /* mt020.201 - Addition for destroying thread attribute object attr */
3689 pthread_attr_destroy(&attr);
3691 #if (ERRCLASS & ERRCLS_DEBUG)
3692 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3697 #ifdef SS_THR_REG_MAP
3698 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3705 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3706 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3708 static U32 stLwpId = 3;
3709 sTsk->dep.lwpId = ++stLwpId;
3711 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3713 /* mt020.201 - Addition for destroying thread attribute object attr */
3714 pthread_attr_destroy(&attr);
3721 PUBLIC int SCreatePThread
3724 pthread_attr_t* attr,
3725 void *(*start_routine) (void *),
3729 PUBLIC int SCreatePThread(tid, attr, start_routine, arg)
3731 pthread_attr_t* attr;
3732 void *(*start_routine) (void *);
3737 #ifdef SS_THR_REG_MAP
3738 U32 threadCreated = FALSE;
3741 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3742 /* Klock work fix ccpu00148484 */
3743 if(threadArg == NULLP)
3747 threadArg->argument = arg;
3748 threadArg->start_routine = start_routine;
3750 TRC0(SCreatePThread);
3752 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3754 #ifdef SS_THR_REG_MAP
3755 /* When the thread is created, we check for the memory mapping table if
3756 * threadId can be placed in thread memory map table. If it is not able to place
3757 * threadId is stored in tmporary array. Once thread is created successful,
3758 * thread_cancel is sent for each thread which are created before. All the
3759 * threads are made to wait on sema which is cancel point for thread.
3761 while(threadCreated == FALSE)
3764 /*pthreadCreateHdlr */
3765 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3770 #ifdef SS_THR_REG_MAP
3771 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3782 * Fun: Set Pthread Attributes
3784 * Desc: This function is used to set various explicit
3785 * pthread attributes like, priority scheduling,etc
3796 PRIVATE S16 ssdSetPthreadAttr
3799 pthread_attr_t *attr
3802 PRIVATE S16 ssdSetPthreadAttr(sTsk, attr)
3804 pthread_attr_t *attr
3807 struct sched_param param;
3809 TRC0 (ssdSetPthreadAttr)
3811 SMemSet(¶m, 0, sizeof(param));
3813 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3814 param.sched_priority = 100 - 1 - tskPrior;
3816 param.sched_priority = 100 - 10 - tskPrior;
3819 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3820 /* TODO:: This can be avoided by reducing the priority
3821 * of iccserv thread in l1_master.sh*/
3823 if (clusterMode == RADIO_CLUSTER_MODE)
3825 if(tskPrior == PRIOR1)
3827 param.sched_priority = 91;
3834 printf("Set priority %u\n", param.sched_priority);
3836 /* Set Scheduler to explicit, without this non of the below
3837 pthread attr works */
3838 #ifdef TENB_RTLIN_CHANGES
3839 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3842 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3843 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3844 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3845 #ifdef TENB_RTLIN_CHANGES
3846 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3848 pthread_attr_setschedparam(attr, ¶m);
3852 } /* ssdSetPthreadAttr */
3854 /************* multi-core support **************/
3855 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3856 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3860 * Fun: Get the current core/cpu affinity for a thread/lwp
3862 * Desc: This function is used to get the current processor/core
3863 * affinity for a a system task (thread/lwp). It sets the
3864 * affinity based on the mode supplied by the caller.
3867 * RFAILED - failed, general (optional)
3875 PUBLIC S16 ssdGetAffinity
3877 SSTskId *tskId, /* filled in with system task ID */
3878 U32 *coreId /* the core/processor id to which the affinity is set */
3881 PUBLIC S16 ssdGetAffinity(tskId, coreId)
3882 SSTskId *tskId; /* filled in with system task ID */
3883 U32 *coreId; /* the core/processor id to which the affinity is set */
3894 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3900 TRC0(ssdGetAffinity);
3902 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3904 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3906 tId = osCp.sTskTbl[tskInd].dep.tId;
3911 /* if tskId is not found in the tskTbl */
3912 if (tskInd == SS_MAX_STSKS)
3914 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3919 /* initialize the cpu mask */
3922 /* set thread affinity for linux */
3923 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3925 #if (ERRCLASS & ERRCLS_DEBUG)
3926 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3929 } /* end if pthread_setaffinity fails */
3931 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3933 if (CPU_ISSET (cpuInd, & cpuSet))
3942 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3944 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3946 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3951 /* if tskId is not found in the tskTbl */
3952 if (tskInd == SS_MAX_STSKS)
3954 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3958 /* set thread affinity for Solaris */
3959 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3961 #if (ERRCLASS & ERRCLS_DEBUG)
3962 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3965 } /* end if processor_bind fails */
3968 #endif /* SS_LINUX */
3972 } /* ssdGetAffinity */
3977 * Fun: Set the core/cpu affinity for a thread/lwp
3979 * Desc: This function is used to set processor/core affinity for a
3980 * a system task (thread/lwp). It sets the affinity based on the
3981 * mode supplied by the caller.
3984 * RFAILED - failed, general (optional)
3992 PUBLIC S16 ssdSetAffinity
3994 SSTskId *tskId, /* filled in with system task ID */
3995 U32 coreId /* the core/processor id to which the affinity has to be set */
3998 PUBLIC S16 ssdSetAffinity(tskId, coreId)
3999 SSTskId *tskId; /* filled in with system task ID */
4000 U32 coreId; /* the core/processor id to which the affinity has to be set */
4009 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4016 TRC0(ssdSetAffinity)
4019 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4021 /* Here tskId can not be used as index as the task may be terminated if
4022 there is a TERM even for that tsk, thus breaking the task Id numbering
4024 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4026 tId = osCp.sTskTbl[tskInd].dep.tId;
4031 /* if tskId is not found in the tskTbl */
4032 if (tskInd == SS_MAX_STSKS)
4034 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4038 /* initialize the cpu mask */
4041 /* set the cpu mask */
4042 CPU_SET(coreId, &cpuSet);
4044 /* set thread affinity for linux */
4045 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4047 #if (ERRCLASS & ERRCLS_DEBUG)
4048 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4051 } /* end if pthread_setaffinity fails */
4055 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4057 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4058 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4060 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4065 /* if tskId is not found in the tskTbl */
4066 if (tskInd == SS_MAX_STSKS)
4068 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4072 /* set thread affinity for Solaris */
4073 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4075 #if (ERRCLASS & ERRCLS_DEBUG)
4076 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4079 } /* end if processor_bind fails */
4082 #endif /* SS_LINUX */
4084 } /* ssdSetAffinity */
4086 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4087 /************ end multi-core support *************/
4092 * Fun: ssdDestroySTsk
4094 * Desc: This function destroys a system task. A terminate
4095 * event message is sent to the thread function.
4105 PUBLIC S16 ssdDestroySTsk
4107 SsSTskEntry *sTsk /* pointer to system task entry */
4110 PUBLIC S16 ssdDestroySTsk(sTsk)
4111 SsSTskEntry *sTsk; /* pointer to system task entry */
4118 TRC0(ssdDestroySTsk);
4121 /* we send a message to this system task to tell it to die */
4122 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4125 #if (ERRCLASS & ERRCLASS_DEBUG)
4126 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4132 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4133 mInfo->eventInfo.event = SS_EVNT_TERM;
4135 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4139 #if (ERRCLASS & ERRCLASS_DEBUG)
4140 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4141 "Could not write to demand queue");
4151 /* mt023.201 - Added SThreadYield function to yield CPU
4155 * Desc: This function defers thread execution to any other ready
4167 PUBLIC S16 SThreadYield
4172 PUBLIC S16 SThreadYield()
4178 /* mt024.201 - seperated Linux and other UNIX implementations
4184 /* Set sleep value to 0 to yield CPU */
4188 RETVALUE(select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4190 #else /* other UNICes */
4192 RETVALUE(sleep(0) == 0 ? ROK : RFAILED);
4194 #endif /* SS_LINUX */
4201 * Fun: Register timer
4203 * Desc: This function is used to register a timer
4204 * function for the service user. System services
4205 * will invoke the timer activation function
4206 * passed to it at the specified intervals.
4210 * Notes: Timing is handled by the common timers. The
4211 * ticks are handled by a thread that uses
4212 * nanosleep() and thus timing precision will not
4219 PUBLIC S16 ssdRegTmr
4221 SsTmrEntry *tmr /* pointer to timer entry */
4224 PUBLIC S16 ssdRegTmr(tmr)
4225 SsTmrEntry *tmr; /* pointer to timer entry */
4234 /* initialize common timers */
4235 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4238 /* start the timer */
4239 arg.tq = osCp.dep.tmrTq;
4240 arg.tqCp = &osCp.dep.tmrTqCp;
4241 arg.timers = tmr->dep.timers;
4246 arg.max = TMR_DEF_MAX;
4247 arg.wait = tmr->interval;
4257 * Fun: Deregister timer
4259 * Desc: This function is used to deregister a timer function.
4269 PUBLIC S16 ssdDeregTmr
4271 SsTmrEntry *tmr /* pointer to timer entry */
4274 PUBLIC S16 ssdDeregTmr(tmr)
4275 SsTmrEntry *tmr; /* pointer to timer entry */
4284 /* stop the timer */
4285 arg.tq = osCp.dep.tmrTq;
4286 arg.tqCp = &osCp.dep.tmrTqCp;
4287 arg.timers = tmr->dep.timers;
4292 arg.max = TMR_DEF_MAX;
4293 arg.wait = tmr->interval;
4303 * Fun: Critical error
4305 * Desc: This function is called when a critical error occurs.
4317 Seq seq, /* sequence number */
4318 Reason reason /* reset reason */
4321 PUBLIC S16 ssdError(seq, reason)
4322 Seq seq; /* sequence number */
4323 Reason reason; /* reset reason */
4334 /* get calling task ID */
4335 tId = pthread_self();
4338 /* set up the message to display */
4339 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4340 "reason = %d\n\n", (U8)tId, seq, reason);
4344 /* delete all system tasks */
4345 for (i = 0; i < SS_MAX_STSKS; i++)
4347 if (osCp.sTskTbl[i].used
4348 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4350 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4356 pthread_exit(NULLP);
4359 /* won't reach here */
4368 * Desc: This function is called to log an error.
4378 PUBLIC Void ssdLogError
4380 Ent ent, /* Calling layer's entity id */
4381 Inst inst, /* Calling layer's instance id */
4382 ProcId procId, /* Calling layer's processor id */
4383 Txt *file, /* file name where error occured */
4384 S32 line, /* line in file where error occured */
4385 ErrCls errCls, /* error class */
4386 ErrCode errCode, /* layer unique error code */
4387 ErrVal errVal, /* error value */
4388 Txt *errDesc /* description of error */
4391 PUBLIC Void ssdLogError(ent, inst, procId, file, line,
4392 errCls, errCode, errVal, errDesc)
4393 Ent ent; /* Calling layer's entity id */
4394 Inst inst; /* Calling layer's instance id */
4395 ProcId procId; /* Calling layer's processor id */
4396 Txt *file; /* file name where error occured */
4397 S32 line; /* line in file where error occured */
4398 ErrCls errCls; /* error class */
4399 ErrCode errCode; /* layer unique error code */
4400 ErrVal errVal; /* error value */
4401 Txt *errDesc; /* description of error */
4415 /* get calling task ID */
4417 tId = pthread_self();
4423 case ERRCLS_ADD_RES:
4424 errClsMsg = "ERRCLS_ADD_RES";
4427 case ERRCLS_INT_PAR:
4428 errClsMsg = "ERRCLS_INT_PAR";
4432 errClsMsg = "ERRCLS_DEBUG";
4435 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4437 errClsMsg = "ERRCLS_FTHA";
4441 errClsMsg = "INVALID ERROR CLASS!";
4446 /*mt009.301 Fixed 64BIT compilation warnings*/
4449 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4450 "file: %s line: %03d errcode: %05d errcls: %s\n"
4451 "errval: %05d errdesc: %s\n",
4452 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4455 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4456 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4457 "errval: %05ld errdesc: %s\n",
4458 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4460 SDisplay(0, errBuf);
4461 /* mt001.301 : Additions */
4462 #ifdef SS_LOGGER_SUPPORT
4464 #endif /* SS_LOGGER_SUPPORT */
4468 /* debug errors halt the system */
4469 if (errCls == ERRCLS_DEBUG)
4471 /* mt001.301 : Additions */
4472 #ifdef SS_LOGGER_SUPPORT
4474 #endif /* SS_LOGGER_SUPPORT */
4475 /* delete all system tasks */
4476 for (i = 0; i < SS_MAX_STSKS; i++)
4478 if (osCp.sTskTbl[i].used
4479 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4481 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4487 pthread_exit(NULLP);
4499 * Fun: Register driver task
4501 * Desc: This function is called to register the handlers for a
4512 PUBLIC S16 ssdRegDrvrTsk
4514 SsDrvrTskEntry *drvrTsk /* driver task entry */
4517 PUBLIC S16 ssdRegDrvrTsk(drvrTsk)
4518 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4521 TRC0(ssdRegDrvrTsk);
4526 /* mt001.30 : Additions */
4529 * Fun: Deregister driver task
4531 * Desc: This function is called to deregister the handlers for a
4542 PUBLIC S16 ssdDeregDrvrTsk
4544 SsDrvrTskEntry *drvrTsk /* driver task entry */
4547 PUBLIC S16 ssdDeregDrvrTsk(drvrTsk)
4548 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4551 TRC0(ssdDeregDrvrTsk);
4562 * mt003.301 Additions - SDeRegTTsk fix
4564 #ifdef SS_MULTIPLE_PROCS
4566 PUBLIC S16 ssdProcTTskTerm
4573 PUBLIC S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4578 #else /*SS_MULTIPLE_PROCS*/
4580 PUBLIC S16 ssdProcTTskTerm
4586 PUBLIC S16 ssdProcTTskTerm(tTsk, idx)
4590 #endif /*SS_MULTIPLE_PROCS*/
4592 #ifdef SS_MULTIPLE_PROCS
4601 TRC0(ssdProcTTskTerm);
4606 /* We check the sTsk element; if it is not NULLP, the
4607 * task is attached. So we have to detach it before
4608 * deregistering the task.
4610 ret = SLock(&osCp.sTskTblLock);
4613 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4616 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4619 #if (ERRCLASS & ERRCLS_DEBUG)
4620 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4622 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4624 #if (ERRCLASS & ERRCLS_DEBUG)
4625 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4633 #ifdef SS_MULTIPLE_PROCS
4635 if (tTsk->initTsk != NULLP)
4638 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4641 &(osCp.tTskTbl[idx].xxCb));
4643 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4646 &(osCp.tTskTbl[idx].xxCb));
4647 #endif /* USE_MEMCAL */
4649 #endif /* SS_MULTIPLE_PROCS */
4651 if (tTsk->sTsk != NULLP)
4655 sTsk->dep.ent = ent;
4656 sTsk->dep.inst = inst;
4658 for (n = 0; n < SS_MAX_TTSKS; n++)
4660 if (sTsk->tTsks[n] == idx)
4662 sTsk->tTsks[n] = SS_INVALID_IDX;
4668 /* call the implementation to detach the task */
4669 ssdDetachTTsk(tTsk);
4671 sTsk->dep.ent = ENTNC;
4672 sTsk->dep.inst = INSTNC;
4675 /* Now we empty the entry for this task and update the table
4678 #ifdef SS_MULTIPLE_PROCS
4679 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4680 #else /* SS_MULTIPLE_PROCS */
4681 osCp.tTskIds[ent][inst] = SS_TSKNC;
4682 #endif /* SS_MULTIPLE_PROCS */
4685 #ifdef SS_MULTIPLE_PROCS
4686 tTsk->proc = PROCNC;
4687 #endif /* SS_MULTIPLE_PROCS */
4689 tTsk->inst = INSTNC;
4690 tTsk->tskType = TTUND;
4691 tTsk->initTsk = NULLP;
4692 tTsk->actvTsk = NULLP;
4695 tTsk->nxt = osCp.nxtTTskEntry;
4696 osCp.nxtTTskEntry = idx;
4699 #ifdef SS_MULTIPLE_PROCS
4700 /* mark the control block for this task as invalid */
4701 osCp.tTskTbl[idx].xxCb = NULLP;
4704 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4705 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4707 #if (ERRCLASS & ERRCLS_DEBUG)
4708 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4715 //#ifndef SPLIT_RLC_DL_TASK
4716 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4717 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4718 EXTERN Void ysMtTskHdlr(Void);
4719 EXTERN Void ysMtPollPhyMsg(U8 region);
4720 EXTERN Void ysMtRcvPhyMsg(Void);
4722 PUBLIC Void *mtTskHdlrT2kL2
4724 Ptr tskPtr /* pointer to task entry */
4727 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4728 Ptr tskPtr; /* pointer to task entry */
4734 /* wait for SS to come up */
4735 /* It is required to block on this semaphore before starting actual processing of
4736 the thread becasue the creator of this thread might want to cance it without
4737 doing any processing. When this semaphore is released, means the creator gives
4738 the go ahead for actual processing and we should never come back to this point */
4739 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4748 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4749 * (processes L1 msgs) */
4755 EXTERN Void ysMtTskHdlr(Void);
4756 EXTERN Void YsPhyRecvMsg();
4758 PUBLIC Void *mtTskHdlrT2kL2
4760 Ptr tskPtr /* pointer to task entry */
4763 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4764 Ptr tskPtr; /* pointer to task entry */
4770 /* get out the system task entry from the parameter */
4771 sTsk = (SsSTskEntry *) tskPtr;
4773 /* wait for SS to come up */
4774 /* It is required to block on this semaphore before starting actual processing of
4775 the thread becasue the creator of this thread might want to cance it without
4776 doing any processing. When this semaphore is released, means the creator gives
4777 the go ahead for actual processing and we should never come back to this point */
4778 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4781 #ifndef RGL_SPECIFIC_CHANGES
4789 #ifdef V5GTF_SPECIFIC_CHANGES
4792 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4793 * (processes L1 msgs) */
4795 /* get a message from the demand queue */
4797 #ifdef RLC_MAC_DAT_REQ_RBUF
4798 rgDlDatReqBatchProc();
4801 ret = mtTskHdlMsg(sTsk);
4804 /* exit the for loop here */
4807 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4814 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4818 PUBLIC void *pthreadCreateHdlr
4823 PUBLIC void *pthreadCreateHdlr(pthreadCreateArg)
4828 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4829 /* mt038.201 changed how sem_wait is called */
4830 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4833 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4841 * Desc: This is the system task handler function. It blocks on
4842 * the system task's demand queue. On receiving a message,
4843 * it identifies the target TAPA task, verifies that the
4844 * TAPA task belongs to this system task and if so, calls
4845 * the activation function of that TAPA task with the
4846 * received message. The task activation function or the
4847 * timer activation function may be called.
4849 * Ret: (thread function)
4857 PUBLIC Void *mtTskHdlr
4859 Ptr tskPtr /* pointer to task entry */
4862 PUBLIC Void *mtTskHdlr(tskPtr)
4863 Ptr tskPtr; /* pointer to task entry */
4869 /* get out the system task entry from the parameter */
4870 sTsk = (SsSTskEntry *) tskPtr;
4873 /* wait for SS to come up */
4875 /* mt038.201 changed how sem_wait is called */
4876 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4878 #ifdef XEON_SPECIFIC_CHANGES
4879 printf("\n**********MT Task Handler********\n");
4883 /* Wait for a message from the demand queue */
4884 #ifdef SS_CDMNDQ_SUPPORT
4885 ret = ssCDmndQWait(&sTsk->dQ);
4887 ret = ssDmndQWait(&sTsk->dQ);
4892 ret = mtTskHdlMsg(sTsk);
4907 * Desc: This is the system task handler function. It blocks on
4908 * the system task's demand queue. On receiving a message,
4909 * it identifies the target TAPA task, verifies that the
4910 * TAPA task belongs to this system task and if so, calls
4911 * the activation function of that TAPA task with the
4912 * received message. The task activation function or the
4913 * timer activation function may be called.
4915 * Ret: (thread function)
4923 PUBLIC S16 mtTskHdlMsg
4928 PUBLIC S16 mtTskHdlMsg(sTsk)
4942 /* mt028.201: modification: multiple procs support related changes */
4943 #ifndef SS_MULTIPLE_PROCS
4945 PAIFTMRS16 tmrActvFnMt = NULLP;
4947 /* mt015.301 Initialized the timer activation functions with NULLP */
4948 PFS16 tmrActvFn = NULLP;
4950 PAIFTMRS16 tmrActvFn;
4952 #endif /* SS_MULTIPLE_PROCS */
4953 /* mt003.301 Modifications */
4954 #ifdef SS_THREAD_PROFILE
4956 #endif /* SS_THREAD_PROFILE */
4959 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4962 /* nothing to receive */
4966 /* if we can't lock this system task entry, return the message */
4967 ret = SLock(&sTsk->lock);
4971 #if (ERRCLASS & ERRCLS_DEBUG)
4972 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4973 "Could not lock system task entry");
4983 mBuf2 = mBuf->b_next;
4985 /* find out what kind of message this is */
4986 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4987 #ifdef SS_MEM_WL_DEBUG
4988 mtTskBuffer1 = mBuf2;
4990 mtTskBuffer2 = mBuf2->b_next;
4992 if(mInfo == 0x5050505)
4996 cmAnalyseBtInfo((PTR) mBuf,4);
4998 printf("\n In trouble .... \n");
5000 else if (mInfo == 0x2020202)
5003 cmAnalyseBtInfo((PTR) mBuf,1);
5004 printf("\n In trouble .... \n");
5006 #endif /* SS_MEM_WL_DEBUG */
5007 switch (mInfo->eventInfo.event)
5009 /* this is a termination event, we die */
5011 /* release the message */
5014 /* Unlock the system task entry and lock the system
5015 * task table to clean our entry up.
5017 SUnlock(&sTsk->lock);
5019 ret = SLock(&osCp.sTskTblLock);
5023 #if (ERRCLASS & ERRCLS_DEBUG)
5024 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5025 "Could not lock system task table");
5027 /* what to do here? */
5031 /* clean up the system task entry */
5034 /* mt003.301 Modifications - SDeRegTTsk */
5035 /* sTsk->numTTsks = 0; */
5036 SDestroyLock(&sTsk->lock);
5037 ssDestroyDmndQ(&sTsk->dQ);
5039 /* lock for current executing TAPA task ID */
5041 /* make this entry available in the system task table */
5042 sTsk->nxt = osCp.nxtSTskEntry;
5043 for (i = 0; i < SS_MAX_STSKS; i++)
5045 if (sTsk == &osCp.sTskTbl[i])
5047 osCp.nxtSTskEntry = i;
5054 /* unlock the system task table */
5055 SUnlock(&osCp.sTskTblLock);
5060 /* this is a data message or a permanent task keep-alive message */
5062 case SS_EVNT_PERMTICK:
5063 /* message to a task. find the destination task */
5064 /* mt028.201: modification: multiple procs support related changes */
5065 #ifdef SS_MULTIPLE_PROCS
5066 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5068 if (procIdIdx == SS_INV_PROCID_IDX)
5074 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5075 #else /* SS_MULTIPLE_PROCS */
5076 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5077 #endif /* SS_MULTIPLE_PROCS */
5079 /* verify that it hasn't been deregistered */
5080 if (idx == SS_TSKNC)
5086 /* verify that this system task is still running it */
5087 tTsk = &osCp.tTskTbl[idx];
5088 if (tTsk->sTsk != sTsk)
5094 /* set the current executing TAPA task ID */
5095 sTsk->dep.ent = mInfo->pst.dstEnt;
5096 sTsk->dep.inst = mInfo->pst.dstInst;
5098 /* copy the Pst structure into a local duplicate */
5099 for (i = 0; i < (S16) sizeof(Pst); i++)
5100 *(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
5102 /* Give the message to the task activation function. If
5103 * its a normal data message, we pass it, if this is a
5104 * keep-alive message for a permanent task then we pass
5105 * NULLP in place of the message to the task activation
5108 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5110 #ifndef RGL_SPECIFIC_CHANGES
5111 #ifdef SS_TSKLOG_ENABLE
5112 U32 t = MacGetTick();
5115 /* mt003.301 Modifications */
5116 #if SS_THREAD_PROFILE
5117 tTsk->curEvent = nPst.event;
5119 #endif /* SS_THREAD_PROFILE */
5120 tTsk->actvTsk(&nPst, mBuf);
5121 #ifndef RGL_SPECIFIC_CHANGES
5122 #ifdef SS_TSKLOG_ENABLE
5123 SStopTask(t,PID_SSI_TSK);
5126 #if SS_THREAD_PROFILE
5128 tTsk->curEvtTime = (U32)(et2 - et1);
5129 tTsk->totTime += (U64)tTsk->curEvtTime;
5130 #endif /* SS_THREAD_PROFILE */
5134 #if (ERRCLASS & ERRCLS_DEBUG)
5135 /* this message should only come to a permanent task */
5136 if (tTsk->tskType != SS_TSK_PERMANENT)
5138 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5142 tTsk->actvTsk(&nPst, NULLP);
5144 /* We need to re-send this message back to ourselves so
5145 * the permanent task continues to run.
5147 /* Check if this task got deregistered or detached
5148 * by the activation function; if so, there's nothing
5149 * more to do here, otherwise go ahead.
5152 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5154 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5155 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5159 /* failure here is a real problem */
5162 #if (ERRCLASS & ERRCLS_DEBUG)
5163 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5164 "Could not write to demand queue");
5170 /* unset the current executing TAPA task ID */
5171 sTsk->dep.ent = ENTNC;
5172 sTsk->dep.inst = INSTNC;
5177 /* timer event. find the timer entry */
5178 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5180 /* lock the timer table, coz we're going to peek in it */
5181 ret = SLock(&osCp.tmrTblLock);
5185 #if (ERRCLASS & ERRCLS_DEBUG)
5186 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5187 "Could not lock timer table");
5193 /* Verify that this timer entry is still around and that it
5194 * belongs to our task.
5196 if (osCp.tmrTbl[idx].used == FALSE
5197 /* mt028.201: modification: multiple procs support related changes */
5198 #ifdef SS_MULTIPLE_PROCS
5199 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5200 #endif /* SS_MULTIPLE_PROCS */
5201 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5202 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5204 SUnlock(&osCp.tmrTblLock);
5209 /* mt005.21: addition */
5210 /* set the current executing TAPA task ID */
5211 sTsk->dep.ent = mInfo->pst.dstEnt;
5212 sTsk->dep.inst = mInfo->pst.dstInst;
5214 #ifndef SS_MULTIPLE_PROCS
5216 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5217 tmrActvFnMt = NULLP;
5218 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5220 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5226 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5229 /* unlock the timer table */
5230 SUnlock(&osCp.tmrTblLock);
5232 /* activate the timer function */
5233 /* mt028.201: modification: multiple procs support related changes */
5234 #ifndef SS_MULTIPLE_PROCS
5238 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5239 osCp.tmrTbl[idx].ownerInst);
5247 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5248 osCp.tmrTbl[idx].ownerInst);
5249 #endif /* SS_MULTIPLE_PROCS */
5251 /*mt005.21: addition */
5252 /* unset the current executing TAPA task ID */
5253 sTsk->dep.ent = ENTNC;
5254 sTsk->dep.inst = INSTNC;
5257 /* return the message buffer */
5261 * mt003.301 - SDeRegTTsk fix
5263 case SS_EVNT_TTSK_TERM:
5264 #ifdef SS_MULTIPLE_PROCS
5265 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5267 if (procIdIdx == SS_INV_PROCID_IDX)
5273 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5274 #else /* SS_MULTIPLE_PROCS */
5275 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5276 #endif /* SS_MULTIPLE_PROCS */
5278 /* verify that it hasn't been deregistered */
5279 if (idx == SS_TSKNC)
5285 /* verify that this system task is still running it */
5286 tTsk = &osCp.tTskTbl[idx];
5287 if (tTsk->sTsk != sTsk)
5292 #ifdef SS_MULTIPLE_PROCS
5293 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5295 ssdProcTTskTerm(tTsk, idx);
5301 #if (ERRCLASS & ERRCLS_DEBUG)
5302 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5309 } while (mBuf != NULLP);
5312 /* unlock the system task entry */
5313 SUnlock(&sTsk->lock);
5316 /* yield for other threads */
5317 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5326 * Fun: mtTmrHdlrPublic
5329 PUBLIC Void mtTmrHdlrPublic
5333 PUBLIC Void mtTmrHdlrPublic()
5336 if (SLock(&osCp.tmrTblLock) != ROK)
5338 #if (ERRCLASS & ERRCLS_DEBUG)
5339 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5343 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5344 /* unlock the timer table */
5345 SUnlock(&osCp.tmrTblLock);
5353 * Desc: The timer handler thread function. Counts time
5354 * and invokes the common timer function on each
5357 * Ret: (thread function)
5364 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5366 PRIVATE Void *mtTmrHdlr
5368 void *parm /* unused */
5371 /* mt009.21: addition */
5372 PRIVATE Void *mtTmrHdlr(parm)
5373 void *parm; /* unused */
5376 /*mt004.301-addede new region*/
5377 /* mt010.301 Removed SS_FAP portion and
5378 * enabled oroginal code in function mtTmrHdlr */
5382 U32 i, cnt, oldTicks, newTicks;
5383 struct timeval tv1,tv2;
5384 /* mt038.201 added return */
5386 /* mt039.201 changes for nanosleep */
5387 struct timespec tsN;
5388 PRIVATE U32 err_in_usec;
5390 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5395 /* mt027.201 - Modification for SRegCfgTmr support */
5396 /* check SS_TICKS_SEC */
5397 if (SS_1MS < SS_TICKS_SEC)
5399 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5402 /* mt025.201 - Addition to stop timer handler till task registration is done */
5403 /* wait for SS to come up */
5404 /* mt038.201 changed how sem_wait is called */
5405 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5408 /* mt027.201 - Modification for SRegCfgTmr support */
5409 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5411 ts.tv_nsec = (MT_TICK_CNT * 1000);
5412 /* mt039.201 changes for nanosleep */
5418 if (gettimeofday(&tv1, NULL) == -1)
5420 #if (ERRCLASS & ERRCLS_DEBUG)
5421 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5422 "Error in clock_gettime");
5432 #ifndef STUB_TTI_HANDLING_5GTF
5433 printf("Returning from mtTmrHdlr()\n");
5438 /* mt039.201 changes for nanosleep */
5439 /* sleep for MT_TICK_CNT milli seconds */
5440 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5441 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5443 ts.tv_nsec = tsN.tv_nsec;
5448 if (gettimeofday(&tv2,NULL) == -1)
5450 #if (ERRCLASS & ERRCLS_DEBUG)
5451 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5452 "Error in clock_gettime");
5456 /*mt013.301 : changed check while calculating timer to fix
5457 * diffrence between MTSS time and real unix time
5459 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5461 time_int = (tv2.tv_usec - tv1.tv_usec);
5463 else if (tv2.tv_sec > tv1.tv_sec)
5465 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5467 else /* ts2 < ts1, this will not happen in normal scenario */
5469 /* to make sure cnt = 1 */
5471 time_int = MT_TICK_CNT;
5474 oldTicks = osCp.dep.sysTicks;
5475 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5476 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5477 newTicks = osCp.dep.sysTicks;
5478 tv1.tv_usec = tv2.tv_usec;
5479 tv1.tv_sec = tv2.tv_sec;
5481 cnt = newTicks - oldTicks;
5483 while(err_in_usec >= MT_TICK_CNT)
5486 err_in_usec -= MT_TICK_CNT;
5488 if( cnt >= MT_MAX_TICK_CNT_VAL)
5489 cnt = MT_MIN_TICK_CNT_VAL;
5490 /* call the common timer tick handler */
5491 for (i = 0; i < cnt; i++)
5493 /* mt008.301: cmPrcTmr is guarded with a lock */
5494 /* lock the timer table */
5495 if (SLock(&osCp.tmrTblLock) != ROK)
5497 #if (ERRCLASS & ERRCLS_DEBUG)
5498 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5502 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5503 /* unlock the timer table */
5504 SUnlock(&osCp.tmrTblLock);
5508 /* mt009.21: addition */
5509 RETVALUE( (Void *) NULLP);
5510 /* will not reach here */
5518 * Desc: Process timer event. Called from the common timer
5519 * code when a timeout occurs.
5529 PUBLIC Void mtTimeout
5531 PTR tCb, /* control block */
5532 S16 evnt /* event */
5535 PUBLIC Void mtTimeout(tCb, evnt)
5536 PTR tCb; /* control block */
5537 S16 evnt; /* event */
5546 #ifndef TENB_RTLIN_CHANGES
5549 /* mt028.201: modification: multiple procs support related changes */
5550 #ifdef SS_MULTIPLE_PROCS
5552 #endif /* SS_MULTIPLE_PROCS */
5553 #ifdef RGL_SPECIFIC_CHANGES
5554 #ifdef MSPD_MLOG_NEW
5555 U32 t = GetTIMETICK();
5562 /* get the timer entry */
5563 tEnt = (SsTmrEntry *) tCb;
5566 /* if the timer was deleted, this will be NULL, so drop it */
5572 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5575 /* Hmmmm, the timer might have been deleted while we've been
5576 * working at getting here, so we just skip this.
5578 if (tEnt->used == FALSE)
5584 /* Set up and send a timer message to the destination tasks'
5587 #ifndef SS_MULTICORE_SUPPORT
5588 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5590 #ifdef RGL_SPECIFIC_CHANGES
5591 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5593 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5598 #if (ERRCLASS & ERRCLS_DEBUG)
5599 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5605 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5606 mInfo->eventInfo.event = SS_EVNT_TIMER;
5607 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5609 mInfo->pst.dstEnt = tEnt->ownerEnt;
5610 mInfo->pst.dstInst = tEnt->ownerInst;
5611 mInfo->pst.srcEnt = tEnt->ownerEnt;
5612 mInfo->pst.srcInst = tEnt->ownerInst;
5613 /* mt028.201: modification: multiple procs support related changes */
5614 #ifndef SS_MULTIPLE_PROCS
5615 mInfo->pst.dstProcId = SFndProcId();
5616 mInfo->pst.srcProcId = SFndProcId();
5617 #else /* SS_MULTIPLE_PROCS */
5618 mInfo->pst.dstProcId = tEnt->ownerProc;
5619 mInfo->pst.srcProcId = tEnt->ownerProc;
5620 #endif /* SS_MULTIPLE_PROCS */
5621 mInfo->pst.selector = SEL_LC_NEW;
5622 #ifndef SS_MULTICORE_SUPPORT
5623 mInfo->pst.region = DFLT_REGION;
5626 mInfo->pst.pool = DFLT_POOL;
5627 mInfo->pst.prior = PRIOR0;
5628 mInfo->pst.route = RTESPEC;
5629 mInfo->pst.event = 0;
5632 #ifndef TENB_RTLIN_CHANGES
5633 /* get a semaphore for the TAPA task table */
5634 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5639 #if (ERRCLASS & ERRCLS_DEBUG)
5640 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5648 /* find the owner TAPA task */
5649 /* mt028.201: modification: multiple procs support related changes */
5650 #ifdef SS_MULTIPLE_PROCS
5651 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5652 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5653 #else /* SS_MULTIPLE_PROCS */
5654 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5655 #endif /* SS_MULTIPLE_PROCS */
5656 if (idx == SS_TSKNC)
5658 #ifndef TENB_RTLIN_CHANGES
5659 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5666 /* ensure that the TAPA task is hale and hearty */
5667 tTsk = &osCp.tTskTbl[idx];
5670 #ifndef TENB_RTLIN_CHANGES
5671 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5676 /* Klock work fix ccpu00148484 */
5677 /* write the timer message to the queue of the destination task */
5678 /* mt008.301 : check sTsk before putting into it's DQ */
5679 if (tTsk->sTsk == NULLP)
5681 #ifndef TENB_RTLIN_CHANGES
5682 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5686 #if (ERRCLASS & ERRCLS_DEBUG)
5687 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5688 "Could not write to demand queue");
5693 #ifdef SS_LOCKLESS_MEMORY
5694 mInfo->pst.region = tTsk->sTsk->region;
5695 mInfo->region = tTsk->sTsk->region;
5696 #endif /* SS_LOCKLESS_MEMORY */
5697 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5698 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5700 #ifndef TENB_RTLIN_CHANGES
5701 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5705 #if (ERRCLASS & ERRCLS_DEBUG)
5706 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5707 "Could not write to demand queue");
5712 /* Fix for ccpu00130657 */
5713 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5714 if (tTsk->sTsk->tskPrior == PRIOR0)
5717 WLS_WakeUp(mtGetWlsHdl());
5724 /* release the semaphore for the TAPA task table */
5725 #ifndef TENB_RTLIN_CHANGES
5726 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5730 /* restart the timer */
5731 arg.tq = osCp.dep.tmrTq;
5732 arg.tqCp = &osCp.dep.tmrTqCp;
5733 arg.timers = tEnt->dep.timers;
5734 arg.cb = (PTR) tEnt;
5738 arg.max = TMR_DEF_MAX;
5739 arg.wait = tEnt->interval;
5741 #ifdef RGL_SPECIFIC_CHANGES
5742 #ifdef MSPD_MLOG_NEW
5743 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5755 * Desc: This thread reads the console and hands over any
5756 * data read to a user function.
5758 * Ret: (thread function)
5766 PRIVATE Void *mtConHdlr
5768 Ptr parm /* unused */
5771 /* mt009.21: addition */
5772 PRIVATE Void *mtConHdlr(parm)
5773 Ptr parm; /* unused */
5780 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5786 /* check if we have a console input file handle */
5787 if (osCp.dep.conInFp == NULLP)
5793 fd = fileno(osCp.dep.conInFp);
5798 if ((read(fd, &data, 1)) != 1)
5804 /* call rdConQ, defined by the system service user */
5814 #ifdef SS_DRVR_SUPPORT
5817 * Fun: Interrupt service task handler
5819 * Desc: This is the interrupt service task handler. It blocks
5820 * on a pipe from which it reads an isFlag structure. The
5821 * structure indicates which interrupt service task is to
5822 * be executed. The thread identifies the task, calls the
5823 * isTsk function and sends itself a message to repeat
5824 * this operation until it receives a message to cease.
5834 /* mt009.21: addition */
5835 PRIVATE Void *mtIsTskHdlr
5837 Ptr tskPtr /* pointer to task entry */
5840 /* mt009.21: addition */
5841 PRIVATE Void *mtIsTskHdlr(tskPtr)
5842 Ptr tskPtr; /* pointer to task entry */
5845 #if (ERRCLASS & ERRCLS_DEBUG)
5856 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5861 switch (isFlag.action)
5864 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5866 /* call the interrupt service task activation function */
5867 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5869 /* send self a message to keep doing this */
5870 isFlag.action = MT_IS_RESET;
5872 #if (ERRCLASS & ERRCLS_DEBUG)
5873 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5874 if (ret != sizeof(isFlag))
5876 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5877 "write() to pipe failed");
5880 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5887 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5892 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5894 /* call the interrupt service task activation function */
5895 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5897 #if (ERRCLASS & ERRCLS_DEBUG)
5898 /* send self a message to do this again */
5899 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5901 if (ret != sizeof(isFlag))
5903 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5904 "write() to pipe failed");
5907 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5915 /* where did THIS come from?? */
5919 /* mt009.21: addition */
5920 RETVALUE( (Void *) NULLP);
5924 #endif /* SS_DRVR_SUPPORT */
5925 #endif /* L2_L3_SPLIT */
5927 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5931 * Fun: mtIntSigHndlr
5933 * Desc: Exit function, shuts down.
5943 PUBLIC Void mtIntSigHndlr
5948 PUBLIC Void mtIntSigHndlr(arg)
5953 TRC0(mtIntSigHndlr);
5955 osCp.dep.sigEvnt=TRUE;
5958 #ifdef TENB_RTLIN_CHANGES
5966 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5971 * Desc: function, shuts down.
5981 PUBLIC Void mtExitClnup
5986 PUBLIC Void mtExitClnup()
5995 SGetSysTime(&ticks);
5997 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5999 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
6001 #ifdef SS_HISTOGRAM_SUPPORT
6005 osCp.dep.sigEvnt=FALSE;
6007 if (osCp.dep.fileOutFp)
6009 fclose(osCp.dep.fileOutFp);
6017 Void SIncrementTtiCount(Void)
6022 Ticks SGetTtiCount(Void)
6031 * Desc: This function displays a string to a given output
6036 * Notes: Buffer should be null terminated.
6038 * channel 0 is reserved for backwards compatibility
6047 S16 chan, /* channel */
6048 Txt *buf /* buffer */
6051 PUBLIC S16 SDisplay(chan, buf)
6052 S16 chan; /* channel */
6053 Txt *buf; /* buffer */
6058 /* mt020.201 - Fixed typo */
6059 #if (ERRCLASS & ERRCLS_INT_PAR)
6062 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6067 #ifndef XEON_SPECIFIC_CHANGES
6068 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6069 ssMemlog(buf, strlen(buf));
6074 /* mt012.301 :FIX for LOG RELATED ISSUE */
6082 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6088 if (osCp.dep.fileOutFp)
6089 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6090 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6093 fflush(osCp.dep.fileOutFp);
6106 * Desc: function, shuts down.
6126 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6127 a loop to overcome the child processes being killed upon exiting the
6129 #ifdef SS_LINUX /* this should have already been defined */
6130 /* mt010.301 removed flag SLES9_PLUS */
6131 /* wait forever for children */
6135 if(osCp.dep.sigEvnt==TRUE)
6142 pthread_exit(NULLP);
6148 * Fun: Set date and time
6150 * Desc: This function is used to set the calendar
6155 * Notes: Unimplemented
6161 PUBLIC S16 SSetDateTime
6163 REG1 DateTime *dt /* date and time */
6166 PUBLIC S16 SSetDateTime(dt)
6167 REG1 DateTime *dt; /* date and time */
6182 * Fun: Get date and time
6184 * Desc: This function is used to determine the calendar
6185 * date and time. This information may be used for
6186 * some management functions.
6197 PUBLIC S16 SGetDateTime
6199 REG1 DateTime *dt /* date and time */
6202 PUBLIC S16 SGetDateTime(dt)
6203 REG1 DateTime *dt; /* date and time */
6206 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6209 struct timespec ptime;
6211 struct timeval ptime;
6220 #if (ERRCLASS & ERRCLS_INT_PAR)
6223 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6232 localtime_r(&tt, &tme);
6235 clock_gettime(CLOCK_REALTIME, &ptime);
6237 gettimeofday(&ptime, NULL);
6239 localtime_r(&ptime.tv_sec, &tme);
6241 dt->month = (U8) tme.tm_mon + 1;
6242 dt->day = (U8) tme.tm_mday;
6243 dt->year = (U8) tme.tm_year;
6244 dt->hour = (U8) tme.tm_hour;
6245 dt->min = (U8) tme.tm_min;
6246 dt->sec = (U8) tme.tm_sec;
6249 #ifdef SS_DATETIME_USEC
6251 dt->usec = ptime.tv_nsec / 1000;
6253 dt->usec = ptime.tv_usec;
6255 #endif /*-- SS_DATETIME_USEC --*/
6261 * Get time from epoch in milliseconds
6263 * Fun: Get time from epoch in milliseconds
6265 * Desc: This function is used to get the time from epoch in milli seconds.
6266 * This information may be used for calculating a layer's activation function
6267 * execution time used for thread profiling.
6276 /* mt003.301 Modifications */
6278 PUBLIC S16 SGetEpcTime
6280 EpcTime *et /* date and time */
6283 PUBLIC S16 SGetEpcTime(et)
6284 EpcTime *et; /* date and time */
6287 /* mt003.301 Modifications */
6289 U64 to_sec = 1000000;
6292 struct timespec ptime;
6294 struct timeval ptime;
6300 #if (ERRCLASS & ERRCLS_INT_PAR)
6309 clock_gettime(CLOCK_REALTIME, &ptime);
6311 gettimeofday(&ptime, NULL);
6312 #endif /* SS_LINUX */
6314 now = (ptime.tv_sec * to_sec);
6317 now += (ptime.tv_nsec / to_nsec);
6318 #else /* SS_LINUX */
6319 now += (ptime.tv_usec);
6321 #endif /* SS_LINUX */
6322 now = (now / to_nsec);
6333 * Fun: Get system time
6335 * Desc: This function is used to determine the system time.
6339 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6345 PUBLIC S16 SGetSysTime
6347 Ticks *sysTime /* system time */
6350 PUBLIC S16 SGetSysTime(sysTime)
6351 Ticks *sysTime; /* system time */
6357 #if (ERRCLASS & ERRCLS_INT_PAR)
6358 if (sysTime == NULLP)
6360 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6366 *sysTime = osCp.dep.sysTicks;
6372 /* mt021.201 - Addition of SGetRefTime function */
6375 * Fun: Get referenced time
6377 * Desc: This function is used to determine the time in seconds
6378 * and microseconds from a reference time. The reference
6379 * time is expressed in seconds from UTC EPOC, January 1,
6385 * Notes: Macros are defined for reference times:
6386 * SS_REFTIME_01_01_1970
6387 * SS_REFTIME_01_01_2002
6393 PUBLIC S16 SGetRefTime
6395 U32 refTime, /* reference time */
6400 PUBLIC S16 SGetRefTime(refTime, sec, usec)
6401 U32 refTime; /* reference time */
6408 struct timespec ptime;
6410 struct timeval ptime;
6416 clock_gettime(CLOCK_REALTIME, &ptime);
6418 gettimeofday(&ptime, NULL);
6421 #if (ERRCLASS & ERRCLS_INT_PAR)
6422 if (sec == NULLP || usec == NULLP)
6424 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6427 /* mt022.201 - Modification to fix compile warning */
6428 if (refTime > (U32)(ptime.tv_sec))
6430 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6435 *sec = ptime.tv_sec - refTime;
6437 *usec = ptime.tv_nsec / 1000;
6439 *usec = ptime.tv_usec;
6449 * Fun: Get Random Number
6451 * Desc: Invoked by layer when a pseudorandom number is required.
6455 * Notes: Suggested approach uses shuffled Linear Congruential
6456 * Operators as described in Byte magazine October
6457 * 1984; "Generating and Testing Pseudorandom Numbers"
6465 Random *value /* random number */
6468 PUBLIC S16 SRandom(value)
6469 Random *value; /* random number */
6475 #if (ERRCLASS & ERRCLS_INT_PAR)
6478 /* mt011.21: addition */
6479 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6485 *value = (Random) rand_r(&osCp.dep.randSeed);
6496 * Desc: This function exits from a task.
6500 * Notes: Currently does nothing.
6511 PUBLIC S16 SExitTsk()
6523 * Fun: Exit Interrupt
6525 * Desc: This function exits from an interrupt.
6529 * Notes: Currently does nothing.
6540 PUBLIC S16 SExitInt()
6552 * Fun: Hold Interrupt
6554 * Desc: This function prohibits interrupts from being enabled until
6555 * release interrupt. This function should be called when
6556 * interrupts are disabled and prior to any call to system
6557 * services either by entry to an interrupt service routine or
6558 * by explicit call to disable interrupt.
6562 * Notes: Currently does nothing
6573 PUBLIC S16 SHoldInt()
6585 * Fun: Release Interrupt
6587 * Desc: This function allows interrupts to be enabled.
6591 * Notes: Currently does nothing.
6602 PUBLIC S16 SRelInt()
6616 * Desc: Enable interrupts
6618 * Ret: ROK on success
6621 * Notes: Currently does nothing.
6627 PUBLIC INLINE S16 SEnbInt
6632 PUBLIC INLINE S16 SEnbInt()
6646 * Desc: Disable interrupts
6648 * Ret: ROK on success
6651 * Notes: Currently does nothing.
6657 PUBLIC INLINE S16 SDisInt
6662 PUBLIC INLINE S16 SDisInt()
6676 * Desc: This function gets the function address stored at the
6677 * specified interrupt vector.
6681 * Notes: Currently does nothing.
6689 VectNmb vectNmb, /* vector number */
6690 PIF *vectFnct /* vector function */
6693 PUBLIC S16 SGetVect(vectNmb, vectFnct)
6694 VectNmb vectNmb; /* vector number */
6695 PIF *vectFnct; /* vector function */
6713 * Desc: This function installs the specified function at the
6714 * specified interrupt vector.
6718 * Notes: Currently does nothing.
6726 VectNmb vectNmb, /* vector number */
6727 PIF vectFnct /* vector function */
6730 PUBLIC S16 SPutVect(vectNmb, vectFnct)
6731 VectNmb vectNmb; /* vector number */
6732 PIF vectFnct; /* vector function */
6745 /* mt028.201: modification: multiple procs support related changes */
6746 #ifndef SS_MULTIPLE_PROCS
6752 * Desc: This function gets the current entity and instance.
6755 * RFAILED - failed, general (optional)
6757 * Notes: This function may be called by the OS or Layer 1
6764 PUBLIC S16 SGetEntInst
6766 Ent *ent, /* entity */
6767 Inst *inst /* instance */
6770 PUBLIC S16 SGetEntInst(ent, inst)
6771 Ent *ent; /* entity */
6772 Inst *inst; /* instance */
6784 #if (ERRCLASS & ERRCLS_INT_PAR)
6785 /* check pointers */
6786 if (ent == NULLP || inst == NULLP)
6788 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6794 /* get the thread id */
6795 tId = pthread_self();
6798 /* find the system task in whose context we're running */
6800 ret = SLock(&osCp.sTskTblLock);
6805 for (i = 0; i < SS_MAX_STSKS; i++)
6807 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6809 sTsk = &osCp.sTskTbl[i];
6815 *ent = sTsk->dep.ent;
6816 *inst = sTsk->dep.inst;
6818 SUnlock(&osCp.sTskTblLock);
6821 RETVALUE(ret == ROK ? ROK : RFAILED);
6829 * Desc: This function sets the current entity and instance.
6839 PUBLIC S16 SSetEntInst
6841 Ent ent, /* entity */
6842 Inst inst /* instance */
6845 PUBLIC S16 SSetEntInst(ent, inst)
6846 Ent ent; /* entity */
6847 Inst inst; /* instance */
6859 #if (ERRCLASS & ERRCLS_INT_PAR)
6860 /* check entity and instance IDs */
6861 if (ent >= ENTNC || inst >= INSTNC)
6863 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6869 /* get the thread id */
6870 tId = pthread_self();
6873 /* find the system task in whose context we're running */
6875 ret = SLock(&osCp.sTskTblLock);
6880 for (i = 0; i < SS_MAX_STSKS; i++)
6882 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6884 sTsk = &osCp.sTskTbl[i];
6890 sTsk->dep.ent = ent;
6891 sTsk->dep.inst = inst;
6893 SUnlock(&osCp.sTskTblLock);
6896 RETVALUE(ret == ROK ? ROK : RFAILED);
6899 #endif /* SS_MULTIPLE_PROCS */
6901 #ifdef SS_DRVR_SUPPORT
6907 * Desc: Set interrupt pending flag
6909 * Ret: ROK on success
6918 PUBLIC INLINE S16 SSetIntPend
6920 U16 id, /* driver task identifier */
6921 Bool flag /* flag */
6924 PUBLIC INLINE S16 SSetIntPend(id, flag)
6925 U16 id; /* driver task identifier */
6926 Bool flag; /* flag */
6935 #if (ERRCLASS & ERRCLS_INT_PAR)
6936 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6938 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6945 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6947 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6955 #endif /* SS_DRVR_SUPPORT */
6958 #ifdef SS_LOCKLESS_MEMORY
6961 * Fun: SGlobMemInfoShow
6963 * Desc: This function displays the memory usage information
6964 * for the destined region. It will show the usage of
6965 * each configured bucket and the heap for the specified region.
6968 * RFAILED Region not registered
6974 PUBLIC S16 SGlobMemInfoShow
6979 PUBLIC S16 SGlobMemInfoShow()
6984 CmMmGlobRegCb *globReg;
6986 TRC1(SGlobMemInfoShow);
6988 globReg = osCp.globRegCb;
6990 sprintf(prntBuf, "--------------------------------------------------------------\n");
6991 SDisplay(0, prntBuf);
6992 sprintf(prntBuf, "Global Region Bucket Information\n");
6993 SDisplay(0, prntBuf);
6994 sprintf(prntBuf, "====================================================\n");
6995 SDisplay(0, prntBuf);
6996 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
6997 SDisplay(0, prntBuf);
6998 sprintf(prntBuf, "====================================================\n");
6999 SDisplay(0, prntBuf);
7002 for (idx = 0; idx < globReg->numBkts; idx++)
7004 #ifdef XEON_SPECIFIC_CHANGES
7005 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
7006 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7009 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
7010 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7012 sprintf(prntBuf, "%2u %12u %8u %9u\n",
7013 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7016 SDisplay(0, prntBuf);
7018 sprintf(prntBuf, "--------------------------------------------------------------\n");
7019 SDisplay(0, prntBuf);
7024 #endif /* SS_LOCKLESS_MEMORY */
7027 Bool IsMemoryThresholdHit(Region reg, Pool pool)
7029 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
7031 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
7034 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
7035 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
7042 /* mt022.201 - Addition of SRegInfoShow function */
7047 * Desc: This function displays the memory usage information
7048 * for the destined region. It will show the usage of
7049 * each configured bucket and the heap for the specified region.
7052 * RFAILED Region not registered
7054 * Notes: A Sample Output from the function
7055 * Bucket Memory: region 1
7056 * ====================================================
7057 * Bucket Number of Blks configured Size Allocated
7058 * ====================================================
7066 * Heap Memory: region 1
7069 * Heap Segmented blocks: 0
7076 PUBLIC S16 SRegInfoShow
7082 PUBLIC S16 SRegInfoShow(region, availmem)
7092 #if (ERRCLASS & ERRCLS_INT_PAR)
7093 if (region > (SS_MAX_REGS-1) )
7095 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7102 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7103 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7104 SDisplay(0, prntBuf);
7105 sprintf(prntBuf, "====================================================\n");
7106 SDisplay(0, prntBuf);
7107 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7108 SDisplay(0, prntBuf);
7109 sprintf(prntBuf, "====================================================\n");
7110 SDisplay(0, prntBuf);
7114 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7116 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7118 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7119 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7120 mtCMMRegCb[region]->bktTbl[idx].size,
7121 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7122 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7124 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7125 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7126 mtCMMRegCb[region]->bktTbl[idx].size,
7127 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7128 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7131 /*mt009.301 Fixed 64BIT compilation warnings*/
7133 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7134 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7135 mtCMMRegCb[region]->bktTbl[idx].size,
7136 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7138 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7139 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7140 mtCMMRegCb[region]->bktTbl[idx].size,
7141 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7143 #endif /* not TENB_RTLIN_CHANGES */
7144 SDisplay(0, prntBuf);
7145 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7146 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7147 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7149 sprintf(prntBuf, "\n---------------\n");
7150 SDisplay(0, prntBuf);
7151 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7152 SDisplay(0, prntBuf);
7153 /*mt009.301 Fixed 64BIT compilation warnings*/
7155 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7157 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7159 SDisplay(0, prntBuf);
7160 /*mt009.301 Fixed 64BIT compilation warnings*/
7162 sprintf(prntBuf, "Heap Allocated: %u\n",
7163 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7165 sprintf(prntBuf, "Heap Allocated: %lu\n",
7166 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7168 SDisplay(0, prntBuf);
7169 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7170 #if (ERRCLASS & ERRCLS_DEBUG)
7171 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7172 mtCMMRegCb[region]->heapCb.numFragBlk);
7173 SDisplay(0, prntBuf);
7178 #ifdef XEON_SPECIFIC_CHANGES
7179 #define SSI_MAX_BKT_THRESHOLD 6
7180 #define SSI_MAX_REG_THRESHOLD 2
7181 U32 SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7182 U32 SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7183 U32 SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7186 PRIVATE Void SInitMemThreshold
7192 PRIVATE Void SInitMemThreshold(region, maxBkt)
7198 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7200 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7201 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7202 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7203 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7208 PUBLIC S16 SRegReachedMemThreshold
7214 PUBLIC S16 SRegReachedMemThreshold(region, maxBkt)
7221 PRIVATE U8 initFlag = 1;
7225 SInitMemThreshold(region, maxBkt);
7228 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7230 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7235 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7239 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7244 RETVALUE(memStatus);
7247 /* mt033.201 - addition of API to return the memory statistical data */
7252 * Desc: This function returns the memory usage information
7253 * for the destined region. It will return the usage of
7254 * each configured bucket and the heap for the specified region.
7257 * RFAILED Region not registered
7265 PUBLIC S16 SGetRegInfo
7268 SsMemDbgInfo *dbgInfo
7271 PUBLIC S16 SGetRegInfo(region, dbgInfo)
7273 SsMemDbgInfo *dbgInfo;
7280 #if (ERRCLASS & ERRCLS_INT_PAR)
7281 if (region >= mtMemoCfg.numRegions )
7283 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7288 dbgInfo->availmem = 0;
7290 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7291 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7293 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7295 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7297 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7298 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7299 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7301 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7302 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7303 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7306 dbgInfo->region = region;
7308 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7310 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7311 mtCMMRegCb[region]->heapCb.avlSize);
7313 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7315 #if (ERRCLASS & ERRCLS_DEBUG)
7316 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7323 PUBLIC S16 SGetRegPoolInfo
7329 PUBLIC S16 SGetRegPoolInfo(numRegion, numPool)
7334 /* Send number of Region available */
7335 *numRegion = mtMemoCfg.numRegions;
7336 /* Send number of Pools available */
7337 *numPool = cfgRegInfo[0].numPools;
7342 /* mt033.201 - addition of APIs to print the memory statistical data
7343 * as defined by SSI enhancements
7345 #ifdef SSI_DEBUG_LEVEL1
7348 * Fun: SPrintRegMemStatusInfo
7350 * Desc: This function displays the memory usage information
7351 * for the destined region. It will show the total memory
7352 * used for static and dynamic memory if typeFlag is
7353 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7354 * memory block allocated for a particular size if typeFlag
7355 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7356 * calling SRegPrintMemStats.
7366 PUBLIC S16 SPrintRegMemStatusInfo
7372 PUBLIC S16 SPrintRegMemStatusInfo(region, typeFlag)
7382 TRC1(SPrintRegMemStatusInfo);
7384 #if (ERRCLASS & ERRCLS_INT_PAR)
7385 if (region >= mtMemoCfg.numRegions )
7387 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7392 /* initialize the counters*/
7396 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7398 /* total static and dynamic memory allocated from all the buckets in region requested */
7399 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7400 SDisplay(0, prntBuf);
7401 sprintf(prntBuf, "===========================================\n");
7402 SDisplay(0, prntBuf);
7403 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7404 SDisplay(0, prntBuf);
7405 sprintf(prntBuf, "===========================================\n");
7406 SDisplay(0, prntBuf);
7407 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7409 /*mt009.301 Fixed 64BIT compilation warnings*/
7411 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7412 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7413 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7415 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7416 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7417 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7419 SDisplay(0, prntBuf);
7420 /* update the total count */
7421 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7422 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7425 /*mt009.301 Fixed 64BIT compilation warnings*/
7427 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7428 SDisplay(0, prntBuf);
7429 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7431 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7432 SDisplay(0, prntBuf);
7433 /*mt010.301 fix for compilation error*/
7434 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7436 SDisplay(0, prntBuf);
7438 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7439 SDisplay(0, prntBuf);
7440 /*mt009.301 Fixed 64BIT compilation warnings*/
7442 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7443 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7445 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7446 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7448 SDisplay(0, prntBuf);
7450 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7452 /* Bucket Memory allocation Statistics */
7453 RETVALUE(SPrintRegMemStats(region));
7458 sprintf(prntBuf, "\n Invalid choice \n");
7459 SDisplay(0, prntBuf);
7467 * Fun: SPrintRegMemStats
7469 * Desc: This function displays the memory usage information for
7470 * the destined region. It will show the number of memory
7471 * block allocated for a particular size from the hash list.
7481 PRIVATE S16 SPrintRegMemStats
7486 PRIVATE S16 SPrintRegMemStats(region)
7490 CmMmHashListCp *hashListCp;
7495 TRC1(SPrintRegMemStats);
7497 hashListCp = &mtCMMRegCb[region]->hashListCp;
7499 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7500 SDisplay(0, prntBuf);
7501 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7502 hashListCp->numOfbins, hashListCp->numOfEntries);
7503 SDisplay(0, prntBuf);
7504 sprintf(prntBuf, "===================================\n");
7505 SDisplay(0, prntBuf);
7506 sprintf(prntBuf, "Block Size Total number of requests\n");
7507 SDisplay(0, prntBuf);
7508 sprintf(prntBuf, "===================================\n");
7509 SDisplay(0, prntBuf);
7511 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7512 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7514 if (hashListCp->hashList[idx].numAttempts)
7517 /*mt009.301 Fixed 64BIT compilation warnings*/
7519 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7520 hashListCp->hashList[idx].numAttempts);
7522 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7523 hashListCp->hashList[idx].numAttempts);
7525 SDisplay(0, prntBuf);
7529 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7530 SDisplay(0, prntBuf);
7531 sprintf(prntBuf, "=================================================\n");
7532 SDisplay(0, prntBuf);
7533 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7534 SDisplay(0, prntBuf);
7535 sprintf(prntBuf, "=================================================\n");
7536 SDisplay(0, prntBuf);
7538 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7539 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7541 /*mt009.301 Fixed 64BIT compilation warnings*/
7543 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7544 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7545 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7547 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7548 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7549 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7551 SDisplay(0, prntBuf);
7553 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7554 SDisplay(0, prntBuf);
7555 /*mt009.301 Fixed 64BIT compilation warnings*/
7557 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7558 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7559 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7561 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7562 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7563 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7565 SDisplay(0, prntBuf);
7566 sprintf(prntBuf, "\n");
7567 SDisplay(0, prntBuf);
7574 * Fun: SRegMemErrHdlr
7576 * Desc: This function handles the errors returned from the memory
7577 * related functions. Customers are suggested to modify this
7578 * API according to their specific requirement.
7588 PUBLIC Void SRegMemErrHdlr
7595 PUBLIC Void SRegMemErrHdlr(region, ptr, errCode)
7603 TRC1(SRegMemErrHdlr);
7605 if (errCode == RDBLFREE)
7607 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7608 SDisplay(0, prntBuf);
7610 else if (errCode == RTRAMPLINGNOK)
7612 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7613 SDisplay(0, prntBuf);
7621 * Fun: SPrintRegMemProfile
7623 * Desc: This function displays the memory profile information
7624 * for the destined region. This function prints for:
7625 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7626 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7636 PUBLIC S16 SPrintRegMemProfile
7641 PUBLIC S16 SPrintRegMemProfile(region)
7647 CmMmBlkHdr *curBktBlk;
7649 Size offsetToNxtBlk;
7656 TRC1(SPrintRegMemProfile);
7658 #if (ERRCLASS & ERRCLS_INT_PAR)
7659 if (region >= mtMemoCfg.numRegions )
7661 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7666 regCb = mtCMMRegCb[region];
7668 /* memory profile */
7669 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7670 SDisplay(0, prntBuf);
7672 /* bucket profile */
7673 sprintf(prntBuf, "\nBucket Profile\n");
7674 SDisplay(0, prntBuf);
7676 for (idx = 0; idx < regCb->numBkts; idx++)
7679 /*mt009.301 Fixed 64BIT compilation warnings*/
7681 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7682 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7684 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7685 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7687 SDisplay(0, prntBuf);
7689 sprintf(prntBuf, "==========================================================================\n");
7690 SDisplay(0, prntBuf);
7691 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7692 SDisplay(0, prntBuf);
7693 sprintf(prntBuf, "==========================================================================\n");
7694 SDisplay(0, prntBuf);
7696 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7698 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7699 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7700 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7702 /*mt009.301 Fixed 64BIT compilation warnings*/
7704 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7706 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7708 SDisplay(0, prntBuf);
7709 /* check if it is a sane block, elxe jump to next block */
7710 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7712 sprintf(prntBuf, " Trampled \n");
7713 SDisplay(0, prntBuf);
7718 if (CMM_IS_STATIC(curBktBlk->memFlags))
7720 /*mt009.301 Fixed 64BIT compilation warnings*/
7722 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7724 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7726 SDisplay(0, prntBuf);
7728 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7730 /*mt009.301 Fixed 64BIT compilation warnings*/
7732 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7734 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7736 SDisplay(0, prntBuf);
7738 else if (CMM_IS_FREE(curBktBlk->memFlags))
7740 /*mt009.301 Fixed 64BIT compilation warnings*/
7742 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7744 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7746 SDisplay(0, prntBuf);
7750 sprintf(prntBuf, " Trampled \n");
7751 SDisplay(0, prntBuf);
7757 sprintf(prntBuf, "\nHeap Profile\n");
7758 SDisplay(0, prntBuf);
7760 /* point to heapCb */
7761 heapCb = &(regCb->heapCb);
7763 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7764 SDisplay(0, prntBuf);
7765 sprintf(prntBuf, "==========================================================================\n");
7766 SDisplay(0, prntBuf);
7767 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7768 SDisplay(0, prntBuf);
7769 sprintf(prntBuf, "==========================================================================\n");
7770 SDisplay(0, prntBuf);
7772 /* traverse the entire heap to output the heap profile */
7773 hdrSize = sizeof(CmHEntry);
7774 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7775 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7777 /*mt009.301 Fixed 64BIT compilation warnings*/
7779 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7781 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7783 SDisplay(0, prntBuf);
7785 /* check if it is a sane block, elxe jump to next block */
7786 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7788 sprintf(prntBuf, " Trampled \n");
7789 SDisplay(0, prntBuf);
7791 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7792 SDisplay(0, prntBuf);
7795 * To go to next block in the heap we do not have any offset value
7796 * other than curHBlk->size. As the block is already trampled
7797 * we cannot rely on this size. So it is better to stop here unless there
7798 * exists any other mechanism(?) to know the offset to next block.
7803 /*mt009.301 Fixed 64BIT compilation warnings*/
7805 sprintf(prntBuf, " %8u", curHBlk->size);
7807 sprintf(prntBuf, " %8lu", curHBlk->size);
7809 SDisplay(0, prntBuf);
7811 if (CMM_IS_STATIC(curHBlk->memFlags))
7813 /*mt009.301 Fixed 64BIT compilation warnings*/
7815 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7817 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7819 SDisplay(0, prntBuf);
7821 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7823 /*mt009.301 Fixed 64BIT compilation warnings*/
7825 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7827 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7829 SDisplay(0, prntBuf);
7831 else if (CMM_IS_FREE(curHBlk->memFlags))
7833 /*mt009.301 Fixed 64BIT compilation warnings*/
7835 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7837 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7839 SDisplay(0, prntBuf);
7843 sprintf(prntBuf, " Trampled \n");
7844 SDisplay(0, prntBuf);
7846 /* goto next block in the heap */
7847 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7853 #endif /* SSI_DEBUG_LEVEL1 */
7855 /*-- mt035.201 : Added new API for timestamp --*/
7858 * Fun: Get TimeStamp
7860 * Desc: This function is used to Get TimeStamp in micro seconds
7871 PUBLIC S16 SGetTimeStamp
7876 PUBLIC S16 SGetTimeStamp(ts)
7882 struct timespec ptime;
7884 struct timeval ptime;
7891 TRC1(SGetTimeStamp);
7894 clock_gettime(CLOCK_REALTIME, &ptime);
7896 gettimeofday(&ptime, NULL);
7899 /* Obtain the time of day, and convert it to a tm struct. --*/
7900 ptm = localtime (&ptime.tv_sec);
7901 /* Klock work fix ccpu00148484 */
7904 /* Format the date and time, down to a single second. --*/
7905 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7908 /* Compute microseconds. --*/
7910 microseconds = ptime.tv_nsec / 1000;
7912 microseconds = ptime.tv_usec;
7915 /* Print the formatted time, in seconds, followed by a decimal point
7916 and the microseconds. --*/
7917 /*mt009.301 Fixed 64BIT compilation warnings*/
7919 sprintf(ts, "%s.%03d", time_string, microseconds);
7921 sprintf(ts, "%s.%03ld", time_string, microseconds);
7927 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7930 * Fun: Get SGetSystemTsk
7932 * Desc: This function is used to Get sytem task id
7942 PUBLIC U32 SGetSystemTsk
7947 PUBLIC U32 SGetSystemTsk()
7950 TRC1(SGetSystemTskS);
7952 RETVALUE(pthread_self());
7954 } /* end of SGetSystemTsk */
7956 #ifdef SS_MULTICORE_SUPPORT
7959 * Fun: Add Timer thread into system task table
7961 * Desc: This function is used to add the system task
7962 * associated with Timer thread.
7972 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void)
7974 PRIVATE SsSTskEntry* ssdAddTmrSTsk()
7980 TRC1(ssdAddTmrSTsk);
7982 /* lock the system task table */
7983 ret = SLock(&osCp.sTskTblLock);
7987 #if (ERRCLASS & ERRCLS_DEBUG)
7988 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7989 "Could not lock system task table");
7995 /* check count of system tasks */
7996 if (osCp.numSTsks == SS_MAX_STSKS)
7999 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8001 #if (ERRCLASS & ERRCLS_DEBUG)
8002 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
8003 "Could not give the Semaphore");
8008 #if (ERRCLASS & ERRCLS_ADD_RES)
8009 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
8016 /* initialize the system task entry with the information we have */
8017 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
8019 /* store the system task priority */
8020 sTsk->tskPrior = SS_NORM_TSK_PRI;
8022 /* initialize the demand queue */
8023 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8026 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8028 #if (ERRCLASS & ERRCLS_DEBUG)
8029 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8030 "Could not give the Semaphore");
8035 #if (ERRCLASS & ERRCLS_DEBUG)
8036 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8037 "Could not initialize demand queue");
8043 /* initialize the system task entry lock */
8044 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8046 ssDestroyDmndQ(&sTsk->dQ);
8048 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8050 #if (ERRCLASS & ERRCLS_DEBUG)
8051 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8052 "Could not give the Semaphore");
8057 #if (ERRCLASS & ERRCLS_DEBUG)
8058 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8059 "Could not initialize system task entry lock");
8066 /* success, update the table */
8067 sTsk->tskId = osCp.nxtSTskEntry;
8069 sTsk->termPend = FALSE;
8070 osCp.nxtSTskEntry = sTsk->nxt;
8073 /* unlock the system task table */
8075 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8077 #if (ERRCLASS & ERRCLS_DEBUG)
8078 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8079 "Could not give the Semaphore");
8086 #endif /* SS_MULTICORE_SUPPORT */
8087 /* mt003.301 Readwrite lock and recursive mutex additions */
8088 #ifdef SS_LOCK_SUPPORT
8091 * Fun: ssdInitLockNew
8093 * Desc: This function is used to initialise lock/mutex
8103 PUBLIC S16 ssdInitLockNew
8109 PUBLIC S16 ssdInitLockNew(lockId, lockType)
8115 #ifdef SS_REC_LOCK_SUPPORT
8116 pthread_mutexattr_t attr;
8117 #endif /* SS_REC_LOCK_SUPPORT */
8118 Txt prntBuf[PRNTSZE];
8121 TRC1(ssdInitLockNew);
8125 #ifdef SS_RDWR_LOCK_SUPPORT
8128 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8130 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8131 SDisplay(0, prntBuf);
8136 #endif /* SS_RDWR_LOCK_SUPPORT */
8137 #ifdef SS_REC_LOCK_SUPPORT
8140 retVal = pthread_mutexattr_init(&attr);
8144 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8149 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8151 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8155 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8156 pthread_mutexattr_destroy(&attr);
8160 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8163 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8164 pthread_mutexattr_destroy(&attr);
8170 #endif /* SS_REC_LOCK_SUPPORT */
8173 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8174 SDisplay(0, prntBuf);
8184 * Desc: This function is used to aquire the read write lock
8194 PUBLIC S16 ssdLockNew
8200 PUBLIC S16 ssdLockNew(lockId, lockType)
8206 Txt prntBuf[PRNTSZE];
8213 #ifdef SS_RDWR_LOCK_SUPPORT
8216 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8218 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8219 SDisplay(0, prntBuf);
8226 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8228 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8229 SDisplay(0, prntBuf);
8236 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8238 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8239 SDisplay(0, prntBuf);
8246 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8248 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8249 SDisplay(0, prntBuf);
8254 #endif /* SS_RDWR_LOCK_SUPPORT */
8255 #ifdef SS_REC_LOCK_SUPPORT
8258 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8260 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8261 SDisplay(0, prntBuf);
8266 #endif /* SS_REC_LOCK_SUPPORT */
8269 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8270 SDisplay(0, prntBuf);
8283 * Desc: This function is used to Unlock the read write lock
8293 PUBLIC S16 ssdUnlockNew
8299 PUBLIC S16 ssdUnlockNew(lockId, lockType)
8305 Txt prntBuf[PRNTSZE];
8312 #ifdef SS_RDWR_LOCK_SUPPORT
8315 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8317 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8318 SDisplay(0, prntBuf);
8323 #endif /* SS_RDWR_LOCK_SUPPORT */
8324 #ifdef SS_REC_LOCK_SUPPORT
8327 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8329 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8330 SDisplay(0, prntBuf);
8335 #endif /* SS_REC_LOCK_SUPPORT */
8338 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8339 SDisplay(0, prntBuf);
8348 * Fun: ssdDestroyLockNew
8350 * Desc: This function is used to destroy the read write lock
8360 PUBLIC S16 ssdDestroyLockNew
8366 PUBLIC S16 ssdDestroyLockNew(lockId, lockType)
8371 Txt prntBuf[PRNTSZE];
8374 TRC1(ssdDestroyLockNew);
8378 #ifdef SS_RDWR_LOCK_SUPPORT
8381 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8383 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8384 SDisplay(0, prntBuf);
8389 #endif /* SS_RDWR_LOCK_SUPPORT */
8390 #ifdef SS_REC_LOCK_SUPPORT
8393 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8395 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8396 SDisplay(0, prntBuf);
8401 #endif /* SS_REC_LOCK_SUPPORT */
8404 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8405 SDisplay(0, prntBuf);
8411 #endif /* SS_LOCK_SUPPORT */
8413 /* mt005.301 : Cavium Changes */
8414 #ifdef SS_SEUM_CAVIUM
8418 * Fun: ssInitRcvWork
8420 * Desc: This is the initializtion function of receive
8424 * RFAILED - failed, general (optional)
8426 * Notes: Function to initialize the work queue packet
8427 * receiving thread. This creates the new thread to
8428 * receive the work and sets the affinity.
8434 PUBLIC S16 ssInitRcvWork
8439 PUBLIC S16 ssInitRcvWork()
8442 pthread_attr_t attr;
8445 TRC1(ssInitRcvWork);
8447 /* set the required attributes */
8448 pthread_attr_init(&attr);
8449 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8450 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8451 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8453 /* Create a new thread to receive the work queue messages */
8454 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8456 pthread_attr_destroy(&attr);
8461 pthread_attr_destroy(&attr);
8465 }/* ssInitRcvWork */
8472 * Desc: This is the handler function of receive
8476 * RFAILED - failed, general (optional)
8478 * Notes:The handler function of the work queue receiver task.
8479 * This will be waiting for the work and after receiving
8480 * it, work will converted and posted to that entityt
8487 PRIVATE void *workRcvTsk
8492 PRIVATE void *workRcvTsk (ptr)
8497 cvmx_wqe_t *workPtr;
8498 Buffer *mBuf, *rcvdBuf;
8499 SsMsgInfo *minfoPtr;
8509 /* get the work if its avilable */
8510 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8512 if ( workPtr == NULLP )
8514 /* If there is no work then sleep for 10 usec */
8516 ts.tv_nsec = 500000;
8518 nanosleep(&ts, NULLP);
8522 switch(workPtr->tag)
8524 /* Switch over according to the tag value */
8525 case SS_CVMX_MBUF_TAG:
8527 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8529 /* Convert the physical address to Pointers */
8530 ret = SConvPhyPtr(&rcvdBuf);
8533 /* mt011.301: Cavium 32 bit changes */
8534 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8538 /* Copy the buffer to this region */
8539 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8542 /* mt011.301: Cavium 32 bit changes */
8543 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8547 /* mt011.301: Cavium 32 bit changes */
8548 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8550 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8552 /* Get the post strucutre and Post the message */
8553 if ( minfoPtr != NULLP)
8555 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8557 (Void)SPstTsk(&pst, mBuf);
8559 /* Free the buffer allocated if it cannot be sent */
8568 /* Invalid tag value, drop the work */
8569 /* mt011.301: Cavium 32 bit changes */
8570 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8579 #endif /* SS_SEUM_CAVIUM */
8581 #ifdef TENB_RTLIN_CHANGES
8582 PUBLIC S16 SInitLock(SLockId *l, U8 t)
8585 pthread_mutexattr_t prior;
8586 pthread_mutexattr_init(&prior);
8587 #ifndef RGL_SPECIFIC_CHANGES
8588 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8590 r = pthread_mutex_init(l, &prior);
8591 pthread_mutexattr_destroy(&prior);
8595 #ifdef SS_THR_REG_MAP
8598 * Fun: ssRegMainThread
8600 * Desc: This function is used to add the memory region
8601 * mapping for the main thread.
8603 * Ret: VOID (Always successful)
8611 PUBLIC Void ssRegMainThread(Void)
8616 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8619 printf("not able to get different Id for main thread\n");
8622 /* Here the default region is added as we dont have any region associated with
8623 * Main thread. The thread should not perform any allocation except
8624 * the initial configuratin
8628 #ifdef XEON_SPECIFIC_CHANGES
8629 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8631 SS_GET_THREAD_MEM_REGION() =
8639 * Fun: ssCheckAndAddMemoryRegionMap
8641 * Desc: This function is used to add the memory region
8642 * mapping for the provided sTsk associated thread.
8643 * If the threadId can be placed in the thread memory
8644 * region mapping table and returns success if it is able
8645 * to place. If not, it keeps the thread ID in the static
8646 * local array and increments the count. Once thread Id
8647 * is successfully placed in the thread memory region mapping
8648 * table, pthread_cancel is sent for all the previous threads
8649 * which are failed to place in table.
8651 * Ret: TRUE - Thread ID successfully placed in thread memory region
8653 * FALSE - If thread Id is not placed in thread memory region
8656 * Notes:mapping tablemapping tablng tablee
8661 PUBLIC S32 ssCheckAndAddMemoryRegionMap
8663 pthread_t threadId, /* Thread Id of system task */
8664 Region region /* Region associated with thread */
8667 PRIVATE U32 createdThreads;
8668 PRIVATE pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8671 TRC1(ssCheckAndAddMemoryRegionMap);
8673 /* Here 0xFF is considered as invalid region and if the mapping table
8674 * contains 0xFF, that mapping entry is free
8678 if(SS_INVALID_THREAD_REG_MAP !=
8679 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8682 /* Klock work fix ccpu00148484 */
8683 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8685 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8686 printf("Not able to get the different thread ID, exiting\n");
8689 createdThreadIds[createdThreads++] = threadId;
8692 /* If we found free mapping table entry, place the region and send pthread_cancel
8693 * for all the thread Ids which are created before this
8697 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8698 #ifdef XEON_SPECIFIC_CHANGES
8699 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8700 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8701 SS_MAX_THREAD_REGION_MAP), region);
8704 for(indx = 0; indx < createdThreads; indx++)
8706 #ifdef XEON_SPECIFIC_CHANGES
8707 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8709 pthread_cancel(createdThreadIds[indx]);
8715 } /* ssCheckAndAddMemoryRegionMap */
8719 * Fun: ssCheckAndDelMemoryRegionMap
8721 * Desc: This function is used to add the memory region
8722 * mapping for the provided sTsk associated thread.
8723 * If the threadId can be placed in the thread memory
8724 * region mapping table and returns success if it is able
8725 * to place. If not, it keeps the thread ID in the static
8726 * local array and increments the count. Once thread Id
8727 * is successfully placed in the thread memory region mapping
8728 * table, pthread_cancel is sent for all the previous threads
8729 * which are failed to place in table.
8731 * Ret: TRUE - Thread ID successfully placed in thread memory region
8733 * FALSE - If thread Id is not placed in thread memory region
8736 * Notes:mapping tablemapping tablng tablee
8741 PUBLIC S32 ssCheckAndDelMemoryRegionMap
8743 pthread_t threadId /* Thread Id of system task */
8747 TRC1(ssCheckAndDelMemoryRegionMap);
8749 /* Raghu To-Do Check with team, is it necessary to acquire lock
8750 * as del and add may go parallel */
8751 /* Here 0xFF is considered as invalid region and if the mapping table
8752 * contains 0xFF, that mapping entry is free
8754 if(SS_INVALID_THREAD_REG_MAP ==
8755 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8758 printf("Invalid Thread ID (%ld)\n", (U32)threadId);
8760 printf("Invalid Thread ID (%d)\n", (U32)threadId);
8764 /* If we found free mapping table entry, place the region and send pthread_cancel
8765 * for all the thread Ids which are created before this
8767 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8771 } /* ssCheckAndAddMemoryRegionMap */
8775 #ifdef SS_TSKLOG_ENABLE
8780 * Desc: This function will return current time through input parameter.
8783 * RFAILED - failed, general (optional)
8790 PUBLIC S16 SStartTask
8792 VOLATILE U32 *startTime,
8796 PUBLIC S16 SStartTask(startTime, taskId)
8797 VOLATILE U32 *startTime;
8801 #ifdef MSPD_MLOG_NEW
8802 *startTime = GetTIMETICK();
8811 * Desc: This function will return current time through input parameter.
8812 * and take the difference of start time provided as input parameter
8816 * RFAILED - failed, general (optional)
8823 PUBLIC S16 SStopTask
8825 VOLATILE U32 startTime,
8829 PUBLIC S16 SStopTask(startTime, taskId)
8830 VOLATILE U32 startTime;
8837 case PID_MAC_HARQ_IND:
8838 case PID_SCH_TTI_IND:
8840 case PID_MAC_DAT_IND:
8841 case PID_MAC_SF_ALLOC_REQ:
8842 case PID_MAC_STA_RSP:
8843 case PID_MAC_DL_SCHD:
8844 case PID_MAC_DL_CQI_IND:
8845 case PID_MAC_UL_CQI_IND:
8846 case PID_MAC_UL_SCHD:
8847 case PID_MAC_TTI_IND:
8848 case PID_CL_RCV_PHY_MSG:
8849 case PID_CL_HARQ_STA_IND:
8850 case PID_MAC_AM_HARQ_RLS:
8851 case PID_CL_DL_BATCH_PROC:
8852 case PID_CL_DLM_PRC_TTI_IND:
8853 case PID_CRC_IND_REAL:
8854 case PID_CRC_IND_DUMMY:
8855 case PID_TTI_LATENCY:
8856 case PID_RECPREQ_PROC:
8859 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8861 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8864 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8872 PUBLIC S16 SStartTask
8874 VOLATILE U32 * startTime,
8878 PUBLIC S16 SStartTask(startTime, taskId)
8879 VOLATILE U32 * startTime;
8888 PUBLIC S16 SStopTask
8890 VOLATILE U32 startTime,
8894 PUBLIC S16 SStopTask(startTime, taskId)
8895 VOLATILE U32 startTime;
8902 #endif /*#ifdef SS_TSKLOG_ENABLE */
8903 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8905 * This primitive is used to calculate the CPU Utilization per Core
8910 * @return Void - function is always success
8913 PUBLIC Void UpdateSocCpuInfo
8915 CmCpuStatsInfo *cpuInfo,
8919 PUBLIC Void UpdateSocCpuInfo(*cpuInfo, idx)
8920 CmCpuStatsInfo *cpuInfo;
8925 S8 mipsStr[MIPS_STRING_LEN];
8932 /* Open the file which holds the MIPS available value */
8933 mipsFd = fopen(MIPS_FILE, "r");
8940 /* Get the free mips available value from the file */
8941 if(NULLP == fgets(mipsStr, 24, mipsFd))
8943 printf("fgets to get the free mips available failed\n");
8948 strtok(mipsStr, " ");
8950 strPart = strtok(NULLP, " ");
8952 if(idx == CM_L2_CPU_UTIL)
8954 if(strPart != NULLP)
8956 l2FreeCpu = atoi(strPart);
8957 l2CpuUsed = 100 - l2FreeCpu;
8958 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8959 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);;
8960 cpuInfo->cpuUtil[0].numSamples++;
8963 if(idx == CM_L3_CPU_UTIL)
8965 strPart = strtok(NULLP, " ");
8966 if(strPart != NULLP)
8968 l3FreeCpu = atoi(strPart);
8969 l3CpuUsed = 100 - l3FreeCpu;
8970 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8971 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);;
8972 cpuInfo->cpuUtil[0].numSamples++;
8975 if(idx == CM_L2_CPU_UTIL)
8977 cpuInfo->numCores = CM_NUM_L2_CORES ;
8979 else if(idx == CM_L3_CPU_UTIL)
8981 cpuInfo->numCores = CM_NUM_L3_CORES ;
8987 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8988 #ifdef SS_MULTICORE_SUPPORT
8991 * Fun: Add Timer thread into system task table
8993 * Desc: This function is used to add the system task
8994 * associated with Timer thread.
9004 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(
9008 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(idx)
9015 TRC1(ssdReAddTmrSTsk);
9017 /* lock the system task table */
9018 ret = SLock(&osCp.sTskTblLock);
9022 #if (ERRCLASS & ERRCLS_DEBUG)
9023 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
9024 "Could not lock system task table");
9030 /* initialize the system task entry with the information we have */
9031 sTsk = &osCp.sTskTbl[idx];
9036 SDestroyLock(&sTsk->lock);
9037 ssDestroyDmndQ(&sTsk->dQ);
9040 /* store the system task priority */
9041 sTsk->tskPrior = SS_NORM_TSK_PRI;
9043 /* initialize the demand queue */
9044 if (ssInitDmndQ(&sTsk->dQ) != ROK)
9047 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9049 #if (ERRCLASS & ERRCLS_DEBUG)
9050 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
9051 "Could not give the Semaphore");
9056 #if (ERRCLASS & ERRCLS_DEBUG)
9057 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
9058 "Could not initialize demand queue");
9064 /* initialize the system task entry lock */
9065 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
9067 ssDestroyDmndQ(&sTsk->dQ);
9069 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9071 #if (ERRCLASS & ERRCLS_DEBUG)
9072 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
9073 "Could not give the Semaphore");
9078 #if (ERRCLASS & ERRCLS_DEBUG)
9079 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9080 "Could not initialize system task entry lock");
9087 /* success, update the table */
9088 sTsk->tskId = idx + 1;
9090 sTsk->termPend = FALSE;
9092 /* unlock the system task table */
9094 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9096 #if (ERRCLASS & ERRCLS_DEBUG)
9097 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9098 "Could not give the Semaphore");
9105 #endif /* SS_MULTICORE_SUPPORT */
9110 * Fun: Initialize timer table
9112 * Desc: This function initializes MTSS-specific information
9113 * in the timer table.
9123 PUBLIC S16 ssdReInitTmr
9128 PUBLIC S16 ssdReInitTmr()
9131 pthread_attr_t attr;
9132 struct sched_param param_sched;
9133 #ifndef XEON_SPECIFIC_CHANGES
9136 #ifdef SS_MULTICORE_SUPPORT
9138 #endif /* SS_MULTICORE_SUPPORT */
9139 #ifdef SS_THR_REG_MAP
9140 U32 threadCreated = FALSE;
9141 #endif /* SS_THR_REG_MAP */
9145 #ifndef XEON_SPECIFIC_CHANGES
9146 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9149 #if (ERRCLASS & ERRCLS_DEBUG)
9150 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9151 "Could not give the Semaphore");
9157 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9158 /* mt010.21: addition */
9160 #ifdef SS_MULTICORE_SUPPORT
9161 sTsk = ssdReAddTmrSTsk(0);
9166 #endif /* SS_MULTICORE_SUPPORT */
9167 /* create the timer handler thread */
9169 pthread_attr_init(&attr);
9170 /* mt021.201 - Addition to set stack size */
9171 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9172 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9173 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9174 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9175 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9176 pthread_attr_setschedparam(&attr, ¶m_sched);
9179 #ifdef SS_THR_REG_MAP
9180 /* When the thread is created, we check for the memory mapping table if
9181 * threadId can be placed in thread memory map table. If it is not able to place
9182 * threadId is stored in tmporary array. Once thread is created successful,
9183 * thread_cancel is sent for each thread which are created before. All the
9184 * threads are made to wait on sema which is cancel point for thread.
9186 while(threadCreated == FALSE)
9189 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9191 /* mt020.201 - Addition for destroying thread attribute object attr */
9192 pthread_attr_destroy(&attr);
9197 #ifdef SS_THR_REG_MAP
9198 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9201 #endif /* SS_THR_REG_MAP */
9202 #ifdef SS_MEM_WL_DEBUG
9203 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9206 /* mt020.201 - Addition for destroying thread attribute object attr */
9207 pthread_attr_destroy(&attr);
9208 sem_post(&osCp.dep.ssStarted);
9212 /**********************************************************************
9214 **********************************************************************/