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 #if defined(RGL_SPECIFIC_CHANGES) || defined(INTEL_WLS)
166 #include <hugetlbfs.h>
170 EXTERN void LwrMacRecvPhyMsg();
173 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
174 EXTERN S16 rgBatchProc (Void);
176 #ifdef RLC_MAC_DAT_REQ_RBUF
177 EXTERN S16 rgDlDatReqBatchProc ARGS((
180 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
181 EXTERN S16 rgBatchProc ARGS((
185 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
186 /* general purpose debug zone */
187 char my_buffer2[4096 * 4] = { 0 };
188 char my_buffer[4096] = { 0 };
189 int my_buffer_idx = 0;
193 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
195 struct sigcontext my_uc_mcontext = { 0 };
200 #include <ucontext.h>
204 #define SIGSEGV_STACK_GENERIC
205 #define REGFORMAT "%x\n"
207 #ifdef XEON_SPECIFIC_CHANGES
208 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
211 void dump_external(void);
214 PRIVATE Void mtDelSigals
219 PRIVATE Void mtDelSignals()
224 memset(&sa, 0, sizeof(struct sigaction));
225 sigemptyset(&sa.sa_mask);
226 sa.sa_handler = SIG_DFL;
227 sigaction(SIGSEGV, &sa, NULL);
229 memset(&sa, 0, sizeof(struct sigaction));
230 sigemptyset(&sa.sa_mask);
231 sa.sa_handler = SIG_DFL;
232 sigaction(SIGILL, &sa, NULL);
236 static void signal_segv(int signum, siginfo_t * info, void *ptr)
238 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
241 ucontext_t *ucontext = (ucontext_t *) ptr;
242 #ifdef XEON_SPECIFIC_CHANGES
244 int *p32 = (int *) 0x2fff0000;
249 printf("segv ooops @ %p\n", info->si_addr);
252 printf("Segmentation Fault!\n");
253 printf("info.si_signo = %d\n", signum);
254 printf("info.si_errno = %d\n", info->si_errno);
255 printf("info.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
256 printf("info.si_addr = %p\n", info->si_addr);
258 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
261 #ifndef RGL_SPECIFIC_CHANGES
262 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
263 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
264 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
265 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
266 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
267 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
268 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
269 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
270 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
271 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
272 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
273 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
274 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
275 printf("reg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
276 printf("reg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
277 printf("reg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
278 printf("reg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
281 printf("Stack trace (non-dedicated):\n");
283 sz = backtrace(buffer, 50);
284 strings = backtrace_symbols(buffer, sz);
285 for (i = 0; i < sz; ++i)
286 printf("%s\n", strings[i]);
288 printf("End of stack trace.");
290 #ifdef XEON_SPECIFIC_CHANGES
295 /* Lets first print our debug information */
296 printf("Before dumping our Debug info\n");
298 printf("After dumping our Debug info\n");
300 /* Disable the signal and make the enodeb to dump. This will make
301 * eNB to generate the core with dumping the ccpu log
308 /* End printing debug information */
313 /*** TBD: IMPORTANT ***
314 *** The following definition is temporary. This must be removed
315 *** when all products have been updated with latest ssi.h file OR
316 *** all ssi.h files have been updated to contain this definitions
318 /* New error class for FTHA added */
320 #define ERRCLS_FTHA 0x8
321 #endif /* ERRCLS_FTHA */
323 typedef struct _SPThreadCreateArg
325 void *argument; /* argument that is to be passed to the actual pthread */
326 void *(*start_routine) (void *); /* function from which pthread starts */
329 PUBLIC void *pthreadCreateHdlr(void* arg);
331 #ifdef SS_LOCKLESS_MEMORY
332 PUBLIC Buffer *mtTskBuffer1;
333 PUBLIC Buffer *mtTskBuffer2;
335 EXTERN pthread_t tmpRegTidMap[20];
336 EXTERN U8 stopBtInfo;
337 EXTERN S16 SGlobMemInfoShow(void);
338 #endif /* SS_LOCKLESS_MEMORY */
341 EXTERN APP_CONTEXT AppContext;
342 EXTERN S32 clusterMode;
345 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
346 EXTERN unsigned int tlPost(void *handle);
349 /* forward references */
350 /* mt003.301 Modifications - Moved to ss_gen.x */
351 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
352 PUBLIC Void *mtTskHdlrT2kL2 ARGS((Void*));
353 PUBLIC void mtSigSegvHndlr ARGS((void));
354 PUBLIC void mtSigUsr2Hndlr ARGS((void));
357 PRIVATE S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
358 PRIVATE Void *mtTskHdlr ARGS((void *));
359 PRIVATE S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
361 PRIVATE Void *mtTmrHdlr ARGS((void *));
362 PRIVATE Void mtTimeout ARGS((PTR tCb, S16 evnt));
364 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
365 PRIVATE Void mtIntSigHndlr ARGS((int));
366 PRIVATE Void mtExitClnup ARGS((void));
369 PRIVATE Void *mtConHdlr ARGS((void *));
373 #ifdef SS_DRVR_SUPPORT
374 PRIVATE Void *mtIsTskHdlr ARGS((void *));
378 /* mt020.201 - Addition for no command line available */
380 PRIVATE Void mtGetOpts ARGS((void));
381 /* mt003.301 Additions - File Based task registration made
382 * common for both MULTICORE and NON-MULTICORE
384 PRIVATE Bool fileBasedMemCfg = FALSE;
387 /* mt033.201 - addition of local function to print the statistics such as
388 * (size vs. numAttempts) and (allocations vs. deallocations)
390 #ifdef SSI_DEBUG_LEVEL1
391 PRIVATE S16 SPrintRegMemStats ARGS((Region region));
392 #endif /* SSI_DEBUG_LEVEL1 */
394 #ifdef SS_MULTICORE_SUPPORT
395 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void);
396 PRIVATE SsSTskEntry* ssdReAddTmrSTsk ARGS((U8 idx));
397 #ifndef SS_LOCKLESS_MEMORY
398 #ifndef RGL_SPECIFIC_CHANGES
399 PRIVATE S16 ssdInitMemInfo ARGS((void));
404 /* mt005.301: Cavium changes */
405 #ifdef SS_SEUM_CAVIUM
406 PRIVATE Void *workRcvTsk ARGS((void *));
407 #endif /* SS_SEUM_CAVIUM */
409 #ifdef SS_THR_REG_MAP
410 PUBLIC S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
412 PUBLIC S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
413 #endif /* SS_THR_REG_MAP */
415 /* type declarations */
417 #ifdef SS_DRVR_SUPPORT
418 typedef struct mtIsFlag
428 /* public variable declarations */
430 PUBLIC Cntr cfgNumRegs = SS_MAX_REGS;
431 /* Set memory configuration as false.
432 * Set to true if memory configuration through file is successfull.
434 PUBLIC Bool memConfigured = FALSE;
435 /* mt022.201 - Modification for shared memory relay region and memcal tool */
436 PUBLIC SsRegCfg cfgRegInfo[SS_MAX_REGS] =
439 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
441 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
442 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
443 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
444 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
445 { SS_POOL_STATIC, 0 }
451 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
453 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
454 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
455 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
456 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
457 { SS_POOL_STATIC, 0 }
460 #endif /* INTEL_WLS */
462 #ifdef SS_LOCKLESS_MEMORY
465 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
467 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
468 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
469 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
470 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
471 { SS_POOL_STATIC, 0 }
475 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
477 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
478 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
479 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
480 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
481 { SS_POOL_STATIC, 0 }
485 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
487 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
488 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
489 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
490 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
491 { SS_POOL_STATIC, 0 }
495 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
497 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
498 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
499 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
500 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
501 { SS_POOL_STATIC, 0 }
504 #endif /* SS_LOCKLESS_MEMORY */
506 /* mt003.301 Modifications - File Based task registration made
507 * common for both MULTICORE and NON-MULTICORE
510 #ifdef SS_LOCKLESS_MEMORY
511 PUBLIC MtDynMemCfg mtDynMemoCfg =
513 SS_MAX_REGS, /* number of regions */
516 SS_DFLT_REGION, /* region id */
517 MT_MAX_BKTS, /* number of buckets */
519 /* block size, no. of blocks, Upper threshold, lower threshold */
520 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
521 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
522 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
523 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
527 SS_DFLT_REGION + 1, /* region id */
528 MT_MAX_BKTS, /* number of buckets */
530 /* block size, no. of blocks, Upper threshold, lower threshold */
531 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
532 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
533 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
534 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
538 SS_DFLT_REGION + 2, /* region id */
539 MT_MAX_BKTS, /* number of buckets */
541 /* block size, no. of blocks, Upper threshold, lower threshold */
542 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
543 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
544 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
545 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
549 SS_DFLT_REGION + 3, /* region id */
550 MT_MAX_BKTS, /* number of buckets */
552 /* block size, no. of blocks, Upper threshold, lower 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},
556 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
560 SS_DFLT_REGION + 4, /* region id */
561 MT_MAX_BKTS, /* number of buckets */
563 /* block size, no. of blocks, Upper threshold, lower threshold */
564 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
565 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
566 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
567 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
570 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
573 SS_DFLT_REGION + 4, /* region id */
574 MT_MAX_BKTS, /* number of buckets */
576 /* block size, no. of blocks, Upper threshold, lower threshold */
577 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
578 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
579 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
580 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
588 PUBLIC MtGlobMemCfg mtGlobMemoCfg =
590 MT_MAX_BKTS, /* number of buckets */
593 /* block size, no. of blocks, Upper threshold, lower threshold */
594 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
595 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
596 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
597 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
599 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
600 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
601 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
602 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
606 #endif /* SS_LOCKLESS_MEMORY */
608 /* mt022.201 - Modification for memory calculator tool */
609 /* mt018.201 - added memory configuration matrix */
610 PUBLIC MtMemCfg mtMemoCfg =
613 SS_MAX_REGS - 1, /* number of regions */
615 #ifndef XEON_SPECIFIC_CHANGES
616 SS_MAX_REGS, /* number of regions */
623 SS_DFLT_REGION, /* region id */
624 MT_MAX_BKTS, /* number of buckets */
625 MT_HEAP_SIZE, /* heap size */
627 #ifndef XEON_SPECIFIC_CHANGES
628 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
629 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
630 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
631 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
633 {256, 491520}, /* 60 pages of 2M*/
634 {512, 12288}, /* 3 pages of 2M */
635 {2048, 99328}, /* 97 Pages of 2M */
636 {8192, 75008}, /* 293 Pages of 2M */
637 {16384, 4096} /* 32 pages of 2M */
642 #ifndef SS_LOCKLESS_MEMORY
644 SS_DFLT_REGION + 1, /* region id */
645 MT_MAX_BKTS, /* number of buckets */
646 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
648 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
649 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
650 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
651 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
659 #endif /* SS_LOCKLESS_MEMORY */
660 #endif /* INTEL_WLS */
661 #ifdef SS_LOCKLESS_MEMORY
663 SS_DFLT_REGION + 1, /* region id */
664 MT_MAX_BKTS, /* number of buckets */
665 MT_HEAP_SIZE, /* heap size */
667 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
668 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
669 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
670 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
674 SS_DFLT_REGION + 2, /* region id */
675 MT_MAX_BKTS, /* number of buckets */
676 MT_HEAP_SIZE, /* heap size */
678 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
679 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
680 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
681 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
685 SS_DFLT_REGION + 3, /* region id */
686 MT_MAX_BKTS, /* number of buckets */
687 MT_HEAP_SIZE, /* heap size */
689 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
690 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
691 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
692 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
696 SS_DFLT_REGION + 4, /* region id */
697 MT_MAX_BKTS, /* number of buckets */
698 MT_HEAP_SIZE, /* heap size */
700 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
701 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
702 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
703 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
707 #endif /* SS_LOCKLESS_MEMORY */
711 /* mt003.301 Modifications - File Based task registration made
712 * common for both MULTICORE and NON-MULTICORE
713 * bucket info, as different regions may request for different no.
716 PUBLIC MtBktCfg mtBktInfo[MT_MAX_BKTS];
717 PUBLIC S16 msArgc; /* argc */
718 PUBLIC Txt **msArgv; /* argv */
719 PUBLIC S16 msOptInd; /* SGetOpt vars */
720 PUBLIC S8 *msOptArg; /* SGetOpt vars */
724 typedef struct _MtRegMemSz
730 PRIVATE MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
734 /* private variable declarations */
735 /* mt018.201 - change mtCMMRegCfg as array of pointers */
736 PRIVATE CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
737 PRIVATE CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
738 /* mt003.301 - Fixed compilation warnings */
739 /*mt004.301-addede new veriable for FAP*/
740 /*mt010.301 - removed veriable defined for FA*/
746 void mtSetNtlHdl(unsigned int hdl)
751 unsigned int mtGetNtlHdl()
753 return(osCp.ntl.hdl);
760 RETVALUE(osCp.wls.intf);
763 #ifdef XEON_MULTIPLE_CELL_CHANGES
764 EXTERN S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
765 EXTERN S16 smWrReadWlsConfigParams (Void);
768 PRIVATE int SOpenWlsIntf()
771 #define WLS_DEVICE_NAME "/dev/wls"
773 #ifdef XEON_SPECIFIC_CHANGES
774 #ifdef XEON_MULTIPLE_CELL_CHANGES
775 hdl = WLS_Open(gWrWlsDeviceName, 1);
777 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
780 hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, (512 *1024 * 1024));
787 printf("Could not open WLS Interface \n");
802 * Desc: This function is the entry point for the final binary. It
803 * calls SInit() in the common code. It can be replaced by a
804 * user function if required (SInit() must still be called).
806 * Ret: none on success
817 int argc, /* argument count */
818 char **argv /* argument vector */
821 PUBLIC int main(argc, argv)
822 int argc; /* argument count */
823 char **argv; /* argument vector */
828 #ifdef XEON_MULTIPLE_CELL_CHANGES
829 /* Read the WLS parameters from the file and copy into global control block */
830 if(smWrReadWlsConfigParams() != ROK)
832 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
834 } /* end of if statement */
840 #endif /* INTEL_WLS */
844 /* mt003.301 Modifications */
847 printf("\n SInit failed, SSI could not start \n");
848 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
852 /*mt010.301 cleanup part exposed to user*/
863 * Desc: This function is the entry point for the final binary. It
864 * calls SInit() in the common code. It can be replaced by a
865 * user function if required (SInit() must still be called).
867 * Ret: none on success
878 int argc, /* argument count */
879 char **argv /* argument vector */
882 PUBLIC int ssMain(argc, argv)
883 int argc; /* argument count */
884 char **argv; /* argument vector */
901 * initialization functions
906 * Fun: Initialize OS control point
908 * Desc: This function initializes MTSS-specific information
909 * in the OS control point.
919 PUBLIC S16 ssdInitGen
924 PUBLIC S16 ssdInitGen()
927 struct sigaction act;
929 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
935 /*mt014.301 : 4GMX release related changes*/
939 /* mt005.301 : Cavium changes */
940 #ifdef SS_SEUM_CAVIUM
941 /* set group mask for the core */
942 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
943 #endif /* SS_SEUM_CAVIUM */
945 osCp.dep.sysTicks = 0;
947 /* mt020.201 - Addition for no command line available */
949 /* parse command line */
951 /* mt003.301 Additions */
952 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
954 printf("\n File Based Memory configuration failed \n");
959 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
960 #ifndef SS_LOCKLESS_MEMORY
961 #ifdef SS_MULTICORE_SUPPORT
962 if(memConfigured == FALSE)
968 /* initialize the started semaphore */
969 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
974 /* mt028.201 added compile time flag to allow not to mask signals */
976 /* mask all signals in the main thread */
978 sigdelset(&set, SIGINT);
979 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
980 sigdelset(&set, SIGSEGV);
981 sigdelset(&set, SIGUSR2);
982 sigdelset(&set, SIGILL);
983 #ifdef XEON_SPECIFIC_CHANGES
984 sigdelset(&set, SIGABRT);
985 sigdelset(&set, SIGTERM);
986 sigdelset(&set, SIGHUP);
989 pthread_sigmask(SIG_SETMASK, &set, NULLP);
990 #endif /* UNMASK_SIG */
992 /* install a SIGINT handler to shutdown */
993 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
995 /*Initialize SIGSEGV Signal */
996 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
998 memset(&sa, 0, sizeof(struct sigaction));
999 sigemptyset(&sa.sa_mask);
1000 sa.sa_sigaction = signal_segv;
1001 sa.sa_flags = SA_SIGINFO;
1002 #ifndef XEON_SPECIFIC_CHANGES
1003 sigaction(SIGSEGV, &sa, NULL);
1005 memset(&sa, 0, sizeof(struct sigaction));
1006 sigemptyset(&sa.sa_mask);
1007 sa.sa_sigaction = signal_segv;
1008 sa.sa_flags = SA_SIGINFO;
1010 sigaction(SIGILL, &sa, NULL);
1012 if(sigaction(SIGILL, &sa, NULL) != 0)
1014 printf("Failed to process sigaction for the SIGILL\n");
1017 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1019 printf("Failed to process sigaction for the SIGSEGV\n");
1022 if(sigaction(SIGABRT, &sa, NULL) != 0)
1024 printf("Failed to process sigaction for the SIGABRT\n");
1027 if(sigaction(SIGTERM, &sa, NULL) != 0)
1029 printf("Failed to process sigaction for the SIGTERM\n");
1032 if(sigaction(SIGHUP, &sa, NULL) != 0)
1034 printf("Failed to process sigaction for the SIGHUP\n");
1039 signal (SIGSEGV, mtSigSegvHndlr);
1040 signal (SIGKILL, mtSigSegvHndlr);
1041 signal (SIGUSR2, mtSigUsr2Hndlr);
1046 signal (SIGINT, mtStopHndlr);
1049 act.sa_handler = mtIntSigHndlr;
1050 sigfillset(&act.sa_mask);
1052 if (sigaction(SIGINT, &act, NULLP) != 0)
1058 /* mt040.201 initialise random seed */
1059 osCp.dep.randSeed = time(NULLP);
1067 * Fun: De-initialize OS control point
1069 * Desc: This function reverses the initialization in ssdInitGen().
1079 PUBLIC Void ssdDeinitGen
1084 PUBLIC Void ssdDeinitGen()
1090 sem_destroy(&osCp.dep.ssStarted);
1095 #ifdef SS_LOCKLESS_MEMORY
1099 * Fun: ssPutDynMemBlkSet
1101 * Desc: Returns the set of dynamic Blocks into the global region
1104 * Ret: ROK - successful,
1105 * RFAILED - unsuccessful.
1113 PUBLIC S16 ssPutDynMemBlkSet
1115 U8 bktIdx, /* Index to bucket list */
1116 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1117 added to global region */
1120 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1121 U8 bktIdx; /* Index to bucket list */
1122 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1123 added to global region */
1126 CmMmGlobRegCb *globReg;
1127 CmMmGlobalBktCb *bktCb;
1131 globReg = osCp.globRegCb;
1133 #if (ERRCLASS & ERRCLS_INT_PAR)
1134 if(bktIdx >= globReg->numBkts)
1138 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1140 bktCb = &(globReg->bktTbl[bktIdx]);
1142 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1144 blkPtr = dynMemSetElem->nextBktPtr;
1145 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1146 free((Void *)blkPtr);
1149 dynMemSetElem->nextBktPtr = NULLP;
1150 dynMemSetElem->numFreeBlks = 0;
1157 * Fun: ssGetDynMemBlkSet
1159 * Desc: Gets the set of dynamic memory blocks from the global region
1162 * Ret: ROK - successful,
1163 * RFAILED - unsuccessful.
1171 PUBLIC S16 ssGetDynMemBlkSet
1173 U8 bktIdx, /* Index to bucket list */
1174 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1175 with new set values */
1178 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1179 U8 bktIdx; /* Index to bucket list */
1180 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1181 with new set values */
1185 CmMmGlobRegCb *globReg;
1186 CmMmGlobalBktCb *bktCb;
1191 globReg = osCp.globRegCb;
1193 #if (ERRCLASS & ERRCLS_INT_PAR)
1194 if(bktIdx >= globReg->numBkts)
1198 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1200 bktCb = &(globReg->bktTbl[bktIdx]);
1201 basePtr = &(dynMemSetElem->nextBktPtr);
1203 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1205 blkPtr = (Data *)malloc(bktCb->size);
1207 basePtr = (CmMmEntry **)blkPtr;
1210 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1214 } /* ssGetDynMemBlkSet */
1219 * Fun: ssPutDynMemBlkSet
1221 * Desc: Returns the set of dynamic Blocks into the global region
1224 * Ret: ROK - successful,
1225 * RFAILED - unsuccessful.
1233 PUBLIC S16 ssPutDynMemBlkSet
1235 U8 bktIdx, /* Index to bucket list */
1236 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1237 added to global region */
1238 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1241 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1242 U8 bktIdx; /* Index to bucket list */
1243 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1244 added to global region */
1245 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1248 CmMmGlobRegCb *globReg;
1249 CmMmGlobalBktCb *bktCb;
1251 CmMmBlkSetElement *globMemNode;
1254 TRC1(ssPutDynMemBlkSet);
1256 globReg = osCp.globRegCb;
1258 #if (ERRCLASS & ERRCLS_INT_PAR)
1259 if(bktIdx >= globReg->numBkts)
1263 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1265 bktCb = &(globReg->bktTbl[bktIdx]);
1267 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1268 try lock is used as it is not required to block as it will be taken
1269 in the next go else it will be blocked for lock as we have to get the
1272 SLock(&(bktCb->bucketLock));
1278 /* Get a free node from the free node linked list */
1279 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1280 if(lstNode == NULLP)
1282 SUnlock(&(bktCb->bucketLock));
1286 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1288 /* Copy the content of the received element information on to free node
1289 * and add it to valid linked list */
1290 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1291 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1292 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1293 dynMemSetElem->numFreeBlks = 0;
1294 dynMemSetElem->nextBktPtr = NULLP;
1296 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1298 SUnlock(&(bktCb->bucketLock));
1306 * Fun: ssGetDynMemBlkSet
1308 * Desc: Gets the set of dynamic memory blocks from the global region
1311 * Ret: ROK - successful,
1312 * RFAILED - unsuccessful.
1314 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1321 PUBLIC S16 ssGetDynMemBlkSet
1323 U8 bktIdx, /* Index to bucket list */
1324 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1325 with new set values */
1326 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1329 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1330 U8 bktIdx; /* Index to bucket list */
1331 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1332 with new set values */
1333 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1336 CmMmGlobRegCb *globReg;
1337 CmMmGlobalBktCb *bktCb;
1339 CmMmBlkSetElement *globMemNode;
1342 TRC1(ssGetDynMemBlkSet);
1344 globReg = osCp.globRegCb;
1346 #if (ERRCLASS & ERRCLS_INT_PAR)
1347 if(bktIdx >= globReg->numBkts)
1351 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1353 bktCb = &(globReg->bktTbl[bktIdx]);
1355 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1356 try lock is used as it is not required to block as it will be taken
1357 in the next go else it will be blocked for lock as we have to get the
1360 SLock(&(bktCb->bucketLock));
1365 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1367 if(lstNode == NULLP)
1369 SUnlock(&(bktCb->bucketLock));
1373 /* Delete the node from the valid linked list and copy the values of the
1374 * elements of structrues into pointer */
1375 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1376 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1377 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1378 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1380 /* Add this node to the free node linked list */
1381 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1383 SUnlock(&(bktCb->bucketLock));
1387 } /* ssGetDynMemBlkSet */
1390 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1392 PRIVATE U32 memoryCheckCounter;
1395 PUBLIC U32 isMemThreshReached(
1399 PUBLIC U32 isMemThreshReached(reg)
1403 CmMmGlobRegCb *globReg;
1404 CmMmGlobalBktCb *bktCb;
1406 TRC3(isMemThreshReached)
1408 globReg = osCp.globRegCb;
1410 #if (ERRCLASS & ERRCLS_INT_PAR)
1411 if(bktIdx >= globReg->numBkts)
1415 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1417 bktCb = &(globReg->bktTbl[bktIdx]);
1419 if(gDynMemAlrm[bktIdx])
1421 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1422 SLock(&(bktCb->bucketLock));
1423 if(bktCb->listValidBktSet.count > 25)
1425 gDynMemAlrm[bktIdx] = FALSE;
1426 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1428 SUnlock(&(bktCb->bucketLock));
1434 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1436 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1437 SLock(&(bktCb->bucketLock));
1438 if(bktCb->listValidBktSet.count < 15 )
1439 gDynMemAlrm[bktIdx] = TRUE;
1440 memoryCheckCounter = 0;
1441 SUnlock(&(bktCb->bucketLock));
1447 #endif /* USE_MALLOC */
1448 #endif /* SS_LOCKLESS_MEMORY */
1450 #ifdef SS_USE_ICC_MEMORY
1453 * Fun: Initialize region/pool tables
1455 * Desc: This function initializes MTSS-specific information
1456 * in the region/pool tables and configures the common
1457 * memory manager for use.
1467 PUBLIC Void * ssGetIccHdl
1472 PUBLIC Void * ssGetIccHdl()
1476 CmMmDynRegCb *dynRegCb;
1478 /* Klock work fix ccpu00148484 */
1479 if(!(region < SS_MAX_REGS))
1484 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1486 RETVALUE(dynRegCb->iccHdl);
1488 #endif /* SS_USE_ICC_MEMORY */
1490 #ifdef T2K_MEM_LEAK_DBG
1491 extern RegionMemLeakInfo regMemLeakInfo;
1492 #endif /* T2K_MEM_LEAK_DBG */
1496 PUBLIC S16 SPartitionWlsMemory()
1501 U64 pageSize[1], hugePageSize;
1504 long int pageSize[1], hugePageSize;
1507 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1509 U8 *regMemStrtAddr = (U8 *)osCp.wls.allocAddr;
1511 gethugepagesizes(pageSize,1);
1512 hugePageSize = pageSize[0];
1513 for (i = 0; i < 1; i++)
1515 mtRegMemSz[i].startAddr = regMemStrtAddr;
1516 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1518 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1519 reqdSz = numHugePg * hugePageSize;
1520 regMemStrtAddr += reqdSz;
1521 #ifdef T2K_MEM_LEAK_DBG
1522 /* Since wls is region 0 */
1523 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1524 regMemLeakInfo.numActvRegions++;
1525 #endif /* T2K_MEM_LEAK_DBG */
1527 //Store last region addr for validation
1528 mtRegMemSz[i].startAddr = regMemStrtAddr;
1532 #ifdef SS_MEM_WL_DEBUG
1533 PUBLIC Void SChkAddrValid(int type, int region, PTR ptr)
1535 char *tryPtr = NULL;
1536 if(type == 0) //Global
1538 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1539 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1541 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1547 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1549 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1555 #endif /* SS_MEM_WL_DEBUG */
1557 PUBLIC S16 SPartitionStaticMemory(U8 *startAddr)
1562 U8 *regMemStrtAddr = (U8 *)startAddr;
1565 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1566 for (i = 1; i < mtMemoCfg.numRegions; i++)
1568 mtRegMemSz[i].startAddr = regMemStrtAddr;
1569 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1570 regMemStrtAddr += reqdSz;
1571 #ifdef T2K_MEM_LEAK_DBG
1572 { /* Since region 1 onwards are used for non wls */
1573 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1574 regMemLeakInfo.numActvRegions++;
1576 #endif /* T2K_MEM_LEAK_DBG */
1580 PUBLIC S16 SAllocateWlsMem()
1588 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1589 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1591 for (i = 0; i < 1; i++)
1593 /* allocate space for the region */
1594 region = &mtMemoCfg.region[i];
1595 reqdMemSz += region->heapsize;
1596 mtRegMemSz[i].reqdSz += region->heapsize;
1598 for (j = 0; j < region->numBkts; j++)
1600 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1601 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1604 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1605 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1607 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1609 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1611 SPartitionWlsMemory();
1614 PUBLIC S16 SAllocateStaticMem()
1623 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1625 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1626 for (i = 1; i < mtMemoCfg.numRegions; i++)
1628 /* allocate space for the region */
1629 region = &mtMemoCfg.region[i];
1630 reqdMemSz += region->heapsize;
1631 mtRegMemSz[i].reqdSz += region->heapsize;
1633 for (j = 0; j < region->numBkts; j++)
1635 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1636 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1640 startAddr = malloc(reqdMemSz + (1024 * 10));
1642 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1644 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1646 SPartitionStaticMemory(startAddr);
1649 #endif /* INTEL_WLS */
1655 * Fun: Initialize region/pool tables
1657 * Desc: This function initializes MTSS-specific information
1658 * in the region/pool tables and configures the common
1659 * memory manager for use.
1669 PUBLIC S16 ssdInitMem
1674 PUBLIC S16 ssdInitMem()
1677 /* mt018.201 - added local variable */
1682 Txt errMsg[256] = {'\0'};
1683 #ifdef SS_LOCKLESS_MEMORY
1684 CmMmDynRegCb *dynRegCb;
1685 #ifdef SS_USE_ICC_MEMORY
1687 CmMmGlobRegCb *globReg;
1690 #endif /* SS_LOCKLESS_MEMORY */
1694 /* Use the default SSI memory manager if the ICC memory manager is not
1695 * avilable. If ICC memory manager is avilable, it will be used for
1696 * all sharable memory allocation and de-allocation */
1697 #ifdef SS_LOCKLESS_MEMORY
1698 #ifdef SS_USE_ICC_MEMORY
1699 #ifndef YS_PHY_3_8_2
1701 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1703 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1704 if(dynRegCb == NULLP)
1708 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1710 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1712 dynRegCb->region = i;
1713 cmMmDynRegInit(dynRegCb);
1714 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1717 /* ysIccHdl = dynRegCb->iccHdl; */
1720 /* Initialize the global region first */
1721 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1723 if(osCp.globRegCb == NULLP)
1728 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1730 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1732 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1734 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1736 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1738 if(globReg->bktTbl[i].startAddr == NULLP)
1742 globReg->bktTbl[i].poolId = i;
1743 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1744 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1745 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1748 globReg->numBkts = mtGlobMemoCfg.numBkts;
1749 cmMmGlobRegInit(globReg);
1751 /* Initialize the dynamic task regions and sanity check for the theshold
1753 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1755 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1756 if(dynRegCb == NULLP)
1760 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1762 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1763 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1764 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1765 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1767 #ifdef XEON_SPECIFIC_CHANGES
1772 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1773 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1774 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1775 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1776 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1778 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1781 dynRegCb->region = i;
1782 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1783 cmMmDynRegInit(dynRegCb);
1785 #endif /* SS_USE_ICC_MEMORY */
1786 #endif /* SS_LOCKLESS_MEMORY */
1788 #ifdef T2K_MEM_LEAK_DBG
1790 /* Initailize mem leak tool memorys for debguing */
1791 regMemLeakInfo.numActvRegions=0;
1792 for(reg=0; reg <SS_MAX_REGS; reg++)
1794 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1795 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1796 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1797 regMemLeakInfo.regStartAddr[reg] = 0;
1800 regMemLeakInfo.regStartAddr[reg] = 0;
1801 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1803 printf("\n mutex init failed\n");
1809 /* Now allocate WLS memory */
1811 SAllocateStaticMem();
1813 /* mt018.201 - CMM Initialization */
1814 for (i = 0; i < mtMemoCfg.numRegions; i++)
1816 /* allocate space for the region control block */
1817 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1818 #ifdef TENB_RTLIN_CHANGES
1819 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1821 if (mtCMMRegCb[i] == NULLP)
1823 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1824 for the Region:%d control block\n",i);
1826 for (k = 0; k < i; k++)
1828 cmMmRegDeInit(mtCMMRegCb[k]);
1829 free(mtCMMRegCfg[k]->vAddr);
1830 free(mtCMMRegCb[k]);
1831 free(mtCMMRegCfg[k]);
1836 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1837 #ifdef TENB_RTLIN_CHANGES
1838 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1840 if (mtCMMRegCfg[i] == NULLP)
1842 for (k = 0; k < i; k++)
1844 cmMmRegDeInit(mtCMMRegCb[k]);
1845 free(mtCMMRegCfg[k]->vAddr);
1846 free(mtCMMRegCb[k]);
1847 free(mtCMMRegCfg[k]);
1849 free(mtCMMRegCb[i]);
1854 /* allocate space for the region */
1855 region = &mtMemoCfg.region[i];
1856 mtCMMRegCfg[i]->size = region->heapsize;
1857 for (j = 0; j < region->numBkts; j++)
1859 /* mt033.201 - addition for including the header size while computing the total size */
1860 #ifdef SSI_DEBUG_LEVEL1
1861 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1862 (region->bkt[j].numBlks);
1864 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1865 #endif /* SSI_DEBUG_LEVEL1 */
1868 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1870 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1873 #ifdef XEON_SPECIFIC_CHANGES
1874 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1875 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1877 #ifdef TENB_RTLIN_CHANGES
1878 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1881 if (mtCMMRegCfg[i]->vAddr == NULLP)
1883 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1884 for the Region:%d \n",i);
1886 for (k = 0; k < i; k++)
1888 cmMmRegDeInit(mtCMMRegCb[k]);
1889 free(mtCMMRegCfg[k]->vAddr);
1890 free(mtCMMRegCb[k]);
1891 free(mtCMMRegCfg[k]);
1893 free(mtCMMRegCb[i]);
1894 free(mtCMMRegCfg[i]);
1899 /* set up the CMM configuration structure */
1900 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1901 mtCMMRegCfg[i]->chFlag = 0;
1902 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1903 mtCMMRegCfg[i]->numBkts = region->numBkts;
1905 for (j = 0; j < region->numBkts; j++)
1907 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1908 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1911 /* initialize the CMM */
1912 #ifdef SS_LOCKLESS_MEMORY
1913 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1915 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1916 #endif /* SS_LOCKLESS_MEMORY */
1918 for (k = 0; k < i; k++)
1920 cmMmRegDeInit(mtCMMRegCb[k]);
1921 free(mtCMMRegCfg[k]->vAddr);
1922 free(mtCMMRegCb[k]);
1923 free(mtCMMRegCfg[k]);
1925 free(mtCMMRegCfg[i]->vAddr);
1926 free(mtCMMRegCb[i]);
1927 free(mtCMMRegCfg[i]);
1932 /* initialize the STREAMS module */
1933 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1934 if (region->regionId == 0)
1936 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
1938 for (k = 0; k < i; k++)
1940 cmMmRegDeInit(mtCMMRegCb[k]);
1941 free(mtCMMRegCfg[k]->vAddr);
1942 free(mtCMMRegCb[k]);
1943 free(mtCMMRegCfg[k]);
1945 cmMmRegDeInit(mtCMMRegCb[i]);
1946 free(mtCMMRegCfg[i]->vAddr);
1947 free(mtCMMRegCb[i]);
1948 free(mtCMMRegCfg[i]);
1953 /* mt001.301 : Additions */
1954 #ifdef SS_MEM_LEAK_STS
1956 #endif /* SS_MEM_LEAK_STS */
1965 * Fun: De-initialize region/pool tables
1967 * Desc: This function reverses the initialization in ssdInitMem().
1977 PUBLIC Void ssdDeinitMem
1982 PUBLIC Void ssdDeinitMem()
1985 /* mt018.201 - added local variables */
1989 /* mt008.301 Additions */
1990 #ifdef SS_MEM_LEAK_STS
1991 cmDeinitMemLeakMdl();
1992 #endif /* SS_MEM_LEAK_STS */
1994 for (i = 0; i < mtMemoCfg.numRegions; i++)
1996 cmMmRegDeInit(mtCMMRegCb[i]);
1997 free(mtCMMRegCfg[i]->vAddr);
1998 free(mtCMMRegCb[i]);
1999 free(mtCMMRegCfg[i]);
2008 * Fun: Initialize task table
2010 * Desc: This function initializes MTSS-specific information
2011 * in the task table.
2021 PUBLIC S16 ssdInitTsk
2026 PUBLIC S16 ssdInitTsk()
2029 /* mt001.301 : Additions */
2030 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2031 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2033 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2038 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2039 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2040 /* initialize system task information */
2041 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2043 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2045 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2052 * Fun: Deinitialize task table
2054 * Desc: This function reverses the initialization perfomed in
2065 PUBLIC Void ssdDeinitTsk
2070 PUBLIC Void ssdDeinitTsk()
2079 #ifdef SS_DRVR_SUPPORT
2082 * Fun: Initialize driver task table
2084 * Desc: This function initializes MTSS-specific information
2085 * in the driver task table.
2095 PUBLIC S16 ssdInitDrvr
2100 PUBLIC S16 ssdInitDrvr()
2105 pthread_attr_t attr;
2111 /* initialize the dependent portion of the driver task entries */
2112 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2114 osCp.drvrTskTbl[i].dep.flag = FALSE;
2118 /* create pipe for communication between SSetIntPend() and
2119 * the isTskHdlr thread.
2121 if (pipe(osCp.dep.isFildes) != 0)
2127 /* create the isTskHdlr thread */
2128 pthread_attr_init(&attr);
2129 /* mt021.201 - Addition to set stack size */
2130 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2131 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2132 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2133 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2135 /* mt020.201 - Addition for destroying thread attribute object attr */
2136 pthread_attr_destroy(&attr);
2142 /*mt014.301 : 4GMX release related changes*/
2143 #ifdef SS_4GMX_UCORE
2151 /* mt020.201 - Addition for destroying thread attribute object attr */
2152 pthread_attr_destroy(&attr);
2161 * Fun: Deinitialize driver information
2163 * Desc: This function reverses the initialization performed in
2174 PUBLIC Void ssdDeinitDrvr
2179 PUBLIC Void ssdDeinitDrvr()
2182 TRC0(ssdDeinitDrvr);
2183 /* mt008.301: Terminate the Driver Task on exit */
2184 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2187 TL_Close(AppContext.hUAII);
2188 if (clusterMode == RADIO_CLUSTER_MODE)
2190 TL_Close(AppContext.hUAII_second);
2196 #endif /* SS_DRVR_SUPPORT */
2201 * Fun: Initialize timer table
2203 * Desc: This function initializes MTSS-specific information
2204 * in the timer table.
2214 PUBLIC S16 ssdInitTmr
2219 PUBLIC S16 ssdInitTmr()
2222 pthread_attr_t attr;
2223 struct sched_param param_sched;
2224 /* mt010.21: addition */
2226 #ifdef SS_MULTICORE_SUPPORT
2228 #endif /* SS_MULTICORE_SUPPORT */
2229 #ifdef SS_THR_REG_MAP
2230 U32 threadCreated = FALSE;
2231 #endif /* SS_THR_REG_MAP */
2236 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2237 /* mt010.21: addition */
2238 osCp.dep.tmrTqCp.nxtEnt = 0;
2239 for (i=0; i< SS_MAX_TMRS; i++)
2241 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2244 #ifdef SS_MULTICORE_SUPPORT
2245 sTsk = ssdAddTmrSTsk();
2250 #endif /* SS_MULTICORE_SUPPORT */
2251 /* create the timer handler thread */
2252 pthread_attr_init(&attr);
2253 /* mt021.201 - Addition to set stack size */
2254 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2255 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2256 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2257 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2258 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2259 pthread_attr_setschedparam(&attr, ¶m_sched);
2262 #ifdef SS_THR_REG_MAP
2263 /* When the thread is created, we check for the memory mapping table if
2264 * threadId can be placed in thread memory map table. If it is not able to place
2265 * threadId is stored in tmporary array. Once thread is created successful,
2266 * thread_cancel is sent for each thread which are created before. All the
2267 * threads are made to wait on sema which is cancel point for thread.
2269 while(threadCreated == FALSE)
2272 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2274 /* mt020.201 - Addition for destroying thread attribute object attr */
2275 pthread_attr_destroy(&attr);
2280 #ifdef SS_THR_REG_MAP
2281 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2284 #endif /* SS_THR_REG_MAP */
2285 #ifdef SS_MEM_WL_DEBUG
2286 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2289 /* mt020.201 - Addition for destroying thread attribute object attr */
2290 pthread_attr_destroy(&attr);
2299 * Fun: Deinitialize timer table
2301 * Desc: This function reverses the initialization performed in
2312 PUBLIC Void ssdDeinitTmr
2317 PUBLIC Void ssdDeinitTmr()
2320 #ifdef SS_MULTICORE_SUPPORT
2323 #endif /* SS_MULTICORE_SUPPORT */
2327 #ifdef SS_MULTICORE_SUPPORT
2328 ret = SLock(&osCp.sTskTblLock);
2332 #if (ERRCLASS & ERRCLS_DEBUG)
2333 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2334 "Could not lock system task table");
2338 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2339 /* clean up the system task entry */
2343 SDestroyLock(&sTsk->lock);
2344 ssDestroyDmndQ(&sTsk->dQ);
2347 /* make this entry available in the system task table */
2348 sTsk->nxt = osCp.nxtSTskEntry;
2349 osCp.nxtSTskEntry = 0;
2353 /* unlock the system task table */
2354 SUnlock(&osCp.sTskTblLock);
2356 #endif /* SS_MULTICORE_SUPPORT */
2357 /* mt008.301: Terminate the timer thread on exit */
2358 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2368 * Desc: Pre-tst() initialization.
2378 PUBLIC S16 ssdInitLog
2383 PUBLIC S16 ssdInitLog()
2386 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2390 pthread_attr_t attr;
2393 #endif /* CONSTDIO */
2398 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2404 osCp.dep.conInFp = (FILE *) stdin;
2405 osCp.dep.conOutFp = (FILE *) stdout;
2406 /* added compile time flag CONRD: mt017.21 */
2410 /* disable canonical input processing */
2411 fd = fileno(osCp.dep.conInFp);
2412 if ((tcgetattr(fd, &tio)) != 0)
2414 printf("Error: disable canonical input processing\n");
2418 tio.c_lflag &= ~ICANON;
2419 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2420 tio.c_cc[VTIME] = 0;
2421 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2423 printf("Error: while tcsetattr() processing\n");
2427 #endif /* CONSTDIO */
2430 /* set up the input fd to block when no data is available */
2431 fd = fileno(osCp.dep.conInFp);
2432 flags = fcntl(fd, F_GETFL, &flags);
2433 flags &= ~O_NONBLOCK;
2434 if (fcntl(fd, F_SETFL, flags) == -1)
2436 printf("Error: while fcntl processing\n");
2441 /* create the console handler thread */
2442 pthread_attr_init(&attr);
2443 /* mt021.201 - Addition to set stack size */
2444 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2445 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2446 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2449 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2451 /* mt020.201 - Addition for destroying thread attribute object attr */
2452 pthread_attr_destroy(&attr);
2454 printf("Error: Logging Thread creation failed \n");
2458 /* mt020.201 - Addition for destroying thread attribute object attr */
2459 pthread_attr_destroy(&attr);
2473 * Desc: This function reverses the initialization performed in
2483 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2485 PUBLIC Void ssdDeinitLog
2490 PUBLIC Void ssdDeinitLog()
2493 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2497 /* mt008.301: Terminate the console reader on exit */
2498 while(pthread_cancel(osCp.dep.conHdlrTID));
2504 /* mt001.301 : Additions */
2509 PUBLIC S16 ssdInitWatchDog
2514 PUBLIC S16 ssdInitWatchDog(port)
2519 Txt prntBuf[PRNTSZE];
2522 #ifdef SS_WATCHDOG_IPV6
2523 struct sockaddr_in6 tmpaddr;
2525 struct sockaddr_in tmpaddr;
2526 #endif /* SS_WATCHDOG_IPV6 */
2527 #ifdef SS_MULTIPLE_PROCS
2528 ProcId procId = SS_WD_WDPROC;
2529 if (SAddProcIdLst(1, &procId) != ROK)
2533 #endif /* SS_MULTIPLE_PROCS */
2535 TRC0(ssdInitWatchDog);
2537 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2539 /* Create a watch dog system task */
2540 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2542 /* Create a watch dog reveiver system task */
2543 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2545 /* Register and attach watch dog TAPA task */
2546 #ifdef SS_MULTIPLE_PROCS
2547 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2548 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2550 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2551 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2552 #endif /* SS_MULTIPLE_PROCS */
2553 /* Register and attach watch dog receiver TAPA task */
2554 #ifdef SS_MULTIPLE_PROCS
2555 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2556 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2558 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2559 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2560 #endif /* SS_MULTIPLE_PROCS */
2562 #ifndef SS_MULTIPLE_PROCS
2563 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2564 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2566 osCp.wdCp.watchDgPst.srcProcId = procId;
2567 osCp.wdCp.watchDgPst.dstProcId = procId;
2568 #endif /* SS_MULTIPLE_PROCS */
2570 /* Initialise the pst structure */
2571 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2572 /* Initialize the watch dog timer resolution default is 1 sec */
2574 cmInitTimers(osCp.wdCp.watchDgTmr, (U8)1);
2575 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2576 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2577 for(idx = 0; idx < 1; idx++)
2579 osCp.wdCp.watchDgTs[idx].first = NULLP;
2580 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2582 #ifdef SS_MULTIPLE_PROCS
2583 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2585 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2586 #endif /* SS_MULTIPLE_PROCS */
2588 /* Create the watch dog receiver socket */
2589 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2590 if(osCp.wdCp.globWd.sock == -1)
2592 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2596 #ifdef SS_WATCHDOG_IPV6
2597 tmpaddr.sin6_len = sizeof(tmpadDr);
2598 tmpaddr.sin6_family = AF_INET6;
2599 tmpaddr.sin6_addr = in6addr_any;
2600 tmpaddr.sin6_port = htons(port);
2602 tmpaddr.sin_family = AF_INET;
2603 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2604 tmpaddr.sin_port = htons(port);
2605 #endif /* SS_WATCHDOG_IPV6 */
2607 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2610 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2614 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2618 #ifndef SS_MULTIPLE_PROCS
2619 pst.srcProcId = SFndProcId();
2620 pst.dstProcId = SFndProcId();
2622 pst.srcProcId = procId;
2623 pst.dstProcId = procId;
2624 #endif /* SS_MULTIPLE_PROCS */
2625 pst.event = EVTSSHRTBTREQ;
2626 ssdInitWatchDgPst(&pst);
2627 SPstTsk(&pst, mBuf);
2633 PUBLIC S16 ssdInitWatchDgPst
2638 PUBLIC S16 ssdInitWatchDgPst(pst)
2642 TRC1(ssInitWatchDgPst);
2644 pst->selector = SS_LOOSE_COUPLING;
2646 pst->region = DFLT_REGION; /* region */
2647 pst->pool = DFLT_POOL; /* pool */
2649 pst->prior = PRIOR0; /* priority */
2650 pst->route = RTESPEC; /* route */
2652 pst->dstEnt = ENTHB; /* destination entity */
2654 pst->srcEnt = ENTDW; /* source entity */
2660 #ifdef SS_MULTIPLE_PROCS
2662 PUBLIC S16 ssdWatchDgActvTmr
2669 PUBLIC S16 ssdWatchDgActvTmr(proc, ent, inst)
2673 PUBLIC S16 ssdWatchDgActvTmr
2678 PUBLIC S16 ssdWatchDgActvTmr()
2680 #endif /* SS_MULTIPLE_PROCS */
2682 TRC3(ssWatchDgActvTmr);
2684 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2690 PUBLIC Void ssdWatchDgTmrEvt
2692 PTR cb, /* control block */
2693 S16 event /* timer number */
2696 PUBLIC Void ssdWatchDgTmrEvt(cb, event)
2697 PTR cb; /* control block */
2698 S16 event; /* timer number */
2701 /* mt003.301 Fixed warings */
2705 Txt prntBuf[PRNTSZE];
2709 TRC2(ssWatchDgTmrEvt);
2715 SPrint("Timer Heartbeat Request Expired");
2717 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2722 SLock(&osCp.wdCp.wdLock);
2723 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2725 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2727 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2729 if(osCp.wdCp.globWd.callback != 0)
2731 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2735 SUnlock(&osCp.wdCp.wdLock);
2737 if(!osCp.wdCp.globWd.watchdogStop)
2739 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2740 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2751 PUBLIC Void ssdStartWatchDgTmr
2758 PUBLIC Void ssdStartWatchDgTmr(cb, event, wait)
2768 Txt prntBuf[PRNTSZE];
2772 TRC2(ssStartWatchDgTmr)
2773 /* mt003.301 Modifications */
2776 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2777 if(event == SS_TMR_HRTBT)
2779 SPrint("\nSTART SS_TMR_HRTBT");
2786 SLock(&osCp.wdCp.wdLock);
2787 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2789 osCp.wdCp.globWd.wdsta[i].status = 0;
2791 SUnlock(&osCp.wdCp.wdLock);
2793 arg.tq = osCp.wdCp.watchDgTs;
2794 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2795 arg.timers = osCp.wdCp.watchDgTmr;
2796 arg.cb = (PTR)NULLP;
2798 arg.wait = osCp.wdCp.globWd.timeout = wait;
2807 PUBLIC Void ssdStopWatchDgTmr
2813 PUBLIC Void ssdStopWatchDgTmr(cb, event)
2821 Txt prntBuf[PRNTSZE];
2825 TRC2(ssStopWatchDgTmr)
2826 /* mt003.301 Modifications */
2829 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2830 if(event == SS_TMR_HRTBT)
2832 SPrint("STOP SS_TMR_HRTBT");
2836 SLock(&osCp.wdCp.wdLock);
2837 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2839 osCp.wdCp.globWd.wdsta[i].status = 0;
2841 SUnlock(&osCp.wdCp.wdLock);
2844 arg.tq = osCp.wdCp.watchDgTs;
2845 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2846 arg.timers = osCp.wdCp.watchDgTmr;
2847 arg.cb = (PTR)NULLP;
2858 PUBLIC S16 ssdSndHrtBtMsg
2864 PUBLIC S16 ssdSndHrtBtMsg(restart, type)
2872 Txt prntBuf[PRNTSZE];
2874 struct sockaddr_in tmpaddr;
2875 char hbMsg[SS_WD_HB_MSG_SIZE];
2879 TRC2(ssdSndHrtBtReq)
2883 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2887 /* Pack the message */
2888 strcpy(hbMsg, "<HB>REQ</HB>");
2890 /* Send the heartbeat messages to all the configured nodes */
2891 SLock(&osCp.wdCp.wdLock);
2892 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2894 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2899 /* Identify the destination node */
2900 #ifdef SS_WATCHDOG_IPV6
2901 tmpaddr.sin6_len = sizeof(tmpaddr);
2902 tmpaddr.sin6_family = AF_INET6;
2903 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2904 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2906 tmpaddr.sin_family = AF_INET;
2907 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2908 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2909 #endif /* SS_WATCHDOG_IPV6 */
2911 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2915 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2916 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2923 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2928 SUnlock(&osCp.wdCp.wdLock);
2933 #endif /* SS_WATCHDOG */
2937 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2943 * Desc: This function gets command line options.
2953 PRIVATE Void mtGetOpts
2958 PRIVATE Void mtGetOpts()
2966 FILE *memOpt; /* memory options file pointer */
2969 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2975 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2977 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2983 #ifdef SS_LOCKLESS_MEMORY
2999 osCp.dep.fileOutFp = (FILE *)NULLP;
3001 /* initialize memOpt */
3002 memOpt = (FILE *) NULLP;
3009 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
3014 /* mt001.301 : Additions */
3015 #ifdef SS_MEM_LEAK_STS
3017 cmMemOpenMemLkFile(msOptArg);
3021 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3024 fileBasedMemCfg = TRUE;
3025 memOpt = fopen(msOptArg, "r");
3027 /* if file does not exist or could not be opened then use the
3028 * default memory configuration as defined in mt_ss.h
3030 if (memOpt == (FILE *) NULLP)
3032 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3033 be opened, using default mem configuration\n", msOptArg);
3038 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3040 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3046 case 0: /*** INPUT: Number of regions ***/
3047 sscanf(line, "%ld", (long *) &numReg);
3048 mtMemoCfg.numRegions = numReg;
3049 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3051 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3057 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3058 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3059 if(numBkts > MT_MAX_BKTS)
3061 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3065 if(numPools > SS_MAX_POOLS_PER_REG)
3067 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3072 * Delay updation from local variable to global
3073 * structure of number of regions and heap data to
3074 * counter error conditions present above.
3076 for(idx = 0; idx < cfgNumRegs; idx++)
3078 mtMemoCfg.region[idx].numBkts = numBkts;
3079 cfgRegInfo[idx].region = idx;
3080 cfgRegInfo[idx].numPools = numPools;
3082 * Initialize the pool info as static type with size zero
3084 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3086 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3087 cfgRegInfo[idx].pools[poolIdx].size = 0;
3092 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3093 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3095 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3097 if(bktIdx >= numBkts)
3099 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3104 mtBktInfo[bktIdx].blkSize = bktSz;
3106 if(bktUpdtCnt == numBkts)
3108 i++; /*done reading bkt info, start reading individual region info*/
3112 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3113 sscanf(line,"%ld",(long *) ®Id);
3114 if(regId >= mtMemoCfg.numRegions)
3116 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3117 #ifndef XEON_SPECIFIC_CHANGES
3122 mtMemoCfg.region[regId].regionId = regId;
3125 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3126 if(bktUpdtCnt < numBkts)
3128 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3129 if(bktIdx >= numBkts)
3131 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3136 if(bktIdx < MT_MAX_BKTS)
3138 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3139 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3140 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3141 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3144 if(bktUpdtCnt == numBkts)
3151 case 5: /* INPUT: Heapsize ***/
3152 sscanf(line, "%ld", (long *) &heapSz);
3153 mtMemoCfg.region[regId].heapsize = heapSz;
3155 if(regUpdtCnt != mtMemoCfg.numRegions)
3164 #ifdef SS_LOCKLESS_MEMORY
3166 sscanf(line, "%ld", (long *) &numBkts);
3167 mtGlobMemoCfg.numBkts = numBkts;
3168 #ifndef XEON_SPECIFIC_CHANGES
3169 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3172 #ifdef XEON_SPECIFIC_CHANGES
3173 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3174 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3175 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3177 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3180 mtDynMemoCfg.region[idx].regionId = idx;
3181 mtDynMemoCfg.region[idx].numBkts = numBkts;
3189 if(bktUpdtCnt < numBkts)
3191 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3192 (long *) &bktSz, (long *) &bktNum,
3193 (long *) &bktSetSize, (long *) &bktRelThr,
3194 (long *) &bktAqurThr);
3195 /* Klock work fix ccpu00148484 */
3196 if(bktIdx < SS_MAX_POOLS_PER_REG)
3198 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3199 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3200 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3201 #ifdef XEON_SPECIFIC_CHANGES
3202 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3203 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3204 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3206 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3208 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3214 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3216 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3217 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3218 #ifdef XEON_SPECIFIC_CHANGES
3219 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3220 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3221 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3227 #ifdef XEON_SPECIFIC_CHANGES
3228 if(bktUpdtCnt == numBkts)
3234 case 8: /* INPUT: Global Heapsize ***/
3235 sscanf(line, "%ld", (long *) &heapSz);
3236 mtGlobMemoCfg.heapSize = heapSz;
3237 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3245 memConfigured = FALSE;
3249 memConfigured = TRUE;
3257 /* mt028.201: modification: multiple procs support related changes */
3258 #ifndef SS_MULTIPLE_PROCS
3261 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3263 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3266 #else /* SS_MULTIPLE_PROCS */
3270 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3272 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3274 SAddProcIdLst(1, &procId);
3277 #endif /* SS_MULTIPLE_PROCS */
3281 osCp.configFilePath = msOptArg;
3305 * Desc: Get options from command line
3307 * Ret: option - success
3309 * EOF - end of options
3311 * Notes: Handles command lines like the following
3314 * then command line should look like this...
3315 * -a foo -b foo1 -c -d foo
3319 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3324 * nloops = atoi(msArgv[msOptInd]);
3327 * state1 = atoi(msArgv[msOptInd]);
3340 int argc, /* argument count */
3341 char **argv, /* argument value */
3342 char *opts /* options */
3345 PUBLIC S16 SGetOpt(argc, argv, opts)
3346 int argc; /* argument count */
3347 char **argv; /* argument value */
3348 char *opts; /* options */
3351 /* mt020.201 - Removed for no command line */
3360 /* mt020.201 - Addition for no command line */
3372 /*mt013.301 : Changes as per coding standards*/
3373 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3379 if (!strcmp(argv[msOptInd], "--"))
3384 else if (argv[msOptInd][0] != '-')
3392 c = argv[msOptInd][sp];
3393 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3395 if (argv[msOptInd][++sp] == '\0')
3406 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3409 if (++msOptInd >= (S16) argc)
3414 else msOptArg = argv[msOptInd++];
3421 if (argv[msOptInd][++sp] == '\0')
3433 #endif /* NOCMDLINE */
3441 * Desc: This function starts system services execution; the
3442 * permanent tasks are started and the system enters a
3453 PUBLIC Void ssdStart
3458 PUBLIC Void ssdStart()
3467 /* mt025.201 - Modification for adding lock to timer handler */
3468 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3470 sem_post(&osCp.dep.ssStarted);
3479 * indirect interface functions to system services service user
3485 * Fun: ssdAttachTTsk
3487 * Desc: This function sends the initial tick message to a TAPA
3488 * task if the task is a permanent task.
3498 PUBLIC S16 ssdAttachTTsk
3500 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3503 PUBLIC S16 ssdAttachTTsk(tTsk)
3504 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3512 TRC0(ssdAttachTTsk);
3515 if (tTsk->tskType == SS_TSK_PERMANENT)
3517 /* Send a permanent tick message to this task, to start
3520 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3523 #if (ERRCLASS & ERRCLS_DEBUG)
3524 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3529 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3530 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3532 /* set up post structure */
3533 /* mt028.201: modification: multiple procs support related changes */
3534 #ifndef SS_MULTIPLE_PROCS
3535 mInfo->pst.dstProcId = SFndProcId();
3536 mInfo->pst.srcProcId = SFndProcId();
3537 #else /* SS_MULTIPLE_PROCS */
3538 mInfo->pst.dstProcId = tTsk->proc;
3539 mInfo->pst.srcProcId = tTsk->proc;
3540 #endif /* SS_MULTIPLE_PROCS */
3541 mInfo->pst.selector = SEL_LC_NEW;
3542 mInfo->pst.region = DFLT_REGION;
3543 mInfo->pst.pool = DFLT_POOL;
3544 mInfo->pst.prior = PRIOR3;
3545 mInfo->pst.route = RTESPEC;
3546 mInfo->pst.event = 0;
3547 mInfo->pst.dstEnt = tTsk->ent;
3548 mInfo->pst.dstInst = tTsk->inst;
3549 mInfo->pst.srcEnt = tTsk->ent;
3550 mInfo->pst.srcInst = tTsk->inst;
3552 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3553 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3559 #if (ERRCLASS & ERRCLS_DEBUG)
3560 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3561 "Could not write to demand queue");
3574 * Fun: ssdDetachTTsk
3576 * Desc: Does nothing.
3586 PUBLIC S16 ssdDetachTTsk
3588 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3591 PUBLIC S16 ssdDetachTTsk(tTsk)
3592 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3595 TRC0(ssdDetachTTsk);
3604 * Fun: ssdCreateSTsk
3606 * Desc: This function creates a system task. A thread is started
3607 * on the system task handler function defined later.
3617 PUBLIC S16 ssdCreateSTsk
3619 SsSTskEntry *sTsk /* pointer to system task entry */
3622 PUBLIC S16 ssdCreateSTsk(sTsk)
3623 SsSTskEntry *sTsk; /* pointer to system task entry */
3626 pthread_attr_t attr;
3627 /* struct sched_param param_sched;*/
3629 #ifdef SS_THR_REG_MAP
3630 U32 threadCreated = FALSE;
3633 TRC0(ssdCreateSTsk);
3636 #ifdef SS_SINGLE_THREADED
3637 /* mt001.301 : Additions */
3639 #ifdef SS_MULTICORE_SUPPORT
3640 if (osCp.numSTsks > 1)
3642 if (osCp.numSTsks > 0)
3643 #endif /* SS_MULTICORE_SUPPORT */
3645 #ifdef SS_MULTICORE_SUPPORT
3646 if (osCp.numSTsks > 3)
3648 if (osCp.numSTsks > 2)
3649 #endif /* SS_MULTICORE_SUPPORT */
3650 #endif /* SS_WATCHDOG */
3657 /* set the current executing entity and instance IDs to
3658 * 'not configured'. create the lock to access them.
3660 sTsk->dep.ent = ENTNC;
3661 sTsk->dep.inst = INSTNC;
3664 /* create the thread */
3665 pthread_attr_init(&attr);
3666 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3668 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3669 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3670 if (sTsk->tskPrior == 0)
3672 printf("Creating RT thread #######################\n");
3673 #ifdef SS_THR_REG_MAP
3674 /* When the thread is created, we check for the memory mapping table if
3675 * threadId can be placed in thread memory map table. If it is not able to place
3676 * threadId is stored in tmporary array. Once thread is created successful,
3677 * thread_cancel is sent for each thread which are created before. All the
3678 * threads are made to wait on sema which is cancel point for thread.
3680 while(threadCreated == FALSE)
3683 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlrT2kL2, (Ptr)sTsk)) != 0)
3686 pthread_attr_destroy(&attr);
3688 #if (ERRCLASS & ERRCLS_DEBUG)
3689 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3694 #ifdef SS_THR_REG_MAP
3695 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3703 #ifdef SS_THR_REG_MAP
3704 /* When the thread is created, we check for the memory mapping table if
3705 * threadId can be placed in thread memory map table. If it is not able to place
3706 * threadId is stored in tmporary array. Once thread is created successful,
3707 * thread_cancel is sent for each thread which are created before. All the
3708 * threads are made to wait on sema which is cancel point for thread.
3710 while(threadCreated == FALSE)
3713 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk)) != 0)
3716 /* mt020.201 - Addition for destroying thread attribute object attr */
3717 pthread_attr_destroy(&attr);
3719 #if (ERRCLASS & ERRCLS_DEBUG)
3720 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3725 #ifdef SS_THR_REG_MAP
3726 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3733 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3734 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3736 static U32 stLwpId = 3;
3737 sTsk->dep.lwpId = ++stLwpId;
3739 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3741 /* mt020.201 - Addition for destroying thread attribute object attr */
3742 pthread_attr_destroy(&attr);
3749 PUBLIC int SCreatePThread
3752 pthread_attr_t* attr,
3753 void *(*start_routine) (void *),
3757 PUBLIC int SCreatePThread(tid, attr, start_routine, arg)
3759 pthread_attr_t* attr;
3760 void *(*start_routine) (void *);
3765 #ifdef SS_THR_REG_MAP
3766 U32 threadCreated = FALSE;
3769 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3770 /* Klock work fix ccpu00148484 */
3771 if(threadArg == NULLP)
3775 threadArg->argument = arg;
3776 threadArg->start_routine = start_routine;
3778 TRC0(SCreatePThread);
3780 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3782 #ifdef SS_THR_REG_MAP
3783 /* When the thread is created, we check for the memory mapping table if
3784 * threadId can be placed in thread memory map table. If it is not able to place
3785 * threadId is stored in tmporary array. Once thread is created successful,
3786 * thread_cancel is sent for each thread which are created before. All the
3787 * threads are made to wait on sema which is cancel point for thread.
3789 while(threadCreated == FALSE)
3792 /*pthreadCreateHdlr */
3793 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3798 #ifdef SS_THR_REG_MAP
3799 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3810 * Fun: Set Pthread Attributes
3812 * Desc: This function is used to set various explicit
3813 * pthread attributes like, priority scheduling,etc
3824 PRIVATE S16 ssdSetPthreadAttr
3827 pthread_attr_t *attr
3830 PRIVATE S16 ssdSetPthreadAttr(sTsk, attr)
3832 pthread_attr_t *attr
3835 struct sched_param param;
3837 TRC0 (ssdSetPthreadAttr)
3839 SMemSet(¶m, 0, sizeof(param));
3841 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3842 param.sched_priority = 100 - 1 - tskPrior;
3844 param.sched_priority = 100 - 10 - tskPrior;
3847 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3848 /* TODO:: This can be avoided by reducing the priority
3849 * of iccserv thread in l1_master.sh*/
3851 if (clusterMode == RADIO_CLUSTER_MODE)
3853 if(tskPrior == PRIOR1)
3855 param.sched_priority = 91;
3862 printf("Set priority %u\n", param.sched_priority);
3864 /* Set Scheduler to explicit, without this non of the below
3865 pthread attr works */
3866 #ifdef TENB_RTLIN_CHANGES
3867 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3870 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3871 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3872 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3873 #ifdef TENB_RTLIN_CHANGES
3874 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3876 pthread_attr_setschedparam(attr, ¶m);
3880 } /* ssdSetPthreadAttr */
3882 /************* multi-core support **************/
3883 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3884 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3888 * Fun: Get the current core/cpu affinity for a thread/lwp
3890 * Desc: This function is used to get the current processor/core
3891 * affinity for a a system task (thread/lwp). It sets the
3892 * affinity based on the mode supplied by the caller.
3895 * RFAILED - failed, general (optional)
3903 PUBLIC S16 ssdGetAffinity
3905 SSTskId *tskId, /* filled in with system task ID */
3906 U32 *coreId /* the core/processor id to which the affinity is set */
3909 PUBLIC S16 ssdGetAffinity(tskId, coreId)
3910 SSTskId *tskId; /* filled in with system task ID */
3911 U32 *coreId; /* the core/processor id to which the affinity is set */
3922 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3928 TRC0(ssdGetAffinity);
3930 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3932 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3934 tId = osCp.sTskTbl[tskInd].dep.tId;
3939 /* if tskId is not found in the tskTbl */
3940 if (tskInd == SS_MAX_STSKS)
3942 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3947 /* initialize the cpu mask */
3950 /* set thread affinity for linux */
3951 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3953 #if (ERRCLASS & ERRCLS_DEBUG)
3954 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3957 } /* end if pthread_setaffinity fails */
3959 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3961 if (CPU_ISSET (cpuInd, & cpuSet))
3970 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3972 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3974 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3979 /* if tskId is not found in the tskTbl */
3980 if (tskInd == SS_MAX_STSKS)
3982 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3986 /* set thread affinity for Solaris */
3987 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3989 #if (ERRCLASS & ERRCLS_DEBUG)
3990 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3993 } /* end if processor_bind fails */
3996 #endif /* SS_LINUX */
4000 } /* ssdGetAffinity */
4005 * Fun: Set the core/cpu affinity for a thread/lwp
4007 * Desc: This function is used to set processor/core affinity for a
4008 * a system task (thread/lwp). It sets the affinity based on the
4009 * mode supplied by the caller.
4012 * RFAILED - failed, general (optional)
4020 PUBLIC S16 ssdSetAffinity
4022 SSTskId *tskId, /* filled in with system task ID */
4023 U32 coreId /* the core/processor id to which the affinity has to be set */
4026 PUBLIC S16 ssdSetAffinity(tskId, coreId)
4027 SSTskId *tskId; /* filled in with system task ID */
4028 U32 coreId; /* the core/processor id to which the affinity has to be set */
4037 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4044 TRC0(ssdSetAffinity)
4047 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4049 /* Here tskId can not be used as index as the task may be terminated if
4050 there is a TERM even for that tsk, thus breaking the task Id numbering
4052 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4054 tId = osCp.sTskTbl[tskInd].dep.tId;
4059 /* if tskId is not found in the tskTbl */
4060 if (tskInd == SS_MAX_STSKS)
4062 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4066 /* initialize the cpu mask */
4069 /* set the cpu mask */
4070 CPU_SET(coreId, &cpuSet);
4072 /* set thread affinity for linux */
4073 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4075 #if (ERRCLASS & ERRCLS_DEBUG)
4076 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4079 } /* end if pthread_setaffinity fails */
4083 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4085 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4086 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4088 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4093 /* if tskId is not found in the tskTbl */
4094 if (tskInd == SS_MAX_STSKS)
4096 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4100 /* set thread affinity for Solaris */
4101 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4103 #if (ERRCLASS & ERRCLS_DEBUG)
4104 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4107 } /* end if processor_bind fails */
4110 #endif /* SS_LINUX */
4112 } /* ssdSetAffinity */
4114 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4115 /************ end multi-core support *************/
4120 * Fun: ssdDestroySTsk
4122 * Desc: This function destroys a system task. A terminate
4123 * event message is sent to the thread function.
4133 PUBLIC S16 ssdDestroySTsk
4135 SsSTskEntry *sTsk /* pointer to system task entry */
4138 PUBLIC S16 ssdDestroySTsk(sTsk)
4139 SsSTskEntry *sTsk; /* pointer to system task entry */
4146 TRC0(ssdDestroySTsk);
4149 /* we send a message to this system task to tell it to die */
4150 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4153 #if (ERRCLASS & ERRCLASS_DEBUG)
4154 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4160 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4161 mInfo->eventInfo.event = SS_EVNT_TERM;
4163 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4167 #if (ERRCLASS & ERRCLASS_DEBUG)
4168 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4169 "Could not write to demand queue");
4179 /* mt023.201 - Added SThreadYield function to yield CPU
4183 * Desc: This function defers thread execution to any other ready
4195 PUBLIC S16 SThreadYield
4200 PUBLIC S16 SThreadYield()
4206 /* mt024.201 - seperated Linux and other UNIX implementations
4212 /* Set sleep value to 0 to yield CPU */
4216 RETVALUE(select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4218 #else /* other UNICes */
4220 RETVALUE(sleep(0) == 0 ? ROK : RFAILED);
4222 #endif /* SS_LINUX */
4229 * Fun: Register timer
4231 * Desc: This function is used to register a timer
4232 * function for the service user. System services
4233 * will invoke the timer activation function
4234 * passed to it at the specified intervals.
4238 * Notes: Timing is handled by the common timers. The
4239 * ticks are handled by a thread that uses
4240 * nanosleep() and thus timing precision will not
4247 PUBLIC S16 ssdRegTmr
4249 SsTmrEntry *tmr /* pointer to timer entry */
4252 PUBLIC S16 ssdRegTmr(tmr)
4253 SsTmrEntry *tmr; /* pointer to timer entry */
4262 /* initialize common timers */
4263 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4266 /* start the timer */
4267 arg.tq = osCp.dep.tmrTq;
4268 arg.tqCp = &osCp.dep.tmrTqCp;
4269 arg.timers = tmr->dep.timers;
4274 arg.max = TMR_DEF_MAX;
4275 arg.wait = tmr->interval;
4285 * Fun: Deregister timer
4287 * Desc: This function is used to deregister a timer function.
4297 PUBLIC S16 ssdDeregTmr
4299 SsTmrEntry *tmr /* pointer to timer entry */
4302 PUBLIC S16 ssdDeregTmr(tmr)
4303 SsTmrEntry *tmr; /* pointer to timer entry */
4312 /* stop the timer */
4313 arg.tq = osCp.dep.tmrTq;
4314 arg.tqCp = &osCp.dep.tmrTqCp;
4315 arg.timers = tmr->dep.timers;
4320 arg.max = TMR_DEF_MAX;
4321 arg.wait = tmr->interval;
4331 * Fun: Critical error
4333 * Desc: This function is called when a critical error occurs.
4345 Seq seq, /* sequence number */
4346 Reason reason /* reset reason */
4349 PUBLIC S16 ssdError(seq, reason)
4350 Seq seq; /* sequence number */
4351 Reason reason; /* reset reason */
4362 /* get calling task ID */
4363 tId = pthread_self();
4366 /* set up the message to display */
4367 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4368 "reason = %d\n\n", (U8)tId, seq, reason);
4372 /* delete all system tasks */
4373 for (i = 0; i < SS_MAX_STSKS; i++)
4375 if (osCp.sTskTbl[i].used
4376 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4378 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4384 pthread_exit(NULLP);
4387 /* won't reach here */
4396 * Desc: This function is called to log an error.
4406 PUBLIC Void ssdLogError
4408 Ent ent, /* Calling layer's entity id */
4409 Inst inst, /* Calling layer's instance id */
4410 ProcId procId, /* Calling layer's processor id */
4411 Txt *file, /* file name where error occured */
4412 S32 line, /* line in file where error occured */
4413 ErrCls errCls, /* error class */
4414 ErrCode errCode, /* layer unique error code */
4415 ErrVal errVal, /* error value */
4416 Txt *errDesc /* description of error */
4419 PUBLIC Void ssdLogError(ent, inst, procId, file, line,
4420 errCls, errCode, errVal, errDesc)
4421 Ent ent; /* Calling layer's entity id */
4422 Inst inst; /* Calling layer's instance id */
4423 ProcId procId; /* Calling layer's processor id */
4424 Txt *file; /* file name where error occured */
4425 S32 line; /* line in file where error occured */
4426 ErrCls errCls; /* error class */
4427 ErrCode errCode; /* layer unique error code */
4428 ErrVal errVal; /* error value */
4429 Txt *errDesc; /* description of error */
4443 /* get calling task ID */
4445 tId = pthread_self();
4451 case ERRCLS_ADD_RES:
4452 errClsMsg = "ERRCLS_ADD_RES";
4455 case ERRCLS_INT_PAR:
4456 errClsMsg = "ERRCLS_INT_PAR";
4460 errClsMsg = "ERRCLS_DEBUG";
4463 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4465 errClsMsg = "ERRCLS_FTHA";
4469 errClsMsg = "INVALID ERROR CLASS!";
4474 /*mt009.301 Fixed 64BIT compilation warnings*/
4477 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4478 "file: %s line: %03d errcode: %05d errcls: %s\n"
4479 "errval: %05d errdesc: %s\n",
4480 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4483 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4484 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4485 "errval: %05ld errdesc: %s\n",
4486 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4488 SDisplay(0, errBuf);
4489 /* mt001.301 : Additions */
4490 #ifdef SS_LOGGER_SUPPORT
4492 #endif /* SS_LOGGER_SUPPORT */
4496 /* debug errors halt the system */
4497 if (errCls == ERRCLS_DEBUG)
4499 /* mt001.301 : Additions */
4500 #ifdef SS_LOGGER_SUPPORT
4502 #endif /* SS_LOGGER_SUPPORT */
4503 /* delete all system tasks */
4504 for (i = 0; i < SS_MAX_STSKS; i++)
4506 if (osCp.sTskTbl[i].used
4507 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4509 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4515 pthread_exit(NULLP);
4527 * Fun: Register driver task
4529 * Desc: This function is called to register the handlers for a
4540 PUBLIC S16 ssdRegDrvrTsk
4542 SsDrvrTskEntry *drvrTsk /* driver task entry */
4545 PUBLIC S16 ssdRegDrvrTsk(drvrTsk)
4546 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4549 TRC0(ssdRegDrvrTsk);
4554 /* mt001.30 : Additions */
4557 * Fun: Deregister driver task
4559 * Desc: This function is called to deregister the handlers for a
4570 PUBLIC S16 ssdDeregDrvrTsk
4572 SsDrvrTskEntry *drvrTsk /* driver task entry */
4575 PUBLIC S16 ssdDeregDrvrTsk(drvrTsk)
4576 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4579 TRC0(ssdDeregDrvrTsk);
4590 * mt003.301 Additions - SDeRegTTsk fix
4592 #ifdef SS_MULTIPLE_PROCS
4594 PUBLIC S16 ssdProcTTskTerm
4601 PUBLIC S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4606 #else /*SS_MULTIPLE_PROCS*/
4608 PUBLIC S16 ssdProcTTskTerm
4614 PUBLIC S16 ssdProcTTskTerm(tTsk, idx)
4618 #endif /*SS_MULTIPLE_PROCS*/
4620 #ifdef SS_MULTIPLE_PROCS
4629 TRC0(ssdProcTTskTerm);
4634 /* We check the sTsk element; if it is not NULLP, the
4635 * task is attached. So we have to detach it before
4636 * deregistering the task.
4638 ret = SLock(&osCp.sTskTblLock);
4641 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4644 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4647 #if (ERRCLASS & ERRCLS_DEBUG)
4648 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4650 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4652 #if (ERRCLASS & ERRCLS_DEBUG)
4653 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4661 #ifdef SS_MULTIPLE_PROCS
4663 if (tTsk->initTsk != NULLP)
4666 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4669 &(osCp.tTskTbl[idx].xxCb));
4671 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4674 &(osCp.tTskTbl[idx].xxCb));
4675 #endif /* USE_MEMCAL */
4677 #endif /* SS_MULTIPLE_PROCS */
4679 if (tTsk->sTsk != NULLP)
4683 sTsk->dep.ent = ent;
4684 sTsk->dep.inst = inst;
4686 for (n = 0; n < SS_MAX_TTSKS; n++)
4688 if (sTsk->tTsks[n] == idx)
4690 sTsk->tTsks[n] = SS_INVALID_IDX;
4696 /* call the implementation to detach the task */
4697 ssdDetachTTsk(tTsk);
4699 sTsk->dep.ent = ENTNC;
4700 sTsk->dep.inst = INSTNC;
4703 /* Now we empty the entry for this task and update the table
4706 #ifdef SS_MULTIPLE_PROCS
4707 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4708 #else /* SS_MULTIPLE_PROCS */
4709 osCp.tTskIds[ent][inst] = SS_TSKNC;
4710 #endif /* SS_MULTIPLE_PROCS */
4713 #ifdef SS_MULTIPLE_PROCS
4714 tTsk->proc = PROCNC;
4715 #endif /* SS_MULTIPLE_PROCS */
4717 tTsk->inst = INSTNC;
4718 tTsk->tskType = TTUND;
4719 tTsk->initTsk = NULLP;
4720 tTsk->actvTsk = NULLP;
4723 tTsk->nxt = osCp.nxtTTskEntry;
4724 osCp.nxtTTskEntry = idx;
4727 #ifdef SS_MULTIPLE_PROCS
4728 /* mark the control block for this task as invalid */
4729 osCp.tTskTbl[idx].xxCb = NULLP;
4732 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4733 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4735 #if (ERRCLASS & ERRCLS_DEBUG)
4736 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4743 //#ifndef SPLIT_RLC_DL_TASK
4744 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4745 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4746 EXTERN Void ysMtTskHdlr(Void);
4747 EXTERN Void ysMtPollPhyMsg(U8 region);
4748 EXTERN Void ysMtRcvPhyMsg(Void);
4750 PUBLIC Void *mtTskHdlrT2kL2
4752 Ptr tskPtr /* pointer to task entry */
4755 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4756 Ptr tskPtr; /* pointer to task entry */
4762 /* wait for SS to come up */
4763 /* It is required to block on this semaphore before starting actual processing of
4764 the thread becasue the creator of this thread might want to cance it without
4765 doing any processing. When this semaphore is released, means the creator gives
4766 the go ahead for actual processing and we should never come back to this point */
4767 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4776 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4777 * (processes L1 msgs) */
4783 EXTERN Void ysMtTskHdlr(Void);
4784 EXTERN Void YsPhyRecvMsg();
4786 PUBLIC Void *mtTskHdlrT2kL2
4788 Ptr tskPtr /* pointer to task entry */
4791 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4792 Ptr tskPtr; /* pointer to task entry */
4798 /* get out the system task entry from the parameter */
4799 sTsk = (SsSTskEntry *) tskPtr;
4801 /* wait for SS to come up */
4802 /* It is required to block on this semaphore before starting actual processing of
4803 the thread becasue the creator of this thread might want to cance it without
4804 doing any processing. When this semaphore is released, means the creator gives
4805 the go ahead for actual processing and we should never come back to this point */
4806 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4809 #ifndef RGL_SPECIFIC_CHANGES
4817 #ifdef V5GTF_SPECIFIC_CHANGES
4820 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4821 * (processes L1 msgs) */
4823 /* get a message from the demand queue */
4825 #ifdef RLC_MAC_DAT_REQ_RBUF
4826 rgDlDatReqBatchProc();
4829 ret = mtTskHdlMsg(sTsk);
4832 /* exit the for loop here */
4835 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4842 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4846 PUBLIC void *pthreadCreateHdlr
4851 PUBLIC void *pthreadCreateHdlr(pthreadCreateArg)
4856 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4857 /* mt038.201 changed how sem_wait is called */
4858 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4861 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4869 * Desc: This is the system task handler function. It blocks on
4870 * the system task's demand queue. On receiving a message,
4871 * it identifies the target TAPA task, verifies that the
4872 * TAPA task belongs to this system task and if so, calls
4873 * the activation function of that TAPA task with the
4874 * received message. The task activation function or the
4875 * timer activation function may be called.
4877 * Ret: (thread function)
4885 PUBLIC Void *mtTskHdlr
4887 Ptr tskPtr /* pointer to task entry */
4890 PUBLIC Void *mtTskHdlr(tskPtr)
4891 Ptr tskPtr; /* pointer to task entry */
4897 /* get out the system task entry from the parameter */
4898 sTsk = (SsSTskEntry *) tskPtr;
4901 /* wait for SS to come up */
4903 /* mt038.201 changed how sem_wait is called */
4904 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4906 #ifdef XEON_SPECIFIC_CHANGES
4907 printf("\n**********MT Task Handler********\n");
4911 #ifndef ODU_TEST_STUB
4916 /* Wait for a message from the demand queue */
4917 #ifdef SS_CDMNDQ_SUPPORT
4918 ret = ssCDmndQWait(&sTsk->dQ);
4920 ret = ssDmndQWait(&sTsk->dQ);
4925 ret = mtTskHdlMsg(sTsk);
4940 * Desc: This is the system task handler function. It blocks on
4941 * the system task's demand queue. On receiving a message,
4942 * it identifies the target TAPA task, verifies that the
4943 * TAPA task belongs to this system task and if so, calls
4944 * the activation function of that TAPA task with the
4945 * received message. The task activation function or the
4946 * timer activation function may be called.
4948 * Ret: (thread function)
4956 PUBLIC S16 mtTskHdlMsg
4961 PUBLIC S16 mtTskHdlMsg(sTsk)
4975 /* mt028.201: modification: multiple procs support related changes */
4976 #ifndef SS_MULTIPLE_PROCS
4978 PAIFTMRS16 tmrActvFnMt = NULLP;
4980 /* mt015.301 Initialized the timer activation functions with NULLP */
4981 PFS16 tmrActvFn = NULLP;
4983 PAIFTMRS16 tmrActvFn;
4985 #endif /* SS_MULTIPLE_PROCS */
4986 /* mt003.301 Modifications */
4987 #ifdef SS_THREAD_PROFILE
4989 #endif /* SS_THREAD_PROFILE */
4992 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4995 /* nothing to receive */
4999 /* if we can't lock this system task entry, return the message */
5000 ret = SLock(&sTsk->lock);
5004 #if (ERRCLASS & ERRCLS_DEBUG)
5005 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
5006 "Could not lock system task entry");
5016 mBuf2 = mBuf->b_next;
5018 /* find out what kind of message this is */
5019 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5020 #ifdef SS_MEM_WL_DEBUG
5021 mtTskBuffer1 = mBuf2;
5023 mtTskBuffer2 = mBuf2->b_next;
5025 if(mInfo == 0x5050505)
5029 cmAnalyseBtInfo((PTR) mBuf,4);
5031 printf("\n In trouble .... \n");
5033 else if (mInfo == 0x2020202)
5036 cmAnalyseBtInfo((PTR) mBuf,1);
5037 printf("\n In trouble .... \n");
5039 #endif /* SS_MEM_WL_DEBUG */
5040 switch (mInfo->eventInfo.event)
5042 /* this is a termination event, we die */
5044 /* release the message */
5047 /* Unlock the system task entry and lock the system
5048 * task table to clean our entry up.
5050 SUnlock(&sTsk->lock);
5052 ret = SLock(&osCp.sTskTblLock);
5056 #if (ERRCLASS & ERRCLS_DEBUG)
5057 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5058 "Could not lock system task table");
5060 /* what to do here? */
5064 /* clean up the system task entry */
5067 /* mt003.301 Modifications - SDeRegTTsk */
5068 /* sTsk->numTTsks = 0; */
5069 SDestroyLock(&sTsk->lock);
5070 ssDestroyDmndQ(&sTsk->dQ);
5072 /* lock for current executing TAPA task ID */
5074 /* make this entry available in the system task table */
5075 sTsk->nxt = osCp.nxtSTskEntry;
5076 for (i = 0; i < SS_MAX_STSKS; i++)
5078 if (sTsk == &osCp.sTskTbl[i])
5080 osCp.nxtSTskEntry = i;
5087 /* unlock the system task table */
5088 SUnlock(&osCp.sTskTblLock);
5093 /* this is a data message or a permanent task keep-alive message */
5095 case SS_EVNT_PERMTICK:
5096 /* message to a task. find the destination task */
5097 /* mt028.201: modification: multiple procs support related changes */
5098 #ifdef SS_MULTIPLE_PROCS
5099 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5101 if (procIdIdx == SS_INV_PROCID_IDX)
5107 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5108 #else /* SS_MULTIPLE_PROCS */
5109 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5110 #endif /* SS_MULTIPLE_PROCS */
5112 /* verify that it hasn't been deregistered */
5113 if (idx == SS_TSKNC)
5119 /* verify that this system task is still running it */
5120 tTsk = &osCp.tTskTbl[idx];
5121 if (tTsk->sTsk != sTsk)
5127 /* set the current executing TAPA task ID */
5128 sTsk->dep.ent = mInfo->pst.dstEnt;
5129 sTsk->dep.inst = mInfo->pst.dstInst;
5131 /* copy the Pst structure into a local duplicate */
5132 for (i = 0; i < (S16) sizeof(Pst); i++)
5133 *(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
5135 /* Give the message to the task activation function. If
5136 * its a normal data message, we pass it, if this is a
5137 * keep-alive message for a permanent task then we pass
5138 * NULLP in place of the message to the task activation
5141 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5143 #ifndef RGL_SPECIFIC_CHANGES
5144 #ifdef SS_TSKLOG_ENABLE
5145 U32 t = MacGetTick();
5148 /* mt003.301 Modifications */
5149 #if SS_THREAD_PROFILE
5150 tTsk->curEvent = nPst.event;
5152 #endif /* SS_THREAD_PROFILE */
5153 tTsk->actvTsk(&nPst, mBuf);
5154 #ifndef RGL_SPECIFIC_CHANGES
5155 #ifdef SS_TSKLOG_ENABLE
5156 SStopTask(t,PID_SSI_TSK);
5159 #if SS_THREAD_PROFILE
5161 tTsk->curEvtTime = (U32)(et2 - et1);
5162 tTsk->totTime += (U64)tTsk->curEvtTime;
5163 #endif /* SS_THREAD_PROFILE */
5167 #if (ERRCLASS & ERRCLS_DEBUG)
5168 /* this message should only come to a permanent task */
5169 if (tTsk->tskType != SS_TSK_PERMANENT)
5171 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5175 tTsk->actvTsk(&nPst, NULLP);
5177 /* We need to re-send this message back to ourselves so
5178 * the permanent task continues to run.
5180 /* Check if this task got deregistered or detached
5181 * by the activation function; if so, there's nothing
5182 * more to do here, otherwise go ahead.
5185 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5187 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5188 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5192 /* failure here is a real problem */
5195 #if (ERRCLASS & ERRCLS_DEBUG)
5196 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5197 "Could not write to demand queue");
5203 /* unset the current executing TAPA task ID */
5204 sTsk->dep.ent = ENTNC;
5205 sTsk->dep.inst = INSTNC;
5210 /* timer event. find the timer entry */
5211 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5213 /* lock the timer table, coz we're going to peek in it */
5214 ret = SLock(&osCp.tmrTblLock);
5218 #if (ERRCLASS & ERRCLS_DEBUG)
5219 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5220 "Could not lock timer table");
5226 /* Verify that this timer entry is still around and that it
5227 * belongs to our task.
5229 if (osCp.tmrTbl[idx].used == FALSE
5230 /* mt028.201: modification: multiple procs support related changes */
5231 #ifdef SS_MULTIPLE_PROCS
5232 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5233 #endif /* SS_MULTIPLE_PROCS */
5234 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5235 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5237 SUnlock(&osCp.tmrTblLock);
5242 /* mt005.21: addition */
5243 /* set the current executing TAPA task ID */
5244 sTsk->dep.ent = mInfo->pst.dstEnt;
5245 sTsk->dep.inst = mInfo->pst.dstInst;
5247 #ifndef SS_MULTIPLE_PROCS
5249 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5250 tmrActvFnMt = NULLP;
5251 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5253 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5259 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5262 /* unlock the timer table */
5263 SUnlock(&osCp.tmrTblLock);
5265 /* activate the timer function */
5266 /* mt028.201: modification: multiple procs support related changes */
5267 #ifndef SS_MULTIPLE_PROCS
5271 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5272 osCp.tmrTbl[idx].ownerInst);
5280 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5281 osCp.tmrTbl[idx].ownerInst);
5282 #endif /* SS_MULTIPLE_PROCS */
5284 /*mt005.21: addition */
5285 /* unset the current executing TAPA task ID */
5286 sTsk->dep.ent = ENTNC;
5287 sTsk->dep.inst = INSTNC;
5290 /* return the message buffer */
5294 * mt003.301 - SDeRegTTsk fix
5296 case SS_EVNT_TTSK_TERM:
5297 #ifdef SS_MULTIPLE_PROCS
5298 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5300 if (procIdIdx == SS_INV_PROCID_IDX)
5306 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5307 #else /* SS_MULTIPLE_PROCS */
5308 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5309 #endif /* SS_MULTIPLE_PROCS */
5311 /* verify that it hasn't been deregistered */
5312 if (idx == SS_TSKNC)
5318 /* verify that this system task is still running it */
5319 tTsk = &osCp.tTskTbl[idx];
5320 if (tTsk->sTsk != sTsk)
5325 #ifdef SS_MULTIPLE_PROCS
5326 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5328 ssdProcTTskTerm(tTsk, idx);
5334 #if (ERRCLASS & ERRCLS_DEBUG)
5335 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5342 } while (mBuf != NULLP);
5345 /* unlock the system task entry */
5346 SUnlock(&sTsk->lock);
5349 /* yield for other threads */
5350 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5359 * Fun: mtTmrHdlrPublic
5362 PUBLIC Void mtTmrHdlrPublic
5366 PUBLIC Void mtTmrHdlrPublic()
5369 if (SLock(&osCp.tmrTblLock) != ROK)
5371 #if (ERRCLASS & ERRCLS_DEBUG)
5372 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5376 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5377 /* unlock the timer table */
5378 SUnlock(&osCp.tmrTblLock);
5386 * Desc: The timer handler thread function. Counts time
5387 * and invokes the common timer function on each
5390 * Ret: (thread function)
5397 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5399 PRIVATE Void *mtTmrHdlr
5401 void *parm /* unused */
5404 /* mt009.21: addition */
5405 PRIVATE Void *mtTmrHdlr(parm)
5406 void *parm; /* unused */
5409 /*mt004.301-addede new region*/
5410 /* mt010.301 Removed SS_FAP portion and
5411 * enabled oroginal code in function mtTmrHdlr */
5415 U32 i, cnt, oldTicks, newTicks;
5416 struct timeval tv1,tv2;
5417 /* mt038.201 added return */
5419 /* mt039.201 changes for nanosleep */
5420 struct timespec tsN;
5421 PRIVATE U32 err_in_usec;
5423 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5428 /* mt027.201 - Modification for SRegCfgTmr support */
5429 /* check SS_TICKS_SEC */
5430 if (SS_1MS < SS_TICKS_SEC)
5432 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5435 /* mt025.201 - Addition to stop timer handler till task registration is done */
5436 /* wait for SS to come up */
5437 /* mt038.201 changed how sem_wait is called */
5438 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5441 /* mt027.201 - Modification for SRegCfgTmr support */
5442 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5444 ts.tv_nsec = (MT_TICK_CNT * 1000);
5445 /* mt039.201 changes for nanosleep */
5451 if (gettimeofday(&tv1, NULL) == -1)
5453 #if (ERRCLASS & ERRCLS_DEBUG)
5454 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5455 "Error in clock_gettime");
5465 #ifndef STUB_TTI_HANDLING_5GTF
5466 printf("Returning from mtTmrHdlr()\n");
5471 /* mt039.201 changes for nanosleep */
5472 /* sleep for MT_TICK_CNT milli seconds */
5473 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5474 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5476 ts.tv_nsec = tsN.tv_nsec;
5481 if (gettimeofday(&tv2,NULL) == -1)
5483 #if (ERRCLASS & ERRCLS_DEBUG)
5484 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5485 "Error in clock_gettime");
5489 /*mt013.301 : changed check while calculating timer to fix
5490 * diffrence between MTSS time and real unix time
5492 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5494 time_int = (tv2.tv_usec - tv1.tv_usec);
5496 else if (tv2.tv_sec > tv1.tv_sec)
5498 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5500 else /* ts2 < ts1, this will not happen in normal scenario */
5502 /* to make sure cnt = 1 */
5504 time_int = MT_TICK_CNT;
5507 oldTicks = osCp.dep.sysTicks;
5508 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5509 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5510 newTicks = osCp.dep.sysTicks;
5511 tv1.tv_usec = tv2.tv_usec;
5512 tv1.tv_sec = tv2.tv_sec;
5514 cnt = newTicks - oldTicks;
5516 while(err_in_usec >= MT_TICK_CNT)
5519 err_in_usec -= MT_TICK_CNT;
5521 if( cnt >= MT_MAX_TICK_CNT_VAL)
5522 cnt = MT_MIN_TICK_CNT_VAL;
5523 /* call the common timer tick handler */
5524 for (i = 0; i < cnt; i++)
5526 /* mt008.301: cmPrcTmr is guarded with a lock */
5527 /* lock the timer table */
5528 if (SLock(&osCp.tmrTblLock) != ROK)
5530 #if (ERRCLASS & ERRCLS_DEBUG)
5531 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5535 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5536 /* unlock the timer table */
5537 SUnlock(&osCp.tmrTblLock);
5541 /* mt009.21: addition */
5542 RETVALUE( (Void *) NULLP);
5543 /* will not reach here */
5551 * Desc: Process timer event. Called from the common timer
5552 * code when a timeout occurs.
5562 PUBLIC Void mtTimeout
5564 PTR tCb, /* control block */
5565 S16 evnt /* event */
5568 PUBLIC Void mtTimeout(tCb, evnt)
5569 PTR tCb; /* control block */
5570 S16 evnt; /* event */
5579 #ifndef TENB_RTLIN_CHANGES
5582 /* mt028.201: modification: multiple procs support related changes */
5583 #ifdef SS_MULTIPLE_PROCS
5585 #endif /* SS_MULTIPLE_PROCS */
5586 #ifdef RGL_SPECIFIC_CHANGES
5587 #ifdef MSPD_MLOG_NEW
5588 U32 t = GetTIMETICK();
5595 /* get the timer entry */
5596 tEnt = (SsTmrEntry *) tCb;
5599 /* if the timer was deleted, this will be NULL, so drop it */
5605 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5608 /* Hmmmm, the timer might have been deleted while we've been
5609 * working at getting here, so we just skip this.
5611 if (tEnt->used == FALSE)
5617 /* Set up and send a timer message to the destination tasks'
5620 #ifndef SS_MULTICORE_SUPPORT
5621 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5623 #ifdef RGL_SPECIFIC_CHANGES
5624 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5626 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5631 #if (ERRCLASS & ERRCLS_DEBUG)
5632 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5638 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5639 mInfo->eventInfo.event = SS_EVNT_TIMER;
5640 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5642 mInfo->pst.dstEnt = tEnt->ownerEnt;
5643 mInfo->pst.dstInst = tEnt->ownerInst;
5644 mInfo->pst.srcEnt = tEnt->ownerEnt;
5645 mInfo->pst.srcInst = tEnt->ownerInst;
5646 /* mt028.201: modification: multiple procs support related changes */
5647 #ifndef SS_MULTIPLE_PROCS
5648 mInfo->pst.dstProcId = SFndProcId();
5649 mInfo->pst.srcProcId = SFndProcId();
5650 #else /* SS_MULTIPLE_PROCS */
5651 mInfo->pst.dstProcId = tEnt->ownerProc;
5652 mInfo->pst.srcProcId = tEnt->ownerProc;
5653 #endif /* SS_MULTIPLE_PROCS */
5654 mInfo->pst.selector = SEL_LC_NEW;
5655 #ifndef SS_MULTICORE_SUPPORT
5656 mInfo->pst.region = DFLT_REGION;
5659 mInfo->pst.pool = DFLT_POOL;
5660 mInfo->pst.prior = PRIOR0;
5661 mInfo->pst.route = RTESPEC;
5662 mInfo->pst.event = 0;
5665 #ifndef TENB_RTLIN_CHANGES
5666 /* get a semaphore for the TAPA task table */
5667 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5672 #if (ERRCLASS & ERRCLS_DEBUG)
5673 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5681 /* find the owner TAPA task */
5682 /* mt028.201: modification: multiple procs support related changes */
5683 #ifdef SS_MULTIPLE_PROCS
5684 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5685 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5686 #else /* SS_MULTIPLE_PROCS */
5687 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5688 #endif /* SS_MULTIPLE_PROCS */
5689 if (idx == SS_TSKNC)
5691 #ifndef TENB_RTLIN_CHANGES
5692 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5699 /* ensure that the TAPA task is hale and hearty */
5700 tTsk = &osCp.tTskTbl[idx];
5703 #ifndef TENB_RTLIN_CHANGES
5704 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5709 /* Klock work fix ccpu00148484 */
5710 /* write the timer message to the queue of the destination task */
5711 /* mt008.301 : check sTsk before putting into it's DQ */
5712 if (tTsk->sTsk == NULLP)
5714 #ifndef TENB_RTLIN_CHANGES
5715 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5719 #if (ERRCLASS & ERRCLS_DEBUG)
5720 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5721 "Could not write to demand queue");
5726 #ifdef SS_LOCKLESS_MEMORY
5727 mInfo->pst.region = tTsk->sTsk->region;
5728 mInfo->region = tTsk->sTsk->region;
5729 #endif /* SS_LOCKLESS_MEMORY */
5730 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5731 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5733 #ifndef TENB_RTLIN_CHANGES
5734 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5738 #if (ERRCLASS & ERRCLS_DEBUG)
5739 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5740 "Could not write to demand queue");
5745 /* Fix for ccpu00130657 */
5746 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5747 if (tTsk->sTsk->tskPrior == PRIOR0)
5750 WLS_WakeUp(mtGetWlsHdl());
5757 /* release the semaphore for the TAPA task table */
5758 #ifndef TENB_RTLIN_CHANGES
5759 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5763 /* restart the timer */
5764 arg.tq = osCp.dep.tmrTq;
5765 arg.tqCp = &osCp.dep.tmrTqCp;
5766 arg.timers = tEnt->dep.timers;
5767 arg.cb = (PTR) tEnt;
5771 arg.max = TMR_DEF_MAX;
5772 arg.wait = tEnt->interval;
5774 #ifdef RGL_SPECIFIC_CHANGES
5775 #ifdef MSPD_MLOG_NEW
5776 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5788 * Desc: This thread reads the console and hands over any
5789 * data read to a user function.
5791 * Ret: (thread function)
5799 PRIVATE Void *mtConHdlr
5801 Ptr parm /* unused */
5804 /* mt009.21: addition */
5805 PRIVATE Void *mtConHdlr(parm)
5806 Ptr parm; /* unused */
5813 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5819 /* check if we have a console input file handle */
5820 if (osCp.dep.conInFp == NULLP)
5826 fd = fileno(osCp.dep.conInFp);
5831 if ((read(fd, &data, 1)) != 1)
5837 /* call rdConQ, defined by the system service user */
5847 #ifdef SS_DRVR_SUPPORT
5850 * Fun: Interrupt service task handler
5852 * Desc: This is the interrupt service task handler. It blocks
5853 * on a pipe from which it reads an isFlag structure. The
5854 * structure indicates which interrupt service task is to
5855 * be executed. The thread identifies the task, calls the
5856 * isTsk function and sends itself a message to repeat
5857 * this operation until it receives a message to cease.
5867 /* mt009.21: addition */
5868 PRIVATE Void *mtIsTskHdlr
5870 Ptr tskPtr /* pointer to task entry */
5873 /* mt009.21: addition */
5874 PRIVATE Void *mtIsTskHdlr(tskPtr)
5875 Ptr tskPtr; /* pointer to task entry */
5878 #if (ERRCLASS & ERRCLS_DEBUG)
5889 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5894 switch (isFlag.action)
5897 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5899 /* call the interrupt service task activation function */
5900 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5902 /* send self a message to keep doing this */
5903 isFlag.action = MT_IS_RESET;
5905 #if (ERRCLASS & ERRCLS_DEBUG)
5906 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5907 if (ret != sizeof(isFlag))
5909 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5910 "write() to pipe failed");
5913 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5920 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5925 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5927 /* call the interrupt service task activation function */
5928 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5930 #if (ERRCLASS & ERRCLS_DEBUG)
5931 /* send self a message to do this again */
5932 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5934 if (ret != sizeof(isFlag))
5936 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5937 "write() to pipe failed");
5940 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5948 /* where did THIS come from?? */
5952 /* mt009.21: addition */
5953 RETVALUE( (Void *) NULLP);
5957 #endif /* SS_DRVR_SUPPORT */
5958 #endif /* L2_L3_SPLIT */
5960 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5964 * Fun: mtIntSigHndlr
5966 * Desc: Exit function, shuts down.
5976 PUBLIC Void mtIntSigHndlr
5981 PUBLIC Void mtIntSigHndlr(arg)
5986 TRC0(mtIntSigHndlr);
5988 osCp.dep.sigEvnt=TRUE;
5991 #ifdef TENB_RTLIN_CHANGES
5999 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
6004 * Desc: function, shuts down.
6014 PUBLIC Void mtExitClnup
6019 PUBLIC Void mtExitClnup()
6028 SGetSysTime(&ticks);
6030 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
6032 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
6034 #ifdef SS_HISTOGRAM_SUPPORT
6038 osCp.dep.sigEvnt=FALSE;
6040 if (osCp.dep.fileOutFp)
6042 fclose(osCp.dep.fileOutFp);
6050 Void SIncrementTtiCount(Void)
6055 Ticks SGetTtiCount(Void)
6064 * Desc: This function displays a string to a given output
6069 * Notes: Buffer should be null terminated.
6071 * channel 0 is reserved for backwards compatibility
6080 S16 chan, /* channel */
6081 Txt *buf /* buffer */
6084 PUBLIC S16 SDisplay(chan, buf)
6085 S16 chan; /* channel */
6086 Txt *buf; /* buffer */
6091 /* mt020.201 - Fixed typo */
6092 #if (ERRCLASS & ERRCLS_INT_PAR)
6095 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6100 #ifndef XEON_SPECIFIC_CHANGES
6101 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6102 ssMemlog(buf, strlen(buf));
6107 /* mt012.301 :FIX for LOG RELATED ISSUE */
6115 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6121 if (osCp.dep.fileOutFp)
6122 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6123 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6126 fflush(osCp.dep.fileOutFp);
6139 * Desc: function, shuts down.
6159 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6160 a loop to overcome the child processes being killed upon exiting the
6162 #ifdef SS_LINUX /* this should have already been defined */
6163 /* mt010.301 removed flag SLES9_PLUS */
6164 /* wait forever for children */
6168 if(osCp.dep.sigEvnt==TRUE)
6175 pthread_exit(NULLP);
6181 * Fun: Set date and time
6183 * Desc: This function is used to set the calendar
6188 * Notes: Unimplemented
6194 PUBLIC S16 SSetDateTime
6196 REG1 DateTime *dt /* date and time */
6199 PUBLIC S16 SSetDateTime(dt)
6200 REG1 DateTime *dt; /* date and time */
6215 * Fun: Get date and time
6217 * Desc: This function is used to determine the calendar
6218 * date and time. This information may be used for
6219 * some management functions.
6230 PUBLIC S16 SGetDateTime
6232 REG1 DateTime *dt /* date and time */
6235 PUBLIC S16 SGetDateTime(dt)
6236 REG1 DateTime *dt; /* date and time */
6239 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6242 struct timespec ptime;
6244 struct timeval ptime;
6253 #if (ERRCLASS & ERRCLS_INT_PAR)
6256 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6265 localtime_r(&tt, &tme);
6268 clock_gettime(CLOCK_REALTIME, &ptime);
6270 gettimeofday(&ptime, NULL);
6272 localtime_r(&ptime.tv_sec, &tme);
6274 dt->month = (U8) tme.tm_mon + 1;
6275 dt->day = (U8) tme.tm_mday;
6276 dt->year = (U8) tme.tm_year;
6277 dt->hour = (U8) tme.tm_hour;
6278 dt->min = (U8) tme.tm_min;
6279 dt->sec = (U8) tme.tm_sec;
6282 #ifdef SS_DATETIME_USEC
6284 dt->usec = ptime.tv_nsec / 1000;
6286 dt->usec = ptime.tv_usec;
6288 #endif /*-- SS_DATETIME_USEC --*/
6294 * Get time from epoch in milliseconds
6296 * Fun: Get time from epoch in milliseconds
6298 * Desc: This function is used to get the time from epoch in milli seconds.
6299 * This information may be used for calculating a layer's activation function
6300 * execution time used for thread profiling.
6309 /* mt003.301 Modifications */
6311 PUBLIC S16 SGetEpcTime
6313 EpcTime *et /* date and time */
6316 PUBLIC S16 SGetEpcTime(et)
6317 EpcTime *et; /* date and time */
6320 /* mt003.301 Modifications */
6322 U64 to_sec = 1000000;
6325 struct timespec ptime;
6327 struct timeval ptime;
6333 #if (ERRCLASS & ERRCLS_INT_PAR)
6342 clock_gettime(CLOCK_REALTIME, &ptime);
6344 gettimeofday(&ptime, NULL);
6345 #endif /* SS_LINUX */
6347 now = (ptime.tv_sec * to_sec);
6350 now += (ptime.tv_nsec / to_nsec);
6351 #else /* SS_LINUX */
6352 now += (ptime.tv_usec);
6354 #endif /* SS_LINUX */
6355 now = (now / to_nsec);
6366 * Fun: Get system time
6368 * Desc: This function is used to determine the system time.
6372 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6378 PUBLIC S16 SGetSysTime
6380 Ticks *sysTime /* system time */
6383 PUBLIC S16 SGetSysTime(sysTime)
6384 Ticks *sysTime; /* system time */
6390 #if (ERRCLASS & ERRCLS_INT_PAR)
6391 if (sysTime == NULLP)
6393 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6399 *sysTime = osCp.dep.sysTicks;
6405 /* mt021.201 - Addition of SGetRefTime function */
6408 * Fun: Get referenced time
6410 * Desc: This function is used to determine the time in seconds
6411 * and microseconds from a reference time. The reference
6412 * time is expressed in seconds from UTC EPOC, January 1,
6418 * Notes: Macros are defined for reference times:
6419 * SS_REFTIME_01_01_1970
6420 * SS_REFTIME_01_01_2002
6426 PUBLIC S16 SGetRefTime
6428 U32 refTime, /* reference time */
6433 PUBLIC S16 SGetRefTime(refTime, sec, usec)
6434 U32 refTime; /* reference time */
6441 struct timespec ptime;
6443 struct timeval ptime;
6449 clock_gettime(CLOCK_REALTIME, &ptime);
6451 gettimeofday(&ptime, NULL);
6454 #if (ERRCLASS & ERRCLS_INT_PAR)
6455 if (sec == NULLP || usec == NULLP)
6457 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6460 /* mt022.201 - Modification to fix compile warning */
6461 if (refTime > (U32)(ptime.tv_sec))
6463 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6468 *sec = ptime.tv_sec - refTime;
6470 *usec = ptime.tv_nsec / 1000;
6472 *usec = ptime.tv_usec;
6482 * Fun: Get Random Number
6484 * Desc: Invoked by layer when a pseudorandom number is required.
6488 * Notes: Suggested approach uses shuffled Linear Congruential
6489 * Operators as described in Byte magazine October
6490 * 1984; "Generating and Testing Pseudorandom Numbers"
6498 Random *value /* random number */
6501 PUBLIC S16 SRandom(value)
6502 Random *value; /* random number */
6508 #if (ERRCLASS & ERRCLS_INT_PAR)
6511 /* mt011.21: addition */
6512 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6518 *value = (Random) rand_r(&osCp.dep.randSeed);
6529 * Desc: This function exits from a task.
6533 * Notes: Currently does nothing.
6544 PUBLIC S16 SExitTsk()
6556 * Fun: Exit Interrupt
6558 * Desc: This function exits from an interrupt.
6562 * Notes: Currently does nothing.
6573 PUBLIC S16 SExitInt()
6585 * Fun: Hold Interrupt
6587 * Desc: This function prohibits interrupts from being enabled until
6588 * release interrupt. This function should be called when
6589 * interrupts are disabled and prior to any call to system
6590 * services either by entry to an interrupt service routine or
6591 * by explicit call to disable interrupt.
6595 * Notes: Currently does nothing
6606 PUBLIC S16 SHoldInt()
6618 * Fun: Release Interrupt
6620 * Desc: This function allows interrupts to be enabled.
6624 * Notes: Currently does nothing.
6635 PUBLIC S16 SRelInt()
6649 * Desc: Enable interrupts
6651 * Ret: ROK on success
6654 * Notes: Currently does nothing.
6660 PUBLIC INLINE S16 SEnbInt
6665 PUBLIC INLINE S16 SEnbInt()
6679 * Desc: Disable interrupts
6681 * Ret: ROK on success
6684 * Notes: Currently does nothing.
6690 PUBLIC INLINE S16 SDisInt
6695 PUBLIC INLINE S16 SDisInt()
6709 * Desc: This function gets the function address stored at the
6710 * specified interrupt vector.
6714 * Notes: Currently does nothing.
6722 VectNmb vectNmb, /* vector number */
6723 PIF *vectFnct /* vector function */
6726 PUBLIC S16 SGetVect(vectNmb, vectFnct)
6727 VectNmb vectNmb; /* vector number */
6728 PIF *vectFnct; /* vector function */
6746 * Desc: This function installs the specified function at the
6747 * specified interrupt vector.
6751 * Notes: Currently does nothing.
6759 VectNmb vectNmb, /* vector number */
6760 PIF vectFnct /* vector function */
6763 PUBLIC S16 SPutVect(vectNmb, vectFnct)
6764 VectNmb vectNmb; /* vector number */
6765 PIF vectFnct; /* vector function */
6778 /* mt028.201: modification: multiple procs support related changes */
6779 #ifndef SS_MULTIPLE_PROCS
6785 * Desc: This function gets the current entity and instance.
6788 * RFAILED - failed, general (optional)
6790 * Notes: This function may be called by the OS or Layer 1
6797 PUBLIC S16 SGetEntInst
6799 Ent *ent, /* entity */
6800 Inst *inst /* instance */
6803 PUBLIC S16 SGetEntInst(ent, inst)
6804 Ent *ent; /* entity */
6805 Inst *inst; /* instance */
6817 #if (ERRCLASS & ERRCLS_INT_PAR)
6818 /* check pointers */
6819 if (ent == NULLP || inst == NULLP)
6821 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6827 /* get the thread id */
6828 tId = pthread_self();
6831 /* find the system task in whose context we're running */
6833 ret = SLock(&osCp.sTskTblLock);
6838 for (i = 0; i < SS_MAX_STSKS; i++)
6840 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6842 sTsk = &osCp.sTskTbl[i];
6848 *ent = sTsk->dep.ent;
6849 *inst = sTsk->dep.inst;
6851 SUnlock(&osCp.sTskTblLock);
6854 RETVALUE(ret == ROK ? ROK : RFAILED);
6862 * Desc: This function sets the current entity and instance.
6872 PUBLIC S16 SSetEntInst
6874 Ent ent, /* entity */
6875 Inst inst /* instance */
6878 PUBLIC S16 SSetEntInst(ent, inst)
6879 Ent ent; /* entity */
6880 Inst inst; /* instance */
6892 #if (ERRCLASS & ERRCLS_INT_PAR)
6893 /* check entity and instance IDs */
6894 if (ent >= ENTNC || inst >= INSTNC)
6896 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6902 /* get the thread id */
6903 tId = pthread_self();
6906 /* find the system task in whose context we're running */
6908 ret = SLock(&osCp.sTskTblLock);
6913 for (i = 0; i < SS_MAX_STSKS; i++)
6915 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6917 sTsk = &osCp.sTskTbl[i];
6923 sTsk->dep.ent = ent;
6924 sTsk->dep.inst = inst;
6926 SUnlock(&osCp.sTskTblLock);
6929 RETVALUE(ret == ROK ? ROK : RFAILED);
6932 #endif /* SS_MULTIPLE_PROCS */
6934 #ifdef SS_DRVR_SUPPORT
6940 * Desc: Set interrupt pending flag
6942 * Ret: ROK on success
6951 PUBLIC INLINE S16 SSetIntPend
6953 U16 id, /* driver task identifier */
6954 Bool flag /* flag */
6957 PUBLIC INLINE S16 SSetIntPend(id, flag)
6958 U16 id; /* driver task identifier */
6959 Bool flag; /* flag */
6968 #if (ERRCLASS & ERRCLS_INT_PAR)
6969 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6971 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6978 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6980 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6988 #endif /* SS_DRVR_SUPPORT */
6991 #ifdef SS_LOCKLESS_MEMORY
6994 * Fun: SGlobMemInfoShow
6996 * Desc: This function displays the memory usage information
6997 * for the destined region. It will show the usage of
6998 * each configured bucket and the heap for the specified region.
7001 * RFAILED Region not registered
7007 PUBLIC S16 SGlobMemInfoShow
7012 PUBLIC S16 SGlobMemInfoShow()
7017 CmMmGlobRegCb *globReg;
7019 TRC1(SGlobMemInfoShow);
7021 globReg = osCp.globRegCb;
7023 sprintf(prntBuf, "--------------------------------------------------------------\n");
7024 SDisplay(0, prntBuf);
7025 sprintf(prntBuf, "Global Region Bucket Information\n");
7026 SDisplay(0, prntBuf);
7027 sprintf(prntBuf, "====================================================\n");
7028 SDisplay(0, prntBuf);
7029 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
7030 SDisplay(0, prntBuf);
7031 sprintf(prntBuf, "====================================================\n");
7032 SDisplay(0, prntBuf);
7035 for (idx = 0; idx < globReg->numBkts; idx++)
7037 #ifdef XEON_SPECIFIC_CHANGES
7038 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
7039 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7042 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
7043 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7045 sprintf(prntBuf, "%2u %12u %8u %9u\n",
7046 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7049 SDisplay(0, prntBuf);
7051 sprintf(prntBuf, "--------------------------------------------------------------\n");
7052 SDisplay(0, prntBuf);
7057 #endif /* SS_LOCKLESS_MEMORY */
7060 Bool IsMemoryThresholdHit(Region reg, Pool pool)
7062 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
7064 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
7067 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
7068 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
7075 /* mt022.201 - Addition of SRegInfoShow function */
7080 * Desc: This function displays the memory usage information
7081 * for the destined region. It will show the usage of
7082 * each configured bucket and the heap for the specified region.
7085 * RFAILED Region not registered
7087 * Notes: A Sample Output from the function
7088 * Bucket Memory: region 1
7089 * ====================================================
7090 * Bucket Number of Blks configured Size Allocated
7091 * ====================================================
7099 * Heap Memory: region 1
7102 * Heap Segmented blocks: 0
7109 PUBLIC S16 SRegInfoShow
7115 PUBLIC S16 SRegInfoShow(region, availmem)
7125 #if (ERRCLASS & ERRCLS_INT_PAR)
7126 if (region > (SS_MAX_REGS-1) )
7128 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7135 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7136 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7137 SDisplay(0, prntBuf);
7138 sprintf(prntBuf, "====================================================\n");
7139 SDisplay(0, prntBuf);
7140 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7141 SDisplay(0, prntBuf);
7142 sprintf(prntBuf, "====================================================\n");
7143 SDisplay(0, prntBuf);
7147 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7149 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7151 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7152 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7153 mtCMMRegCb[region]->bktTbl[idx].size,
7154 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7155 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7157 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7158 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7159 mtCMMRegCb[region]->bktTbl[idx].size,
7160 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7161 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7164 /*mt009.301 Fixed 64BIT compilation warnings*/
7166 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7167 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7168 mtCMMRegCb[region]->bktTbl[idx].size,
7169 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7171 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7172 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7173 mtCMMRegCb[region]->bktTbl[idx].size,
7174 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7176 #endif /* not TENB_RTLIN_CHANGES */
7177 SDisplay(0, prntBuf);
7178 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7179 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7180 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7182 sprintf(prntBuf, "\n---------------\n");
7183 SDisplay(0, prntBuf);
7184 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7185 SDisplay(0, prntBuf);
7186 /*mt009.301 Fixed 64BIT compilation warnings*/
7188 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7190 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7192 SDisplay(0, prntBuf);
7193 /*mt009.301 Fixed 64BIT compilation warnings*/
7195 sprintf(prntBuf, "Heap Allocated: %u\n",
7196 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7198 sprintf(prntBuf, "Heap Allocated: %lu\n",
7199 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7201 SDisplay(0, prntBuf);
7202 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7203 #if (ERRCLASS & ERRCLS_DEBUG)
7204 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7205 mtCMMRegCb[region]->heapCb.numFragBlk);
7206 SDisplay(0, prntBuf);
7211 #ifdef XEON_SPECIFIC_CHANGES
7212 #define SSI_MAX_BKT_THRESHOLD 6
7213 #define SSI_MAX_REG_THRESHOLD 2
7214 U32 SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7215 U32 SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7216 U32 SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7219 PRIVATE Void SInitMemThreshold
7225 PRIVATE Void SInitMemThreshold(region, maxBkt)
7231 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7233 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7234 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7235 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7236 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7241 PUBLIC S16 SRegReachedMemThreshold
7247 PUBLIC S16 SRegReachedMemThreshold(region, maxBkt)
7254 PRIVATE U8 initFlag = 1;
7258 SInitMemThreshold(region, maxBkt);
7261 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7263 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7268 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7272 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7277 RETVALUE(memStatus);
7280 /* mt033.201 - addition of API to return the memory statistical data */
7285 * Desc: This function returns the memory usage information
7286 * for the destined region. It will return the usage of
7287 * each configured bucket and the heap for the specified region.
7290 * RFAILED Region not registered
7298 PUBLIC S16 SGetRegInfo
7301 SsMemDbgInfo *dbgInfo
7304 PUBLIC S16 SGetRegInfo(region, dbgInfo)
7306 SsMemDbgInfo *dbgInfo;
7313 #if (ERRCLASS & ERRCLS_INT_PAR)
7314 if (region >= mtMemoCfg.numRegions )
7316 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7321 dbgInfo->availmem = 0;
7323 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7324 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7326 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7328 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7330 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7331 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7332 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7334 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7335 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7336 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7339 dbgInfo->region = region;
7341 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7343 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7344 mtCMMRegCb[region]->heapCb.avlSize);
7346 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7348 #if (ERRCLASS & ERRCLS_DEBUG)
7349 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7356 PUBLIC S16 SGetRegPoolInfo
7362 PUBLIC S16 SGetRegPoolInfo(numRegion, numPool)
7367 /* Send number of Region available */
7368 *numRegion = mtMemoCfg.numRegions;
7369 /* Send number of Pools available */
7370 *numPool = cfgRegInfo[0].numPools;
7375 /* mt033.201 - addition of APIs to print the memory statistical data
7376 * as defined by SSI enhancements
7378 #ifdef SSI_DEBUG_LEVEL1
7381 * Fun: SPrintRegMemStatusInfo
7383 * Desc: This function displays the memory usage information
7384 * for the destined region. It will show the total memory
7385 * used for static and dynamic memory if typeFlag is
7386 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7387 * memory block allocated for a particular size if typeFlag
7388 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7389 * calling SRegPrintMemStats.
7399 PUBLIC S16 SPrintRegMemStatusInfo
7405 PUBLIC S16 SPrintRegMemStatusInfo(region, typeFlag)
7415 TRC1(SPrintRegMemStatusInfo);
7417 #if (ERRCLASS & ERRCLS_INT_PAR)
7418 if (region >= mtMemoCfg.numRegions )
7420 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7425 /* initialize the counters*/
7429 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7431 /* total static and dynamic memory allocated from all the buckets in region requested */
7432 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7433 SDisplay(0, prntBuf);
7434 sprintf(prntBuf, "===========================================\n");
7435 SDisplay(0, prntBuf);
7436 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7437 SDisplay(0, prntBuf);
7438 sprintf(prntBuf, "===========================================\n");
7439 SDisplay(0, prntBuf);
7440 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7442 /*mt009.301 Fixed 64BIT compilation warnings*/
7444 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7445 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7446 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7448 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7449 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7450 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7452 SDisplay(0, prntBuf);
7453 /* update the total count */
7454 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7455 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7458 /*mt009.301 Fixed 64BIT compilation warnings*/
7460 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7461 SDisplay(0, prntBuf);
7462 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7464 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7465 SDisplay(0, prntBuf);
7466 /*mt010.301 fix for compilation error*/
7467 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7469 SDisplay(0, prntBuf);
7471 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7472 SDisplay(0, prntBuf);
7473 /*mt009.301 Fixed 64BIT compilation warnings*/
7475 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7476 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7478 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7479 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7481 SDisplay(0, prntBuf);
7483 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7485 /* Bucket Memory allocation Statistics */
7486 RETVALUE(SPrintRegMemStats(region));
7491 sprintf(prntBuf, "\n Invalid choice \n");
7492 SDisplay(0, prntBuf);
7500 * Fun: SPrintRegMemStats
7502 * Desc: This function displays the memory usage information for
7503 * the destined region. It will show the number of memory
7504 * block allocated for a particular size from the hash list.
7514 PRIVATE S16 SPrintRegMemStats
7519 PRIVATE S16 SPrintRegMemStats(region)
7523 CmMmHashListCp *hashListCp;
7528 TRC1(SPrintRegMemStats);
7530 hashListCp = &mtCMMRegCb[region]->hashListCp;
7532 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7533 SDisplay(0, prntBuf);
7534 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7535 hashListCp->numOfbins, hashListCp->numOfEntries);
7536 SDisplay(0, prntBuf);
7537 sprintf(prntBuf, "===================================\n");
7538 SDisplay(0, prntBuf);
7539 sprintf(prntBuf, "Block Size Total number of requests\n");
7540 SDisplay(0, prntBuf);
7541 sprintf(prntBuf, "===================================\n");
7542 SDisplay(0, prntBuf);
7544 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7545 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7547 if (hashListCp->hashList[idx].numAttempts)
7550 /*mt009.301 Fixed 64BIT compilation warnings*/
7552 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7553 hashListCp->hashList[idx].numAttempts);
7555 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7556 hashListCp->hashList[idx].numAttempts);
7558 SDisplay(0, prntBuf);
7562 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7563 SDisplay(0, prntBuf);
7564 sprintf(prntBuf, "=================================================\n");
7565 SDisplay(0, prntBuf);
7566 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7567 SDisplay(0, prntBuf);
7568 sprintf(prntBuf, "=================================================\n");
7569 SDisplay(0, prntBuf);
7571 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7572 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7574 /*mt009.301 Fixed 64BIT compilation warnings*/
7576 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7577 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7578 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7580 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7581 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7582 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7584 SDisplay(0, prntBuf);
7586 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7587 SDisplay(0, prntBuf);
7588 /*mt009.301 Fixed 64BIT compilation warnings*/
7590 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7591 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7592 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7594 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7595 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7596 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7598 SDisplay(0, prntBuf);
7599 sprintf(prntBuf, "\n");
7600 SDisplay(0, prntBuf);
7607 * Fun: SRegMemErrHdlr
7609 * Desc: This function handles the errors returned from the memory
7610 * related functions. Customers are suggested to modify this
7611 * API according to their specific requirement.
7621 PUBLIC Void SRegMemErrHdlr
7628 PUBLIC Void SRegMemErrHdlr(region, ptr, errCode)
7636 TRC1(SRegMemErrHdlr);
7638 if (errCode == RDBLFREE)
7640 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7641 SDisplay(0, prntBuf);
7643 else if (errCode == RTRAMPLINGNOK)
7645 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7646 SDisplay(0, prntBuf);
7654 * Fun: SPrintRegMemProfile
7656 * Desc: This function displays the memory profile information
7657 * for the destined region. This function prints for:
7658 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7659 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7669 PUBLIC S16 SPrintRegMemProfile
7674 PUBLIC S16 SPrintRegMemProfile(region)
7680 CmMmBlkHdr *curBktBlk;
7682 Size offsetToNxtBlk;
7689 TRC1(SPrintRegMemProfile);
7691 #if (ERRCLASS & ERRCLS_INT_PAR)
7692 if (region >= mtMemoCfg.numRegions )
7694 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7699 regCb = mtCMMRegCb[region];
7701 /* memory profile */
7702 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7703 SDisplay(0, prntBuf);
7705 /* bucket profile */
7706 sprintf(prntBuf, "\nBucket Profile\n");
7707 SDisplay(0, prntBuf);
7709 for (idx = 0; idx < regCb->numBkts; idx++)
7712 /*mt009.301 Fixed 64BIT compilation warnings*/
7714 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7715 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7717 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7718 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7720 SDisplay(0, prntBuf);
7722 sprintf(prntBuf, "==========================================================================\n");
7723 SDisplay(0, prntBuf);
7724 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7725 SDisplay(0, prntBuf);
7726 sprintf(prntBuf, "==========================================================================\n");
7727 SDisplay(0, prntBuf);
7729 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7731 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7732 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7733 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7735 /*mt009.301 Fixed 64BIT compilation warnings*/
7737 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7739 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7741 SDisplay(0, prntBuf);
7742 /* check if it is a sane block, elxe jump to next block */
7743 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7745 sprintf(prntBuf, " Trampled \n");
7746 SDisplay(0, prntBuf);
7751 if (CMM_IS_STATIC(curBktBlk->memFlags))
7753 /*mt009.301 Fixed 64BIT compilation warnings*/
7755 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7757 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7759 SDisplay(0, prntBuf);
7761 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7763 /*mt009.301 Fixed 64BIT compilation warnings*/
7765 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7767 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7769 SDisplay(0, prntBuf);
7771 else if (CMM_IS_FREE(curBktBlk->memFlags))
7773 /*mt009.301 Fixed 64BIT compilation warnings*/
7775 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7777 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7779 SDisplay(0, prntBuf);
7783 sprintf(prntBuf, " Trampled \n");
7784 SDisplay(0, prntBuf);
7790 sprintf(prntBuf, "\nHeap Profile\n");
7791 SDisplay(0, prntBuf);
7793 /* point to heapCb */
7794 heapCb = &(regCb->heapCb);
7796 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7797 SDisplay(0, prntBuf);
7798 sprintf(prntBuf, "==========================================================================\n");
7799 SDisplay(0, prntBuf);
7800 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7801 SDisplay(0, prntBuf);
7802 sprintf(prntBuf, "==========================================================================\n");
7803 SDisplay(0, prntBuf);
7805 /* traverse the entire heap to output the heap profile */
7806 hdrSize = sizeof(CmHEntry);
7807 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7808 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7810 /*mt009.301 Fixed 64BIT compilation warnings*/
7812 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7814 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7816 SDisplay(0, prntBuf);
7818 /* check if it is a sane block, elxe jump to next block */
7819 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7821 sprintf(prntBuf, " Trampled \n");
7822 SDisplay(0, prntBuf);
7824 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7825 SDisplay(0, prntBuf);
7828 * To go to next block in the heap we do not have any offset value
7829 * other than curHBlk->size. As the block is already trampled
7830 * we cannot rely on this size. So it is better to stop here unless there
7831 * exists any other mechanism(?) to know the offset to next block.
7836 /*mt009.301 Fixed 64BIT compilation warnings*/
7838 sprintf(prntBuf, " %8u", curHBlk->size);
7840 sprintf(prntBuf, " %8lu", curHBlk->size);
7842 SDisplay(0, prntBuf);
7844 if (CMM_IS_STATIC(curHBlk->memFlags))
7846 /*mt009.301 Fixed 64BIT compilation warnings*/
7848 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7850 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7852 SDisplay(0, prntBuf);
7854 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7856 /*mt009.301 Fixed 64BIT compilation warnings*/
7858 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7860 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7862 SDisplay(0, prntBuf);
7864 else if (CMM_IS_FREE(curHBlk->memFlags))
7866 /*mt009.301 Fixed 64BIT compilation warnings*/
7868 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7870 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7872 SDisplay(0, prntBuf);
7876 sprintf(prntBuf, " Trampled \n");
7877 SDisplay(0, prntBuf);
7879 /* goto next block in the heap */
7880 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7886 #endif /* SSI_DEBUG_LEVEL1 */
7888 /*-- mt035.201 : Added new API for timestamp --*/
7891 * Fun: Get TimeStamp
7893 * Desc: This function is used to Get TimeStamp in micro seconds
7904 PUBLIC S16 SGetTimeStamp
7909 PUBLIC S16 SGetTimeStamp(ts)
7915 struct timespec ptime;
7917 struct timeval ptime;
7924 TRC1(SGetTimeStamp);
7927 clock_gettime(CLOCK_REALTIME, &ptime);
7929 gettimeofday(&ptime, NULL);
7932 /* Obtain the time of day, and convert it to a tm struct. --*/
7933 ptm = localtime (&ptime.tv_sec);
7934 /* Klock work fix ccpu00148484 */
7937 /* Format the date and time, down to a single second. --*/
7938 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7941 /* Compute microseconds. --*/
7943 microseconds = ptime.tv_nsec / 1000;
7945 microseconds = ptime.tv_usec;
7948 /* Print the formatted time, in seconds, followed by a decimal point
7949 and the microseconds. --*/
7950 /*mt009.301 Fixed 64BIT compilation warnings*/
7952 sprintf(ts, "%s.%03d", time_string, microseconds);
7954 sprintf(ts, "%s.%03ld", time_string, microseconds);
7960 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7963 * Fun: Get SGetSystemTsk
7965 * Desc: This function is used to Get sytem task id
7975 PUBLIC U32 SGetSystemTsk
7980 PUBLIC U32 SGetSystemTsk()
7983 TRC1(SGetSystemTskS);
7985 RETVALUE(pthread_self());
7987 } /* end of SGetSystemTsk */
7989 #ifdef SS_MULTICORE_SUPPORT
7992 * Fun: Add Timer thread into system task table
7994 * Desc: This function is used to add the system task
7995 * associated with Timer thread.
8005 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void)
8007 PRIVATE SsSTskEntry* ssdAddTmrSTsk()
8013 TRC1(ssdAddTmrSTsk);
8015 /* lock the system task table */
8016 ret = SLock(&osCp.sTskTblLock);
8020 #if (ERRCLASS & ERRCLS_DEBUG)
8021 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8022 "Could not lock system task table");
8028 /* check count of system tasks */
8029 if (osCp.numSTsks == SS_MAX_STSKS)
8032 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8034 #if (ERRCLASS & ERRCLS_DEBUG)
8035 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
8036 "Could not give the Semaphore");
8041 #if (ERRCLASS & ERRCLS_ADD_RES)
8042 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
8049 /* initialize the system task entry with the information we have */
8050 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
8052 /* store the system task priority */
8053 sTsk->tskPrior = SS_NORM_TSK_PRI;
8055 /* initialize the demand queue */
8056 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8059 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8061 #if (ERRCLASS & ERRCLS_DEBUG)
8062 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8063 "Could not give the Semaphore");
8068 #if (ERRCLASS & ERRCLS_DEBUG)
8069 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8070 "Could not initialize demand queue");
8076 /* initialize the system task entry lock */
8077 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8079 ssDestroyDmndQ(&sTsk->dQ);
8081 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8083 #if (ERRCLASS & ERRCLS_DEBUG)
8084 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8085 "Could not give the Semaphore");
8090 #if (ERRCLASS & ERRCLS_DEBUG)
8091 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8092 "Could not initialize system task entry lock");
8099 /* success, update the table */
8100 sTsk->tskId = osCp.nxtSTskEntry;
8102 sTsk->termPend = FALSE;
8103 osCp.nxtSTskEntry = sTsk->nxt;
8106 /* unlock the system task table */
8108 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8110 #if (ERRCLASS & ERRCLS_DEBUG)
8111 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8112 "Could not give the Semaphore");
8119 #endif /* SS_MULTICORE_SUPPORT */
8120 /* mt003.301 Readwrite lock and recursive mutex additions */
8121 #ifdef SS_LOCK_SUPPORT
8124 * Fun: ssdInitLockNew
8126 * Desc: This function is used to initialise lock/mutex
8136 PUBLIC S16 ssdInitLockNew
8142 PUBLIC S16 ssdInitLockNew(lockId, lockType)
8148 #ifdef SS_REC_LOCK_SUPPORT
8149 pthread_mutexattr_t attr;
8150 #endif /* SS_REC_LOCK_SUPPORT */
8151 Txt prntBuf[PRNTSZE];
8154 TRC1(ssdInitLockNew);
8158 #ifdef SS_RDWR_LOCK_SUPPORT
8161 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8163 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8164 SDisplay(0, prntBuf);
8169 #endif /* SS_RDWR_LOCK_SUPPORT */
8170 #ifdef SS_REC_LOCK_SUPPORT
8173 retVal = pthread_mutexattr_init(&attr);
8177 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8182 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8184 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8188 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8189 pthread_mutexattr_destroy(&attr);
8193 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8196 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8197 pthread_mutexattr_destroy(&attr);
8203 #endif /* SS_REC_LOCK_SUPPORT */
8206 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8207 SDisplay(0, prntBuf);
8217 * Desc: This function is used to aquire the read write lock
8227 PUBLIC S16 ssdLockNew
8233 PUBLIC S16 ssdLockNew(lockId, lockType)
8239 Txt prntBuf[PRNTSZE];
8246 #ifdef SS_RDWR_LOCK_SUPPORT
8249 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8251 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8252 SDisplay(0, prntBuf);
8259 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8261 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8262 SDisplay(0, prntBuf);
8269 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8271 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8272 SDisplay(0, prntBuf);
8279 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8281 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8282 SDisplay(0, prntBuf);
8287 #endif /* SS_RDWR_LOCK_SUPPORT */
8288 #ifdef SS_REC_LOCK_SUPPORT
8291 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8293 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8294 SDisplay(0, prntBuf);
8299 #endif /* SS_REC_LOCK_SUPPORT */
8302 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8303 SDisplay(0, prntBuf);
8316 * Desc: This function is used to Unlock the read write lock
8326 PUBLIC S16 ssdUnlockNew
8332 PUBLIC S16 ssdUnlockNew(lockId, lockType)
8338 Txt prntBuf[PRNTSZE];
8345 #ifdef SS_RDWR_LOCK_SUPPORT
8348 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8350 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8351 SDisplay(0, prntBuf);
8356 #endif /* SS_RDWR_LOCK_SUPPORT */
8357 #ifdef SS_REC_LOCK_SUPPORT
8360 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8362 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8363 SDisplay(0, prntBuf);
8368 #endif /* SS_REC_LOCK_SUPPORT */
8371 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8372 SDisplay(0, prntBuf);
8381 * Fun: ssdDestroyLockNew
8383 * Desc: This function is used to destroy the read write lock
8393 PUBLIC S16 ssdDestroyLockNew
8399 PUBLIC S16 ssdDestroyLockNew(lockId, lockType)
8404 Txt prntBuf[PRNTSZE];
8407 TRC1(ssdDestroyLockNew);
8411 #ifdef SS_RDWR_LOCK_SUPPORT
8414 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8416 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8417 SDisplay(0, prntBuf);
8422 #endif /* SS_RDWR_LOCK_SUPPORT */
8423 #ifdef SS_REC_LOCK_SUPPORT
8426 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8428 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8429 SDisplay(0, prntBuf);
8434 #endif /* SS_REC_LOCK_SUPPORT */
8437 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8438 SDisplay(0, prntBuf);
8444 #endif /* SS_LOCK_SUPPORT */
8446 /* mt005.301 : Cavium Changes */
8447 #ifdef SS_SEUM_CAVIUM
8451 * Fun: ssInitRcvWork
8453 * Desc: This is the initializtion function of receive
8457 * RFAILED - failed, general (optional)
8459 * Notes: Function to initialize the work queue packet
8460 * receiving thread. This creates the new thread to
8461 * receive the work and sets the affinity.
8467 PUBLIC S16 ssInitRcvWork
8472 PUBLIC S16 ssInitRcvWork()
8475 pthread_attr_t attr;
8478 TRC1(ssInitRcvWork);
8480 /* set the required attributes */
8481 pthread_attr_init(&attr);
8482 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8483 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8484 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8486 /* Create a new thread to receive the work queue messages */
8487 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8489 pthread_attr_destroy(&attr);
8494 pthread_attr_destroy(&attr);
8498 }/* ssInitRcvWork */
8505 * Desc: This is the handler function of receive
8509 * RFAILED - failed, general (optional)
8511 * Notes:The handler function of the work queue receiver task.
8512 * This will be waiting for the work and after receiving
8513 * it, work will converted and posted to that entityt
8520 PRIVATE void *workRcvTsk
8525 PRIVATE void *workRcvTsk (ptr)
8530 cvmx_wqe_t *workPtr;
8531 Buffer *mBuf, *rcvdBuf;
8532 SsMsgInfo *minfoPtr;
8542 /* get the work if its avilable */
8543 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8545 if ( workPtr == NULLP )
8547 /* If there is no work then sleep for 10 usec */
8549 ts.tv_nsec = 500000;
8551 nanosleep(&ts, NULLP);
8555 switch(workPtr->tag)
8557 /* Switch over according to the tag value */
8558 case SS_CVMX_MBUF_TAG:
8560 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8562 /* Convert the physical address to Pointers */
8563 ret = SConvPhyPtr(&rcvdBuf);
8566 /* mt011.301: Cavium 32 bit changes */
8567 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8571 /* Copy the buffer to this region */
8572 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8575 /* mt011.301: Cavium 32 bit changes */
8576 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8580 /* mt011.301: Cavium 32 bit changes */
8581 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8583 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8585 /* Get the post strucutre and Post the message */
8586 if ( minfoPtr != NULLP)
8588 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8590 (Void)SPstTsk(&pst, mBuf);
8592 /* Free the buffer allocated if it cannot be sent */
8601 /* Invalid tag value, drop the work */
8602 /* mt011.301: Cavium 32 bit changes */
8603 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8612 #endif /* SS_SEUM_CAVIUM */
8614 #ifdef TENB_RTLIN_CHANGES
8615 PUBLIC S16 SInitLock(SLockId *l, U8 t)
8618 pthread_mutexattr_t prior;
8619 pthread_mutexattr_init(&prior);
8620 #ifndef RGL_SPECIFIC_CHANGES
8621 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8623 r = pthread_mutex_init(l, &prior);
8624 pthread_mutexattr_destroy(&prior);
8628 #ifdef SS_THR_REG_MAP
8631 * Fun: ssRegMainThread
8633 * Desc: This function is used to add the memory region
8634 * mapping for the main thread.
8636 * Ret: VOID (Always successful)
8644 PUBLIC Void ssRegMainThread(Void)
8647 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8649 printf("not able to get different Id for main thread\n");
8652 /* Here the default region is added as we dont have any region associated with
8653 * Main thread. The thread should not perform any allocation except
8654 * the initial configuratin
8656 #ifdef XEON_SPECIFIC_CHANGES
8657 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8659 SS_GET_THREAD_MEM_REGION() =
8666 * Fun: ssCheckAndAddMemoryRegionMap
8668 * Desc: This function is used to add the memory region
8669 * mapping for the provided sTsk associated thread.
8670 * If the threadId can be placed in the thread memory
8671 * region mapping table and returns success if it is able
8672 * to place. If not, it keeps the thread ID in the static
8673 * local array and increments the count. Once thread Id
8674 * is successfully placed in the thread memory region mapping
8675 * table, pthread_cancel is sent for all the previous threads
8676 * which are failed to place in table.
8678 * Ret: TRUE - Thread ID successfully placed in thread memory region
8680 * FALSE - If thread Id is not placed in thread memory region
8683 * Notes:mapping tablemapping tablng tablee
8688 PUBLIC S32 ssCheckAndAddMemoryRegionMap
8690 pthread_t threadId, /* Thread Id of system task */
8691 Region region /* Region associated with thread */
8694 PRIVATE U32 createdThreads;
8695 PRIVATE pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8698 TRC1(ssCheckAndAddMemoryRegionMap);
8700 /* Here 0xFF is considered as invalid region and if the mapping table
8701 * contains 0xFF, that mapping entry is free
8703 if(SS_INVALID_THREAD_REG_MAP !=
8704 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8706 /* Klock work fix ccpu00148484 */
8707 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8709 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8710 printf("Not able to get the different thread ID, exiting\n");
8713 createdThreadIds[createdThreads++] = threadId;
8716 /* If we found free mapping table entry, place the region and send pthread_cancel
8717 * for all the thread Ids which are created before this
8719 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8720 #ifdef XEON_SPECIFIC_CHANGES
8721 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8722 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8723 SS_MAX_THREAD_REGION_MAP), region);
8725 for(indx = 0; indx < createdThreads; indx++)
8727 #ifdef XEON_SPECIFIC_CHANGES
8728 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8730 pthread_cancel(createdThreadIds[indx]);
8736 } /* ssCheckAndAddMemoryRegionMap */
8740 * Fun: ssCheckAndDelMemoryRegionMap
8742 * Desc: This function is used to add the memory region
8743 * mapping for the provided sTsk associated thread.
8744 * If the threadId can be placed in the thread memory
8745 * region mapping table and returns success if it is able
8746 * to place. If not, it keeps the thread ID in the static
8747 * local array and increments the count. Once thread Id
8748 * is successfully placed in the thread memory region mapping
8749 * table, pthread_cancel is sent for all the previous threads
8750 * which are failed to place in table.
8752 * Ret: TRUE - Thread ID successfully placed in thread memory region
8754 * FALSE - If thread Id is not placed in thread memory region
8757 * Notes:mapping tablemapping tablng tablee
8762 PUBLIC S32 ssCheckAndDelMemoryRegionMap
8764 pthread_t threadId /* Thread Id of system task */
8768 TRC1(ssCheckAndDelMemoryRegionMap);
8770 /* Raghu To-Do Check with team, is it necessary to acquire lock
8771 * as del and add may go parallel */
8772 /* Here 0xFF is considered as invalid region and if the mapping table
8773 * contains 0xFF, that mapping entry is free
8775 if(SS_INVALID_THREAD_REG_MAP ==
8776 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8779 printf("Invalid Thread ID (%ld)\n", (U32)threadId);
8781 printf("Invalid Thread ID (%d)\n", (U32)threadId);
8785 /* If we found free mapping table entry, place the region and send pthread_cancel
8786 * for all the thread Ids which are created before this
8788 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8792 } /* ssCheckAndAddMemoryRegionMap */
8796 #ifdef SS_TSKLOG_ENABLE
8801 * Desc: This function will return current time through input parameter.
8804 * RFAILED - failed, general (optional)
8811 PUBLIC S16 SStartTask
8813 VOLATILE U32 *startTime,
8817 PUBLIC S16 SStartTask(startTime, taskId)
8818 VOLATILE U32 *startTime;
8822 #ifdef MSPD_MLOG_NEW
8823 *startTime = GetTIMETICK();
8832 * Desc: This function will return current time through input parameter.
8833 * and take the difference of start time provided as input parameter
8837 * RFAILED - failed, general (optional)
8844 PUBLIC S16 SStopTask
8846 VOLATILE U32 startTime,
8850 PUBLIC S16 SStopTask(startTime, taskId)
8851 VOLATILE U32 startTime;
8858 case PID_MAC_HARQ_IND:
8859 case PID_SCH_TTI_IND:
8861 case PID_MAC_DAT_IND:
8862 case PID_MAC_SF_ALLOC_REQ:
8863 case PID_MAC_STA_RSP:
8864 case PID_MAC_DL_SCHD:
8865 case PID_MAC_DL_CQI_IND:
8866 case PID_MAC_UL_CQI_IND:
8867 case PID_MAC_UL_SCHD:
8868 case PID_MAC_TTI_IND:
8869 case PID_CL_RCV_PHY_MSG:
8870 case PID_CL_HARQ_STA_IND:
8871 case PID_MAC_AM_HARQ_RLS:
8872 case PID_CL_DL_BATCH_PROC:
8873 case PID_CL_DLM_PRC_TTI_IND:
8874 case PID_CRC_IND_REAL:
8875 case PID_CRC_IND_DUMMY:
8876 case PID_TTI_LATENCY:
8877 case PID_RECPREQ_PROC:
8880 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8882 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8885 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8893 PUBLIC S16 SStartTask
8895 VOLATILE U32 * startTime,
8899 PUBLIC S16 SStartTask(startTime, taskId)
8900 VOLATILE U32 * startTime;
8909 PUBLIC S16 SStopTask
8911 VOLATILE U32 startTime,
8915 PUBLIC S16 SStopTask(startTime, taskId)
8916 VOLATILE U32 startTime;
8923 #endif /*#ifdef SS_TSKLOG_ENABLE */
8924 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8926 * This primitive is used to calculate the CPU Utilization per Core
8931 * @return Void - function is always success
8934 PUBLIC Void UpdateSocCpuInfo
8936 CmCpuStatsInfo *cpuInfo,
8940 PUBLIC Void UpdateSocCpuInfo(*cpuInfo, idx)
8941 CmCpuStatsInfo *cpuInfo;
8946 S8 mipsStr[MIPS_STRING_LEN];
8953 /* Open the file which holds the MIPS available value */
8954 mipsFd = fopen(MIPS_FILE, "r");
8961 /* Get the free mips available value from the file */
8962 if(NULLP == fgets(mipsStr, 24, mipsFd))
8964 printf("fgets to get the free mips available failed\n");
8969 strtok(mipsStr, " ");
8971 strPart = strtok(NULLP, " ");
8973 if(idx == CM_L2_CPU_UTIL)
8975 if(strPart != NULLP)
8977 l2FreeCpu = atoi(strPart);
8978 l2CpuUsed = 100 - l2FreeCpu;
8979 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8980 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);;
8981 cpuInfo->cpuUtil[0].numSamples++;
8984 if(idx == CM_L3_CPU_UTIL)
8986 strPart = strtok(NULLP, " ");
8987 if(strPart != NULLP)
8989 l3FreeCpu = atoi(strPart);
8990 l3CpuUsed = 100 - l3FreeCpu;
8991 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8992 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);;
8993 cpuInfo->cpuUtil[0].numSamples++;
8996 if(idx == CM_L2_CPU_UTIL)
8998 cpuInfo->numCores = CM_NUM_L2_CORES ;
9000 else if(idx == CM_L3_CPU_UTIL)
9002 cpuInfo->numCores = CM_NUM_L3_CORES ;
9008 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
9009 #ifdef SS_MULTICORE_SUPPORT
9012 * Fun: Add Timer thread into system task table
9014 * Desc: This function is used to add the system task
9015 * associated with Timer thread.
9025 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(
9029 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(idx)
9036 TRC1(ssdReAddTmrSTsk);
9038 /* lock the system task table */
9039 ret = SLock(&osCp.sTskTblLock);
9043 #if (ERRCLASS & ERRCLS_DEBUG)
9044 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
9045 "Could not lock system task table");
9051 /* initialize the system task entry with the information we have */
9052 sTsk = &osCp.sTskTbl[idx];
9057 SDestroyLock(&sTsk->lock);
9058 ssDestroyDmndQ(&sTsk->dQ);
9061 /* store the system task priority */
9062 sTsk->tskPrior = SS_NORM_TSK_PRI;
9064 /* initialize the demand queue */
9065 if (ssInitDmndQ(&sTsk->dQ) != ROK)
9068 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9070 #if (ERRCLASS & ERRCLS_DEBUG)
9071 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
9072 "Could not give the Semaphore");
9077 #if (ERRCLASS & ERRCLS_DEBUG)
9078 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
9079 "Could not initialize demand queue");
9085 /* initialize the system task entry lock */
9086 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
9088 ssDestroyDmndQ(&sTsk->dQ);
9090 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9092 #if (ERRCLASS & ERRCLS_DEBUG)
9093 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
9094 "Could not give the Semaphore");
9099 #if (ERRCLASS & ERRCLS_DEBUG)
9100 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9101 "Could not initialize system task entry lock");
9108 /* success, update the table */
9109 sTsk->tskId = idx + 1;
9111 sTsk->termPend = FALSE;
9113 /* unlock the system task table */
9115 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9117 #if (ERRCLASS & ERRCLS_DEBUG)
9118 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9119 "Could not give the Semaphore");
9126 #endif /* SS_MULTICORE_SUPPORT */
9131 * Fun: Initialize timer table
9133 * Desc: This function initializes MTSS-specific information
9134 * in the timer table.
9144 PUBLIC S16 ssdReInitTmr
9149 PUBLIC S16 ssdReInitTmr()
9152 pthread_attr_t attr;
9153 struct sched_param param_sched;
9154 #ifndef XEON_SPECIFIC_CHANGES
9157 #ifdef SS_MULTICORE_SUPPORT
9159 #endif /* SS_MULTICORE_SUPPORT */
9160 #ifdef SS_THR_REG_MAP
9161 U32 threadCreated = FALSE;
9162 #endif /* SS_THR_REG_MAP */
9166 #ifndef XEON_SPECIFIC_CHANGES
9167 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9170 #if (ERRCLASS & ERRCLS_DEBUG)
9171 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9172 "Could not give the Semaphore");
9178 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9179 /* mt010.21: addition */
9181 #ifdef SS_MULTICORE_SUPPORT
9182 sTsk = ssdReAddTmrSTsk(0);
9187 #endif /* SS_MULTICORE_SUPPORT */
9188 /* create the timer handler thread */
9190 pthread_attr_init(&attr);
9191 /* mt021.201 - Addition to set stack size */
9192 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9193 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9194 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9195 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9196 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9197 pthread_attr_setschedparam(&attr, ¶m_sched);
9200 #ifdef SS_THR_REG_MAP
9201 /* When the thread is created, we check for the memory mapping table if
9202 * threadId can be placed in thread memory map table. If it is not able to place
9203 * threadId is stored in tmporary array. Once thread is created successful,
9204 * thread_cancel is sent for each thread which are created before. All the
9205 * threads are made to wait on sema which is cancel point for thread.
9207 while(threadCreated == FALSE)
9210 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9212 /* mt020.201 - Addition for destroying thread attribute object attr */
9213 pthread_attr_destroy(&attr);
9218 #ifdef SS_THR_REG_MAP
9219 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9222 #endif /* SS_THR_REG_MAP */
9223 #ifdef SS_MEM_WL_DEBUG
9224 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9227 /* mt020.201 - Addition for destroying thread attribute object attr */
9228 pthread_attr_destroy(&attr);
9229 sem_post(&osCp.dep.ssStarted);
9233 /**********************************************************************
9235 **********************************************************************/