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;
1407 TRC3(isMemThreshReached)
1409 globReg = osCp.globRegCb;
1411 #if (ERRCLASS & ERRCLS_INT_PAR)
1412 if(bktIdx >= globReg->numBkts)
1416 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1418 bktCb = &(globReg->bktTbl[bktIdx]);
1420 if(gDynMemAlrm[bktIdx])
1422 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1423 SLock(&(bktCb->bucketLock));
1424 if(bktCb->listValidBktSet.count > 25)
1426 gDynMemAlrm[bktIdx] = FALSE;
1427 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1429 SUnlock(&(bktCb->bucketLock));
1435 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1437 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1438 SLock(&(bktCb->bucketLock));
1439 if(bktCb->listValidBktSet.count < 15 )
1440 gDynMemAlrm[bktIdx] = TRUE;
1441 memoryCheckCounter = 0;
1442 SUnlock(&(bktCb->bucketLock));
1448 #endif /* USE_MALLOC */
1449 #endif /* SS_LOCKLESS_MEMORY */
1451 #ifdef SS_USE_ICC_MEMORY
1454 * Fun: Initialize region/pool tables
1456 * Desc: This function initializes MTSS-specific information
1457 * in the region/pool tables and configures the common
1458 * memory manager for use.
1468 PUBLIC Void * ssGetIccHdl
1473 PUBLIC Void * ssGetIccHdl()
1477 CmMmDynRegCb *dynRegCb;
1479 /* Klock work fix ccpu00148484 */
1480 if(!(region < SS_MAX_REGS))
1485 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1487 RETVALUE(dynRegCb->iccHdl);
1489 #endif /* SS_USE_ICC_MEMORY */
1491 #ifdef T2K_MEM_LEAK_DBG
1492 extern RegionMemLeakInfo regMemLeakInfo;
1493 #endif /* T2K_MEM_LEAK_DBG */
1497 PUBLIC S16 SPartitionWlsMemory()
1502 U64 pageSize[1], hugePageSize;
1505 long int pageSize[1], hugePageSize;
1508 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1510 U8 *regMemStrtAddr = (U8 *)osCp.wls.allocAddr;
1512 gethugepagesizes(pageSize,1);
1513 hugePageSize = pageSize[0];
1514 for (i = 0; i < 1; i++)
1516 mtRegMemSz[i].startAddr = regMemStrtAddr;
1517 //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1519 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1520 reqdSz = numHugePg * hugePageSize;
1521 regMemStrtAddr += reqdSz;
1522 #ifdef T2K_MEM_LEAK_DBG
1523 /* Since wls is region 0 */
1524 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1525 regMemLeakInfo.numActvRegions++;
1526 #endif /* T2K_MEM_LEAK_DBG */
1528 //Store last region addr for validation
1529 mtRegMemSz[i].startAddr = regMemStrtAddr;
1533 #ifdef SS_MEM_WL_DEBUG
1534 PUBLIC Void SChkAddrValid(int type, int region, PTR ptr)
1536 char *tryPtr = NULL;
1537 if(type == 0) //Global
1539 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1540 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1542 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1548 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1550 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1556 #endif /* SS_MEM_WL_DEBUG */
1558 PUBLIC S16 SPartitionStaticMemory(U8 *startAddr)
1563 U8 *regMemStrtAddr = (U8 *)startAddr;
1566 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1567 for (i = 1; i < mtMemoCfg.numRegions; i++)
1569 mtRegMemSz[i].startAddr = regMemStrtAddr;
1570 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1571 regMemStrtAddr += reqdSz;
1572 #ifdef T2K_MEM_LEAK_DBG
1573 { /* Since region 1 onwards are used for non wls */
1574 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1575 regMemLeakInfo.numActvRegions++;
1577 #endif /* T2K_MEM_LEAK_DBG */
1581 PUBLIC S16 SAllocateWlsMem()
1589 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1590 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1592 for (i = 0; i < 1; i++)
1594 /* allocate space for the region */
1595 region = &mtMemoCfg.region[i];
1596 reqdMemSz += region->heapsize;
1597 mtRegMemSz[i].reqdSz += region->heapsize;
1599 for (j = 0; j < region->numBkts; j++)
1601 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1602 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1605 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1606 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1608 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1610 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1612 SPartitionWlsMemory();
1615 PUBLIC S16 SAllocateStaticMem()
1624 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1626 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1627 for (i = 1; i < mtMemoCfg.numRegions; i++)
1629 /* allocate space for the region */
1630 region = &mtMemoCfg.region[i];
1631 reqdMemSz += region->heapsize;
1632 mtRegMemSz[i].reqdSz += region->heapsize;
1634 for (j = 0; j < region->numBkts; j++)
1636 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1637 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1641 startAddr = malloc(reqdMemSz + (1024 * 10));
1643 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1645 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1647 SPartitionStaticMemory(startAddr);
1650 #endif /* INTEL_WLS */
1656 * Fun: Initialize region/pool tables
1658 * Desc: This function initializes MTSS-specific information
1659 * in the region/pool tables and configures the common
1660 * memory manager for use.
1670 PUBLIC S16 ssdInitMem
1675 PUBLIC S16 ssdInitMem()
1678 /* mt018.201 - added local variable */
1683 Txt errMsg[256] = {'\0'};
1684 #ifdef SS_LOCKLESS_MEMORY
1685 CmMmDynRegCb *dynRegCb;
1686 #ifdef SS_USE_ICC_MEMORY
1688 CmMmGlobRegCb *globReg;
1691 #endif /* SS_LOCKLESS_MEMORY */
1695 /* Use the default SSI memory manager if the ICC memory manager is not
1696 * avilable. If ICC memory manager is avilable, it will be used for
1697 * all sharable memory allocation and de-allocation */
1698 #ifdef SS_LOCKLESS_MEMORY
1699 #ifdef SS_USE_ICC_MEMORY
1700 #ifndef YS_PHY_3_8_2
1702 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1704 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1705 if(dynRegCb == NULLP)
1709 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1711 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1713 dynRegCb->region = i;
1714 cmMmDynRegInit(dynRegCb);
1715 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1718 /* ysIccHdl = dynRegCb->iccHdl; */
1721 /* Initialize the global region first */
1722 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1724 if(osCp.globRegCb == NULLP)
1729 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1731 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1733 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1735 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1737 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1739 if(globReg->bktTbl[i].startAddr == NULLP)
1743 globReg->bktTbl[i].poolId = i;
1744 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1745 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1746 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1749 globReg->numBkts = mtGlobMemoCfg.numBkts;
1750 cmMmGlobRegInit(globReg);
1752 /* Initialize the dynamic task regions and sanity check for the theshold
1754 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1756 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1757 if(dynRegCb == NULLP)
1761 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1763 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1764 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1765 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1766 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1768 #ifdef XEON_SPECIFIC_CHANGES
1773 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1774 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1775 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1776 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1777 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1779 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1782 dynRegCb->region = i;
1783 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1784 cmMmDynRegInit(dynRegCb);
1786 #endif /* SS_USE_ICC_MEMORY */
1787 #endif /* SS_LOCKLESS_MEMORY */
1789 #ifdef T2K_MEM_LEAK_DBG
1791 /* Initailize mem leak tool memorys for debguing */
1792 regMemLeakInfo.numActvRegions=0;
1793 for(reg=0; reg <SS_MAX_REGS; reg++)
1795 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1796 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1797 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1798 regMemLeakInfo.regStartAddr[reg] = 0;
1801 regMemLeakInfo.regStartAddr[reg] = 0;
1802 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1804 printf("\n mutex init failed\n");
1810 /* Now allocate WLS memory */
1812 SAllocateStaticMem();
1814 /* mt018.201 - CMM Initialization */
1815 for (i = 0; i < mtMemoCfg.numRegions; i++)
1817 /* allocate space for the region control block */
1818 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1819 #ifdef TENB_RTLIN_CHANGES
1820 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1822 if (mtCMMRegCb[i] == NULLP)
1824 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1825 for the Region:%d control block\n",i);
1827 for (k = 0; k < i; k++)
1829 cmMmRegDeInit(mtCMMRegCb[k]);
1830 free(mtCMMRegCfg[k]->vAddr);
1831 free(mtCMMRegCb[k]);
1832 free(mtCMMRegCfg[k]);
1837 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1838 #ifdef TENB_RTLIN_CHANGES
1839 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1841 if (mtCMMRegCfg[i] == NULLP)
1843 for (k = 0; k < i; k++)
1845 cmMmRegDeInit(mtCMMRegCb[k]);
1846 free(mtCMMRegCfg[k]->vAddr);
1847 free(mtCMMRegCb[k]);
1848 free(mtCMMRegCfg[k]);
1850 free(mtCMMRegCb[i]);
1855 /* allocate space for the region */
1856 region = &mtMemoCfg.region[i];
1857 mtCMMRegCfg[i]->size = region->heapsize;
1858 for (j = 0; j < region->numBkts; j++)
1860 /* mt033.201 - addition for including the header size while computing the total size */
1861 #ifdef SSI_DEBUG_LEVEL1
1862 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1863 (region->bkt[j].numBlks);
1865 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1866 #endif /* SSI_DEBUG_LEVEL1 */
1869 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1871 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1874 #ifdef XEON_SPECIFIC_CHANGES
1875 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1876 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1878 #ifdef TENB_RTLIN_CHANGES
1879 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1882 if (mtCMMRegCfg[i]->vAddr == NULLP)
1884 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1885 for the Region:%d \n",i);
1887 for (k = 0; k < i; k++)
1889 cmMmRegDeInit(mtCMMRegCb[k]);
1890 free(mtCMMRegCfg[k]->vAddr);
1891 free(mtCMMRegCb[k]);
1892 free(mtCMMRegCfg[k]);
1894 free(mtCMMRegCb[i]);
1895 free(mtCMMRegCfg[i]);
1900 /* set up the CMM configuration structure */
1901 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1902 mtCMMRegCfg[i]->chFlag = 0;
1903 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1904 mtCMMRegCfg[i]->numBkts = region->numBkts;
1906 for (j = 0; j < region->numBkts; j++)
1908 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1909 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1912 /* initialize the CMM */
1913 #ifdef SS_LOCKLESS_MEMORY
1914 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1916 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1917 #endif /* SS_LOCKLESS_MEMORY */
1919 for (k = 0; k < i; k++)
1921 cmMmRegDeInit(mtCMMRegCb[k]);
1922 free(mtCMMRegCfg[k]->vAddr);
1923 free(mtCMMRegCb[k]);
1924 free(mtCMMRegCfg[k]);
1926 free(mtCMMRegCfg[i]->vAddr);
1927 free(mtCMMRegCb[i]);
1928 free(mtCMMRegCfg[i]);
1933 /* initialize the STREAMS module */
1934 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1935 if (region->regionId == 0)
1937 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
1939 for (k = 0; k < i; k++)
1941 cmMmRegDeInit(mtCMMRegCb[k]);
1942 free(mtCMMRegCfg[k]->vAddr);
1943 free(mtCMMRegCb[k]);
1944 free(mtCMMRegCfg[k]);
1946 cmMmRegDeInit(mtCMMRegCb[i]);
1947 free(mtCMMRegCfg[i]->vAddr);
1948 free(mtCMMRegCb[i]);
1949 free(mtCMMRegCfg[i]);
1954 /* mt001.301 : Additions */
1955 #ifdef SS_MEM_LEAK_STS
1957 #endif /* SS_MEM_LEAK_STS */
1966 * Fun: De-initialize region/pool tables
1968 * Desc: This function reverses the initialization in ssdInitMem().
1978 PUBLIC Void ssdDeinitMem
1983 PUBLIC Void ssdDeinitMem()
1986 /* mt018.201 - added local variables */
1990 /* mt008.301 Additions */
1991 #ifdef SS_MEM_LEAK_STS
1992 cmDeinitMemLeakMdl();
1993 #endif /* SS_MEM_LEAK_STS */
1995 for (i = 0; i < mtMemoCfg.numRegions; i++)
1997 cmMmRegDeInit(mtCMMRegCb[i]);
1998 free(mtCMMRegCfg[i]->vAddr);
1999 free(mtCMMRegCb[i]);
2000 free(mtCMMRegCfg[i]);
2009 * Fun: Initialize task table
2011 * Desc: This function initializes MTSS-specific information
2012 * in the task table.
2022 PUBLIC S16 ssdInitTsk
2027 PUBLIC S16 ssdInitTsk()
2030 /* mt001.301 : Additions */
2031 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2032 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2034 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2039 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2040 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2041 /* initialize system task information */
2042 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2044 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2046 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2053 * Fun: Deinitialize task table
2055 * Desc: This function reverses the initialization perfomed in
2066 PUBLIC Void ssdDeinitTsk
2071 PUBLIC Void ssdDeinitTsk()
2080 #ifdef SS_DRVR_SUPPORT
2083 * Fun: Initialize driver task table
2085 * Desc: This function initializes MTSS-specific information
2086 * in the driver task table.
2096 PUBLIC S16 ssdInitDrvr
2101 PUBLIC S16 ssdInitDrvr()
2106 pthread_attr_t attr;
2112 /* initialize the dependent portion of the driver task entries */
2113 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2115 osCp.drvrTskTbl[i].dep.flag = FALSE;
2119 /* create pipe for communication between SSetIntPend() and
2120 * the isTskHdlr thread.
2122 if (pipe(osCp.dep.isFildes) != 0)
2128 /* create the isTskHdlr thread */
2129 pthread_attr_init(&attr);
2130 /* mt021.201 - Addition to set stack size */
2131 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2132 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2133 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2134 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2136 /* mt020.201 - Addition for destroying thread attribute object attr */
2137 pthread_attr_destroy(&attr);
2143 /*mt014.301 : 4GMX release related changes*/
2144 #ifdef SS_4GMX_UCORE
2152 /* mt020.201 - Addition for destroying thread attribute object attr */
2153 pthread_attr_destroy(&attr);
2162 * Fun: Deinitialize driver information
2164 * Desc: This function reverses the initialization performed in
2175 PUBLIC Void ssdDeinitDrvr
2180 PUBLIC Void ssdDeinitDrvr()
2183 TRC0(ssdDeinitDrvr);
2184 /* mt008.301: Terminate the Driver Task on exit */
2185 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2188 TL_Close(AppContext.hUAII);
2189 if (clusterMode == RADIO_CLUSTER_MODE)
2191 TL_Close(AppContext.hUAII_second);
2197 #endif /* SS_DRVR_SUPPORT */
2202 * Fun: Initialize timer table
2204 * Desc: This function initializes MTSS-specific information
2205 * in the timer table.
2215 PUBLIC S16 ssdInitTmr
2220 PUBLIC S16 ssdInitTmr()
2223 pthread_attr_t attr;
2224 struct sched_param param_sched;
2225 /* mt010.21: addition */
2227 #ifdef SS_MULTICORE_SUPPORT
2229 #endif /* SS_MULTICORE_SUPPORT */
2230 #ifdef SS_THR_REG_MAP
2231 U32 threadCreated = FALSE;
2232 #endif /* SS_THR_REG_MAP */
2237 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2238 /* mt010.21: addition */
2239 osCp.dep.tmrTqCp.nxtEnt = 0;
2240 for (i=0; i< SS_MAX_TMRS; i++)
2242 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2245 #ifdef SS_MULTICORE_SUPPORT
2246 sTsk = ssdAddTmrSTsk();
2251 #endif /* SS_MULTICORE_SUPPORT */
2252 /* create the timer handler thread */
2253 pthread_attr_init(&attr);
2254 /* mt021.201 - Addition to set stack size */
2255 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2256 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2257 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2258 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2259 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2260 pthread_attr_setschedparam(&attr, ¶m_sched);
2263 #ifdef SS_THR_REG_MAP
2264 /* When the thread is created, we check for the memory mapping table if
2265 * threadId can be placed in thread memory map table. If it is not able to place
2266 * threadId is stored in tmporary array. Once thread is created successful,
2267 * thread_cancel is sent for each thread which are created before. All the
2268 * threads are made to wait on sema which is cancel point for thread.
2270 while(threadCreated == FALSE)
2273 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2275 /* mt020.201 - Addition for destroying thread attribute object attr */
2276 pthread_attr_destroy(&attr);
2281 #ifdef SS_THR_REG_MAP
2282 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2285 #endif /* SS_THR_REG_MAP */
2286 #ifdef SS_MEM_WL_DEBUG
2287 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2290 /* mt020.201 - Addition for destroying thread attribute object attr */
2291 pthread_attr_destroy(&attr);
2300 * Fun: Deinitialize timer table
2302 * Desc: This function reverses the initialization performed in
2313 PUBLIC Void ssdDeinitTmr
2318 PUBLIC Void ssdDeinitTmr()
2321 #ifdef SS_MULTICORE_SUPPORT
2324 #endif /* SS_MULTICORE_SUPPORT */
2328 #ifdef SS_MULTICORE_SUPPORT
2329 ret = SLock(&osCp.sTskTblLock);
2333 #if (ERRCLASS & ERRCLS_DEBUG)
2334 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2335 "Could not lock system task table");
2339 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2340 /* clean up the system task entry */
2344 SDestroyLock(&sTsk->lock);
2345 ssDestroyDmndQ(&sTsk->dQ);
2348 /* make this entry available in the system task table */
2349 sTsk->nxt = osCp.nxtSTskEntry;
2350 osCp.nxtSTskEntry = 0;
2354 /* unlock the system task table */
2355 SUnlock(&osCp.sTskTblLock);
2357 #endif /* SS_MULTICORE_SUPPORT */
2358 /* mt008.301: Terminate the timer thread on exit */
2359 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2369 * Desc: Pre-tst() initialization.
2379 PUBLIC S16 ssdInitLog
2384 PUBLIC S16 ssdInitLog()
2387 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2391 pthread_attr_t attr;
2394 #endif /* CONSTDIO */
2399 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2405 osCp.dep.conInFp = (FILE *) stdin;
2406 osCp.dep.conOutFp = (FILE *) stdout;
2407 /* added compile time flag CONRD: mt017.21 */
2411 /* disable canonical input processing */
2412 fd = fileno(osCp.dep.conInFp);
2413 if ((tcgetattr(fd, &tio)) != 0)
2415 printf("Error: disable canonical input processing\n");
2419 tio.c_lflag &= ~ICANON;
2420 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2421 tio.c_cc[VTIME] = 0;
2422 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2424 printf("Error: while tcsetattr() processing\n");
2428 #endif /* CONSTDIO */
2431 /* set up the input fd to block when no data is available */
2432 fd = fileno(osCp.dep.conInFp);
2433 flags = fcntl(fd, F_GETFL, &flags);
2434 flags &= ~O_NONBLOCK;
2435 if (fcntl(fd, F_SETFL, flags) == -1)
2437 printf("Error: while fcntl processing\n");
2442 /* create the console handler thread */
2443 pthread_attr_init(&attr);
2444 /* mt021.201 - Addition to set stack size */
2445 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2446 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2447 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2450 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2452 /* mt020.201 - Addition for destroying thread attribute object attr */
2453 pthread_attr_destroy(&attr);
2455 printf("Error: Logging Thread creation failed \n");
2459 /* mt020.201 - Addition for destroying thread attribute object attr */
2460 pthread_attr_destroy(&attr);
2474 * Desc: This function reverses the initialization performed in
2484 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2486 PUBLIC Void ssdDeinitLog
2491 PUBLIC Void ssdDeinitLog()
2494 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2498 /* mt008.301: Terminate the console reader on exit */
2499 while(pthread_cancel(osCp.dep.conHdlrTID));
2505 /* mt001.301 : Additions */
2510 PUBLIC S16 ssdInitWatchDog
2515 PUBLIC S16 ssdInitWatchDog(port)
2520 Txt prntBuf[PRNTSZE];
2523 #ifdef SS_WATCHDOG_IPV6
2524 struct sockaddr_in6 tmpaddr;
2526 struct sockaddr_in tmpaddr;
2527 #endif /* SS_WATCHDOG_IPV6 */
2528 #ifdef SS_MULTIPLE_PROCS
2529 ProcId procId = SS_WD_WDPROC;
2530 if (SAddProcIdLst(1, &procId) != ROK)
2534 #endif /* SS_MULTIPLE_PROCS */
2536 TRC0(ssdInitWatchDog);
2538 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2540 /* Create a watch dog system task */
2541 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2543 /* Create a watch dog reveiver system task */
2544 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2546 /* Register and attach watch dog TAPA task */
2547 #ifdef SS_MULTIPLE_PROCS
2548 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2549 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2551 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2552 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2553 #endif /* SS_MULTIPLE_PROCS */
2554 /* Register and attach watch dog receiver TAPA task */
2555 #ifdef SS_MULTIPLE_PROCS
2556 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2557 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2559 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2560 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2561 #endif /* SS_MULTIPLE_PROCS */
2563 #ifndef SS_MULTIPLE_PROCS
2564 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2565 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2567 osCp.wdCp.watchDgPst.srcProcId = procId;
2568 osCp.wdCp.watchDgPst.dstProcId = procId;
2569 #endif /* SS_MULTIPLE_PROCS */
2571 /* Initialise the pst structure */
2572 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2573 /* Initialize the watch dog timer resolution default is 1 sec */
2575 cmInitTimers(osCp.wdCp.watchDgTmr, (U8)1);
2576 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2577 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2578 for(idx = 0; idx < 1; idx++)
2580 osCp.wdCp.watchDgTs[idx].first = NULLP;
2581 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2583 #ifdef SS_MULTIPLE_PROCS
2584 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2586 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2587 #endif /* SS_MULTIPLE_PROCS */
2589 /* Create the watch dog receiver socket */
2590 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2591 if(osCp.wdCp.globWd.sock == -1)
2593 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2597 #ifdef SS_WATCHDOG_IPV6
2598 tmpaddr.sin6_len = sizeof(tmpadDr);
2599 tmpaddr.sin6_family = AF_INET6;
2600 tmpaddr.sin6_addr = in6addr_any;
2601 tmpaddr.sin6_port = htons(port);
2603 tmpaddr.sin_family = AF_INET;
2604 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2605 tmpaddr.sin_port = htons(port);
2606 #endif /* SS_WATCHDOG_IPV6 */
2608 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2611 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2615 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2619 #ifndef SS_MULTIPLE_PROCS
2620 pst.srcProcId = SFndProcId();
2621 pst.dstProcId = SFndProcId();
2623 pst.srcProcId = procId;
2624 pst.dstProcId = procId;
2625 #endif /* SS_MULTIPLE_PROCS */
2626 pst.event = EVTSSHRTBTREQ;
2627 ssdInitWatchDgPst(&pst);
2628 SPstTsk(&pst, mBuf);
2634 PUBLIC S16 ssdInitWatchDgPst
2639 PUBLIC S16 ssdInitWatchDgPst(pst)
2643 TRC1(ssInitWatchDgPst);
2645 pst->selector = SS_LOOSE_COUPLING;
2647 pst->region = DFLT_REGION; /* region */
2648 pst->pool = DFLT_POOL; /* pool */
2650 pst->prior = PRIOR0; /* priority */
2651 pst->route = RTESPEC; /* route */
2653 pst->dstEnt = ENTHB; /* destination entity */
2655 pst->srcEnt = ENTDW; /* source entity */
2661 #ifdef SS_MULTIPLE_PROCS
2663 PUBLIC S16 ssdWatchDgActvTmr
2670 PUBLIC S16 ssdWatchDgActvTmr(proc, ent, inst)
2674 PUBLIC S16 ssdWatchDgActvTmr
2679 PUBLIC S16 ssdWatchDgActvTmr()
2681 #endif /* SS_MULTIPLE_PROCS */
2683 TRC3(ssWatchDgActvTmr);
2685 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2691 PUBLIC Void ssdWatchDgTmrEvt
2693 PTR cb, /* control block */
2694 S16 event /* timer number */
2697 PUBLIC Void ssdWatchDgTmrEvt(cb, event)
2698 PTR cb; /* control block */
2699 S16 event; /* timer number */
2702 /* mt003.301 Fixed warings */
2706 Txt prntBuf[PRNTSZE];
2710 TRC2(ssWatchDgTmrEvt);
2716 SPrint("Timer Heartbeat Request Expired");
2718 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2723 SLock(&osCp.wdCp.wdLock);
2724 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2726 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2728 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2730 if(osCp.wdCp.globWd.callback != 0)
2732 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2736 SUnlock(&osCp.wdCp.wdLock);
2738 if(!osCp.wdCp.globWd.watchdogStop)
2740 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2741 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2752 PUBLIC Void ssdStartWatchDgTmr
2759 PUBLIC Void ssdStartWatchDgTmr(cb, event, wait)
2769 Txt prntBuf[PRNTSZE];
2773 TRC2(ssStartWatchDgTmr)
2774 /* mt003.301 Modifications */
2777 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2778 if(event == SS_TMR_HRTBT)
2780 SPrint("\nSTART SS_TMR_HRTBT");
2787 SLock(&osCp.wdCp.wdLock);
2788 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2790 osCp.wdCp.globWd.wdsta[i].status = 0;
2792 SUnlock(&osCp.wdCp.wdLock);
2794 arg.tq = osCp.wdCp.watchDgTs;
2795 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2796 arg.timers = osCp.wdCp.watchDgTmr;
2797 arg.cb = (PTR)NULLP;
2799 arg.wait = osCp.wdCp.globWd.timeout = wait;
2808 PUBLIC Void ssdStopWatchDgTmr
2814 PUBLIC Void ssdStopWatchDgTmr(cb, event)
2822 Txt prntBuf[PRNTSZE];
2826 TRC2(ssStopWatchDgTmr)
2827 /* mt003.301 Modifications */
2830 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2831 if(event == SS_TMR_HRTBT)
2833 SPrint("STOP SS_TMR_HRTBT");
2837 SLock(&osCp.wdCp.wdLock);
2838 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2840 osCp.wdCp.globWd.wdsta[i].status = 0;
2842 SUnlock(&osCp.wdCp.wdLock);
2845 arg.tq = osCp.wdCp.watchDgTs;
2846 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2847 arg.timers = osCp.wdCp.watchDgTmr;
2848 arg.cb = (PTR)NULLP;
2859 PUBLIC S16 ssdSndHrtBtMsg
2865 PUBLIC S16 ssdSndHrtBtMsg(restart, type)
2873 Txt prntBuf[PRNTSZE];
2875 struct sockaddr_in tmpaddr;
2876 char hbMsg[SS_WD_HB_MSG_SIZE];
2880 TRC2(ssdSndHrtBtReq)
2884 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2888 /* Pack the message */
2889 strcpy(hbMsg, "<HB>REQ</HB>");
2891 /* Send the heartbeat messages to all the configured nodes */
2892 SLock(&osCp.wdCp.wdLock);
2893 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2895 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2900 /* Identify the destination node */
2901 #ifdef SS_WATCHDOG_IPV6
2902 tmpaddr.sin6_len = sizeof(tmpaddr);
2903 tmpaddr.sin6_family = AF_INET6;
2904 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2905 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2907 tmpaddr.sin_family = AF_INET;
2908 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2909 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2910 #endif /* SS_WATCHDOG_IPV6 */
2912 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2916 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2917 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2924 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2929 SUnlock(&osCp.wdCp.wdLock);
2934 #endif /* SS_WATCHDOG */
2938 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2944 * Desc: This function gets command line options.
2954 PRIVATE Void mtGetOpts
2959 PRIVATE Void mtGetOpts()
2967 FILE *memOpt; /* memory options file pointer */
2970 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2976 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2978 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2984 #ifdef SS_LOCKLESS_MEMORY
3000 osCp.dep.fileOutFp = (FILE *)NULLP;
3002 /* initialize memOpt */
3003 memOpt = (FILE *) NULLP;
3010 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
3015 /* mt001.301 : Additions */
3016 #ifdef SS_MEM_LEAK_STS
3018 cmMemOpenMemLkFile(msOptArg);
3022 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3025 fileBasedMemCfg = TRUE;
3026 memOpt = fopen(msOptArg, "r");
3028 /* if file does not exist or could not be opened then use the
3029 * default memory configuration as defined in mt_ss.h
3031 if (memOpt == (FILE *) NULLP)
3033 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3034 be opened, using default mem configuration\n", msOptArg);
3039 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3041 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3047 case 0: /*** INPUT: Number of regions ***/
3048 sscanf(line, "%ld", (long *) &numReg);
3049 mtMemoCfg.numRegions = numReg;
3050 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3052 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3058 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3059 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3060 if(numBkts > MT_MAX_BKTS)
3062 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3066 if(numPools > SS_MAX_POOLS_PER_REG)
3068 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3073 * Delay updation from local variable to global
3074 * structure of number of regions and heap data to
3075 * counter error conditions present above.
3077 for(idx = 0; idx < cfgNumRegs; idx++)
3079 mtMemoCfg.region[idx].numBkts = numBkts;
3080 cfgRegInfo[idx].region = idx;
3081 cfgRegInfo[idx].numPools = numPools;
3083 * Initialize the pool info as static type with size zero
3085 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3087 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3088 cfgRegInfo[idx].pools[poolIdx].size = 0;
3093 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3094 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3096 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3098 if(bktIdx >= numBkts)
3100 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3105 mtBktInfo[bktIdx].blkSize = bktSz;
3107 if(bktUpdtCnt == numBkts)
3109 i++; /*done reading bkt info, start reading individual region info*/
3113 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3114 sscanf(line,"%ld",(long *) ®Id);
3115 if(regId >= mtMemoCfg.numRegions)
3117 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3118 #ifndef XEON_SPECIFIC_CHANGES
3123 mtMemoCfg.region[regId].regionId = regId;
3126 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3127 if(bktUpdtCnt < numBkts)
3129 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3130 if(bktIdx >= numBkts)
3132 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3137 if(bktIdx < MT_MAX_BKTS)
3139 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3140 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3141 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3142 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3145 if(bktUpdtCnt == numBkts)
3152 case 5: /* INPUT: Heapsize ***/
3153 sscanf(line, "%ld", (long *) &heapSz);
3154 mtMemoCfg.region[regId].heapsize = heapSz;
3156 if(regUpdtCnt != mtMemoCfg.numRegions)
3165 #ifdef SS_LOCKLESS_MEMORY
3167 sscanf(line, "%ld", (long *) &numBkts);
3168 mtGlobMemoCfg.numBkts = numBkts;
3169 #ifndef XEON_SPECIFIC_CHANGES
3170 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3173 #ifdef XEON_SPECIFIC_CHANGES
3174 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3175 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3176 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3178 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3181 mtDynMemoCfg.region[idx].regionId = idx;
3182 mtDynMemoCfg.region[idx].numBkts = numBkts;
3190 if(bktUpdtCnt < numBkts)
3192 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3193 (long *) &bktSz, (long *) &bktNum,
3194 (long *) &bktSetSize, (long *) &bktRelThr,
3195 (long *) &bktAqurThr);
3196 /* Klock work fix ccpu00148484 */
3197 if(bktIdx < SS_MAX_POOLS_PER_REG)
3199 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3200 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3201 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3202 #ifdef XEON_SPECIFIC_CHANGES
3203 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3204 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3205 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3207 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3209 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3215 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3217 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3218 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3219 #ifdef XEON_SPECIFIC_CHANGES
3220 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3221 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3222 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3228 #ifdef XEON_SPECIFIC_CHANGES
3229 if(bktUpdtCnt == numBkts)
3235 case 8: /* INPUT: Global Heapsize ***/
3236 sscanf(line, "%ld", (long *) &heapSz);
3237 mtGlobMemoCfg.heapSize = heapSz;
3238 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3246 memConfigured = FALSE;
3250 memConfigured = TRUE;
3258 /* mt028.201: modification: multiple procs support related changes */
3259 #ifndef SS_MULTIPLE_PROCS
3262 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3264 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3267 #else /* SS_MULTIPLE_PROCS */
3271 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3273 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3275 SAddProcIdLst(1, &procId);
3278 #endif /* SS_MULTIPLE_PROCS */
3282 osCp.configFilePath = msOptArg;
3306 * Desc: Get options from command line
3308 * Ret: option - success
3310 * EOF - end of options
3312 * Notes: Handles command lines like the following
3315 * then command line should look like this...
3316 * -a foo -b foo1 -c -d foo
3320 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3325 * nloops = atoi(msArgv[msOptInd]);
3328 * state1 = atoi(msArgv[msOptInd]);
3341 int argc, /* argument count */
3342 char **argv, /* argument value */
3343 char *opts /* options */
3346 PUBLIC S16 SGetOpt(argc, argv, opts)
3347 int argc; /* argument count */
3348 char **argv; /* argument value */
3349 char *opts; /* options */
3352 /* mt020.201 - Removed for no command line */
3361 /* mt020.201 - Addition for no command line */
3373 /*mt013.301 : Changes as per coding standards*/
3374 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3380 if (!strcmp(argv[msOptInd], "--"))
3385 else if (argv[msOptInd][0] != '-')
3393 c = argv[msOptInd][sp];
3394 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3396 if (argv[msOptInd][++sp] == '\0')
3407 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3410 if (++msOptInd >= (S16) argc)
3415 else msOptArg = argv[msOptInd++];
3422 if (argv[msOptInd][++sp] == '\0')
3434 #endif /* NOCMDLINE */
3442 * Desc: This function starts system services execution; the
3443 * permanent tasks are started and the system enters a
3454 PUBLIC Void ssdStart
3459 PUBLIC Void ssdStart()
3468 /* mt025.201 - Modification for adding lock to timer handler */
3469 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3471 sem_post(&osCp.dep.ssStarted);
3480 * indirect interface functions to system services service user
3486 * Fun: ssdAttachTTsk
3488 * Desc: This function sends the initial tick message to a TAPA
3489 * task if the task is a permanent task.
3499 PUBLIC S16 ssdAttachTTsk
3501 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3504 PUBLIC S16 ssdAttachTTsk(tTsk)
3505 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3513 TRC0(ssdAttachTTsk);
3516 if (tTsk->tskType == SS_TSK_PERMANENT)
3518 /* Send a permanent tick message to this task, to start
3521 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3524 #if (ERRCLASS & ERRCLS_DEBUG)
3525 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3530 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3531 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3533 /* set up post structure */
3534 /* mt028.201: modification: multiple procs support related changes */
3535 #ifndef SS_MULTIPLE_PROCS
3536 mInfo->pst.dstProcId = SFndProcId();
3537 mInfo->pst.srcProcId = SFndProcId();
3538 #else /* SS_MULTIPLE_PROCS */
3539 mInfo->pst.dstProcId = tTsk->proc;
3540 mInfo->pst.srcProcId = tTsk->proc;
3541 #endif /* SS_MULTIPLE_PROCS */
3542 mInfo->pst.selector = SEL_LC_NEW;
3543 mInfo->pst.region = DFLT_REGION;
3544 mInfo->pst.pool = DFLT_POOL;
3545 mInfo->pst.prior = PRIOR3;
3546 mInfo->pst.route = RTESPEC;
3547 mInfo->pst.event = 0;
3548 mInfo->pst.dstEnt = tTsk->ent;
3549 mInfo->pst.dstInst = tTsk->inst;
3550 mInfo->pst.srcEnt = tTsk->ent;
3551 mInfo->pst.srcInst = tTsk->inst;
3553 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3554 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3560 #if (ERRCLASS & ERRCLS_DEBUG)
3561 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3562 "Could not write to demand queue");
3575 * Fun: ssdDetachTTsk
3577 * Desc: Does nothing.
3587 PUBLIC S16 ssdDetachTTsk
3589 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3592 PUBLIC S16 ssdDetachTTsk(tTsk)
3593 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3596 TRC0(ssdDetachTTsk);
3605 * Fun: ssdCreateSTsk
3607 * Desc: This function creates a system task. A thread is started
3608 * on the system task handler function defined later.
3618 PUBLIC S16 ssdCreateSTsk
3620 SsSTskEntry *sTsk /* pointer to system task entry */
3623 PUBLIC S16 ssdCreateSTsk(sTsk)
3624 SsSTskEntry *sTsk; /* pointer to system task entry */
3627 pthread_attr_t attr;
3628 /* struct sched_param param_sched;*/
3630 #ifdef SS_THR_REG_MAP
3631 U32 threadCreated = FALSE;
3634 TRC0(ssdCreateSTsk);
3637 #ifdef SS_SINGLE_THREADED
3638 /* mt001.301 : Additions */
3640 #ifdef SS_MULTICORE_SUPPORT
3641 if (osCp.numSTsks > 1)
3643 if (osCp.numSTsks > 0)
3644 #endif /* SS_MULTICORE_SUPPORT */
3646 #ifdef SS_MULTICORE_SUPPORT
3647 if (osCp.numSTsks > 3)
3649 if (osCp.numSTsks > 2)
3650 #endif /* SS_MULTICORE_SUPPORT */
3651 #endif /* SS_WATCHDOG */
3658 /* set the current executing entity and instance IDs to
3659 * 'not configured'. create the lock to access them.
3661 sTsk->dep.ent = ENTNC;
3662 sTsk->dep.inst = INSTNC;
3665 /* create the thread */
3666 pthread_attr_init(&attr);
3667 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3669 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3670 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3671 if (sTsk->tskPrior == 0)
3673 printf("Creating RT thread #######################\n");
3674 #ifdef SS_THR_REG_MAP
3675 /* When the thread is created, we check for the memory mapping table if
3676 * threadId can be placed in thread memory map table. If it is not able to place
3677 * threadId is stored in tmporary array. Once thread is created successful,
3678 * thread_cancel is sent for each thread which are created before. All the
3679 * threads are made to wait on sema which is cancel point for thread.
3681 while(threadCreated == FALSE)
3684 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlrT2kL2, (Ptr)sTsk)) != 0)
3687 pthread_attr_destroy(&attr);
3689 #if (ERRCLASS & ERRCLS_DEBUG)
3690 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3695 #ifdef SS_THR_REG_MAP
3696 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3704 #ifdef SS_THR_REG_MAP
3705 /* When the thread is created, we check for the memory mapping table if
3706 * threadId can be placed in thread memory map table. If it is not able to place
3707 * threadId is stored in tmporary array. Once thread is created successful,
3708 * thread_cancel is sent for each thread which are created before. All the
3709 * threads are made to wait on sema which is cancel point for thread.
3711 while(threadCreated == FALSE)
3714 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk)) != 0)
3717 /* mt020.201 - Addition for destroying thread attribute object attr */
3718 pthread_attr_destroy(&attr);
3720 #if (ERRCLASS & ERRCLS_DEBUG)
3721 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3726 #ifdef SS_THR_REG_MAP
3727 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3734 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3735 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3737 static U32 stLwpId = 3;
3738 sTsk->dep.lwpId = ++stLwpId;
3740 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3742 /* mt020.201 - Addition for destroying thread attribute object attr */
3743 pthread_attr_destroy(&attr);
3750 PUBLIC int SCreatePThread
3753 pthread_attr_t* attr,
3754 void *(*start_routine) (void *),
3758 PUBLIC int SCreatePThread(tid, attr, start_routine, arg)
3760 pthread_attr_t* attr;
3761 void *(*start_routine) (void *);
3766 #ifdef SS_THR_REG_MAP
3767 U32 threadCreated = FALSE;
3770 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3771 /* Klock work fix ccpu00148484 */
3772 if(threadArg == NULLP)
3776 threadArg->argument = arg;
3777 threadArg->start_routine = start_routine;
3779 TRC0(SCreatePThread);
3781 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3783 #ifdef SS_THR_REG_MAP
3784 /* When the thread is created, we check for the memory mapping table if
3785 * threadId can be placed in thread memory map table. If it is not able to place
3786 * threadId is stored in tmporary array. Once thread is created successful,
3787 * thread_cancel is sent for each thread which are created before. All the
3788 * threads are made to wait on sema which is cancel point for thread.
3790 while(threadCreated == FALSE)
3793 /*pthreadCreateHdlr */
3794 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3799 #ifdef SS_THR_REG_MAP
3800 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3811 * Fun: Set Pthread Attributes
3813 * Desc: This function is used to set various explicit
3814 * pthread attributes like, priority scheduling,etc
3825 PRIVATE S16 ssdSetPthreadAttr
3828 pthread_attr_t *attr
3831 PRIVATE S16 ssdSetPthreadAttr(sTsk, attr)
3833 pthread_attr_t *attr
3836 struct sched_param param;
3838 TRC0 (ssdSetPthreadAttr)
3840 SMemSet(¶m, 0, sizeof(param));
3842 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3843 param.sched_priority = 100 - 1 - tskPrior;
3845 param.sched_priority = 100 - 10 - tskPrior;
3848 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3849 /* TODO:: This can be avoided by reducing the priority
3850 * of iccserv thread in l1_master.sh*/
3852 if (clusterMode == RADIO_CLUSTER_MODE)
3854 if(tskPrior == PRIOR1)
3856 param.sched_priority = 91;
3863 printf("Set priority %u\n", param.sched_priority);
3865 /* Set Scheduler to explicit, without this non of the below
3866 pthread attr works */
3867 #ifdef TENB_RTLIN_CHANGES
3868 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3871 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3872 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3873 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3874 #ifdef TENB_RTLIN_CHANGES
3875 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3877 pthread_attr_setschedparam(attr, ¶m);
3881 } /* ssdSetPthreadAttr */
3883 /************* multi-core support **************/
3884 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3885 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3889 * Fun: Get the current core/cpu affinity for a thread/lwp
3891 * Desc: This function is used to get the current processor/core
3892 * affinity for a a system task (thread/lwp). It sets the
3893 * affinity based on the mode supplied by the caller.
3896 * RFAILED - failed, general (optional)
3904 PUBLIC S16 ssdGetAffinity
3906 SSTskId *tskId, /* filled in with system task ID */
3907 U32 *coreId /* the core/processor id to which the affinity is set */
3910 PUBLIC S16 ssdGetAffinity(tskId, coreId)
3911 SSTskId *tskId; /* filled in with system task ID */
3912 U32 *coreId; /* the core/processor id to which the affinity is set */
3923 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3929 TRC0(ssdGetAffinity);
3931 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3933 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3935 tId = osCp.sTskTbl[tskInd].dep.tId;
3940 /* if tskId is not found in the tskTbl */
3941 if (tskInd == SS_MAX_STSKS)
3943 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3948 /* initialize the cpu mask */
3951 /* set thread affinity for linux */
3952 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3954 #if (ERRCLASS & ERRCLS_DEBUG)
3955 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3958 } /* end if pthread_setaffinity fails */
3960 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3962 if (CPU_ISSET (cpuInd, & cpuSet))
3971 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3973 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3975 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3980 /* if tskId is not found in the tskTbl */
3981 if (tskInd == SS_MAX_STSKS)
3983 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3987 /* set thread affinity for Solaris */
3988 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3990 #if (ERRCLASS & ERRCLS_DEBUG)
3991 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3994 } /* end if processor_bind fails */
3997 #endif /* SS_LINUX */
4001 } /* ssdGetAffinity */
4006 * Fun: Set the core/cpu affinity for a thread/lwp
4008 * Desc: This function is used to set processor/core affinity for a
4009 * a system task (thread/lwp). It sets the affinity based on the
4010 * mode supplied by the caller.
4013 * RFAILED - failed, general (optional)
4021 PUBLIC S16 ssdSetAffinity
4023 SSTskId *tskId, /* filled in with system task ID */
4024 U32 coreId /* the core/processor id to which the affinity has to be set */
4027 PUBLIC S16 ssdSetAffinity(tskId, coreId)
4028 SSTskId *tskId; /* filled in with system task ID */
4029 U32 coreId; /* the core/processor id to which the affinity has to be set */
4038 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4045 TRC0(ssdSetAffinity)
4048 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4050 /* Here tskId can not be used as index as the task may be terminated if
4051 there is a TERM even for that tsk, thus breaking the task Id numbering
4053 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4055 tId = osCp.sTskTbl[tskInd].dep.tId;
4060 /* if tskId is not found in the tskTbl */
4061 if (tskInd == SS_MAX_STSKS)
4063 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4067 /* initialize the cpu mask */
4070 /* set the cpu mask */
4071 CPU_SET(coreId, &cpuSet);
4073 /* set thread affinity for linux */
4074 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4076 #if (ERRCLASS & ERRCLS_DEBUG)
4077 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4080 } /* end if pthread_setaffinity fails */
4084 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4086 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4087 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4089 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4094 /* if tskId is not found in the tskTbl */
4095 if (tskInd == SS_MAX_STSKS)
4097 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4101 /* set thread affinity for Solaris */
4102 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4104 #if (ERRCLASS & ERRCLS_DEBUG)
4105 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4108 } /* end if processor_bind fails */
4111 #endif /* SS_LINUX */
4113 } /* ssdSetAffinity */
4115 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4116 /************ end multi-core support *************/
4121 * Fun: ssdDestroySTsk
4123 * Desc: This function destroys a system task. A terminate
4124 * event message is sent to the thread function.
4134 PUBLIC S16 ssdDestroySTsk
4136 SsSTskEntry *sTsk /* pointer to system task entry */
4139 PUBLIC S16 ssdDestroySTsk(sTsk)
4140 SsSTskEntry *sTsk; /* pointer to system task entry */
4147 TRC0(ssdDestroySTsk);
4150 /* we send a message to this system task to tell it to die */
4151 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4154 #if (ERRCLASS & ERRCLASS_DEBUG)
4155 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4161 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4162 mInfo->eventInfo.event = SS_EVNT_TERM;
4164 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4168 #if (ERRCLASS & ERRCLASS_DEBUG)
4169 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4170 "Could not write to demand queue");
4180 /* mt023.201 - Added SThreadYield function to yield CPU
4184 * Desc: This function defers thread execution to any other ready
4196 PUBLIC S16 SThreadYield
4201 PUBLIC S16 SThreadYield()
4207 /* mt024.201 - seperated Linux and other UNIX implementations
4213 /* Set sleep value to 0 to yield CPU */
4217 RETVALUE(select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4219 #else /* other UNICes */
4221 RETVALUE(sleep(0) == 0 ? ROK : RFAILED);
4223 #endif /* SS_LINUX */
4230 * Fun: Register timer
4232 * Desc: This function is used to register a timer
4233 * function for the service user. System services
4234 * will invoke the timer activation function
4235 * passed to it at the specified intervals.
4239 * Notes: Timing is handled by the common timers. The
4240 * ticks are handled by a thread that uses
4241 * nanosleep() and thus timing precision will not
4248 PUBLIC S16 ssdRegTmr
4250 SsTmrEntry *tmr /* pointer to timer entry */
4253 PUBLIC S16 ssdRegTmr(tmr)
4254 SsTmrEntry *tmr; /* pointer to timer entry */
4263 /* initialize common timers */
4264 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4267 /* start the timer */
4268 arg.tq = osCp.dep.tmrTq;
4269 arg.tqCp = &osCp.dep.tmrTqCp;
4270 arg.timers = tmr->dep.timers;
4275 arg.max = TMR_DEF_MAX;
4276 arg.wait = tmr->interval;
4286 * Fun: Deregister timer
4288 * Desc: This function is used to deregister a timer function.
4298 PUBLIC S16 ssdDeregTmr
4300 SsTmrEntry *tmr /* pointer to timer entry */
4303 PUBLIC S16 ssdDeregTmr(tmr)
4304 SsTmrEntry *tmr; /* pointer to timer entry */
4313 /* stop the timer */
4314 arg.tq = osCp.dep.tmrTq;
4315 arg.tqCp = &osCp.dep.tmrTqCp;
4316 arg.timers = tmr->dep.timers;
4321 arg.max = TMR_DEF_MAX;
4322 arg.wait = tmr->interval;
4332 * Fun: Critical error
4334 * Desc: This function is called when a critical error occurs.
4346 Seq seq, /* sequence number */
4347 Reason reason /* reset reason */
4350 PUBLIC S16 ssdError(seq, reason)
4351 Seq seq; /* sequence number */
4352 Reason reason; /* reset reason */
4363 /* get calling task ID */
4364 tId = pthread_self();
4367 /* set up the message to display */
4368 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4369 "reason = %d\n\n", (U8)tId, seq, reason);
4373 /* delete all system tasks */
4374 for (i = 0; i < SS_MAX_STSKS; i++)
4376 if (osCp.sTskTbl[i].used
4377 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4379 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4385 pthread_exit(NULLP);
4388 /* won't reach here */
4397 * Desc: This function is called to log an error.
4407 PUBLIC Void ssdLogError
4409 Ent ent, /* Calling layer's entity id */
4410 Inst inst, /* Calling layer's instance id */
4411 ProcId procId, /* Calling layer's processor id */
4412 Txt *file, /* file name where error occured */
4413 S32 line, /* line in file where error occured */
4414 ErrCls errCls, /* error class */
4415 ErrCode errCode, /* layer unique error code */
4416 ErrVal errVal, /* error value */
4417 Txt *errDesc /* description of error */
4420 PUBLIC Void ssdLogError(ent, inst, procId, file, line,
4421 errCls, errCode, errVal, errDesc)
4422 Ent ent; /* Calling layer's entity id */
4423 Inst inst; /* Calling layer's instance id */
4424 ProcId procId; /* Calling layer's processor id */
4425 Txt *file; /* file name where error occured */
4426 S32 line; /* line in file where error occured */
4427 ErrCls errCls; /* error class */
4428 ErrCode errCode; /* layer unique error code */
4429 ErrVal errVal; /* error value */
4430 Txt *errDesc; /* description of error */
4444 /* get calling task ID */
4446 tId = pthread_self();
4452 case ERRCLS_ADD_RES:
4453 errClsMsg = "ERRCLS_ADD_RES";
4456 case ERRCLS_INT_PAR:
4457 errClsMsg = "ERRCLS_INT_PAR";
4461 errClsMsg = "ERRCLS_DEBUG";
4464 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4466 errClsMsg = "ERRCLS_FTHA";
4470 errClsMsg = "INVALID ERROR CLASS!";
4475 /*mt009.301 Fixed 64BIT compilation warnings*/
4478 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4479 "file: %s line: %03d errcode: %05d errcls: %s\n"
4480 "errval: %05d errdesc: %s\n",
4481 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4484 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4485 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4486 "errval: %05ld errdesc: %s\n",
4487 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4489 SDisplay(0, errBuf);
4490 /* mt001.301 : Additions */
4491 #ifdef SS_LOGGER_SUPPORT
4493 #endif /* SS_LOGGER_SUPPORT */
4497 /* debug errors halt the system */
4498 if (errCls == ERRCLS_DEBUG)
4500 /* mt001.301 : Additions */
4501 #ifdef SS_LOGGER_SUPPORT
4503 #endif /* SS_LOGGER_SUPPORT */
4504 /* delete all system tasks */
4505 for (i = 0; i < SS_MAX_STSKS; i++)
4507 if (osCp.sTskTbl[i].used
4508 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4510 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4516 pthread_exit(NULLP);
4528 * Fun: Register driver task
4530 * Desc: This function is called to register the handlers for a
4541 PUBLIC S16 ssdRegDrvrTsk
4543 SsDrvrTskEntry *drvrTsk /* driver task entry */
4546 PUBLIC S16 ssdRegDrvrTsk(drvrTsk)
4547 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4550 TRC0(ssdRegDrvrTsk);
4555 /* mt001.30 : Additions */
4558 * Fun: Deregister driver task
4560 * Desc: This function is called to deregister the handlers for a
4571 PUBLIC S16 ssdDeregDrvrTsk
4573 SsDrvrTskEntry *drvrTsk /* driver task entry */
4576 PUBLIC S16 ssdDeregDrvrTsk(drvrTsk)
4577 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4580 TRC0(ssdDeregDrvrTsk);
4591 * mt003.301 Additions - SDeRegTTsk fix
4593 #ifdef SS_MULTIPLE_PROCS
4595 PUBLIC S16 ssdProcTTskTerm
4602 PUBLIC S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4607 #else /*SS_MULTIPLE_PROCS*/
4609 PUBLIC S16 ssdProcTTskTerm
4615 PUBLIC S16 ssdProcTTskTerm(tTsk, idx)
4619 #endif /*SS_MULTIPLE_PROCS*/
4621 #ifdef SS_MULTIPLE_PROCS
4630 TRC0(ssdProcTTskTerm);
4635 /* We check the sTsk element; if it is not NULLP, the
4636 * task is attached. So we have to detach it before
4637 * deregistering the task.
4639 ret = SLock(&osCp.sTskTblLock);
4642 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4645 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4648 #if (ERRCLASS & ERRCLS_DEBUG)
4649 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4651 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4653 #if (ERRCLASS & ERRCLS_DEBUG)
4654 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4662 #ifdef SS_MULTIPLE_PROCS
4664 if (tTsk->initTsk != NULLP)
4667 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4670 &(osCp.tTskTbl[idx].xxCb));
4672 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4675 &(osCp.tTskTbl[idx].xxCb));
4676 #endif /* USE_MEMCAL */
4678 #endif /* SS_MULTIPLE_PROCS */
4680 if (tTsk->sTsk != NULLP)
4684 sTsk->dep.ent = ent;
4685 sTsk->dep.inst = inst;
4687 for (n = 0; n < SS_MAX_TTSKS; n++)
4689 if (sTsk->tTsks[n] == idx)
4691 sTsk->tTsks[n] = SS_INVALID_IDX;
4697 /* call the implementation to detach the task */
4698 ssdDetachTTsk(tTsk);
4700 sTsk->dep.ent = ENTNC;
4701 sTsk->dep.inst = INSTNC;
4704 /* Now we empty the entry for this task and update the table
4707 #ifdef SS_MULTIPLE_PROCS
4708 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4709 #else /* SS_MULTIPLE_PROCS */
4710 osCp.tTskIds[ent][inst] = SS_TSKNC;
4711 #endif /* SS_MULTIPLE_PROCS */
4714 #ifdef SS_MULTIPLE_PROCS
4715 tTsk->proc = PROCNC;
4716 #endif /* SS_MULTIPLE_PROCS */
4718 tTsk->inst = INSTNC;
4719 tTsk->tskType = TTUND;
4720 tTsk->initTsk = NULLP;
4721 tTsk->actvTsk = NULLP;
4724 tTsk->nxt = osCp.nxtTTskEntry;
4725 osCp.nxtTTskEntry = idx;
4728 #ifdef SS_MULTIPLE_PROCS
4729 /* mark the control block for this task as invalid */
4730 osCp.tTskTbl[idx].xxCb = NULLP;
4733 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4734 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4736 #if (ERRCLASS & ERRCLS_DEBUG)
4737 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4744 //#ifndef SPLIT_RLC_DL_TASK
4745 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4746 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4747 EXTERN Void ysMtTskHdlr(Void);
4748 EXTERN Void ysMtPollPhyMsg(U8 region);
4749 EXTERN Void ysMtRcvPhyMsg(Void);
4751 PUBLIC Void *mtTskHdlrT2kL2
4753 Ptr tskPtr /* pointer to task entry */
4756 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4757 Ptr tskPtr; /* pointer to task entry */
4763 /* wait for SS to come up */
4764 /* It is required to block on this semaphore before starting actual processing of
4765 the thread becasue the creator of this thread might want to cance it without
4766 doing any processing. When this semaphore is released, means the creator gives
4767 the go ahead for actual processing and we should never come back to this point */
4768 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4777 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4778 * (processes L1 msgs) */
4784 EXTERN Void ysMtTskHdlr(Void);
4785 EXTERN Void YsPhyRecvMsg();
4787 PUBLIC Void *mtTskHdlrT2kL2
4789 Ptr tskPtr /* pointer to task entry */
4792 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4793 Ptr tskPtr; /* pointer to task entry */
4799 /* get out the system task entry from the parameter */
4800 sTsk = (SsSTskEntry *) tskPtr;
4802 /* wait for SS to come up */
4803 /* It is required to block on this semaphore before starting actual processing of
4804 the thread becasue the creator of this thread might want to cance it without
4805 doing any processing. When this semaphore is released, means the creator gives
4806 the go ahead for actual processing and we should never come back to this point */
4807 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4810 #ifndef RGL_SPECIFIC_CHANGES
4818 #ifdef V5GTF_SPECIFIC_CHANGES
4821 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4822 * (processes L1 msgs) */
4824 /* get a message from the demand queue */
4826 #ifdef RLC_MAC_DAT_REQ_RBUF
4827 rgDlDatReqBatchProc();
4830 ret = mtTskHdlMsg(sTsk);
4833 /* exit the for loop here */
4836 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4843 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4847 PUBLIC void *pthreadCreateHdlr
4852 PUBLIC void *pthreadCreateHdlr(pthreadCreateArg)
4857 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4858 /* mt038.201 changed how sem_wait is called */
4859 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4862 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4870 * Desc: This is the system task handler function. It blocks on
4871 * the system task's demand queue. On receiving a message,
4872 * it identifies the target TAPA task, verifies that the
4873 * TAPA task belongs to this system task and if so, calls
4874 * the activation function of that TAPA task with the
4875 * received message. The task activation function or the
4876 * timer activation function may be called.
4878 * Ret: (thread function)
4886 PUBLIC Void *mtTskHdlr
4888 Ptr tskPtr /* pointer to task entry */
4891 PUBLIC Void *mtTskHdlr(tskPtr)
4892 Ptr tskPtr; /* pointer to task entry */
4898 /* get out the system task entry from the parameter */
4899 sTsk = (SsSTskEntry *) tskPtr;
4902 /* wait for SS to come up */
4904 /* mt038.201 changed how sem_wait is called */
4905 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4907 #ifdef XEON_SPECIFIC_CHANGES
4908 printf("\n**********MT Task Handler********\n");
4912 #ifndef ODU_TEST_STUB
4917 /* Wait for a message from the demand queue */
4918 #ifdef SS_CDMNDQ_SUPPORT
4919 ret = ssCDmndQWait(&sTsk->dQ);
4921 ret = ssDmndQWait(&sTsk->dQ);
4926 ret = mtTskHdlMsg(sTsk);
4941 * Desc: This is the system task handler function. It blocks on
4942 * the system task's demand queue. On receiving a message,
4943 * it identifies the target TAPA task, verifies that the
4944 * TAPA task belongs to this system task and if so, calls
4945 * the activation function of that TAPA task with the
4946 * received message. The task activation function or the
4947 * timer activation function may be called.
4949 * Ret: (thread function)
4957 PUBLIC S16 mtTskHdlMsg
4962 PUBLIC S16 mtTskHdlMsg(sTsk)
4976 /* mt028.201: modification: multiple procs support related changes */
4977 #ifndef SS_MULTIPLE_PROCS
4979 PAIFTMRS16 tmrActvFnMt = NULLP;
4981 /* mt015.301 Initialized the timer activation functions with NULLP */
4982 PFS16 tmrActvFn = NULLP;
4984 PAIFTMRS16 tmrActvFn;
4986 #endif /* SS_MULTIPLE_PROCS */
4987 /* mt003.301 Modifications */
4988 #ifdef SS_THREAD_PROFILE
4990 #endif /* SS_THREAD_PROFILE */
4993 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4996 /* nothing to receive */
5000 /* if we can't lock this system task entry, return the message */
5001 ret = SLock(&sTsk->lock);
5005 #if (ERRCLASS & ERRCLS_DEBUG)
5006 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
5007 "Could not lock system task entry");
5017 mBuf2 = mBuf->b_next;
5019 /* find out what kind of message this is */
5020 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5021 #ifdef SS_MEM_WL_DEBUG
5022 mtTskBuffer1 = mBuf2;
5024 mtTskBuffer2 = mBuf2->b_next;
5026 if(mInfo == 0x5050505)
5030 cmAnalyseBtInfo((PTR) mBuf,4);
5032 printf("\n In trouble .... \n");
5034 else if (mInfo == 0x2020202)
5037 cmAnalyseBtInfo((PTR) mBuf,1);
5038 printf("\n In trouble .... \n");
5040 #endif /* SS_MEM_WL_DEBUG */
5041 switch (mInfo->eventInfo.event)
5043 /* this is a termination event, we die */
5045 /* release the message */
5048 /* Unlock the system task entry and lock the system
5049 * task table to clean our entry up.
5051 SUnlock(&sTsk->lock);
5053 ret = SLock(&osCp.sTskTblLock);
5057 #if (ERRCLASS & ERRCLS_DEBUG)
5058 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5059 "Could not lock system task table");
5061 /* what to do here? */
5065 /* clean up the system task entry */
5068 /* mt003.301 Modifications - SDeRegTTsk */
5069 /* sTsk->numTTsks = 0; */
5070 SDestroyLock(&sTsk->lock);
5071 ssDestroyDmndQ(&sTsk->dQ);
5073 /* lock for current executing TAPA task ID */
5075 /* make this entry available in the system task table */
5076 sTsk->nxt = osCp.nxtSTskEntry;
5077 for (i = 0; i < SS_MAX_STSKS; i++)
5079 if (sTsk == &osCp.sTskTbl[i])
5081 osCp.nxtSTskEntry = i;
5088 /* unlock the system task table */
5089 SUnlock(&osCp.sTskTblLock);
5094 /* this is a data message or a permanent task keep-alive message */
5096 case SS_EVNT_PERMTICK:
5097 /* message to a task. find the destination task */
5098 /* mt028.201: modification: multiple procs support related changes */
5099 #ifdef SS_MULTIPLE_PROCS
5100 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5102 if (procIdIdx == SS_INV_PROCID_IDX)
5108 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5109 #else /* SS_MULTIPLE_PROCS */
5110 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5111 #endif /* SS_MULTIPLE_PROCS */
5113 /* verify that it hasn't been deregistered */
5114 if (idx == SS_TSKNC)
5120 /* verify that this system task is still running it */
5121 tTsk = &osCp.tTskTbl[idx];
5122 if (tTsk->sTsk != sTsk)
5128 /* set the current executing TAPA task ID */
5129 sTsk->dep.ent = mInfo->pst.dstEnt;
5130 sTsk->dep.inst = mInfo->pst.dstInst;
5132 /* copy the Pst structure into a local duplicate */
5133 for (i = 0; i < (S16) sizeof(Pst); i++)
5134 *(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
5136 /* Give the message to the task activation function. If
5137 * its a normal data message, we pass it, if this is a
5138 * keep-alive message for a permanent task then we pass
5139 * NULLP in place of the message to the task activation
5142 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5144 #ifndef RGL_SPECIFIC_CHANGES
5145 #ifdef SS_TSKLOG_ENABLE
5146 U32 t = MacGetTick();
5149 /* mt003.301 Modifications */
5150 #if SS_THREAD_PROFILE
5151 tTsk->curEvent = nPst.event;
5153 #endif /* SS_THREAD_PROFILE */
5154 tTsk->actvTsk(&nPst, mBuf);
5155 #ifndef RGL_SPECIFIC_CHANGES
5156 #ifdef SS_TSKLOG_ENABLE
5157 SStopTask(t,PID_SSI_TSK);
5160 #if SS_THREAD_PROFILE
5162 tTsk->curEvtTime = (U32)(et2 - et1);
5163 tTsk->totTime += (U64)tTsk->curEvtTime;
5164 #endif /* SS_THREAD_PROFILE */
5168 #if (ERRCLASS & ERRCLS_DEBUG)
5169 /* this message should only come to a permanent task */
5170 if (tTsk->tskType != SS_TSK_PERMANENT)
5172 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5176 tTsk->actvTsk(&nPst, NULLP);
5178 /* We need to re-send this message back to ourselves so
5179 * the permanent task continues to run.
5181 /* Check if this task got deregistered or detached
5182 * by the activation function; if so, there's nothing
5183 * more to do here, otherwise go ahead.
5186 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5188 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5189 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5193 /* failure here is a real problem */
5196 #if (ERRCLASS & ERRCLS_DEBUG)
5197 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5198 "Could not write to demand queue");
5204 /* unset the current executing TAPA task ID */
5205 sTsk->dep.ent = ENTNC;
5206 sTsk->dep.inst = INSTNC;
5211 /* timer event. find the timer entry */
5212 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5214 /* lock the timer table, coz we're going to peek in it */
5215 ret = SLock(&osCp.tmrTblLock);
5219 #if (ERRCLASS & ERRCLS_DEBUG)
5220 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5221 "Could not lock timer table");
5227 /* Verify that this timer entry is still around and that it
5228 * belongs to our task.
5230 if (osCp.tmrTbl[idx].used == FALSE
5231 /* mt028.201: modification: multiple procs support related changes */
5232 #ifdef SS_MULTIPLE_PROCS
5233 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5234 #endif /* SS_MULTIPLE_PROCS */
5235 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5236 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5238 SUnlock(&osCp.tmrTblLock);
5243 /* mt005.21: addition */
5244 /* set the current executing TAPA task ID */
5245 sTsk->dep.ent = mInfo->pst.dstEnt;
5246 sTsk->dep.inst = mInfo->pst.dstInst;
5248 #ifndef SS_MULTIPLE_PROCS
5250 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5251 tmrActvFnMt = NULLP;
5252 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5254 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5260 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5263 /* unlock the timer table */
5264 SUnlock(&osCp.tmrTblLock);
5266 /* activate the timer function */
5267 /* mt028.201: modification: multiple procs support related changes */
5268 #ifndef SS_MULTIPLE_PROCS
5272 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5273 osCp.tmrTbl[idx].ownerInst);
5281 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5282 osCp.tmrTbl[idx].ownerInst);
5283 #endif /* SS_MULTIPLE_PROCS */
5285 /*mt005.21: addition */
5286 /* unset the current executing TAPA task ID */
5287 sTsk->dep.ent = ENTNC;
5288 sTsk->dep.inst = INSTNC;
5291 /* return the message buffer */
5295 * mt003.301 - SDeRegTTsk fix
5297 case SS_EVNT_TTSK_TERM:
5298 #ifdef SS_MULTIPLE_PROCS
5299 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5301 if (procIdIdx == SS_INV_PROCID_IDX)
5307 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5308 #else /* SS_MULTIPLE_PROCS */
5309 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5310 #endif /* SS_MULTIPLE_PROCS */
5312 /* verify that it hasn't been deregistered */
5313 if (idx == SS_TSKNC)
5319 /* verify that this system task is still running it */
5320 tTsk = &osCp.tTskTbl[idx];
5321 if (tTsk->sTsk != sTsk)
5326 #ifdef SS_MULTIPLE_PROCS
5327 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5329 ssdProcTTskTerm(tTsk, idx);
5335 #if (ERRCLASS & ERRCLS_DEBUG)
5336 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5343 } while (mBuf != NULLP);
5346 /* unlock the system task entry */
5347 SUnlock(&sTsk->lock);
5350 /* yield for other threads */
5351 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5360 * Fun: mtTmrHdlrPublic
5363 PUBLIC Void mtTmrHdlrPublic
5367 PUBLIC Void mtTmrHdlrPublic()
5370 if (SLock(&osCp.tmrTblLock) != ROK)
5372 #if (ERRCLASS & ERRCLS_DEBUG)
5373 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5377 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5378 /* unlock the timer table */
5379 SUnlock(&osCp.tmrTblLock);
5387 * Desc: The timer handler thread function. Counts time
5388 * and invokes the common timer function on each
5391 * Ret: (thread function)
5398 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5400 PRIVATE Void *mtTmrHdlr
5402 void *parm /* unused */
5405 /* mt009.21: addition */
5406 PRIVATE Void *mtTmrHdlr(parm)
5407 void *parm; /* unused */
5410 /*mt004.301-addede new region*/
5411 /* mt010.301 Removed SS_FAP portion and
5412 * enabled oroginal code in function mtTmrHdlr */
5416 U32 i, cnt, oldTicks, newTicks;
5417 struct timeval tv1,tv2;
5418 /* mt038.201 added return */
5420 /* mt039.201 changes for nanosleep */
5421 struct timespec tsN;
5422 PRIVATE U32 err_in_usec;
5424 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5429 /* mt027.201 - Modification for SRegCfgTmr support */
5430 /* check SS_TICKS_SEC */
5431 if (SS_1MS < SS_TICKS_SEC)
5433 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5436 /* mt025.201 - Addition to stop timer handler till task registration is done */
5437 /* wait for SS to come up */
5438 /* mt038.201 changed how sem_wait is called */
5439 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5442 /* mt027.201 - Modification for SRegCfgTmr support */
5443 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5445 ts.tv_nsec = (MT_TICK_CNT * 1000);
5446 /* mt039.201 changes for nanosleep */
5452 if (gettimeofday(&tv1, NULL) == -1)
5454 #if (ERRCLASS & ERRCLS_DEBUG)
5455 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5456 "Error in clock_gettime");
5466 #ifndef STUB_TTI_HANDLING_5GTF
5467 printf("Returning from mtTmrHdlr()\n");
5472 /* mt039.201 changes for nanosleep */
5473 /* sleep for MT_TICK_CNT milli seconds */
5474 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5475 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5477 ts.tv_nsec = tsN.tv_nsec;
5482 if (gettimeofday(&tv2,NULL) == -1)
5484 #if (ERRCLASS & ERRCLS_DEBUG)
5485 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5486 "Error in clock_gettime");
5490 /*mt013.301 : changed check while calculating timer to fix
5491 * diffrence between MTSS time and real unix time
5493 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5495 time_int = (tv2.tv_usec - tv1.tv_usec);
5497 else if (tv2.tv_sec > tv1.tv_sec)
5499 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5501 else /* ts2 < ts1, this will not happen in normal scenario */
5503 /* to make sure cnt = 1 */
5505 time_int = MT_TICK_CNT;
5508 oldTicks = osCp.dep.sysTicks;
5509 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5510 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5511 newTicks = osCp.dep.sysTicks;
5512 tv1.tv_usec = tv2.tv_usec;
5513 tv1.tv_sec = tv2.tv_sec;
5515 cnt = newTicks - oldTicks;
5517 while(err_in_usec >= MT_TICK_CNT)
5520 err_in_usec -= MT_TICK_CNT;
5522 if( cnt >= MT_MAX_TICK_CNT_VAL)
5523 cnt = MT_MIN_TICK_CNT_VAL;
5524 /* call the common timer tick handler */
5525 for (i = 0; i < cnt; i++)
5527 /* mt008.301: cmPrcTmr is guarded with a lock */
5528 /* lock the timer table */
5529 if (SLock(&osCp.tmrTblLock) != ROK)
5531 #if (ERRCLASS & ERRCLS_DEBUG)
5532 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5536 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5537 /* unlock the timer table */
5538 SUnlock(&osCp.tmrTblLock);
5542 /* mt009.21: addition */
5543 RETVALUE( (Void *) NULLP);
5544 /* will not reach here */
5552 * Desc: Process timer event. Called from the common timer
5553 * code when a timeout occurs.
5563 PUBLIC Void mtTimeout
5565 PTR tCb, /* control block */
5566 S16 evnt /* event */
5569 PUBLIC Void mtTimeout(tCb, evnt)
5570 PTR tCb; /* control block */
5571 S16 evnt; /* event */
5580 #ifndef TENB_RTLIN_CHANGES
5583 /* mt028.201: modification: multiple procs support related changes */
5584 #ifdef SS_MULTIPLE_PROCS
5586 #endif /* SS_MULTIPLE_PROCS */
5587 #ifdef RGL_SPECIFIC_CHANGES
5588 #ifdef MSPD_MLOG_NEW
5589 U32 t = GetTIMETICK();
5596 /* get the timer entry */
5597 tEnt = (SsTmrEntry *) tCb;
5600 /* if the timer was deleted, this will be NULL, so drop it */
5606 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5609 /* Hmmmm, the timer might have been deleted while we've been
5610 * working at getting here, so we just skip this.
5612 if (tEnt->used == FALSE)
5618 /* Set up and send a timer message to the destination tasks'
5621 #ifndef SS_MULTICORE_SUPPORT
5622 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5624 #ifdef RGL_SPECIFIC_CHANGES
5625 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5627 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5632 #if (ERRCLASS & ERRCLS_DEBUG)
5633 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5639 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5640 mInfo->eventInfo.event = SS_EVNT_TIMER;
5641 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5643 mInfo->pst.dstEnt = tEnt->ownerEnt;
5644 mInfo->pst.dstInst = tEnt->ownerInst;
5645 mInfo->pst.srcEnt = tEnt->ownerEnt;
5646 mInfo->pst.srcInst = tEnt->ownerInst;
5647 /* mt028.201: modification: multiple procs support related changes */
5648 #ifndef SS_MULTIPLE_PROCS
5649 mInfo->pst.dstProcId = SFndProcId();
5650 mInfo->pst.srcProcId = SFndProcId();
5651 #else /* SS_MULTIPLE_PROCS */
5652 mInfo->pst.dstProcId = tEnt->ownerProc;
5653 mInfo->pst.srcProcId = tEnt->ownerProc;
5654 #endif /* SS_MULTIPLE_PROCS */
5655 mInfo->pst.selector = SEL_LC_NEW;
5656 #ifndef SS_MULTICORE_SUPPORT
5657 mInfo->pst.region = DFLT_REGION;
5660 mInfo->pst.pool = DFLT_POOL;
5661 mInfo->pst.prior = PRIOR0;
5662 mInfo->pst.route = RTESPEC;
5663 mInfo->pst.event = 0;
5666 #ifndef TENB_RTLIN_CHANGES
5667 /* get a semaphore for the TAPA task table */
5668 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5673 #if (ERRCLASS & ERRCLS_DEBUG)
5674 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5682 /* find the owner TAPA task */
5683 /* mt028.201: modification: multiple procs support related changes */
5684 #ifdef SS_MULTIPLE_PROCS
5685 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5686 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5687 #else /* SS_MULTIPLE_PROCS */
5688 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5689 #endif /* SS_MULTIPLE_PROCS */
5690 if (idx == SS_TSKNC)
5692 #ifndef TENB_RTLIN_CHANGES
5693 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5700 /* ensure that the TAPA task is hale and hearty */
5701 tTsk = &osCp.tTskTbl[idx];
5704 #ifndef TENB_RTLIN_CHANGES
5705 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5710 /* Klock work fix ccpu00148484 */
5711 /* write the timer message to the queue of the destination task */
5712 /* mt008.301 : check sTsk before putting into it's DQ */
5713 if (tTsk->sTsk == NULLP)
5715 #ifndef TENB_RTLIN_CHANGES
5716 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5720 #if (ERRCLASS & ERRCLS_DEBUG)
5721 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5722 "Could not write to demand queue");
5727 #ifdef SS_LOCKLESS_MEMORY
5728 mInfo->pst.region = tTsk->sTsk->region;
5729 mInfo->region = tTsk->sTsk->region;
5730 #endif /* SS_LOCKLESS_MEMORY */
5731 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5732 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5734 #ifndef TENB_RTLIN_CHANGES
5735 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5739 #if (ERRCLASS & ERRCLS_DEBUG)
5740 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5741 "Could not write to demand queue");
5746 /* Fix for ccpu00130657 */
5747 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5748 if (tTsk->sTsk->tskPrior == PRIOR0)
5751 WLS_WakeUp(mtGetWlsHdl());
5758 /* release the semaphore for the TAPA task table */
5759 #ifndef TENB_RTLIN_CHANGES
5760 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5764 /* restart the timer */
5765 arg.tq = osCp.dep.tmrTq;
5766 arg.tqCp = &osCp.dep.tmrTqCp;
5767 arg.timers = tEnt->dep.timers;
5768 arg.cb = (PTR) tEnt;
5772 arg.max = TMR_DEF_MAX;
5773 arg.wait = tEnt->interval;
5775 #ifdef RGL_SPECIFIC_CHANGES
5776 #ifdef MSPD_MLOG_NEW
5777 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5789 * Desc: This thread reads the console and hands over any
5790 * data read to a user function.
5792 * Ret: (thread function)
5800 PRIVATE Void *mtConHdlr
5802 Ptr parm /* unused */
5805 /* mt009.21: addition */
5806 PRIVATE Void *mtConHdlr(parm)
5807 Ptr parm; /* unused */
5814 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5820 /* check if we have a console input file handle */
5821 if (osCp.dep.conInFp == NULLP)
5827 fd = fileno(osCp.dep.conInFp);
5832 if ((read(fd, &data, 1)) != 1)
5838 /* call rdConQ, defined by the system service user */
5848 #ifdef SS_DRVR_SUPPORT
5851 * Fun: Interrupt service task handler
5853 * Desc: This is the interrupt service task handler. It blocks
5854 * on a pipe from which it reads an isFlag structure. The
5855 * structure indicates which interrupt service task is to
5856 * be executed. The thread identifies the task, calls the
5857 * isTsk function and sends itself a message to repeat
5858 * this operation until it receives a message to cease.
5868 /* mt009.21: addition */
5869 PRIVATE Void *mtIsTskHdlr
5871 Ptr tskPtr /* pointer to task entry */
5874 /* mt009.21: addition */
5875 PRIVATE Void *mtIsTskHdlr(tskPtr)
5876 Ptr tskPtr; /* pointer to task entry */
5879 #if (ERRCLASS & ERRCLS_DEBUG)
5890 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5895 switch (isFlag.action)
5898 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5900 /* call the interrupt service task activation function */
5901 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5903 /* send self a message to keep doing this */
5904 isFlag.action = MT_IS_RESET;
5906 #if (ERRCLASS & ERRCLS_DEBUG)
5907 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5908 if (ret != sizeof(isFlag))
5910 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5911 "write() to pipe failed");
5914 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5921 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5926 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5928 /* call the interrupt service task activation function */
5929 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5931 #if (ERRCLASS & ERRCLS_DEBUG)
5932 /* send self a message to do this again */
5933 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5935 if (ret != sizeof(isFlag))
5937 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5938 "write() to pipe failed");
5941 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5949 /* where did THIS come from?? */
5953 /* mt009.21: addition */
5954 RETVALUE( (Void *) NULLP);
5958 #endif /* SS_DRVR_SUPPORT */
5959 #endif /* L2_L3_SPLIT */
5961 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5965 * Fun: mtIntSigHndlr
5967 * Desc: Exit function, shuts down.
5977 PUBLIC Void mtIntSigHndlr
5982 PUBLIC Void mtIntSigHndlr(arg)
5987 TRC0(mtIntSigHndlr);
5989 osCp.dep.sigEvnt=TRUE;
5992 #ifdef TENB_RTLIN_CHANGES
6000 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
6005 * Desc: function, shuts down.
6015 PUBLIC Void mtExitClnup
6020 PUBLIC Void mtExitClnup()
6029 SGetSysTime(&ticks);
6031 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
6033 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
6035 #ifdef SS_HISTOGRAM_SUPPORT
6039 osCp.dep.sigEvnt=FALSE;
6041 if (osCp.dep.fileOutFp)
6043 fclose(osCp.dep.fileOutFp);
6051 Void SIncrementTtiCount(Void)
6056 Ticks SGetTtiCount(Void)
6065 * Desc: This function displays a string to a given output
6070 * Notes: Buffer should be null terminated.
6072 * channel 0 is reserved for backwards compatibility
6081 S16 chan, /* channel */
6082 Txt *buf /* buffer */
6085 PUBLIC S16 SDisplay(chan, buf)
6086 S16 chan; /* channel */
6087 Txt *buf; /* buffer */
6092 /* mt020.201 - Fixed typo */
6093 #if (ERRCLASS & ERRCLS_INT_PAR)
6096 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6101 #ifndef XEON_SPECIFIC_CHANGES
6102 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6103 ssMemlog(buf, strlen(buf));
6108 /* mt012.301 :FIX for LOG RELATED ISSUE */
6116 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6122 if (osCp.dep.fileOutFp)
6123 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6124 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6127 fflush(osCp.dep.fileOutFp);
6140 * Desc: function, shuts down.
6160 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6161 a loop to overcome the child processes being killed upon exiting the
6163 #ifdef SS_LINUX /* this should have already been defined */
6164 /* mt010.301 removed flag SLES9_PLUS */
6165 /* wait forever for children */
6169 if(osCp.dep.sigEvnt==TRUE)
6176 pthread_exit(NULLP);
6182 * Fun: Set date and time
6184 * Desc: This function is used to set the calendar
6189 * Notes: Unimplemented
6195 PUBLIC S16 SSetDateTime
6197 REG1 DateTime *dt /* date and time */
6200 PUBLIC S16 SSetDateTime(dt)
6201 REG1 DateTime *dt; /* date and time */
6216 * Fun: Get date and time
6218 * Desc: This function is used to determine the calendar
6219 * date and time. This information may be used for
6220 * some management functions.
6231 PUBLIC S16 SGetDateTime
6233 REG1 DateTime *dt /* date and time */
6236 PUBLIC S16 SGetDateTime(dt)
6237 REG1 DateTime *dt; /* date and time */
6240 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6243 struct timespec ptime;
6245 struct timeval ptime;
6254 #if (ERRCLASS & ERRCLS_INT_PAR)
6257 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6266 localtime_r(&tt, &tme);
6269 clock_gettime(CLOCK_REALTIME, &ptime);
6271 gettimeofday(&ptime, NULL);
6273 localtime_r(&ptime.tv_sec, &tme);
6275 dt->month = (U8) tme.tm_mon + 1;
6276 dt->day = (U8) tme.tm_mday;
6277 dt->year = (U8) tme.tm_year;
6278 dt->hour = (U8) tme.tm_hour;
6279 dt->min = (U8) tme.tm_min;
6280 dt->sec = (U8) tme.tm_sec;
6283 #ifdef SS_DATETIME_USEC
6285 dt->usec = ptime.tv_nsec / 1000;
6287 dt->usec = ptime.tv_usec;
6289 #endif /*-- SS_DATETIME_USEC --*/
6295 * Get time from epoch in milliseconds
6297 * Fun: Get time from epoch in milliseconds
6299 * Desc: This function is used to get the time from epoch in milli seconds.
6300 * This information may be used for calculating a layer's activation function
6301 * execution time used for thread profiling.
6310 /* mt003.301 Modifications */
6312 PUBLIC S16 SGetEpcTime
6314 EpcTime *et /* date and time */
6317 PUBLIC S16 SGetEpcTime(et)
6318 EpcTime *et; /* date and time */
6321 /* mt003.301 Modifications */
6323 U64 to_sec = 1000000;
6326 struct timespec ptime;
6328 struct timeval ptime;
6334 #if (ERRCLASS & ERRCLS_INT_PAR)
6343 clock_gettime(CLOCK_REALTIME, &ptime);
6345 gettimeofday(&ptime, NULL);
6346 #endif /* SS_LINUX */
6348 now = (ptime.tv_sec * to_sec);
6351 now += (ptime.tv_nsec / to_nsec);
6352 #else /* SS_LINUX */
6353 now += (ptime.tv_usec);
6355 #endif /* SS_LINUX */
6356 now = (now / to_nsec);
6367 * Fun: Get system time
6369 * Desc: This function is used to determine the system time.
6373 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6379 PUBLIC S16 SGetSysTime
6381 Ticks *sysTime /* system time */
6384 PUBLIC S16 SGetSysTime(sysTime)
6385 Ticks *sysTime; /* system time */
6391 #if (ERRCLASS & ERRCLS_INT_PAR)
6392 if (sysTime == NULLP)
6394 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6400 *sysTime = osCp.dep.sysTicks;
6406 /* mt021.201 - Addition of SGetRefTime function */
6409 * Fun: Get referenced time
6411 * Desc: This function is used to determine the time in seconds
6412 * and microseconds from a reference time. The reference
6413 * time is expressed in seconds from UTC EPOC, January 1,
6419 * Notes: Macros are defined for reference times:
6420 * SS_REFTIME_01_01_1970
6421 * SS_REFTIME_01_01_2002
6427 PUBLIC S16 SGetRefTime
6429 U32 refTime, /* reference time */
6434 PUBLIC S16 SGetRefTime(refTime, sec, usec)
6435 U32 refTime; /* reference time */
6442 struct timespec ptime;
6444 struct timeval ptime;
6450 clock_gettime(CLOCK_REALTIME, &ptime);
6452 gettimeofday(&ptime, NULL);
6455 #if (ERRCLASS & ERRCLS_INT_PAR)
6456 if (sec == NULLP || usec == NULLP)
6458 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6461 /* mt022.201 - Modification to fix compile warning */
6462 if (refTime > (U32)(ptime.tv_sec))
6464 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6469 *sec = ptime.tv_sec - refTime;
6471 *usec = ptime.tv_nsec / 1000;
6473 *usec = ptime.tv_usec;
6483 * Fun: Get Random Number
6485 * Desc: Invoked by layer when a pseudorandom number is required.
6489 * Notes: Suggested approach uses shuffled Linear Congruential
6490 * Operators as described in Byte magazine October
6491 * 1984; "Generating and Testing Pseudorandom Numbers"
6499 Random *value /* random number */
6502 PUBLIC S16 SRandom(value)
6503 Random *value; /* random number */
6509 #if (ERRCLASS & ERRCLS_INT_PAR)
6512 /* mt011.21: addition */
6513 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6519 *value = (Random) rand_r(&osCp.dep.randSeed);
6530 * Desc: This function exits from a task.
6534 * Notes: Currently does nothing.
6545 PUBLIC S16 SExitTsk()
6557 * Fun: Exit Interrupt
6559 * Desc: This function exits from an interrupt.
6563 * Notes: Currently does nothing.
6574 PUBLIC S16 SExitInt()
6586 * Fun: Hold Interrupt
6588 * Desc: This function prohibits interrupts from being enabled until
6589 * release interrupt. This function should be called when
6590 * interrupts are disabled and prior to any call to system
6591 * services either by entry to an interrupt service routine or
6592 * by explicit call to disable interrupt.
6596 * Notes: Currently does nothing
6607 PUBLIC S16 SHoldInt()
6619 * Fun: Release Interrupt
6621 * Desc: This function allows interrupts to be enabled.
6625 * Notes: Currently does nothing.
6636 PUBLIC S16 SRelInt()
6650 * Desc: Enable interrupts
6652 * Ret: ROK on success
6655 * Notes: Currently does nothing.
6661 PUBLIC INLINE S16 SEnbInt
6666 PUBLIC INLINE S16 SEnbInt()
6680 * Desc: Disable interrupts
6682 * Ret: ROK on success
6685 * Notes: Currently does nothing.
6691 PUBLIC INLINE S16 SDisInt
6696 PUBLIC INLINE S16 SDisInt()
6710 * Desc: This function gets the function address stored at the
6711 * specified interrupt vector.
6715 * Notes: Currently does nothing.
6723 VectNmb vectNmb, /* vector number */
6724 PIF *vectFnct /* vector function */
6727 PUBLIC S16 SGetVect(vectNmb, vectFnct)
6728 VectNmb vectNmb; /* vector number */
6729 PIF *vectFnct; /* vector function */
6747 * Desc: This function installs the specified function at the
6748 * specified interrupt vector.
6752 * Notes: Currently does nothing.
6760 VectNmb vectNmb, /* vector number */
6761 PIF vectFnct /* vector function */
6764 PUBLIC S16 SPutVect(vectNmb, vectFnct)
6765 VectNmb vectNmb; /* vector number */
6766 PIF vectFnct; /* vector function */
6779 /* mt028.201: modification: multiple procs support related changes */
6780 #ifndef SS_MULTIPLE_PROCS
6786 * Desc: This function gets the current entity and instance.
6789 * RFAILED - failed, general (optional)
6791 * Notes: This function may be called by the OS or Layer 1
6798 PUBLIC S16 SGetEntInst
6800 Ent *ent, /* entity */
6801 Inst *inst /* instance */
6804 PUBLIC S16 SGetEntInst(ent, inst)
6805 Ent *ent; /* entity */
6806 Inst *inst; /* instance */
6818 #if (ERRCLASS & ERRCLS_INT_PAR)
6819 /* check pointers */
6820 if (ent == NULLP || inst == NULLP)
6822 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6828 /* get the thread id */
6829 tId = pthread_self();
6832 /* find the system task in whose context we're running */
6834 ret = SLock(&osCp.sTskTblLock);
6839 for (i = 0; i < SS_MAX_STSKS; i++)
6841 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6843 sTsk = &osCp.sTskTbl[i];
6849 *ent = sTsk->dep.ent;
6850 *inst = sTsk->dep.inst;
6852 SUnlock(&osCp.sTskTblLock);
6855 RETVALUE(ret == ROK ? ROK : RFAILED);
6863 * Desc: This function sets the current entity and instance.
6873 PUBLIC S16 SSetEntInst
6875 Ent ent, /* entity */
6876 Inst inst /* instance */
6879 PUBLIC S16 SSetEntInst(ent, inst)
6880 Ent ent; /* entity */
6881 Inst inst; /* instance */
6893 #if (ERRCLASS & ERRCLS_INT_PAR)
6894 /* check entity and instance IDs */
6895 if (ent >= ENTNC || inst >= INSTNC)
6897 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6903 /* get the thread id */
6904 tId = pthread_self();
6907 /* find the system task in whose context we're running */
6909 ret = SLock(&osCp.sTskTblLock);
6914 for (i = 0; i < SS_MAX_STSKS; i++)
6916 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6918 sTsk = &osCp.sTskTbl[i];
6924 sTsk->dep.ent = ent;
6925 sTsk->dep.inst = inst;
6927 SUnlock(&osCp.sTskTblLock);
6930 RETVALUE(ret == ROK ? ROK : RFAILED);
6933 #endif /* SS_MULTIPLE_PROCS */
6935 #ifdef SS_DRVR_SUPPORT
6941 * Desc: Set interrupt pending flag
6943 * Ret: ROK on success
6952 PUBLIC INLINE S16 SSetIntPend
6954 U16 id, /* driver task identifier */
6955 Bool flag /* flag */
6958 PUBLIC INLINE S16 SSetIntPend(id, flag)
6959 U16 id; /* driver task identifier */
6960 Bool flag; /* flag */
6969 #if (ERRCLASS & ERRCLS_INT_PAR)
6970 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6972 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6979 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6981 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6989 #endif /* SS_DRVR_SUPPORT */
6992 #ifdef SS_LOCKLESS_MEMORY
6995 * Fun: SGlobMemInfoShow
6997 * Desc: This function displays the memory usage information
6998 * for the destined region. It will show the usage of
6999 * each configured bucket and the heap for the specified region.
7002 * RFAILED Region not registered
7008 PUBLIC S16 SGlobMemInfoShow
7013 PUBLIC S16 SGlobMemInfoShow()
7018 CmMmGlobRegCb *globReg;
7020 TRC1(SGlobMemInfoShow);
7022 globReg = osCp.globRegCb;
7024 sprintf(prntBuf, "--------------------------------------------------------------\n");
7025 SDisplay(0, prntBuf);
7026 sprintf(prntBuf, "Global Region Bucket Information\n");
7027 SDisplay(0, prntBuf);
7028 sprintf(prntBuf, "====================================================\n");
7029 SDisplay(0, prntBuf);
7030 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
7031 SDisplay(0, prntBuf);
7032 sprintf(prntBuf, "====================================================\n");
7033 SDisplay(0, prntBuf);
7036 for (idx = 0; idx < globReg->numBkts; idx++)
7038 #ifdef XEON_SPECIFIC_CHANGES
7039 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
7040 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7043 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
7044 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7046 sprintf(prntBuf, "%2u %12u %8u %9u\n",
7047 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7050 SDisplay(0, prntBuf);
7052 sprintf(prntBuf, "--------------------------------------------------------------\n");
7053 SDisplay(0, prntBuf);
7058 #endif /* SS_LOCKLESS_MEMORY */
7061 Bool IsMemoryThresholdHit(Region reg, Pool pool)
7063 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
7065 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
7068 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
7069 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
7076 /* mt022.201 - Addition of SRegInfoShow function */
7081 * Desc: This function displays the memory usage information
7082 * for the destined region. It will show the usage of
7083 * each configured bucket and the heap for the specified region.
7086 * RFAILED Region not registered
7088 * Notes: A Sample Output from the function
7089 * Bucket Memory: region 1
7090 * ====================================================
7091 * Bucket Number of Blks configured Size Allocated
7092 * ====================================================
7100 * Heap Memory: region 1
7103 * Heap Segmented blocks: 0
7110 PUBLIC S16 SRegInfoShow
7116 PUBLIC S16 SRegInfoShow(region, availmem)
7126 #if (ERRCLASS & ERRCLS_INT_PAR)
7127 if (region > (SS_MAX_REGS-1) )
7129 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7136 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7137 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7138 SDisplay(0, prntBuf);
7139 sprintf(prntBuf, "====================================================\n");
7140 SDisplay(0, prntBuf);
7141 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7142 SDisplay(0, prntBuf);
7143 sprintf(prntBuf, "====================================================\n");
7144 SDisplay(0, prntBuf);
7148 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7150 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7152 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7153 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7154 mtCMMRegCb[region]->bktTbl[idx].size,
7155 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7156 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7158 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7159 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7160 mtCMMRegCb[region]->bktTbl[idx].size,
7161 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7162 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7165 /*mt009.301 Fixed 64BIT compilation warnings*/
7167 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7168 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7169 mtCMMRegCb[region]->bktTbl[idx].size,
7170 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7172 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7173 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7174 mtCMMRegCb[region]->bktTbl[idx].size,
7175 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7177 #endif /* not TENB_RTLIN_CHANGES */
7178 SDisplay(0, prntBuf);
7179 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7180 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7181 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7183 sprintf(prntBuf, "\n---------------\n");
7184 SDisplay(0, prntBuf);
7185 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7186 SDisplay(0, prntBuf);
7187 /*mt009.301 Fixed 64BIT compilation warnings*/
7189 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7191 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7193 SDisplay(0, prntBuf);
7194 /*mt009.301 Fixed 64BIT compilation warnings*/
7196 sprintf(prntBuf, "Heap Allocated: %u\n",
7197 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7199 sprintf(prntBuf, "Heap Allocated: %lu\n",
7200 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7202 SDisplay(0, prntBuf);
7203 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7204 #if (ERRCLASS & ERRCLS_DEBUG)
7205 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7206 mtCMMRegCb[region]->heapCb.numFragBlk);
7207 SDisplay(0, prntBuf);
7212 #ifdef XEON_SPECIFIC_CHANGES
7213 #define SSI_MAX_BKT_THRESHOLD 6
7214 #define SSI_MAX_REG_THRESHOLD 2
7215 U32 SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7216 U32 SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7217 U32 SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7220 PRIVATE Void SInitMemThreshold
7226 PRIVATE Void SInitMemThreshold(region, maxBkt)
7232 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7234 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7235 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7236 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7237 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7242 PUBLIC S16 SRegReachedMemThreshold
7248 PUBLIC S16 SRegReachedMemThreshold(region, maxBkt)
7255 PRIVATE U8 initFlag = 1;
7259 SInitMemThreshold(region, maxBkt);
7262 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7264 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7269 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7273 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7278 RETVALUE(memStatus);
7281 /* mt033.201 - addition of API to return the memory statistical data */
7286 * Desc: This function returns the memory usage information
7287 * for the destined region. It will return the usage of
7288 * each configured bucket and the heap for the specified region.
7291 * RFAILED Region not registered
7299 PUBLIC S16 SGetRegInfo
7302 SsMemDbgInfo *dbgInfo
7305 PUBLIC S16 SGetRegInfo(region, dbgInfo)
7307 SsMemDbgInfo *dbgInfo;
7314 #if (ERRCLASS & ERRCLS_INT_PAR)
7315 if (region >= mtMemoCfg.numRegions )
7317 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7322 dbgInfo->availmem = 0;
7324 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7325 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7327 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7329 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7331 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7332 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7333 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7335 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7336 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7337 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7340 dbgInfo->region = region;
7342 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7344 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7345 mtCMMRegCb[region]->heapCb.avlSize);
7347 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7349 #if (ERRCLASS & ERRCLS_DEBUG)
7350 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7357 PUBLIC S16 SGetRegPoolInfo
7363 PUBLIC S16 SGetRegPoolInfo(numRegion, numPool)
7368 /* Send number of Region available */
7369 *numRegion = mtMemoCfg.numRegions;
7370 /* Send number of Pools available */
7371 *numPool = cfgRegInfo[0].numPools;
7376 /* mt033.201 - addition of APIs to print the memory statistical data
7377 * as defined by SSI enhancements
7379 #ifdef SSI_DEBUG_LEVEL1
7382 * Fun: SPrintRegMemStatusInfo
7384 * Desc: This function displays the memory usage information
7385 * for the destined region. It will show the total memory
7386 * used for static and dynamic memory if typeFlag is
7387 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7388 * memory block allocated for a particular size if typeFlag
7389 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7390 * calling SRegPrintMemStats.
7400 PUBLIC S16 SPrintRegMemStatusInfo
7406 PUBLIC S16 SPrintRegMemStatusInfo(region, typeFlag)
7416 TRC1(SPrintRegMemStatusInfo);
7418 #if (ERRCLASS & ERRCLS_INT_PAR)
7419 if (region >= mtMemoCfg.numRegions )
7421 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7426 /* initialize the counters*/
7430 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7432 /* total static and dynamic memory allocated from all the buckets in region requested */
7433 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7434 SDisplay(0, prntBuf);
7435 sprintf(prntBuf, "===========================================\n");
7436 SDisplay(0, prntBuf);
7437 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7438 SDisplay(0, prntBuf);
7439 sprintf(prntBuf, "===========================================\n");
7440 SDisplay(0, prntBuf);
7441 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7443 /*mt009.301 Fixed 64BIT compilation warnings*/
7445 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7446 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7447 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7449 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7450 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7451 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7453 SDisplay(0, prntBuf);
7454 /* update the total count */
7455 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7456 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7459 /*mt009.301 Fixed 64BIT compilation warnings*/
7461 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7462 SDisplay(0, prntBuf);
7463 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7465 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7466 SDisplay(0, prntBuf);
7467 /*mt010.301 fix for compilation error*/
7468 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7470 SDisplay(0, prntBuf);
7472 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7473 SDisplay(0, prntBuf);
7474 /*mt009.301 Fixed 64BIT compilation warnings*/
7476 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7477 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7479 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7480 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7482 SDisplay(0, prntBuf);
7484 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7486 /* Bucket Memory allocation Statistics */
7487 RETVALUE(SPrintRegMemStats(region));
7492 sprintf(prntBuf, "\n Invalid choice \n");
7493 SDisplay(0, prntBuf);
7501 * Fun: SPrintRegMemStats
7503 * Desc: This function displays the memory usage information for
7504 * the destined region. It will show the number of memory
7505 * block allocated for a particular size from the hash list.
7515 PRIVATE S16 SPrintRegMemStats
7520 PRIVATE S16 SPrintRegMemStats(region)
7524 CmMmHashListCp *hashListCp;
7529 TRC1(SPrintRegMemStats);
7531 hashListCp = &mtCMMRegCb[region]->hashListCp;
7533 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7534 SDisplay(0, prntBuf);
7535 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7536 hashListCp->numOfbins, hashListCp->numOfEntries);
7537 SDisplay(0, prntBuf);
7538 sprintf(prntBuf, "===================================\n");
7539 SDisplay(0, prntBuf);
7540 sprintf(prntBuf, "Block Size Total number of requests\n");
7541 SDisplay(0, prntBuf);
7542 sprintf(prntBuf, "===================================\n");
7543 SDisplay(0, prntBuf);
7545 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7546 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7548 if (hashListCp->hashList[idx].numAttempts)
7551 /*mt009.301 Fixed 64BIT compilation warnings*/
7553 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7554 hashListCp->hashList[idx].numAttempts);
7556 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7557 hashListCp->hashList[idx].numAttempts);
7559 SDisplay(0, prntBuf);
7563 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7564 SDisplay(0, prntBuf);
7565 sprintf(prntBuf, "=================================================\n");
7566 SDisplay(0, prntBuf);
7567 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7568 SDisplay(0, prntBuf);
7569 sprintf(prntBuf, "=================================================\n");
7570 SDisplay(0, prntBuf);
7572 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7573 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7575 /*mt009.301 Fixed 64BIT compilation warnings*/
7577 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7578 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7579 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7581 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7582 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7583 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7585 SDisplay(0, prntBuf);
7587 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7588 SDisplay(0, prntBuf);
7589 /*mt009.301 Fixed 64BIT compilation warnings*/
7591 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7592 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7593 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7595 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7596 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7597 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7599 SDisplay(0, prntBuf);
7600 sprintf(prntBuf, "\n");
7601 SDisplay(0, prntBuf);
7608 * Fun: SRegMemErrHdlr
7610 * Desc: This function handles the errors returned from the memory
7611 * related functions. Customers are suggested to modify this
7612 * API according to their specific requirement.
7622 PUBLIC Void SRegMemErrHdlr
7629 PUBLIC Void SRegMemErrHdlr(region, ptr, errCode)
7637 TRC1(SRegMemErrHdlr);
7639 if (errCode == RDBLFREE)
7641 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7642 SDisplay(0, prntBuf);
7644 else if (errCode == RTRAMPLINGNOK)
7646 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7647 SDisplay(0, prntBuf);
7655 * Fun: SPrintRegMemProfile
7657 * Desc: This function displays the memory profile information
7658 * for the destined region. This function prints for:
7659 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7660 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7670 PUBLIC S16 SPrintRegMemProfile
7675 PUBLIC S16 SPrintRegMemProfile(region)
7681 CmMmBlkHdr *curBktBlk;
7683 Size offsetToNxtBlk;
7690 TRC1(SPrintRegMemProfile);
7692 #if (ERRCLASS & ERRCLS_INT_PAR)
7693 if (region >= mtMemoCfg.numRegions )
7695 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7700 regCb = mtCMMRegCb[region];
7702 /* memory profile */
7703 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7704 SDisplay(0, prntBuf);
7706 /* bucket profile */
7707 sprintf(prntBuf, "\nBucket Profile\n");
7708 SDisplay(0, prntBuf);
7710 for (idx = 0; idx < regCb->numBkts; idx++)
7713 /*mt009.301 Fixed 64BIT compilation warnings*/
7715 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7716 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7718 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7719 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7721 SDisplay(0, prntBuf);
7723 sprintf(prntBuf, "==========================================================================\n");
7724 SDisplay(0, prntBuf);
7725 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7726 SDisplay(0, prntBuf);
7727 sprintf(prntBuf, "==========================================================================\n");
7728 SDisplay(0, prntBuf);
7730 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7732 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7733 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7734 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7736 /*mt009.301 Fixed 64BIT compilation warnings*/
7738 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7740 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7742 SDisplay(0, prntBuf);
7743 /* check if it is a sane block, elxe jump to next block */
7744 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7746 sprintf(prntBuf, " Trampled \n");
7747 SDisplay(0, prntBuf);
7752 if (CMM_IS_STATIC(curBktBlk->memFlags))
7754 /*mt009.301 Fixed 64BIT compilation warnings*/
7756 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7758 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7760 SDisplay(0, prntBuf);
7762 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7764 /*mt009.301 Fixed 64BIT compilation warnings*/
7766 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7768 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7770 SDisplay(0, prntBuf);
7772 else if (CMM_IS_FREE(curBktBlk->memFlags))
7774 /*mt009.301 Fixed 64BIT compilation warnings*/
7776 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7778 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7780 SDisplay(0, prntBuf);
7784 sprintf(prntBuf, " Trampled \n");
7785 SDisplay(0, prntBuf);
7791 sprintf(prntBuf, "\nHeap Profile\n");
7792 SDisplay(0, prntBuf);
7794 /* point to heapCb */
7795 heapCb = &(regCb->heapCb);
7797 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7798 SDisplay(0, prntBuf);
7799 sprintf(prntBuf, "==========================================================================\n");
7800 SDisplay(0, prntBuf);
7801 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7802 SDisplay(0, prntBuf);
7803 sprintf(prntBuf, "==========================================================================\n");
7804 SDisplay(0, prntBuf);
7806 /* traverse the entire heap to output the heap profile */
7807 hdrSize = sizeof(CmHEntry);
7808 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7809 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7811 /*mt009.301 Fixed 64BIT compilation warnings*/
7813 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7815 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7817 SDisplay(0, prntBuf);
7819 /* check if it is a sane block, elxe jump to next block */
7820 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7822 sprintf(prntBuf, " Trampled \n");
7823 SDisplay(0, prntBuf);
7825 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7826 SDisplay(0, prntBuf);
7829 * To go to next block in the heap we do not have any offset value
7830 * other than curHBlk->size. As the block is already trampled
7831 * we cannot rely on this size. So it is better to stop here unless there
7832 * exists any other mechanism(?) to know the offset to next block.
7837 /*mt009.301 Fixed 64BIT compilation warnings*/
7839 sprintf(prntBuf, " %8u", curHBlk->size);
7841 sprintf(prntBuf, " %8lu", curHBlk->size);
7843 SDisplay(0, prntBuf);
7845 if (CMM_IS_STATIC(curHBlk->memFlags))
7847 /*mt009.301 Fixed 64BIT compilation warnings*/
7849 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7851 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7853 SDisplay(0, prntBuf);
7855 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7857 /*mt009.301 Fixed 64BIT compilation warnings*/
7859 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7861 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7863 SDisplay(0, prntBuf);
7865 else if (CMM_IS_FREE(curHBlk->memFlags))
7867 /*mt009.301 Fixed 64BIT compilation warnings*/
7869 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7871 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7873 SDisplay(0, prntBuf);
7877 sprintf(prntBuf, " Trampled \n");
7878 SDisplay(0, prntBuf);
7880 /* goto next block in the heap */
7881 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7887 #endif /* SSI_DEBUG_LEVEL1 */
7889 /*-- mt035.201 : Added new API for timestamp --*/
7892 * Fun: Get TimeStamp
7894 * Desc: This function is used to Get TimeStamp in micro seconds
7905 PUBLIC S16 SGetTimeStamp
7910 PUBLIC S16 SGetTimeStamp(ts)
7916 struct timespec ptime;
7918 struct timeval ptime;
7925 TRC1(SGetTimeStamp);
7928 clock_gettime(CLOCK_REALTIME, &ptime);
7930 gettimeofday(&ptime, NULL);
7933 /* Obtain the time of day, and convert it to a tm struct. --*/
7934 ptm = localtime (&ptime.tv_sec);
7935 /* Klock work fix ccpu00148484 */
7938 /* Format the date and time, down to a single second. --*/
7939 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7942 /* Compute microseconds. --*/
7944 microseconds = ptime.tv_nsec / 1000;
7946 microseconds = ptime.tv_usec;
7949 /* Print the formatted time, in seconds, followed by a decimal point
7950 and the microseconds. --*/
7951 /*mt009.301 Fixed 64BIT compilation warnings*/
7953 sprintf(ts, "%s.%03d", time_string, microseconds);
7955 sprintf(ts, "%s.%03ld", time_string, microseconds);
7961 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7964 * Fun: Get SGetSystemTsk
7966 * Desc: This function is used to Get sytem task id
7976 PUBLIC U32 SGetSystemTsk
7981 PUBLIC U32 SGetSystemTsk()
7984 TRC1(SGetSystemTskS);
7986 RETVALUE(pthread_self());
7988 } /* end of SGetSystemTsk */
7990 #ifdef SS_MULTICORE_SUPPORT
7993 * Fun: Add Timer thread into system task table
7995 * Desc: This function is used to add the system task
7996 * associated with Timer thread.
8006 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void)
8008 PRIVATE SsSTskEntry* ssdAddTmrSTsk()
8014 TRC1(ssdAddTmrSTsk);
8016 /* lock the system task table */
8017 ret = SLock(&osCp.sTskTblLock);
8021 #if (ERRCLASS & ERRCLS_DEBUG)
8022 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8023 "Could not lock system task table");
8029 /* check count of system tasks */
8030 if (osCp.numSTsks == SS_MAX_STSKS)
8033 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8035 #if (ERRCLASS & ERRCLS_DEBUG)
8036 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
8037 "Could not give the Semaphore");
8042 #if (ERRCLASS & ERRCLS_ADD_RES)
8043 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
8050 /* initialize the system task entry with the information we have */
8051 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
8053 /* store the system task priority */
8054 sTsk->tskPrior = SS_NORM_TSK_PRI;
8056 /* initialize the demand queue */
8057 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8060 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8062 #if (ERRCLASS & ERRCLS_DEBUG)
8063 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8064 "Could not give the Semaphore");
8069 #if (ERRCLASS & ERRCLS_DEBUG)
8070 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8071 "Could not initialize demand queue");
8077 /* initialize the system task entry lock */
8078 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8080 ssDestroyDmndQ(&sTsk->dQ);
8082 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8084 #if (ERRCLASS & ERRCLS_DEBUG)
8085 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8086 "Could not give the Semaphore");
8091 #if (ERRCLASS & ERRCLS_DEBUG)
8092 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8093 "Could not initialize system task entry lock");
8100 /* success, update the table */
8101 sTsk->tskId = osCp.nxtSTskEntry;
8103 sTsk->termPend = FALSE;
8104 osCp.nxtSTskEntry = sTsk->nxt;
8107 /* unlock the system task table */
8109 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8111 #if (ERRCLASS & ERRCLS_DEBUG)
8112 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8113 "Could not give the Semaphore");
8120 #endif /* SS_MULTICORE_SUPPORT */
8121 /* mt003.301 Readwrite lock and recursive mutex additions */
8122 #ifdef SS_LOCK_SUPPORT
8125 * Fun: ssdInitLockNew
8127 * Desc: This function is used to initialise lock/mutex
8137 PUBLIC S16 ssdInitLockNew
8143 PUBLIC S16 ssdInitLockNew(lockId, lockType)
8149 #ifdef SS_REC_LOCK_SUPPORT
8150 pthread_mutexattr_t attr;
8151 #endif /* SS_REC_LOCK_SUPPORT */
8152 Txt prntBuf[PRNTSZE];
8155 TRC1(ssdInitLockNew);
8159 #ifdef SS_RDWR_LOCK_SUPPORT
8162 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8164 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8165 SDisplay(0, prntBuf);
8170 #endif /* SS_RDWR_LOCK_SUPPORT */
8171 #ifdef SS_REC_LOCK_SUPPORT
8174 retVal = pthread_mutexattr_init(&attr);
8178 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8183 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8185 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8189 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8190 pthread_mutexattr_destroy(&attr);
8194 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8197 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8198 pthread_mutexattr_destroy(&attr);
8204 #endif /* SS_REC_LOCK_SUPPORT */
8207 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8208 SDisplay(0, prntBuf);
8218 * Desc: This function is used to aquire the read write lock
8228 PUBLIC S16 ssdLockNew
8234 PUBLIC S16 ssdLockNew(lockId, lockType)
8240 Txt prntBuf[PRNTSZE];
8247 #ifdef SS_RDWR_LOCK_SUPPORT
8250 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8252 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8253 SDisplay(0, prntBuf);
8260 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8262 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8263 SDisplay(0, prntBuf);
8270 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8272 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8273 SDisplay(0, prntBuf);
8280 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8282 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8283 SDisplay(0, prntBuf);
8288 #endif /* SS_RDWR_LOCK_SUPPORT */
8289 #ifdef SS_REC_LOCK_SUPPORT
8292 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8294 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8295 SDisplay(0, prntBuf);
8300 #endif /* SS_REC_LOCK_SUPPORT */
8303 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8304 SDisplay(0, prntBuf);
8317 * Desc: This function is used to Unlock the read write lock
8327 PUBLIC S16 ssdUnlockNew
8333 PUBLIC S16 ssdUnlockNew(lockId, lockType)
8339 Txt prntBuf[PRNTSZE];
8346 #ifdef SS_RDWR_LOCK_SUPPORT
8349 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8351 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8352 SDisplay(0, prntBuf);
8357 #endif /* SS_RDWR_LOCK_SUPPORT */
8358 #ifdef SS_REC_LOCK_SUPPORT
8361 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8363 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8364 SDisplay(0, prntBuf);
8369 #endif /* SS_REC_LOCK_SUPPORT */
8372 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8373 SDisplay(0, prntBuf);
8382 * Fun: ssdDestroyLockNew
8384 * Desc: This function is used to destroy the read write lock
8394 PUBLIC S16 ssdDestroyLockNew
8400 PUBLIC S16 ssdDestroyLockNew(lockId, lockType)
8405 Txt prntBuf[PRNTSZE];
8408 TRC1(ssdDestroyLockNew);
8412 #ifdef SS_RDWR_LOCK_SUPPORT
8415 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8417 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8418 SDisplay(0, prntBuf);
8423 #endif /* SS_RDWR_LOCK_SUPPORT */
8424 #ifdef SS_REC_LOCK_SUPPORT
8427 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8429 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8430 SDisplay(0, prntBuf);
8435 #endif /* SS_REC_LOCK_SUPPORT */
8438 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8439 SDisplay(0, prntBuf);
8445 #endif /* SS_LOCK_SUPPORT */
8447 /* mt005.301 : Cavium Changes */
8448 #ifdef SS_SEUM_CAVIUM
8452 * Fun: ssInitRcvWork
8454 * Desc: This is the initializtion function of receive
8458 * RFAILED - failed, general (optional)
8460 * Notes: Function to initialize the work queue packet
8461 * receiving thread. This creates the new thread to
8462 * receive the work and sets the affinity.
8468 PUBLIC S16 ssInitRcvWork
8473 PUBLIC S16 ssInitRcvWork()
8476 pthread_attr_t attr;
8479 TRC1(ssInitRcvWork);
8481 /* set the required attributes */
8482 pthread_attr_init(&attr);
8483 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8484 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8485 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8487 /* Create a new thread to receive the work queue messages */
8488 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8490 pthread_attr_destroy(&attr);
8495 pthread_attr_destroy(&attr);
8499 }/* ssInitRcvWork */
8506 * Desc: This is the handler function of receive
8510 * RFAILED - failed, general (optional)
8512 * Notes:The handler function of the work queue receiver task.
8513 * This will be waiting for the work and after receiving
8514 * it, work will converted and posted to that entityt
8521 PRIVATE void *workRcvTsk
8526 PRIVATE void *workRcvTsk (ptr)
8531 cvmx_wqe_t *workPtr;
8532 Buffer *mBuf, *rcvdBuf;
8533 SsMsgInfo *minfoPtr;
8543 /* get the work if its avilable */
8544 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8546 if ( workPtr == NULLP )
8548 /* If there is no work then sleep for 10 usec */
8550 ts.tv_nsec = 500000;
8552 nanosleep(&ts, NULLP);
8556 switch(workPtr->tag)
8558 /* Switch over according to the tag value */
8559 case SS_CVMX_MBUF_TAG:
8561 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8563 /* Convert the physical address to Pointers */
8564 ret = SConvPhyPtr(&rcvdBuf);
8567 /* mt011.301: Cavium 32 bit changes */
8568 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8572 /* Copy the buffer to this region */
8573 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8576 /* mt011.301: Cavium 32 bit changes */
8577 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8581 /* mt011.301: Cavium 32 bit changes */
8582 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8584 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8586 /* Get the post strucutre and Post the message */
8587 if ( minfoPtr != NULLP)
8589 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8591 (Void)SPstTsk(&pst, mBuf);
8593 /* Free the buffer allocated if it cannot be sent */
8602 /* Invalid tag value, drop the work */
8603 /* mt011.301: Cavium 32 bit changes */
8604 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8613 #endif /* SS_SEUM_CAVIUM */
8615 #ifdef TENB_RTLIN_CHANGES
8616 PUBLIC S16 SInitLock(SLockId *l, U8 t)
8619 pthread_mutexattr_t prior;
8620 pthread_mutexattr_init(&prior);
8621 #ifndef RGL_SPECIFIC_CHANGES
8622 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8624 r = pthread_mutex_init(l, &prior);
8625 pthread_mutexattr_destroy(&prior);
8629 #ifdef SS_THR_REG_MAP
8632 * Fun: ssRegMainThread
8634 * Desc: This function is used to add the memory region
8635 * mapping for the main thread.
8637 * Ret: VOID (Always successful)
8645 PUBLIC Void ssRegMainThread(Void)
8648 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8650 printf("not able to get different Id for main thread\n");
8653 /* Here the default region is added as we dont have any region associated with
8654 * Main thread. The thread should not perform any allocation except
8655 * the initial configuratin
8657 #ifdef XEON_SPECIFIC_CHANGES
8658 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8660 SS_GET_THREAD_MEM_REGION() =
8667 * Fun: ssCheckAndAddMemoryRegionMap
8669 * Desc: This function is used to add the memory region
8670 * mapping for the provided sTsk associated thread.
8671 * If the threadId can be placed in the thread memory
8672 * region mapping table and returns success if it is able
8673 * to place. If not, it keeps the thread ID in the static
8674 * local array and increments the count. Once thread Id
8675 * is successfully placed in the thread memory region mapping
8676 * table, pthread_cancel is sent for all the previous threads
8677 * which are failed to place in table.
8679 * Ret: TRUE - Thread ID successfully placed in thread memory region
8681 * FALSE - If thread Id is not placed in thread memory region
8684 * Notes:mapping tablemapping tablng tablee
8689 PUBLIC S32 ssCheckAndAddMemoryRegionMap
8691 pthread_t threadId, /* Thread Id of system task */
8692 Region region /* Region associated with thread */
8695 PRIVATE U32 createdThreads;
8696 PRIVATE pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8699 TRC1(ssCheckAndAddMemoryRegionMap);
8701 /* Here 0xFF is considered as invalid region and if the mapping table
8702 * contains 0xFF, that mapping entry is free
8704 if(SS_INVALID_THREAD_REG_MAP !=
8705 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8707 /* Klock work fix ccpu00148484 */
8708 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8710 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8711 printf("Not able to get the different thread ID, exiting\n");
8714 createdThreadIds[createdThreads++] = threadId;
8717 /* If we found free mapping table entry, place the region and send pthread_cancel
8718 * for all the thread Ids which are created before this
8720 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8721 #ifdef XEON_SPECIFIC_CHANGES
8722 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8723 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8724 SS_MAX_THREAD_REGION_MAP), region);
8726 for(indx = 0; indx < createdThreads; indx++)
8728 #ifdef XEON_SPECIFIC_CHANGES
8729 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8731 pthread_cancel(createdThreadIds[indx]);
8737 } /* ssCheckAndAddMemoryRegionMap */
8741 * Fun: ssCheckAndDelMemoryRegionMap
8743 * Desc: This function is used to add the memory region
8744 * mapping for the provided sTsk associated thread.
8745 * If the threadId can be placed in the thread memory
8746 * region mapping table and returns success if it is able
8747 * to place. If not, it keeps the thread ID in the static
8748 * local array and increments the count. Once thread Id
8749 * is successfully placed in the thread memory region mapping
8750 * table, pthread_cancel is sent for all the previous threads
8751 * which are failed to place in table.
8753 * Ret: TRUE - Thread ID successfully placed in thread memory region
8755 * FALSE - If thread Id is not placed in thread memory region
8758 * Notes:mapping tablemapping tablng tablee
8763 PUBLIC S32 ssCheckAndDelMemoryRegionMap
8765 pthread_t threadId /* Thread Id of system task */
8769 TRC1(ssCheckAndDelMemoryRegionMap);
8771 /* Raghu To-Do Check with team, is it necessary to acquire lock
8772 * as del and add may go parallel */
8773 /* Here 0xFF is considered as invalid region and if the mapping table
8774 * contains 0xFF, that mapping entry is free
8776 if(SS_INVALID_THREAD_REG_MAP ==
8777 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8780 printf("Invalid Thread ID (%ld)\n", (U32)threadId);
8782 printf("Invalid Thread ID (%d)\n", (U32)threadId);
8786 /* If we found free mapping table entry, place the region and send pthread_cancel
8787 * for all the thread Ids which are created before this
8789 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8793 } /* ssCheckAndAddMemoryRegionMap */
8797 #ifdef SS_TSKLOG_ENABLE
8802 * Desc: This function will return current time through input parameter.
8805 * RFAILED - failed, general (optional)
8812 PUBLIC S16 SStartTask
8814 VOLATILE U32 *startTime,
8818 PUBLIC S16 SStartTask(startTime, taskId)
8819 VOLATILE U32 *startTime;
8823 #ifdef MSPD_MLOG_NEW
8824 *startTime = GetTIMETICK();
8833 * Desc: This function will return current time through input parameter.
8834 * and take the difference of start time provided as input parameter
8838 * RFAILED - failed, general (optional)
8845 PUBLIC S16 SStopTask
8847 VOLATILE U32 startTime,
8851 PUBLIC S16 SStopTask(startTime, taskId)
8852 VOLATILE U32 startTime;
8859 case PID_MAC_HARQ_IND:
8860 case PID_SCH_TTI_IND:
8862 case PID_MAC_DAT_IND:
8863 case PID_MAC_SF_ALLOC_REQ:
8864 case PID_MAC_STA_RSP:
8865 case PID_MAC_DL_SCHD:
8866 case PID_MAC_DL_CQI_IND:
8867 case PID_MAC_UL_CQI_IND:
8868 case PID_MAC_UL_SCHD:
8869 case PID_MAC_TTI_IND:
8870 case PID_CL_RCV_PHY_MSG:
8871 case PID_CL_HARQ_STA_IND:
8872 case PID_MAC_AM_HARQ_RLS:
8873 case PID_CL_DL_BATCH_PROC:
8874 case PID_CL_DLM_PRC_TTI_IND:
8875 case PID_CRC_IND_REAL:
8876 case PID_CRC_IND_DUMMY:
8877 case PID_TTI_LATENCY:
8878 case PID_RECPREQ_PROC:
8881 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8883 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8886 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8894 PUBLIC S16 SStartTask
8896 VOLATILE U32 * startTime,
8900 PUBLIC S16 SStartTask(startTime, taskId)
8901 VOLATILE U32 * startTime;
8910 PUBLIC S16 SStopTask
8912 VOLATILE U32 startTime,
8916 PUBLIC S16 SStopTask(startTime, taskId)
8917 VOLATILE U32 startTime;
8924 #endif /*#ifdef SS_TSKLOG_ENABLE */
8925 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8927 * This primitive is used to calculate the CPU Utilization per Core
8932 * @return Void - function is always success
8935 PUBLIC Void UpdateSocCpuInfo
8937 CmCpuStatsInfo *cpuInfo,
8941 PUBLIC Void UpdateSocCpuInfo(*cpuInfo, idx)
8942 CmCpuStatsInfo *cpuInfo;
8947 S8 mipsStr[MIPS_STRING_LEN];
8954 /* Open the file which holds the MIPS available value */
8955 mipsFd = fopen(MIPS_FILE, "r");
8962 /* Get the free mips available value from the file */
8963 if(NULLP == fgets(mipsStr, 24, mipsFd))
8965 printf("fgets to get the free mips available failed\n");
8970 strtok(mipsStr, " ");
8972 strPart = strtok(NULLP, " ");
8974 if(idx == CM_L2_CPU_UTIL)
8976 if(strPart != NULLP)
8978 l2FreeCpu = atoi(strPart);
8979 l2CpuUsed = 100 - l2FreeCpu;
8980 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8981 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);;
8982 cpuInfo->cpuUtil[0].numSamples++;
8985 if(idx == CM_L3_CPU_UTIL)
8987 strPart = strtok(NULLP, " ");
8988 if(strPart != NULLP)
8990 l3FreeCpu = atoi(strPart);
8991 l3CpuUsed = 100 - l3FreeCpu;
8992 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8993 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);;
8994 cpuInfo->cpuUtil[0].numSamples++;
8997 if(idx == CM_L2_CPU_UTIL)
8999 cpuInfo->numCores = CM_NUM_L2_CORES ;
9001 else if(idx == CM_L3_CPU_UTIL)
9003 cpuInfo->numCores = CM_NUM_L3_CORES ;
9009 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
9010 #ifdef SS_MULTICORE_SUPPORT
9013 * Fun: Add Timer thread into system task table
9015 * Desc: This function is used to add the system task
9016 * associated with Timer thread.
9026 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(
9030 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(idx)
9037 TRC1(ssdReAddTmrSTsk);
9039 /* lock the system task table */
9040 ret = SLock(&osCp.sTskTblLock);
9044 #if (ERRCLASS & ERRCLS_DEBUG)
9045 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
9046 "Could not lock system task table");
9052 /* initialize the system task entry with the information we have */
9053 sTsk = &osCp.sTskTbl[idx];
9058 SDestroyLock(&sTsk->lock);
9059 ssDestroyDmndQ(&sTsk->dQ);
9062 /* store the system task priority */
9063 sTsk->tskPrior = SS_NORM_TSK_PRI;
9065 /* initialize the demand queue */
9066 if (ssInitDmndQ(&sTsk->dQ) != ROK)
9069 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9071 #if (ERRCLASS & ERRCLS_DEBUG)
9072 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
9073 "Could not give the Semaphore");
9078 #if (ERRCLASS & ERRCLS_DEBUG)
9079 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
9080 "Could not initialize demand queue");
9086 /* initialize the system task entry lock */
9087 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
9089 ssDestroyDmndQ(&sTsk->dQ);
9091 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9093 #if (ERRCLASS & ERRCLS_DEBUG)
9094 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
9095 "Could not give the Semaphore");
9100 #if (ERRCLASS & ERRCLS_DEBUG)
9101 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9102 "Could not initialize system task entry lock");
9109 /* success, update the table */
9110 sTsk->tskId = idx + 1;
9112 sTsk->termPend = FALSE;
9114 /* unlock the system task table */
9116 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9118 #if (ERRCLASS & ERRCLS_DEBUG)
9119 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9120 "Could not give the Semaphore");
9127 #endif /* SS_MULTICORE_SUPPORT */
9132 * Fun: Initialize timer table
9134 * Desc: This function initializes MTSS-specific information
9135 * in the timer table.
9145 PUBLIC S16 ssdReInitTmr
9150 PUBLIC S16 ssdReInitTmr()
9153 pthread_attr_t attr;
9154 struct sched_param param_sched;
9155 #ifndef XEON_SPECIFIC_CHANGES
9158 #ifdef SS_MULTICORE_SUPPORT
9160 #endif /* SS_MULTICORE_SUPPORT */
9161 #ifdef SS_THR_REG_MAP
9162 U32 threadCreated = FALSE;
9163 #endif /* SS_THR_REG_MAP */
9167 #ifndef XEON_SPECIFIC_CHANGES
9168 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9171 #if (ERRCLASS & ERRCLS_DEBUG)
9172 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9173 "Could not give the Semaphore");
9179 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9180 /* mt010.21: addition */
9182 #ifdef SS_MULTICORE_SUPPORT
9183 sTsk = ssdReAddTmrSTsk(0);
9188 #endif /* SS_MULTICORE_SUPPORT */
9189 /* create the timer handler thread */
9191 pthread_attr_init(&attr);
9192 /* mt021.201 - Addition to set stack size */
9193 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9194 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9195 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9196 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9197 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9198 pthread_attr_setschedparam(&attr, ¶m_sched);
9201 #ifdef SS_THR_REG_MAP
9202 /* When the thread is created, we check for the memory mapping table if
9203 * threadId can be placed in thread memory map table. If it is not able to place
9204 * threadId is stored in tmporary array. Once thread is created successful,
9205 * thread_cancel is sent for each thread which are created before. All the
9206 * threads are made to wait on sema which is cancel point for thread.
9208 while(threadCreated == FALSE)
9211 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9213 /* mt020.201 - Addition for destroying thread attribute object attr */
9214 pthread_attr_destroy(&attr);
9219 #ifdef SS_THR_REG_MAP
9220 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9223 #endif /* SS_THR_REG_MAP */
9224 #ifdef SS_MEM_WL_DEBUG
9225 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9228 /* mt020.201 - Addition for destroying thread attribute object attr */
9229 pthread_attr_destroy(&attr);
9230 sem_post(&osCp.dep.ssStarted);
9234 /**********************************************************************
9236 **********************************************************************/