1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: Multi-threaded System Services - Solaris
25 Desc: C source code for the MTSS-Solaris implementation of
30 *********************************************************************21*/
35 #ifndef _POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE 199309L
38 /* mt003.301 moved env files to use the __USE_UNIX98 flag in sys includes */
39 #include "envopt.h" /* environment options */
40 #include "envdep.h" /* environment dependent */
41 #include "envind.h" /* environment independent */
48 #include <sys/types.h>
53 /* mt003.301: included sys/time.h
54 * for both solaris and linux
57 /* mt008.21: addition */
62 /* header include files (.h) */
65 #include "gen.h" /* general layer */
66 #include "ssi.h" /* system services */
68 #include "cm5.h" /* common timers */
70 #include "mt_ss.h" /* MTSS specific */
71 #include "mt_err.h" /* MTSS error defines */
73 #include "ss_queue.h" /* queues */
74 #include "ss_task.h" /* tasking */
75 #include "ss_msg.h" /* messaging */
76 #include "ss_mem.h" /* memory management interface */
77 #include "ss_gen.h" /* general */
78 /* mt003.301 Additions - Task deregistration */
79 #include "ss_err.h" /* error */
80 #include "cm_mem.h" /* common memory manager */
81 #include "cm_lte.h" /* common lte param */
82 /* mt001.301 : Additions */
83 #ifdef SS_THREAD_PROFILE
86 #ifdef SS_LOCKLESS_MEMORY
91 /* multi-core support enhancement */
92 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
93 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
99 #include <sys/types.h>
100 #include <sys/processor.h>
101 #include <sys/procset.h>
103 #endif /* SS_LINUX */
104 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
105 /* mt001.301 : Additions */
107 #include <sys/types.h>
108 #include <sys/socket.h>
109 #include <netinet/in.h>
110 #include <arpa/inet.h>
111 #endif /* SS_WATCHDOG */
113 /* header/extern include files (.x) */
115 #include "gen.x" /* general layer */
116 #include "ssi.x" /* system services */
118 #include "cm5.x" /* common timers */
120 #include "mt_ss.x" /* MTSS specific */
121 #ifdef SS_LOCKLESS_MEMORY
122 #include "mt_ss_wl.x" /* MTSS specific */
123 #endif /* SS_LOCKLESS_MEMORY */
125 #include "ss_queue.x" /* queues */
126 #include "ss_task.x" /* tasking */
127 #include "ss_timer.x" /* timers */
128 #include "ss_strm.x" /* STREAMS */
129 #include "ss_msg.x" /* messaging */
130 #include "ss_mem.x" /* memory management interface */
131 #include "ss_drvr.x" /* driver tasks */
132 #include "ss_gen.x" /* general */
133 #ifdef SS_LOCKLESS_MEMORY
134 #include "cm_llist.x"
136 #include "cm_mem_wl.x" /* common memory manager */
138 #include "cm_mem.x" /* common memory manager */
139 #endif /* SS_LOCKLESS_MEMORY */
140 #include "cm_lte.x" /* common memory manager */
141 /* mt001.301 : Additions */
142 #ifdef SS_LOGGER_SUPPORT
144 #endif /* SS_LOGGER_SUPPORT */
146 /*mt005.301: Cavium Changes */
147 #ifdef SS_SEUM_CAVIUM
148 /* cvmx includes files */
149 #include "cvmx-config.h"
151 #include "cvmx-pow.h"
152 #include "cvmx-tim.h"
153 #include "cvmx-fpa.h"
154 #include "cvmx-helper-fpa.h"
155 #include "cvmx-malloc.h"
156 #endif /* SS_SEUM_CAVIUM */
159 #include "mt_plat_t33.h"
160 #include "mt_plat_t33.x"
161 #include "sys/syscall.h"
164 #ifdef RGL_SPECIFIC_CHANGES
166 #include <hugetlbfs.h>
169 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
170 EXTERN S16 rgBatchProc (Void);
172 #ifdef RLC_MAC_DAT_REQ_RBUF
173 EXTERN S16 rgDlDatReqBatchProc ARGS((
176 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
177 EXTERN S16 rgBatchProc ARGS((
181 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
182 /* general purpose debug zone */
183 char my_buffer2[4096 * 4] = { 0 };
184 char my_buffer[4096] = { 0 };
185 int my_buffer_idx = 0;
189 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
191 struct sigcontext my_uc_mcontext = { 0 };
196 #include <ucontext.h>
200 #define SIGSEGV_STACK_GENERIC
201 #define REGFORMAT "%x\n"
203 #ifdef XEON_SPECIFIC_CHANGES
204 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
207 void dump_external(void);
210 PRIVATE Void mtDelSigals
215 PRIVATE Void mtDelSignals()
220 memset(&sa, 0, sizeof(struct sigaction));
221 sigemptyset(&sa.sa_mask);
222 sa.sa_handler = SIG_DFL;
223 sigaction(SIGSEGV, &sa, NULL);
225 memset(&sa, 0, sizeof(struct sigaction));
226 sigemptyset(&sa.sa_mask);
227 sa.sa_handler = SIG_DFL;
228 sigaction(SIGILL, &sa, NULL);
232 static void signal_segv(int signum, siginfo_t * info, void *ptr)
234 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
237 ucontext_t *ucontext = (ucontext_t *) ptr;
238 #ifdef XEON_SPECIFIC_CHANGES
240 int *p32 = (int *) 0x2fff0000;
245 printf("segv ooops @ %p\n", info->si_addr);
248 printf("Segmentation Fault!\n");
249 printf("info.si_signo = %d\n", signum);
250 printf("info.si_errno = %d\n", info->si_errno);
251 printf("info.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
252 printf("info.si_addr = %p\n", info->si_addr);
254 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
257 #ifndef RGL_SPECIFIC_CHANGES
258 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
259 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
260 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
261 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
262 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
263 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
264 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
265 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
266 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
267 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
268 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
269 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
270 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
271 printf("reg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
272 printf("reg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
273 printf("reg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
274 printf("reg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
277 printf("Stack trace (non-dedicated):\n");
279 sz = backtrace(buffer, 50);
280 strings = backtrace_symbols(buffer, sz);
281 for (i = 0; i < sz; ++i)
282 printf("%s\n", strings[i]);
284 printf("End of stack trace.");
286 #ifdef XEON_SPECIFIC_CHANGES
291 /* Lets first print our debug information */
292 printf("Before dumping our Debug info\n");
294 printf("After dumping our Debug info\n");
296 /* Disable the signal and make the enodeb to dump. This will make
297 * eNB to generate the core with dumping the ccpu log
304 /* End printing debug information */
309 /*** TBD: IMPORTANT ***
310 *** The following definition is temporary. This must be removed
311 *** when all products have been updated with latest ssi.h file OR
312 *** all ssi.h files have been updated to contain this definitions
314 /* New error class for FTHA added */
316 #define ERRCLS_FTHA 0x8
317 #endif /* ERRCLS_FTHA */
319 typedef struct _SPThreadCreateArg
321 void *argument; /* argument that is to be passed to the actual pthread */
322 void *(*start_routine) (void *); /* function from which pthread starts */
325 PUBLIC void *pthreadCreateHdlr(void* arg);
327 #ifdef SS_LOCKLESS_MEMORY
328 PUBLIC Buffer *mtTskBuffer1;
329 PUBLIC Buffer *mtTskBuffer2;
331 EXTERN pthread_t tmpRegTidMap[20];
332 EXTERN U8 stopBtInfo;
333 EXTERN S16 SGlobMemInfoShow(void);
334 #endif /* SS_LOCKLESS_MEMORY */
337 EXTERN APP_CONTEXT AppContext;
338 EXTERN S32 clusterMode;
341 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
342 EXTERN unsigned int tlPost(void *handle);
345 /* forward references */
346 /* mt003.301 Modifications - Moved to ss_gen.x */
347 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
348 PUBLIC Void *mtTskHdlrT2kL2 ARGS((Void*));
349 PUBLIC void mtSigSegvHndlr ARGS((void));
350 PUBLIC void mtSigUsr2Hndlr ARGS((void));
353 PRIVATE S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
354 PRIVATE Void *mtTskHdlr ARGS((void *));
355 PRIVATE S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
357 PRIVATE Void *mtTmrHdlr ARGS((void *));
358 PRIVATE Void mtTimeout ARGS((PTR tCb, S16 evnt));
360 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
361 PRIVATE Void mtIntSigHndlr ARGS((int));
362 PRIVATE Void mtExitClnup ARGS((void));
365 PRIVATE Void *mtConHdlr ARGS((void *));
369 #ifdef SS_DRVR_SUPPORT
370 PRIVATE Void *mtIsTskHdlr ARGS((void *));
374 /* mt020.201 - Addition for no command line available */
376 PRIVATE Void mtGetOpts ARGS((void));
377 /* mt003.301 Additions - File Based task registration made
378 * common for both MULTICORE and NON-MULTICORE
380 PRIVATE Bool fileBasedMemCfg = FALSE;
383 /* mt033.201 - addition of local function to print the statistics such as
384 * (size vs. numAttempts) and (allocations vs. deallocations)
386 #ifdef SSI_DEBUG_LEVEL1
387 PRIVATE S16 SPrintRegMemStats ARGS((Region region));
388 #endif /* SSI_DEBUG_LEVEL1 */
390 #ifdef SS_MULTICORE_SUPPORT
391 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void);
392 PRIVATE SsSTskEntry* ssdReAddTmrSTsk ARGS((U8 idx));
393 #ifndef SS_LOCKLESS_MEMORY
394 #ifndef RGL_SPECIFIC_CHANGES
395 PRIVATE S16 ssdInitMemInfo ARGS((void));
400 /* mt005.301: Cavium changes */
401 #ifdef SS_SEUM_CAVIUM
402 PRIVATE Void *workRcvTsk ARGS((void *));
403 #endif /* SS_SEUM_CAVIUM */
405 #ifdef SS_THR_REG_MAP
406 PUBLIC S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
408 PUBLIC S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
409 #endif /* SS_THR_REG_MAP */
411 /* type declarations */
413 #ifdef SS_DRVR_SUPPORT
414 typedef struct mtIsFlag
424 /* public variable declarations */
426 PUBLIC Cntr cfgNumRegs = SS_MAX_REGS;
427 /* Set memory configuration as false.
428 * Set to true if memory configuration through file is successfull.
430 PUBLIC Bool memConfigured = FALSE;
431 /* mt022.201 - Modification for shared memory relay region and memcal tool */
432 PUBLIC SsRegCfg cfgRegInfo[SS_MAX_REGS] =
435 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
437 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
438 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
439 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
440 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
441 { SS_POOL_STATIC, 0 }
447 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
449 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
450 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
451 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
452 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
453 { SS_POOL_STATIC, 0 }
456 #endif /* INTEL_WLS */
458 #ifdef SS_LOCKLESS_MEMORY
461 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
463 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
464 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
465 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
466 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
467 { SS_POOL_STATIC, 0 }
471 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
473 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
474 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
475 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
476 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
477 { SS_POOL_STATIC, 0 }
481 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
483 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
484 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
485 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
486 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
487 { SS_POOL_STATIC, 0 }
491 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
493 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
494 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
495 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
496 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
497 { SS_POOL_STATIC, 0 }
500 #endif /* SS_LOCKLESS_MEMORY */
502 /* mt003.301 Modifications - File Based task registration made
503 * common for both MULTICORE and NON-MULTICORE
506 #ifdef SS_LOCKLESS_MEMORY
507 PUBLIC MtDynMemCfg mtDynMemoCfg =
509 SS_MAX_REGS, /* number of regions */
512 SS_DFLT_REGION, /* region id */
513 MT_MAX_BKTS, /* number of buckets */
515 /* block size, no. of blocks, Upper threshold, lower threshold */
516 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
517 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
518 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
519 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
523 SS_DFLT_REGION + 1, /* region id */
524 MT_MAX_BKTS, /* number of buckets */
526 /* block size, no. of blocks, Upper threshold, lower threshold */
527 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
528 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
529 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
530 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
534 SS_DFLT_REGION + 2, /* region id */
535 MT_MAX_BKTS, /* number of buckets */
537 /* block size, no. of blocks, Upper threshold, lower threshold */
538 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
539 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
540 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
541 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
545 SS_DFLT_REGION + 3, /* region id */
546 MT_MAX_BKTS, /* number of buckets */
548 /* block size, no. of blocks, Upper threshold, lower threshold */
549 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
550 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
551 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
552 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
556 SS_DFLT_REGION + 4, /* region id */
557 MT_MAX_BKTS, /* number of buckets */
559 /* block size, no. of blocks, Upper threshold, lower threshold */
560 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
561 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
562 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
563 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
566 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
569 SS_DFLT_REGION + 4, /* region id */
570 MT_MAX_BKTS, /* number of buckets */
572 /* block size, no. of blocks, Upper threshold, lower threshold */
573 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
574 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
575 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
576 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
584 PUBLIC MtGlobMemCfg mtGlobMemoCfg =
586 MT_MAX_BKTS, /* number of buckets */
589 /* block size, no. of blocks, Upper threshold, lower threshold */
590 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
591 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
592 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
593 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
595 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
596 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
597 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
598 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
602 #endif /* SS_LOCKLESS_MEMORY */
604 /* mt022.201 - Modification for memory calculator tool */
605 /* mt018.201 - added memory configuration matrix */
606 PUBLIC MtMemCfg mtMemoCfg =
609 SS_MAX_REGS - 1, /* number of regions */
611 #ifndef XEON_SPECIFIC_CHANGES
612 SS_MAX_REGS, /* number of regions */
619 SS_DFLT_REGION, /* region id */
620 MT_MAX_BKTS, /* number of buckets */
621 MT_HEAP_SIZE, /* heap size */
623 #ifndef XEON_SPECIFIC_CHANGES
624 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
625 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
626 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
627 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
629 {256, 491520}, /* 60 pages of 2M*/
630 {512, 12288}, /* 3 pages of 2M */
631 {2048, 99328}, /* 97 Pages of 2M */
632 {8192, 75008}, /* 293 Pages of 2M */
633 {16384, 4096} /* 32 pages of 2M */
638 #ifndef SS_LOCKLESS_MEMORY
640 SS_DFLT_REGION + 1, /* region id */
641 MT_MAX_BKTS, /* number of buckets */
642 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
644 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
645 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
646 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
647 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
655 #endif /* SS_LOCKLESS_MEMORY */
656 #endif /* INTEL_WLS */
657 #ifdef SS_LOCKLESS_MEMORY
659 SS_DFLT_REGION + 1, /* region id */
660 MT_MAX_BKTS, /* number of buckets */
661 MT_HEAP_SIZE, /* heap size */
663 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
664 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
665 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
666 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
670 SS_DFLT_REGION + 2, /* region id */
671 MT_MAX_BKTS, /* number of buckets */
672 MT_HEAP_SIZE, /* heap size */
674 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
675 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
676 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
677 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
681 SS_DFLT_REGION + 3, /* region id */
682 MT_MAX_BKTS, /* number of buckets */
683 MT_HEAP_SIZE, /* heap size */
685 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
686 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
687 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
688 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
692 SS_DFLT_REGION + 4, /* region id */
693 MT_MAX_BKTS, /* number of buckets */
694 MT_HEAP_SIZE, /* heap size */
696 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
697 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
698 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
699 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
703 #endif /* SS_LOCKLESS_MEMORY */
707 /* mt003.301 Modifications - File Based task registration made
708 * common for both MULTICORE and NON-MULTICORE
709 * bucket info, as different regions may request for different no.
712 PUBLIC MtBktCfg mtBktInfo[MT_MAX_BKTS];
713 PUBLIC S16 msArgc; /* argc */
714 PUBLIC Txt **msArgv; /* argv */
715 PUBLIC S16 msOptInd; /* SGetOpt vars */
716 PUBLIC S8 *msOptArg; /* SGetOpt vars */
720 typedef struct _MtRegMemSz
726 PRIVATE MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
730 /* private variable declarations */
731 /* mt018.201 - change mtCMMRegCfg as array of pointers */
732 PRIVATE CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
733 PRIVATE CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
734 /* mt003.301 - Fixed compilation warnings */
735 /*mt004.301-addede new veriable for FAP*/
736 /*mt010.301 - removed veriable defined for FA*/
742 void mtSetNtlHdl(unsigned int hdl)
747 unsigned int mtGetNtlHdl()
749 return(osCp.ntl.hdl);
756 RETVALUE(osCp.wls.intf);
759 #ifdef XEON_MULTIPLE_CELL_CHANGES
760 EXTERN S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
761 EXTERN S16 smWrReadWlsConfigParams (Void);
764 PRIVATE int SOpenWlsIntf()
767 #define WLS_DEVICE_NAME "/dev/wls"
769 #ifdef XEON_SPECIFIC_CHANGES
770 #ifdef XEON_MULTIPLE_CELL_CHANGES
771 hdl = WLS_Open(gWrWlsDeviceName, 1);
773 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
776 hdl = WLS_Open(WLS_DEVICE_NAME, 0);
783 printf("Could not open WLS Interface \n");
798 * Desc: This function is the entry point for the final binary. It
799 * calls SInit() in the common code. It can be replaced by a
800 * user function if required (SInit() must still be called).
802 * Ret: none on success
813 int argc, /* argument count */
814 char **argv /* argument vector */
817 PUBLIC int main(argc, argv)
818 int argc; /* argument count */
819 char **argv; /* argument vector */
824 #ifdef XEON_MULTIPLE_CELL_CHANGES
825 /* Read the WLS parameters from the file and copy into global control block */
826 if(smWrReadWlsConfigParams() != ROK)
828 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
830 } /* end of if statement */
836 #endif /* INTEL_WLS */
840 /* mt003.301 Modifications */
843 printf("\n SInit failed, SSI could not start \n");
844 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
848 /*mt010.301 cleanup part exposed to user*/
859 * Desc: This function is the entry point for the final binary. It
860 * calls SInit() in the common code. It can be replaced by a
861 * user function if required (SInit() must still be called).
863 * Ret: none on success
874 int argc, /* argument count */
875 char **argv /* argument vector */
878 PUBLIC int ssMain(argc, argv)
879 int argc; /* argument count */
880 char **argv; /* argument vector */
897 * initialization functions
902 * Fun: Initialize OS control point
904 * Desc: This function initializes MTSS-specific information
905 * in the OS control point.
915 PUBLIC S16 ssdInitGen
920 PUBLIC S16 ssdInitGen()
923 struct sigaction act;
925 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
931 /*mt014.301 : 4GMX release related changes*/
935 /* mt005.301 : Cavium changes */
936 #ifdef SS_SEUM_CAVIUM
937 /* set group mask for the core */
938 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
939 #endif /* SS_SEUM_CAVIUM */
941 osCp.dep.sysTicks = 0;
943 /* mt020.201 - Addition for no command line available */
945 /* parse command line */
947 /* mt003.301 Additions */
948 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
950 printf("\n File Based Memory configuration failed \n");
955 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
956 #ifndef SS_LOCKLESS_MEMORY
957 #ifdef SS_MULTICORE_SUPPORT
958 if(memConfigured == FALSE)
964 /* initialize the started semaphore */
965 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
970 /* mt028.201 added compile time flag to allow not to mask signals */
972 /* mask all signals in the main thread */
974 sigdelset(&set, SIGINT);
975 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
976 sigdelset(&set, SIGSEGV);
977 sigdelset(&set, SIGUSR2);
978 sigdelset(&set, SIGILL);
979 #ifdef XEON_SPECIFIC_CHANGES
980 sigdelset(&set, SIGABRT);
981 sigdelset(&set, SIGTERM);
982 sigdelset(&set, SIGHUP);
985 pthread_sigmask(SIG_SETMASK, &set, NULLP);
986 #endif /* UNMASK_SIG */
988 /* install a SIGINT handler to shutdown */
989 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
991 /*Initialize SIGSEGV Signal */
992 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
994 memset(&sa, 0, sizeof(struct sigaction));
995 sigemptyset(&sa.sa_mask);
996 sa.sa_sigaction = signal_segv;
997 sa.sa_flags = SA_SIGINFO;
998 #ifndef XEON_SPECIFIC_CHANGES
999 sigaction(SIGSEGV, &sa, NULL);
1001 memset(&sa, 0, sizeof(struct sigaction));
1002 sigemptyset(&sa.sa_mask);
1003 sa.sa_sigaction = signal_segv;
1004 sa.sa_flags = SA_SIGINFO;
1006 sigaction(SIGILL, &sa, NULL);
1008 if(sigaction(SIGILL, &sa, NULL) != 0)
1010 printf("Failed to process sigaction for the SIGILL\n");
1013 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1015 printf("Failed to process sigaction for the SIGSEGV\n");
1018 if(sigaction(SIGABRT, &sa, NULL) != 0)
1020 printf("Failed to process sigaction for the SIGABRT\n");
1023 if(sigaction(SIGTERM, &sa, NULL) != 0)
1025 printf("Failed to process sigaction for the SIGTERM\n");
1028 if(sigaction(SIGHUP, &sa, NULL) != 0)
1030 printf("Failed to process sigaction for the SIGHUP\n");
1035 signal (SIGSEGV, mtSigSegvHndlr);
1036 signal (SIGKILL, mtSigSegvHndlr);
1037 signal (SIGUSR2, mtSigUsr2Hndlr);
1042 signal (SIGINT, mtStopHndlr);
1045 act.sa_handler = mtIntSigHndlr;
1046 sigfillset(&act.sa_mask);
1048 if (sigaction(SIGINT, &act, NULLP) != 0)
1054 /* mt040.201 initialise random seed */
1055 osCp.dep.randSeed = time(NULLP);
1063 * Fun: De-initialize OS control point
1065 * Desc: This function reverses the initialization in ssdInitGen().
1075 PUBLIC Void ssdDeinitGen
1080 PUBLIC Void ssdDeinitGen()
1086 sem_destroy(&osCp.dep.ssStarted);
1091 #ifdef SS_LOCKLESS_MEMORY
1095 * Fun: ssPutDynMemBlkSet
1097 * Desc: Returns the set of dynamic Blocks into the global region
1100 * Ret: ROK - successful,
1101 * RFAILED - unsuccessful.
1109 PUBLIC S16 ssPutDynMemBlkSet
1111 U8 bktIdx, /* Index to bucket list */
1112 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1113 added to global region */
1116 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1117 U8 bktIdx; /* Index to bucket list */
1118 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1119 added to global region */
1122 CmMmGlobRegCb *globReg;
1123 CmMmGlobalBktCb *bktCb;
1127 globReg = osCp.globRegCb;
1129 #if (ERRCLASS & ERRCLS_INT_PAR)
1130 if(bktIdx >= globReg->numBkts)
1134 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1136 bktCb = &(globReg->bktTbl[bktIdx]);
1138 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1140 blkPtr = dynMemSetElem->nextBktPtr;
1141 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1142 free((Void *)blkPtr);
1145 dynMemSetElem->nextBktPtr = NULLP;
1146 dynMemSetElem->numFreeBlks = 0;
1153 * Fun: ssGetDynMemBlkSet
1155 * Desc: Gets the set of dynamic memory blocks from the global region
1158 * Ret: ROK - successful,
1159 * RFAILED - unsuccessful.
1167 PUBLIC S16 ssGetDynMemBlkSet
1169 U8 bktIdx, /* Index to bucket list */
1170 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1171 with new set values */
1174 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1175 U8 bktIdx; /* Index to bucket list */
1176 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1177 with new set values */
1181 CmMmGlobRegCb *globReg;
1182 CmMmGlobalBktCb *bktCb;
1187 globReg = osCp.globRegCb;
1189 #if (ERRCLASS & ERRCLS_INT_PAR)
1190 if(bktIdx >= globReg->numBkts)
1194 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1196 bktCb = &(globReg->bktTbl[bktIdx]);
1197 basePtr = &(dynMemSetElem->nextBktPtr);
1199 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1201 blkPtr = (Data *)malloc(bktCb->size);
1203 basePtr = (CmMmEntry **)blkPtr;
1206 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1210 } /* ssGetDynMemBlkSet */
1215 * Fun: ssPutDynMemBlkSet
1217 * Desc: Returns the set of dynamic Blocks into the global region
1220 * Ret: ROK - successful,
1221 * RFAILED - unsuccessful.
1229 PUBLIC S16 ssPutDynMemBlkSet
1231 U8 bktIdx, /* Index to bucket list */
1232 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1233 added to global region */
1234 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1237 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1238 U8 bktIdx; /* Index to bucket list */
1239 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1240 added to global region */
1241 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1244 CmMmGlobRegCb *globReg;
1245 CmMmGlobalBktCb *bktCb;
1247 CmMmBlkSetElement *globMemNode;
1250 TRC1(ssPutDynMemBlkSet);
1252 globReg = osCp.globRegCb;
1254 #if (ERRCLASS & ERRCLS_INT_PAR)
1255 if(bktIdx >= globReg->numBkts)
1259 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1261 bktCb = &(globReg->bktTbl[bktIdx]);
1263 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1264 try lock is used as it is not required to block as it will be taken
1265 in the next go else it will be blocked for lock as we have to get the
1268 SLock(&(bktCb->bucketLock));
1274 /* Get a free node from the free node linked list */
1275 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1276 if(lstNode == NULLP)
1278 SUnlock(&(bktCb->bucketLock));
1282 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1284 /* Copy the content of the received element information on to free node
1285 * and add it to valid linked list */
1286 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1287 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1288 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1289 dynMemSetElem->numFreeBlks = 0;
1290 dynMemSetElem->nextBktPtr = NULLP;
1292 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1294 SUnlock(&(bktCb->bucketLock));
1302 * Fun: ssGetDynMemBlkSet
1304 * Desc: Gets the set of dynamic memory blocks from the global region
1307 * Ret: ROK - successful,
1308 * RFAILED - unsuccessful.
1310 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1317 PUBLIC S16 ssGetDynMemBlkSet
1319 U8 bktIdx, /* Index to bucket list */
1320 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1321 with new set values */
1322 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1325 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1326 U8 bktIdx; /* Index to bucket list */
1327 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1328 with new set values */
1329 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1332 CmMmGlobRegCb *globReg;
1333 CmMmGlobalBktCb *bktCb;
1335 CmMmBlkSetElement *globMemNode;
1338 TRC1(ssGetDynMemBlkSet);
1340 globReg = osCp.globRegCb;
1342 #if (ERRCLASS & ERRCLS_INT_PAR)
1343 if(bktIdx >= globReg->numBkts)
1347 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1349 bktCb = &(globReg->bktTbl[bktIdx]);
1351 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1352 try lock is used as it is not required to block as it will be taken
1353 in the next go else it will be blocked for lock as we have to get the
1356 SLock(&(bktCb->bucketLock));
1361 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1363 if(lstNode == NULLP)
1365 SUnlock(&(bktCb->bucketLock));
1369 /* Delete the node from the valid linked list and copy the values of the
1370 * elements of structrues into pointer */
1371 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1372 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1373 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1374 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1376 /* Add this node to the free node linked list */
1377 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1379 SUnlock(&(bktCb->bucketLock));
1383 } /* ssGetDynMemBlkSet */
1386 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1388 PRIVATE U32 memoryCheckCounter;
1391 PUBLIC U32 isMemThreshReached(
1395 PUBLIC U32 isMemThreshReached(reg)
1399 CmMmGlobRegCb *globReg;
1400 CmMmGlobalBktCb *bktCb;
1403 TRC3(isMemThreshReached)
1405 globReg = osCp.globRegCb;
1407 #if (ERRCLASS & ERRCLS_INT_PAR)
1408 if(bktIdx >= globReg->numBkts)
1412 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1414 bktCb = &(globReg->bktTbl[bktIdx]);
1416 if(gDynMemAlrm[bktIdx])
1418 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1419 SLock(&(bktCb->bucketLock));
1420 if(bktCb->listValidBktSet.count > 25)
1422 gDynMemAlrm[bktIdx] = FALSE;
1423 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1425 SUnlock(&(bktCb->bucketLock));
1431 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1433 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1434 SLock(&(bktCb->bucketLock));
1435 if(bktCb->listValidBktSet.count < 15 )
1436 gDynMemAlrm[bktIdx] = TRUE;
1437 memoryCheckCounter = 0;
1438 SUnlock(&(bktCb->bucketLock));
1444 #endif /* USE_MALLOC */
1445 #endif /* SS_LOCKLESS_MEMORY */
1447 #ifdef SS_USE_ICC_MEMORY
1450 * Fun: Initialize region/pool tables
1452 * Desc: This function initializes MTSS-specific information
1453 * in the region/pool tables and configures the common
1454 * memory manager for use.
1464 PUBLIC Void * ssGetIccHdl
1469 PUBLIC Void * ssGetIccHdl()
1473 CmMmDynRegCb *dynRegCb;
1475 /* Klock work fix ccpu00148484 */
1476 if(!(region < SS_MAX_REGS))
1481 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1483 RETVALUE(dynRegCb->iccHdl);
1485 #endif /* SS_USE_ICC_MEMORY */
1487 #ifdef T2K_MEM_LEAK_DBG
1488 extern RegionMemLeakInfo regMemLeakInfo;
1489 #endif /* T2K_MEM_LEAK_DBG */
1493 PUBLIC S16 SPartitionWlsMemory()
1498 U64 pageSize[1], hugePageSize;
1501 long int pageSize[1], hugePageSize;
1504 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1506 U8 *regMemStrtAddr = (U8 *)osCp.wls.allocAddr;
1508 gethugepagesizes(pageSize,1);
1509 hugePageSize = pageSize[0];
1510 for (i = 0; i < 1; i++)
1512 mtRegMemSz[i].startAddr = regMemStrtAddr;
1513 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1515 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1516 reqdSz = numHugePg * hugePageSize;
1517 regMemStrtAddr += reqdSz;
1518 #ifdef T2K_MEM_LEAK_DBG
1519 /* Since wls is region 0 */
1520 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1521 regMemLeakInfo.numActvRegions++;
1522 #endif /* T2K_MEM_LEAK_DBG */
1524 //Store last region addr for validation
1525 mtRegMemSz[i].startAddr = regMemStrtAddr;
1529 #ifdef SS_MEM_WL_DEBUG
1530 PUBLIC Void SChkAddrValid(int type, int region, PTR ptr)
1532 char *tryPtr = NULL;
1533 if(type == 0) //Global
1535 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1536 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1538 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1544 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1546 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1552 #endif /* SS_MEM_WL_DEBUG */
1554 PUBLIC S16 SPartitionStaticMemory(U8 *startAddr)
1559 U8 *regMemStrtAddr = (U8 *)startAddr;
1562 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1563 for (i = 1; i < mtMemoCfg.numRegions; i++)
1565 mtRegMemSz[i].startAddr = regMemStrtAddr;
1566 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1567 regMemStrtAddr += reqdSz;
1568 #ifdef T2K_MEM_LEAK_DBG
1569 { /* Since region 1 onwards are used for non wls */
1570 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1571 regMemLeakInfo.numActvRegions++;
1573 #endif /* T2K_MEM_LEAK_DBG */
1577 PUBLIC S16 SAllocateWlsMem()
1585 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1586 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1588 for (i = 0; i < 1; i++)
1590 /* allocate space for the region */
1591 region = &mtMemoCfg.region[i];
1592 reqdMemSz += region->heapsize;
1593 mtRegMemSz[i].reqdSz += region->heapsize;
1595 for (j = 0; j < region->numBkts; j++)
1597 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1598 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1601 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1602 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1604 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1606 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1608 SPartitionWlsMemory();
1611 PUBLIC S16 SAllocateStaticMem()
1620 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1622 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1623 for (i = 1; i < mtMemoCfg.numRegions; i++)
1625 /* allocate space for the region */
1626 region = &mtMemoCfg.region[i];
1627 reqdMemSz += region->heapsize;
1628 mtRegMemSz[i].reqdSz += region->heapsize;
1630 for (j = 0; j < region->numBkts; j++)
1632 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1633 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1637 startAddr = malloc(reqdMemSz + (1024 * 10));
1639 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1641 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1643 SPartitionStaticMemory(startAddr);
1646 #endif /* INTEL_WLS */
1652 * Fun: Initialize region/pool tables
1654 * Desc: This function initializes MTSS-specific information
1655 * in the region/pool tables and configures the common
1656 * memory manager for use.
1666 PUBLIC S16 ssdInitMem
1671 PUBLIC S16 ssdInitMem()
1674 /* mt018.201 - added local variable */
1679 Txt errMsg[256] = {'\0'};
1680 #ifdef SS_LOCKLESS_MEMORY
1681 CmMmDynRegCb *dynRegCb;
1682 #ifdef SS_USE_ICC_MEMORY
1684 CmMmGlobRegCb *globReg;
1687 #endif /* SS_LOCKLESS_MEMORY */
1691 /* Use the default SSI memory manager if the ICC memory manager is not
1692 * avilable. If ICC memory manager is avilable, it will be used for
1693 * all sharable memory allocation and de-allocation */
1694 #ifdef SS_LOCKLESS_MEMORY
1695 #ifdef SS_USE_ICC_MEMORY
1696 #ifndef YS_PHY_3_8_2
1698 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1700 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1701 if(dynRegCb == NULLP)
1705 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1707 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1709 dynRegCb->region = i;
1710 cmMmDynRegInit(dynRegCb);
1711 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1714 /* ysIccHdl = dynRegCb->iccHdl; */
1717 /* Initialize the global region first */
1718 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1720 if(osCp.globRegCb == NULLP)
1725 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1727 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1729 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1731 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1733 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1735 if(globReg->bktTbl[i].startAddr == NULLP)
1739 globReg->bktTbl[i].poolId = i;
1740 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1741 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1742 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1745 globReg->numBkts = mtGlobMemoCfg.numBkts;
1746 cmMmGlobRegInit(globReg);
1748 /* Initialize the dynamic task regions and sanity check for the theshold
1750 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1752 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1753 if(dynRegCb == NULLP)
1757 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1759 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1760 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1761 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1762 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1764 #ifdef XEON_SPECIFIC_CHANGES
1769 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1770 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1771 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1772 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1773 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1775 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1778 dynRegCb->region = i;
1779 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1780 cmMmDynRegInit(dynRegCb);
1782 #endif /* SS_USE_ICC_MEMORY */
1783 #endif /* SS_LOCKLESS_MEMORY */
1785 #ifdef T2K_MEM_LEAK_DBG
1787 /* Initailize mem leak tool memorys for debguing */
1788 regMemLeakInfo.numActvRegions=0;
1789 for(reg=0; reg <SS_MAX_REGS; reg++)
1791 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1792 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1793 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1794 regMemLeakInfo.regStartAddr[reg] = 0;
1797 regMemLeakInfo.regStartAddr[reg] = 0;
1798 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1800 printf("\n mutex init failed\n");
1806 /* Now allocate WLS memory */
1808 SAllocateStaticMem();
1810 /* mt018.201 - CMM Initialization */
1811 for (i = 0; i < mtMemoCfg.numRegions; i++)
1813 /* allocate space for the region control block */
1814 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1815 #ifdef TENB_RTLIN_CHANGES
1816 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1818 if (mtCMMRegCb[i] == NULLP)
1820 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1821 for the Region:%d control block\n",i);
1823 for (k = 0; k < i; k++)
1825 cmMmRegDeInit(mtCMMRegCb[k]);
1826 free(mtCMMRegCfg[k]->vAddr);
1827 free(mtCMMRegCb[k]);
1828 free(mtCMMRegCfg[k]);
1833 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1834 #ifdef TENB_RTLIN_CHANGES
1835 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1837 if (mtCMMRegCfg[i] == NULLP)
1839 for (k = 0; k < i; k++)
1841 cmMmRegDeInit(mtCMMRegCb[k]);
1842 free(mtCMMRegCfg[k]->vAddr);
1843 free(mtCMMRegCb[k]);
1844 free(mtCMMRegCfg[k]);
1846 free(mtCMMRegCb[i]);
1851 /* allocate space for the region */
1852 region = &mtMemoCfg.region[i];
1853 mtCMMRegCfg[i]->size = region->heapsize;
1854 for (j = 0; j < region->numBkts; j++)
1856 /* mt033.201 - addition for including the header size while computing the total size */
1857 #ifdef SSI_DEBUG_LEVEL1
1858 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1859 (region->bkt[j].numBlks);
1861 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1862 #endif /* SSI_DEBUG_LEVEL1 */
1865 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1867 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1870 #ifdef XEON_SPECIFIC_CHANGES
1871 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1872 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1874 #ifdef TENB_RTLIN_CHANGES
1875 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1878 if (mtCMMRegCfg[i]->vAddr == NULLP)
1880 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1881 for the Region:%d \n",i);
1883 for (k = 0; k < i; k++)
1885 cmMmRegDeInit(mtCMMRegCb[k]);
1886 free(mtCMMRegCfg[k]->vAddr);
1887 free(mtCMMRegCb[k]);
1888 free(mtCMMRegCfg[k]);
1890 free(mtCMMRegCb[i]);
1891 free(mtCMMRegCfg[i]);
1896 /* set up the CMM configuration structure */
1897 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1898 mtCMMRegCfg[i]->chFlag = 0;
1899 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1900 mtCMMRegCfg[i]->numBkts = region->numBkts;
1902 for (j = 0; j < region->numBkts; j++)
1904 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1905 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1908 /* initialize the CMM */
1909 #ifdef SS_LOCKLESS_MEMORY
1910 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1912 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1913 #endif /* SS_LOCKLESS_MEMORY */
1915 for (k = 0; k < i; k++)
1917 cmMmRegDeInit(mtCMMRegCb[k]);
1918 free(mtCMMRegCfg[k]->vAddr);
1919 free(mtCMMRegCb[k]);
1920 free(mtCMMRegCfg[k]);
1922 free(mtCMMRegCfg[i]->vAddr);
1923 free(mtCMMRegCb[i]);
1924 free(mtCMMRegCfg[i]);
1929 /* initialize the STREAMS module */
1930 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1931 if (region->regionId == 0)
1933 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
1935 for (k = 0; k < i; k++)
1937 cmMmRegDeInit(mtCMMRegCb[k]);
1938 free(mtCMMRegCfg[k]->vAddr);
1939 free(mtCMMRegCb[k]);
1940 free(mtCMMRegCfg[k]);
1942 cmMmRegDeInit(mtCMMRegCb[i]);
1943 free(mtCMMRegCfg[i]->vAddr);
1944 free(mtCMMRegCb[i]);
1945 free(mtCMMRegCfg[i]);
1950 /* mt001.301 : Additions */
1951 #ifdef SS_MEM_LEAK_STS
1953 #endif /* SS_MEM_LEAK_STS */
1962 * Fun: De-initialize region/pool tables
1964 * Desc: This function reverses the initialization in ssdInitMem().
1974 PUBLIC Void ssdDeinitMem
1979 PUBLIC Void ssdDeinitMem()
1982 /* mt018.201 - added local variables */
1986 /* mt008.301 Additions */
1987 #ifdef SS_MEM_LEAK_STS
1988 cmDeinitMemLeakMdl();
1989 #endif /* SS_MEM_LEAK_STS */
1991 for (i = 0; i < mtMemoCfg.numRegions; i++)
1993 cmMmRegDeInit(mtCMMRegCb[i]);
1994 free(mtCMMRegCfg[i]->vAddr);
1995 free(mtCMMRegCb[i]);
1996 free(mtCMMRegCfg[i]);
2005 * Fun: Initialize task table
2007 * Desc: This function initializes MTSS-specific information
2008 * in the task table.
2018 PUBLIC S16 ssdInitTsk
2023 PUBLIC S16 ssdInitTsk()
2026 /* mt001.301 : Additions */
2027 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2028 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2030 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2035 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2036 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2037 /* initialize system task information */
2038 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2040 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2042 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2049 * Fun: Deinitialize task table
2051 * Desc: This function reverses the initialization perfomed in
2062 PUBLIC Void ssdDeinitTsk
2067 PUBLIC Void ssdDeinitTsk()
2076 #ifdef SS_DRVR_SUPPORT
2079 * Fun: Initialize driver task table
2081 * Desc: This function initializes MTSS-specific information
2082 * in the driver task table.
2092 PUBLIC S16 ssdInitDrvr
2097 PUBLIC S16 ssdInitDrvr()
2102 pthread_attr_t attr;
2108 /* initialize the dependent portion of the driver task entries */
2109 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2111 osCp.drvrTskTbl[i].dep.flag = FALSE;
2115 /* create pipe for communication between SSetIntPend() and
2116 * the isTskHdlr thread.
2118 if (pipe(osCp.dep.isFildes) != 0)
2124 /* create the isTskHdlr thread */
2125 pthread_attr_init(&attr);
2126 /* mt021.201 - Addition to set stack size */
2127 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2128 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2129 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2130 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2132 /* mt020.201 - Addition for destroying thread attribute object attr */
2133 pthread_attr_destroy(&attr);
2139 /*mt014.301 : 4GMX release related changes*/
2140 #ifdef SS_4GMX_UCORE
2148 /* mt020.201 - Addition for destroying thread attribute object attr */
2149 pthread_attr_destroy(&attr);
2158 * Fun: Deinitialize driver information
2160 * Desc: This function reverses the initialization performed in
2171 PUBLIC Void ssdDeinitDrvr
2176 PUBLIC Void ssdDeinitDrvr()
2179 TRC0(ssdDeinitDrvr);
2180 /* mt008.301: Terminate the Driver Task on exit */
2181 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2184 TL_Close(AppContext.hUAII);
2185 if (clusterMode == RADIO_CLUSTER_MODE)
2187 TL_Close(AppContext.hUAII_second);
2193 #endif /* SS_DRVR_SUPPORT */
2198 * Fun: Initialize timer table
2200 * Desc: This function initializes MTSS-specific information
2201 * in the timer table.
2211 PUBLIC S16 ssdInitTmr
2216 PUBLIC S16 ssdInitTmr()
2219 pthread_attr_t attr;
2220 struct sched_param param_sched;
2221 /* mt010.21: addition */
2223 #ifdef SS_MULTICORE_SUPPORT
2225 #endif /* SS_MULTICORE_SUPPORT */
2226 #ifdef SS_THR_REG_MAP
2227 U32 threadCreated = FALSE;
2228 #endif /* SS_THR_REG_MAP */
2233 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2234 /* mt010.21: addition */
2235 osCp.dep.tmrTqCp.nxtEnt = 0;
2236 for (i=0; i< SS_MAX_TMRS; i++)
2238 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2241 #ifdef SS_MULTICORE_SUPPORT
2242 sTsk = ssdAddTmrSTsk();
2247 #endif /* SS_MULTICORE_SUPPORT */
2248 /* create the timer handler thread */
2249 pthread_attr_init(&attr);
2250 /* mt021.201 - Addition to set stack size */
2251 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2252 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2253 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2254 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2255 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2256 pthread_attr_setschedparam(&attr, ¶m_sched);
2259 #ifdef SS_THR_REG_MAP
2260 /* When the thread is created, we check for the memory mapping table if
2261 * threadId can be placed in thread memory map table. If it is not able to place
2262 * threadId is stored in tmporary array. Once thread is created successful,
2263 * thread_cancel is sent for each thread which are created before. All the
2264 * threads are made to wait on sema which is cancel point for thread.
2266 while(threadCreated == FALSE)
2269 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2271 /* mt020.201 - Addition for destroying thread attribute object attr */
2272 pthread_attr_destroy(&attr);
2277 #ifdef SS_THR_REG_MAP
2278 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2281 #endif /* SS_THR_REG_MAP */
2282 #ifdef SS_MEM_WL_DEBUG
2283 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2286 /* mt020.201 - Addition for destroying thread attribute object attr */
2287 pthread_attr_destroy(&attr);
2296 * Fun: Deinitialize timer table
2298 * Desc: This function reverses the initialization performed in
2309 PUBLIC Void ssdDeinitTmr
2314 PUBLIC Void ssdDeinitTmr()
2317 #ifdef SS_MULTICORE_SUPPORT
2320 #endif /* SS_MULTICORE_SUPPORT */
2324 #ifdef SS_MULTICORE_SUPPORT
2325 ret = SLock(&osCp.sTskTblLock);
2329 #if (ERRCLASS & ERRCLS_DEBUG)
2330 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2331 "Could not lock system task table");
2335 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2336 /* clean up the system task entry */
2340 SDestroyLock(&sTsk->lock);
2341 ssDestroyDmndQ(&sTsk->dQ);
2344 /* make this entry available in the system task table */
2345 sTsk->nxt = osCp.nxtSTskEntry;
2346 osCp.nxtSTskEntry = 0;
2350 /* unlock the system task table */
2351 SUnlock(&osCp.sTskTblLock);
2353 #endif /* SS_MULTICORE_SUPPORT */
2354 /* mt008.301: Terminate the timer thread on exit */
2355 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2365 * Desc: Pre-tst() initialization.
2375 PUBLIC S16 ssdInitLog
2380 PUBLIC S16 ssdInitLog()
2383 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2387 pthread_attr_t attr;
2390 #endif /* CONSTDIO */
2395 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2401 osCp.dep.conInFp = (FILE *) stdin;
2402 osCp.dep.conOutFp = (FILE *) stdout;
2403 /* added compile time flag CONRD: mt017.21 */
2407 /* disable canonical input processing */
2408 fd = fileno(osCp.dep.conInFp);
2409 if ((tcgetattr(fd, &tio)) != 0)
2411 printf("Error: disable canonical input processing\n");
2415 tio.c_lflag &= ~ICANON;
2416 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2417 tio.c_cc[VTIME] = 0;
2418 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2420 printf("Error: while tcsetattr() processing\n");
2424 #endif /* CONSTDIO */
2427 /* set up the input fd to block when no data is available */
2428 fd = fileno(osCp.dep.conInFp);
2429 flags = fcntl(fd, F_GETFL, &flags);
2430 flags &= ~O_NONBLOCK;
2431 if (fcntl(fd, F_SETFL, flags) == -1)
2433 printf("Error: while fcntl processing\n");
2438 /* create the console handler thread */
2439 pthread_attr_init(&attr);
2440 /* mt021.201 - Addition to set stack size */
2441 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2442 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2443 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2446 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2448 /* mt020.201 - Addition for destroying thread attribute object attr */
2449 pthread_attr_destroy(&attr);
2451 printf("Error: Logging Thread creation failed \n");
2455 /* mt020.201 - Addition for destroying thread attribute object attr */
2456 pthread_attr_destroy(&attr);
2470 * Desc: This function reverses the initialization performed in
2480 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2482 PUBLIC Void ssdDeinitLog
2487 PUBLIC Void ssdDeinitLog()
2490 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2494 /* mt008.301: Terminate the console reader on exit */
2495 while(pthread_cancel(osCp.dep.conHdlrTID));
2501 /* mt001.301 : Additions */
2506 PUBLIC S16 ssdInitWatchDog
2511 PUBLIC S16 ssdInitWatchDog(port)
2516 Txt prntBuf[PRNTSZE];
2519 #ifdef SS_WATCHDOG_IPV6
2520 struct sockaddr_in6 tmpaddr;
2522 struct sockaddr_in tmpaddr;
2523 #endif /* SS_WATCHDOG_IPV6 */
2524 #ifdef SS_MULTIPLE_PROCS
2525 ProcId procId = SS_WD_WDPROC;
2526 if (SAddProcIdLst(1, &procId) != ROK)
2530 #endif /* SS_MULTIPLE_PROCS */
2532 TRC0(ssdInitWatchDog);
2534 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2536 /* Create a watch dog system task */
2537 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2539 /* Create a watch dog reveiver system task */
2540 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2542 /* Register and attach watch dog TAPA task */
2543 #ifdef SS_MULTIPLE_PROCS
2544 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2545 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2547 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2548 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2549 #endif /* SS_MULTIPLE_PROCS */
2550 /* Register and attach watch dog receiver TAPA task */
2551 #ifdef SS_MULTIPLE_PROCS
2552 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2553 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2555 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2556 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2557 #endif /* SS_MULTIPLE_PROCS */
2559 #ifndef SS_MULTIPLE_PROCS
2560 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2561 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2563 osCp.wdCp.watchDgPst.srcProcId = procId;
2564 osCp.wdCp.watchDgPst.dstProcId = procId;
2565 #endif /* SS_MULTIPLE_PROCS */
2567 /* Initialise the pst structure */
2568 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2569 /* Initialize the watch dog timer resolution default is 1 sec */
2571 cmInitTimers(osCp.wdCp.watchDgTmr, (U8)1);
2572 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2573 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2574 for(idx = 0; idx < 1; idx++)
2576 osCp.wdCp.watchDgTs[idx].first = NULLP;
2577 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2579 #ifdef SS_MULTIPLE_PROCS
2580 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2582 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2583 #endif /* SS_MULTIPLE_PROCS */
2585 /* Create the watch dog receiver socket */
2586 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2587 if(osCp.wdCp.globWd.sock == -1)
2589 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2593 #ifdef SS_WATCHDOG_IPV6
2594 tmpaddr.sin6_len = sizeof(tmpadDr);
2595 tmpaddr.sin6_family = AF_INET6;
2596 tmpaddr.sin6_addr = in6addr_any;
2597 tmpaddr.sin6_port = htons(port);
2599 tmpaddr.sin_family = AF_INET;
2600 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2601 tmpaddr.sin_port = htons(port);
2602 #endif /* SS_WATCHDOG_IPV6 */
2604 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2607 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2611 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2615 #ifndef SS_MULTIPLE_PROCS
2616 pst.srcProcId = SFndProcId();
2617 pst.dstProcId = SFndProcId();
2619 pst.srcProcId = procId;
2620 pst.dstProcId = procId;
2621 #endif /* SS_MULTIPLE_PROCS */
2622 pst.event = EVTSSHRTBTREQ;
2623 ssdInitWatchDgPst(&pst);
2624 SPstTsk(&pst, mBuf);
2630 PUBLIC S16 ssdInitWatchDgPst
2635 PUBLIC S16 ssdInitWatchDgPst(pst)
2639 TRC1(ssInitWatchDgPst);
2641 pst->selector = SS_LOOSE_COUPLING;
2643 pst->region = DFLT_REGION; /* region */
2644 pst->pool = DFLT_POOL; /* pool */
2646 pst->prior = PRIOR0; /* priority */
2647 pst->route = RTESPEC; /* route */
2649 pst->dstEnt = ENTHB; /* destination entity */
2651 pst->srcEnt = ENTDW; /* source entity */
2657 #ifdef SS_MULTIPLE_PROCS
2659 PUBLIC S16 ssdWatchDgActvTmr
2666 PUBLIC S16 ssdWatchDgActvTmr(proc, ent, inst)
2670 PUBLIC S16 ssdWatchDgActvTmr
2675 PUBLIC S16 ssdWatchDgActvTmr()
2677 #endif /* SS_MULTIPLE_PROCS */
2679 TRC3(ssWatchDgActvTmr);
2681 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2687 PUBLIC Void ssdWatchDgTmrEvt
2689 PTR cb, /* control block */
2690 S16 event /* timer number */
2693 PUBLIC Void ssdWatchDgTmrEvt(cb, event)
2694 PTR cb; /* control block */
2695 S16 event; /* timer number */
2698 /* mt003.301 Fixed warings */
2702 Txt prntBuf[PRNTSZE];
2706 TRC2(ssWatchDgTmrEvt);
2712 SPrint("Timer Heartbeat Request Expired");
2714 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2719 SLock(&osCp.wdCp.wdLock);
2720 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2722 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2724 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2726 if(osCp.wdCp.globWd.callback != 0)
2728 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2732 SUnlock(&osCp.wdCp.wdLock);
2734 if(!osCp.wdCp.globWd.watchdogStop)
2736 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2737 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2748 PUBLIC Void ssdStartWatchDgTmr
2755 PUBLIC Void ssdStartWatchDgTmr(cb, event, wait)
2765 Txt prntBuf[PRNTSZE];
2769 TRC2(ssStartWatchDgTmr)
2770 /* mt003.301 Modifications */
2773 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2774 if(event == SS_TMR_HRTBT)
2776 SPrint("\nSTART SS_TMR_HRTBT");
2783 SLock(&osCp.wdCp.wdLock);
2784 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2786 osCp.wdCp.globWd.wdsta[i].status = 0;
2788 SUnlock(&osCp.wdCp.wdLock);
2790 arg.tq = osCp.wdCp.watchDgTs;
2791 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2792 arg.timers = osCp.wdCp.watchDgTmr;
2793 arg.cb = (PTR)NULLP;
2795 arg.wait = osCp.wdCp.globWd.timeout = wait;
2804 PUBLIC Void ssdStopWatchDgTmr
2810 PUBLIC Void ssdStopWatchDgTmr(cb, event)
2818 Txt prntBuf[PRNTSZE];
2822 TRC2(ssStopWatchDgTmr)
2823 /* mt003.301 Modifications */
2826 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2827 if(event == SS_TMR_HRTBT)
2829 SPrint("STOP SS_TMR_HRTBT");
2833 SLock(&osCp.wdCp.wdLock);
2834 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2836 osCp.wdCp.globWd.wdsta[i].status = 0;
2838 SUnlock(&osCp.wdCp.wdLock);
2841 arg.tq = osCp.wdCp.watchDgTs;
2842 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2843 arg.timers = osCp.wdCp.watchDgTmr;
2844 arg.cb = (PTR)NULLP;
2855 PUBLIC S16 ssdSndHrtBtMsg
2861 PUBLIC S16 ssdSndHrtBtMsg(restart, type)
2869 Txt prntBuf[PRNTSZE];
2871 struct sockaddr_in tmpaddr;
2872 char hbMsg[SS_WD_HB_MSG_SIZE];
2876 TRC2(ssdSndHrtBtReq)
2880 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2884 /* Pack the message */
2885 strcpy(hbMsg, "<HB>REQ</HB>");
2887 /* Send the heartbeat messages to all the configured nodes */
2888 SLock(&osCp.wdCp.wdLock);
2889 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2891 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2896 /* Identify the destination node */
2897 #ifdef SS_WATCHDOG_IPV6
2898 tmpaddr.sin6_len = sizeof(tmpaddr);
2899 tmpaddr.sin6_family = AF_INET6;
2900 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2901 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2903 tmpaddr.sin_family = AF_INET;
2904 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2905 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2906 #endif /* SS_WATCHDOG_IPV6 */
2908 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2912 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2913 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2920 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2925 SUnlock(&osCp.wdCp.wdLock);
2930 #endif /* SS_WATCHDOG */
2934 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2940 * Desc: This function gets command line options.
2950 PRIVATE Void mtGetOpts
2955 PRIVATE Void mtGetOpts()
2963 FILE *memOpt; /* memory options file pointer */
2966 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2972 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2974 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2980 #ifdef SS_LOCKLESS_MEMORY
2996 osCp.dep.fileOutFp = (FILE *)NULLP;
2998 /* initialize memOpt */
2999 memOpt = (FILE *) NULLP;
3006 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
3011 /* mt001.301 : Additions */
3012 #ifdef SS_MEM_LEAK_STS
3014 cmMemOpenMemLkFile(msOptArg);
3018 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3021 fileBasedMemCfg = TRUE;
3022 memOpt = fopen(msOptArg, "r");
3024 /* if file does not exist or could not be opened then use the
3025 * default memory configuration as defined in mt_ss.h
3027 if (memOpt == (FILE *) NULLP)
3029 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3030 be opened, using default mem configuration\n", msOptArg);
3035 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3037 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3043 case 0: /*** INPUT: Number of regions ***/
3044 sscanf(line, "%ld", (long *) &numReg);
3045 mtMemoCfg.numRegions = numReg;
3046 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3048 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3054 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3055 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3056 if(numBkts > MT_MAX_BKTS)
3058 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3062 if(numPools > SS_MAX_POOLS_PER_REG)
3064 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3069 * Delay updation from local variable to global
3070 * structure of number of regions and heap data to
3071 * counter error conditions present above.
3073 for(idx = 0; idx < cfgNumRegs; idx++)
3075 mtMemoCfg.region[idx].numBkts = numBkts;
3076 cfgRegInfo[idx].region = idx;
3077 cfgRegInfo[idx].numPools = numPools;
3079 * Initialize the pool info as static type with size zero
3081 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3083 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3084 cfgRegInfo[idx].pools[poolIdx].size = 0;
3089 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3090 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3092 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3094 if(bktIdx >= numBkts)
3096 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3101 mtBktInfo[bktIdx].blkSize = bktSz;
3103 if(bktUpdtCnt == numBkts)
3105 i++; /*done reading bkt info, start reading individual region info*/
3109 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3110 sscanf(line,"%ld",(long *) ®Id);
3111 if(regId >= mtMemoCfg.numRegions)
3113 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3114 #ifndef XEON_SPECIFIC_CHANGES
3119 mtMemoCfg.region[regId].regionId = regId;
3122 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3123 if(bktUpdtCnt < numBkts)
3125 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3126 if(bktIdx >= numBkts)
3128 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3133 if(bktIdx < MT_MAX_BKTS)
3135 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3136 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3137 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3138 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3141 if(bktUpdtCnt == numBkts)
3148 case 5: /* INPUT: Heapsize ***/
3149 sscanf(line, "%ld", (long *) &heapSz);
3150 mtMemoCfg.region[regId].heapsize = heapSz;
3152 if(regUpdtCnt != mtMemoCfg.numRegions)
3161 #ifdef SS_LOCKLESS_MEMORY
3163 sscanf(line, "%ld", (long *) &numBkts);
3164 mtGlobMemoCfg.numBkts = numBkts;
3165 #ifndef XEON_SPECIFIC_CHANGES
3166 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3169 #ifdef XEON_SPECIFIC_CHANGES
3170 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3171 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3172 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3174 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3177 mtDynMemoCfg.region[idx].regionId = idx;
3178 mtDynMemoCfg.region[idx].numBkts = numBkts;
3186 if(bktUpdtCnt < numBkts)
3188 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3189 (long *) &bktSz, (long *) &bktNum,
3190 (long *) &bktSetSize, (long *) &bktRelThr,
3191 (long *) &bktAqurThr);
3192 /* Klock work fix ccpu00148484 */
3193 if(bktIdx < SS_MAX_POOLS_PER_REG)
3195 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3196 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3197 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3198 #ifdef XEON_SPECIFIC_CHANGES
3199 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3200 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3201 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3203 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3205 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3211 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3213 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3214 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3215 #ifdef XEON_SPECIFIC_CHANGES
3216 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3217 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3218 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3224 #ifdef XEON_SPECIFIC_CHANGES
3225 if(bktUpdtCnt == numBkts)
3231 case 8: /* INPUT: Global Heapsize ***/
3232 sscanf(line, "%ld", (long *) &heapSz);
3233 mtGlobMemoCfg.heapSize = heapSz;
3234 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3242 memConfigured = FALSE;
3246 memConfigured = TRUE;
3254 /* mt028.201: modification: multiple procs support related changes */
3255 #ifndef SS_MULTIPLE_PROCS
3258 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3260 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3263 #else /* SS_MULTIPLE_PROCS */
3267 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3269 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3271 SAddProcIdLst(1, &procId);
3274 #endif /* SS_MULTIPLE_PROCS */
3278 osCp.configFilePath = msOptArg;
3302 * Desc: Get options from command line
3304 * Ret: option - success
3306 * EOF - end of options
3308 * Notes: Handles command lines like the following
3311 * then command line should look like this...
3312 * -a foo -b foo1 -c -d foo
3316 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3321 * nloops = atoi(msArgv[msOptInd]);
3324 * state1 = atoi(msArgv[msOptInd]);
3337 int argc, /* argument count */
3338 char **argv, /* argument value */
3339 char *opts /* options */
3342 PUBLIC S16 SGetOpt(argc, argv, opts)
3343 int argc; /* argument count */
3344 char **argv; /* argument value */
3345 char *opts; /* options */
3348 /* mt020.201 - Removed for no command line */
3357 /* mt020.201 - Addition for no command line */
3369 /*mt013.301 : Changes as per coding standards*/
3370 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3376 if (!strcmp(argv[msOptInd], "--"))
3381 else if (argv[msOptInd][0] != '-')
3389 c = argv[msOptInd][sp];
3390 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3392 if (argv[msOptInd][++sp] == '\0')
3403 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3406 if (++msOptInd >= (S16) argc)
3411 else msOptArg = argv[msOptInd++];
3418 if (argv[msOptInd][++sp] == '\0')
3430 #endif /* NOCMDLINE */
3438 * Desc: This function starts system services execution; the
3439 * permanent tasks are started and the system enters a
3450 PUBLIC Void ssdStart
3455 PUBLIC Void ssdStart()
3464 /* mt025.201 - Modification for adding lock to timer handler */
3465 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3467 sem_post(&osCp.dep.ssStarted);
3476 * indirect interface functions to system services service user
3482 * Fun: ssdAttachTTsk
3484 * Desc: This function sends the initial tick message to a TAPA
3485 * task if the task is a permanent task.
3495 PUBLIC S16 ssdAttachTTsk
3497 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3500 PUBLIC S16 ssdAttachTTsk(tTsk)
3501 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3509 TRC0(ssdAttachTTsk);
3512 if (tTsk->tskType == SS_TSK_PERMANENT)
3514 /* Send a permanent tick message to this task, to start
3517 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3520 #if (ERRCLASS & ERRCLS_DEBUG)
3521 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3526 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3527 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3529 /* set up post structure */
3530 /* mt028.201: modification: multiple procs support related changes */
3531 #ifndef SS_MULTIPLE_PROCS
3532 mInfo->pst.dstProcId = SFndProcId();
3533 mInfo->pst.srcProcId = SFndProcId();
3534 #else /* SS_MULTIPLE_PROCS */
3535 mInfo->pst.dstProcId = tTsk->proc;
3536 mInfo->pst.srcProcId = tTsk->proc;
3537 #endif /* SS_MULTIPLE_PROCS */
3538 mInfo->pst.selector = SEL_LC_NEW;
3539 mInfo->pst.region = DFLT_REGION;
3540 mInfo->pst.pool = DFLT_POOL;
3541 mInfo->pst.prior = PRIOR3;
3542 mInfo->pst.route = RTESPEC;
3543 mInfo->pst.event = 0;
3544 mInfo->pst.dstEnt = tTsk->ent;
3545 mInfo->pst.dstInst = tTsk->inst;
3546 mInfo->pst.srcEnt = tTsk->ent;
3547 mInfo->pst.srcInst = tTsk->inst;
3549 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3550 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3556 #if (ERRCLASS & ERRCLS_DEBUG)
3557 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3558 "Could not write to demand queue");
3571 * Fun: ssdDetachTTsk
3573 * Desc: Does nothing.
3583 PUBLIC S16 ssdDetachTTsk
3585 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3588 PUBLIC S16 ssdDetachTTsk(tTsk)
3589 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3592 TRC0(ssdDetachTTsk);
3601 * Fun: ssdCreateSTsk
3603 * Desc: This function creates a system task. A thread is started
3604 * on the system task handler function defined later.
3614 PUBLIC S16 ssdCreateSTsk
3616 SsSTskEntry *sTsk /* pointer to system task entry */
3619 PUBLIC S16 ssdCreateSTsk(sTsk)
3620 SsSTskEntry *sTsk; /* pointer to system task entry */
3623 pthread_attr_t attr;
3624 /* struct sched_param param_sched;*/
3626 #ifdef SS_THR_REG_MAP
3627 U32 threadCreated = FALSE;
3630 TRC0(ssdCreateSTsk);
3633 #ifdef SS_SINGLE_THREADED
3634 /* mt001.301 : Additions */
3636 #ifdef SS_MULTICORE_SUPPORT
3637 if (osCp.numSTsks > 1)
3639 if (osCp.numSTsks > 0)
3640 #endif /* SS_MULTICORE_SUPPORT */
3642 #ifdef SS_MULTICORE_SUPPORT
3643 if (osCp.numSTsks > 3)
3645 if (osCp.numSTsks > 2)
3646 #endif /* SS_MULTICORE_SUPPORT */
3647 #endif /* SS_WATCHDOG */
3654 /* set the current executing entity and instance IDs to
3655 * 'not configured'. create the lock to access them.
3657 sTsk->dep.ent = ENTNC;
3658 sTsk->dep.inst = INSTNC;
3661 /* create the thread */
3662 pthread_attr_init(&attr);
3663 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3665 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3666 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3667 if (sTsk->tskPrior == 0)
3669 printf("Creating RT thread #######################\n");
3670 #ifdef SS_THR_REG_MAP
3671 /* When the thread is created, we check for the memory mapping table if
3672 * threadId can be placed in thread memory map table. If it is not able to place
3673 * threadId is stored in tmporary array. Once thread is created successful,
3674 * thread_cancel is sent for each thread which are created before. All the
3675 * threads are made to wait on sema which is cancel point for thread.
3677 while(threadCreated == FALSE)
3680 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlrT2kL2, (Ptr)sTsk)) != 0)
3683 pthread_attr_destroy(&attr);
3685 #if (ERRCLASS & ERRCLS_DEBUG)
3686 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3691 #ifdef SS_THR_REG_MAP
3692 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3700 #ifdef SS_THR_REG_MAP
3701 /* When the thread is created, we check for the memory mapping table if
3702 * threadId can be placed in thread memory map table. If it is not able to place
3703 * threadId is stored in tmporary array. Once thread is created successful,
3704 * thread_cancel is sent for each thread which are created before. All the
3705 * threads are made to wait on sema which is cancel point for thread.
3707 while(threadCreated == FALSE)
3710 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk)) != 0)
3713 /* mt020.201 - Addition for destroying thread attribute object attr */
3714 pthread_attr_destroy(&attr);
3716 #if (ERRCLASS & ERRCLS_DEBUG)
3717 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3722 #ifdef SS_THR_REG_MAP
3723 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3730 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3731 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3733 static U32 stLwpId = 3;
3734 sTsk->dep.lwpId = ++stLwpId;
3736 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3738 /* mt020.201 - Addition for destroying thread attribute object attr */
3739 pthread_attr_destroy(&attr);
3746 PUBLIC int SCreatePThread
3749 pthread_attr_t* attr,
3750 void *(*start_routine) (void *),
3754 PUBLIC int SCreatePThread(tid, attr, start_routine, arg)
3756 pthread_attr_t* attr;
3757 void *(*start_routine) (void *);
3762 #ifdef SS_THR_REG_MAP
3763 U32 threadCreated = FALSE;
3766 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3767 /* Klock work fix ccpu00148484 */
3768 if(threadArg == NULLP)
3772 threadArg->argument = arg;
3773 threadArg->start_routine = start_routine;
3775 TRC0(SCreatePThread);
3777 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3779 #ifdef SS_THR_REG_MAP
3780 /* When the thread is created, we check for the memory mapping table if
3781 * threadId can be placed in thread memory map table. If it is not able to place
3782 * threadId is stored in tmporary array. Once thread is created successful,
3783 * thread_cancel is sent for each thread which are created before. All the
3784 * threads are made to wait on sema which is cancel point for thread.
3786 while(threadCreated == FALSE)
3789 /*pthreadCreateHdlr */
3790 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3795 #ifdef SS_THR_REG_MAP
3796 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3807 * Fun: Set Pthread Attributes
3809 * Desc: This function is used to set various explicit
3810 * pthread attributes like, priority scheduling,etc
3821 PRIVATE S16 ssdSetPthreadAttr
3824 pthread_attr_t *attr
3827 PRIVATE S16 ssdSetPthreadAttr(sTsk, attr)
3829 pthread_attr_t *attr
3832 struct sched_param param;
3834 TRC0 (ssdSetPthreadAttr)
3836 SMemSet(¶m, 0, sizeof(param));
3838 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3839 param.sched_priority = 100 - 1 - tskPrior;
3841 param.sched_priority = 100 - 10 - tskPrior;
3844 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3845 /* TODO:: This can be avoided by reducing the priority
3846 * of iccserv thread in l1_master.sh*/
3848 if (clusterMode == RADIO_CLUSTER_MODE)
3850 if(tskPrior == PRIOR1)
3852 param.sched_priority = 91;
3859 printf("Set priority %u\n", param.sched_priority);
3861 /* Set Scheduler to explicit, without this non of the below
3862 pthread attr works */
3863 #ifdef TENB_RTLIN_CHANGES
3864 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3867 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3868 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3869 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3870 #ifdef TENB_RTLIN_CHANGES
3871 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3873 pthread_attr_setschedparam(attr, ¶m);
3877 } /* ssdSetPthreadAttr */
3879 /************* multi-core support **************/
3880 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3881 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3885 * Fun: Get the current core/cpu affinity for a thread/lwp
3887 * Desc: This function is used to get the current processor/core
3888 * affinity for a a system task (thread/lwp). It sets the
3889 * affinity based on the mode supplied by the caller.
3892 * RFAILED - failed, general (optional)
3900 PUBLIC S16 ssdGetAffinity
3902 SSTskId *tskId, /* filled in with system task ID */
3903 U32 *coreId /* the core/processor id to which the affinity is set */
3906 PUBLIC S16 ssdGetAffinity(tskId, coreId)
3907 SSTskId *tskId; /* filled in with system task ID */
3908 U32 *coreId; /* the core/processor id to which the affinity is set */
3919 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3925 TRC0(ssdGetAffinity);
3927 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3929 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3931 tId = osCp.sTskTbl[tskInd].dep.tId;
3936 /* if tskId is not found in the tskTbl */
3937 if (tskInd == SS_MAX_STSKS)
3939 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3944 /* initialize the cpu mask */
3947 /* set thread affinity for linux */
3948 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3950 #if (ERRCLASS & ERRCLS_DEBUG)
3951 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3954 } /* end if pthread_setaffinity fails */
3956 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3958 if (CPU_ISSET (cpuInd, & cpuSet))
3967 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3969 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3971 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3976 /* if tskId is not found in the tskTbl */
3977 if (tskInd == SS_MAX_STSKS)
3979 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3983 /* set thread affinity for Solaris */
3984 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3986 #if (ERRCLASS & ERRCLS_DEBUG)
3987 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3990 } /* end if processor_bind fails */
3993 #endif /* SS_LINUX */
3997 } /* ssdGetAffinity */
4002 * Fun: Set the core/cpu affinity for a thread/lwp
4004 * Desc: This function is used to set processor/core affinity for a
4005 * a system task (thread/lwp). It sets the affinity based on the
4006 * mode supplied by the caller.
4009 * RFAILED - failed, general (optional)
4017 PUBLIC S16 ssdSetAffinity
4019 SSTskId *tskId, /* filled in with system task ID */
4020 U32 coreId /* the core/processor id to which the affinity has to be set */
4023 PUBLIC S16 ssdSetAffinity(tskId, coreId)
4024 SSTskId *tskId; /* filled in with system task ID */
4025 U32 coreId; /* the core/processor id to which the affinity has to be set */
4034 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4041 TRC0(ssdSetAffinity)
4044 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4046 /* Here tskId can not be used as index as the task may be terminated if
4047 there is a TERM even for that tsk, thus breaking the task Id numbering
4049 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4051 tId = osCp.sTskTbl[tskInd].dep.tId;
4056 /* if tskId is not found in the tskTbl */
4057 if (tskInd == SS_MAX_STSKS)
4059 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4063 /* initialize the cpu mask */
4066 /* set the cpu mask */
4067 CPU_SET(coreId, &cpuSet);
4069 /* set thread affinity for linux */
4070 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4072 #if (ERRCLASS & ERRCLS_DEBUG)
4073 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4076 } /* end if pthread_setaffinity fails */
4080 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4082 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4083 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4085 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4090 /* if tskId is not found in the tskTbl */
4091 if (tskInd == SS_MAX_STSKS)
4093 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4097 /* set thread affinity for Solaris */
4098 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4100 #if (ERRCLASS & ERRCLS_DEBUG)
4101 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4104 } /* end if processor_bind fails */
4107 #endif /* SS_LINUX */
4109 } /* ssdSetAffinity */
4111 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4112 /************ end multi-core support *************/
4117 * Fun: ssdDestroySTsk
4119 * Desc: This function destroys a system task. A terminate
4120 * event message is sent to the thread function.
4130 PUBLIC S16 ssdDestroySTsk
4132 SsSTskEntry *sTsk /* pointer to system task entry */
4135 PUBLIC S16 ssdDestroySTsk(sTsk)
4136 SsSTskEntry *sTsk; /* pointer to system task entry */
4143 TRC0(ssdDestroySTsk);
4146 /* we send a message to this system task to tell it to die */
4147 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4150 #if (ERRCLASS & ERRCLASS_DEBUG)
4151 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4157 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4158 mInfo->eventInfo.event = SS_EVNT_TERM;
4160 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4164 #if (ERRCLASS & ERRCLASS_DEBUG)
4165 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4166 "Could not write to demand queue");
4176 /* mt023.201 - Added SThreadYield function to yield CPU
4180 * Desc: This function defers thread execution to any other ready
4192 PUBLIC S16 SThreadYield
4197 PUBLIC S16 SThreadYield()
4203 /* mt024.201 - seperated Linux and other UNIX implementations
4209 /* Set sleep value to 0 to yield CPU */
4213 RETVALUE(select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4215 #else /* other UNICes */
4217 RETVALUE(sleep(0) == 0 ? ROK : RFAILED);
4219 #endif /* SS_LINUX */
4226 * Fun: Register timer
4228 * Desc: This function is used to register a timer
4229 * function for the service user. System services
4230 * will invoke the timer activation function
4231 * passed to it at the specified intervals.
4235 * Notes: Timing is handled by the common timers. The
4236 * ticks are handled by a thread that uses
4237 * nanosleep() and thus timing precision will not
4244 PUBLIC S16 ssdRegTmr
4246 SsTmrEntry *tmr /* pointer to timer entry */
4249 PUBLIC S16 ssdRegTmr(tmr)
4250 SsTmrEntry *tmr; /* pointer to timer entry */
4259 /* initialize common timers */
4260 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4263 /* start the timer */
4264 arg.tq = osCp.dep.tmrTq;
4265 arg.tqCp = &osCp.dep.tmrTqCp;
4266 arg.timers = tmr->dep.timers;
4271 arg.max = TMR_DEF_MAX;
4272 arg.wait = tmr->interval;
4282 * Fun: Deregister timer
4284 * Desc: This function is used to deregister a timer function.
4294 PUBLIC S16 ssdDeregTmr
4296 SsTmrEntry *tmr /* pointer to timer entry */
4299 PUBLIC S16 ssdDeregTmr(tmr)
4300 SsTmrEntry *tmr; /* pointer to timer entry */
4309 /* stop the timer */
4310 arg.tq = osCp.dep.tmrTq;
4311 arg.tqCp = &osCp.dep.tmrTqCp;
4312 arg.timers = tmr->dep.timers;
4317 arg.max = TMR_DEF_MAX;
4318 arg.wait = tmr->interval;
4328 * Fun: Critical error
4330 * Desc: This function is called when a critical error occurs.
4342 Seq seq, /* sequence number */
4343 Reason reason /* reset reason */
4346 PUBLIC S16 ssdError(seq, reason)
4347 Seq seq; /* sequence number */
4348 Reason reason; /* reset reason */
4359 /* get calling task ID */
4360 tId = pthread_self();
4363 /* set up the message to display */
4364 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4365 "reason = %d\n\n", (U8)tId, seq, reason);
4369 /* delete all system tasks */
4370 for (i = 0; i < SS_MAX_STSKS; i++)
4372 if (osCp.sTskTbl[i].used
4373 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4375 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4381 pthread_exit(NULLP);
4384 /* won't reach here */
4393 * Desc: This function is called to log an error.
4403 PUBLIC Void ssdLogError
4405 Ent ent, /* Calling layer's entity id */
4406 Inst inst, /* Calling layer's instance id */
4407 ProcId procId, /* Calling layer's processor id */
4408 Txt *file, /* file name where error occured */
4409 S32 line, /* line in file where error occured */
4410 ErrCls errCls, /* error class */
4411 ErrCode errCode, /* layer unique error code */
4412 ErrVal errVal, /* error value */
4413 Txt *errDesc /* description of error */
4416 PUBLIC Void ssdLogError(ent, inst, procId, file, line,
4417 errCls, errCode, errVal, errDesc)
4418 Ent ent; /* Calling layer's entity id */
4419 Inst inst; /* Calling layer's instance id */
4420 ProcId procId; /* Calling layer's processor id */
4421 Txt *file; /* file name where error occured */
4422 S32 line; /* line in file where error occured */
4423 ErrCls errCls; /* error class */
4424 ErrCode errCode; /* layer unique error code */
4425 ErrVal errVal; /* error value */
4426 Txt *errDesc; /* description of error */
4440 /* get calling task ID */
4442 tId = pthread_self();
4448 case ERRCLS_ADD_RES:
4449 errClsMsg = "ERRCLS_ADD_RES";
4452 case ERRCLS_INT_PAR:
4453 errClsMsg = "ERRCLS_INT_PAR";
4457 errClsMsg = "ERRCLS_DEBUG";
4460 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4462 errClsMsg = "ERRCLS_FTHA";
4466 errClsMsg = "INVALID ERROR CLASS!";
4471 /*mt009.301 Fixed 64BIT compilation warnings*/
4474 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4475 "file: %s line: %03d errcode: %05d errcls: %s\n"
4476 "errval: %05d errdesc: %s\n",
4477 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4480 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4481 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4482 "errval: %05ld errdesc: %s\n",
4483 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4485 SDisplay(0, errBuf);
4486 /* mt001.301 : Additions */
4487 #ifdef SS_LOGGER_SUPPORT
4489 #endif /* SS_LOGGER_SUPPORT */
4493 /* debug errors halt the system */
4494 if (errCls == ERRCLS_DEBUG)
4496 /* mt001.301 : Additions */
4497 #ifdef SS_LOGGER_SUPPORT
4499 #endif /* SS_LOGGER_SUPPORT */
4500 /* delete all system tasks */
4501 for (i = 0; i < SS_MAX_STSKS; i++)
4503 if (osCp.sTskTbl[i].used
4504 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4506 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4512 pthread_exit(NULLP);
4524 * Fun: Register driver task
4526 * Desc: This function is called to register the handlers for a
4537 PUBLIC S16 ssdRegDrvrTsk
4539 SsDrvrTskEntry *drvrTsk /* driver task entry */
4542 PUBLIC S16 ssdRegDrvrTsk(drvrTsk)
4543 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4546 TRC0(ssdRegDrvrTsk);
4551 /* mt001.30 : Additions */
4554 * Fun: Deregister driver task
4556 * Desc: This function is called to deregister the handlers for a
4567 PUBLIC S16 ssdDeregDrvrTsk
4569 SsDrvrTskEntry *drvrTsk /* driver task entry */
4572 PUBLIC S16 ssdDeregDrvrTsk(drvrTsk)
4573 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4576 TRC0(ssdDeregDrvrTsk);
4587 * mt003.301 Additions - SDeRegTTsk fix
4589 #ifdef SS_MULTIPLE_PROCS
4591 PUBLIC S16 ssdProcTTskTerm
4598 PUBLIC S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4603 #else /*SS_MULTIPLE_PROCS*/
4605 PUBLIC S16 ssdProcTTskTerm
4611 PUBLIC S16 ssdProcTTskTerm(tTsk, idx)
4615 #endif /*SS_MULTIPLE_PROCS*/
4617 #ifdef SS_MULTIPLE_PROCS
4626 TRC0(ssdProcTTskTerm);
4631 /* We check the sTsk element; if it is not NULLP, the
4632 * task is attached. So we have to detach it before
4633 * deregistering the task.
4635 ret = SLock(&osCp.sTskTblLock);
4638 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4641 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4644 #if (ERRCLASS & ERRCLS_DEBUG)
4645 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4647 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4649 #if (ERRCLASS & ERRCLS_DEBUG)
4650 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4658 #ifdef SS_MULTIPLE_PROCS
4660 if (tTsk->initTsk != NULLP)
4663 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4666 &(osCp.tTskTbl[idx].xxCb));
4668 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4671 &(osCp.tTskTbl[idx].xxCb));
4672 #endif /* USE_MEMCAL */
4674 #endif /* SS_MULTIPLE_PROCS */
4676 if (tTsk->sTsk != NULLP)
4680 sTsk->dep.ent = ent;
4681 sTsk->dep.inst = inst;
4683 for (n = 0; n < SS_MAX_TTSKS; n++)
4685 if (sTsk->tTsks[n] == idx)
4687 sTsk->tTsks[n] = SS_INVALID_IDX;
4693 /* call the implementation to detach the task */
4694 ssdDetachTTsk(tTsk);
4696 sTsk->dep.ent = ENTNC;
4697 sTsk->dep.inst = INSTNC;
4700 /* Now we empty the entry for this task and update the table
4703 #ifdef SS_MULTIPLE_PROCS
4704 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4705 #else /* SS_MULTIPLE_PROCS */
4706 osCp.tTskIds[ent][inst] = SS_TSKNC;
4707 #endif /* SS_MULTIPLE_PROCS */
4710 #ifdef SS_MULTIPLE_PROCS
4711 tTsk->proc = PROCNC;
4712 #endif /* SS_MULTIPLE_PROCS */
4714 tTsk->inst = INSTNC;
4715 tTsk->tskType = TTUND;
4716 tTsk->initTsk = NULLP;
4717 tTsk->actvTsk = NULLP;
4720 tTsk->nxt = osCp.nxtTTskEntry;
4721 osCp.nxtTTskEntry = idx;
4724 #ifdef SS_MULTIPLE_PROCS
4725 /* mark the control block for this task as invalid */
4726 osCp.tTskTbl[idx].xxCb = NULLP;
4729 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4730 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4732 #if (ERRCLASS & ERRCLS_DEBUG)
4733 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4740 //#ifndef SPLIT_RLC_DL_TASK
4741 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4742 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4743 EXTERN Void ysMtTskHdlr(Void);
4744 EXTERN Void ysMtPollPhyMsg(U8 region);
4745 EXTERN Void ysMtRcvPhyMsg(Void);
4747 PUBLIC Void *mtTskHdlrT2kL2
4749 Ptr tskPtr /* pointer to task entry */
4752 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4753 Ptr tskPtr; /* pointer to task entry */
4759 /* wait for SS to come up */
4760 /* It is required to block on this semaphore before starting actual processing of
4761 the thread becasue the creator of this thread might want to cance it without
4762 doing any processing. When this semaphore is released, means the creator gives
4763 the go ahead for actual processing and we should never come back to this point */
4764 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4773 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4774 * (processes L1 msgs) */
4780 EXTERN Void ysMtTskHdlr(Void);
4781 EXTERN Void YsPhyRecvMsg();
4783 PUBLIC Void *mtTskHdlrT2kL2
4785 Ptr tskPtr /* pointer to task entry */
4788 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4789 Ptr tskPtr; /* pointer to task entry */
4795 /* get out the system task entry from the parameter */
4796 sTsk = (SsSTskEntry *) tskPtr;
4798 /* wait for SS to come up */
4799 /* It is required to block on this semaphore before starting actual processing of
4800 the thread becasue the creator of this thread might want to cance it without
4801 doing any processing. When this semaphore is released, means the creator gives
4802 the go ahead for actual processing and we should never come back to this point */
4803 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4806 #ifndef RGL_SPECIFIC_CHANGES
4814 #ifdef V5GTF_SPECIFIC_CHANGES
4817 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4818 * (processes L1 msgs) */
4820 /* get a message from the demand queue */
4822 #ifdef RLC_MAC_DAT_REQ_RBUF
4823 rgDlDatReqBatchProc();
4826 ret = mtTskHdlMsg(sTsk);
4829 /* exit the for loop here */
4832 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4839 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4843 PUBLIC void *pthreadCreateHdlr
4848 PUBLIC void *pthreadCreateHdlr(pthreadCreateArg)
4853 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4854 /* mt038.201 changed how sem_wait is called */
4855 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4858 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4866 * Desc: This is the system task handler function. It blocks on
4867 * the system task's demand queue. On receiving a message,
4868 * it identifies the target TAPA task, verifies that the
4869 * TAPA task belongs to this system task and if so, calls
4870 * the activation function of that TAPA task with the
4871 * received message. The task activation function or the
4872 * timer activation function may be called.
4874 * Ret: (thread function)
4882 PUBLIC Void *mtTskHdlr
4884 Ptr tskPtr /* pointer to task entry */
4887 PUBLIC Void *mtTskHdlr(tskPtr)
4888 Ptr tskPtr; /* pointer to task entry */
4894 /* get out the system task entry from the parameter */
4895 sTsk = (SsSTskEntry *) tskPtr;
4898 /* wait for SS to come up */
4900 /* mt038.201 changed how sem_wait is called */
4901 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4903 #ifdef XEON_SPECIFIC_CHANGES
4904 printf("\n**********MT Task Handler********\n");
4908 /* Wait for a message from the demand queue */
4909 #ifdef SS_CDMNDQ_SUPPORT
4910 ret = ssCDmndQWait(&sTsk->dQ);
4912 ret = ssDmndQWait(&sTsk->dQ);
4917 ret = mtTskHdlMsg(sTsk);
4932 * Desc: This is the system task handler function. It blocks on
4933 * the system task's demand queue. On receiving a message,
4934 * it identifies the target TAPA task, verifies that the
4935 * TAPA task belongs to this system task and if so, calls
4936 * the activation function of that TAPA task with the
4937 * received message. The task activation function or the
4938 * timer activation function may be called.
4940 * Ret: (thread function)
4948 PUBLIC S16 mtTskHdlMsg
4953 PUBLIC S16 mtTskHdlMsg(sTsk)
4967 /* mt028.201: modification: multiple procs support related changes */
4968 #ifndef SS_MULTIPLE_PROCS
4970 PAIFTMRS16 tmrActvFnMt = NULLP;
4972 /* mt015.301 Initialized the timer activation functions with NULLP */
4973 PFS16 tmrActvFn = NULLP;
4975 PAIFTMRS16 tmrActvFn;
4977 #endif /* SS_MULTIPLE_PROCS */
4978 /* mt003.301 Modifications */
4979 #ifdef SS_THREAD_PROFILE
4981 #endif /* SS_THREAD_PROFILE */
4984 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4987 /* nothing to receive */
4991 /* if we can't lock this system task entry, return the message */
4992 ret = SLock(&sTsk->lock);
4996 #if (ERRCLASS & ERRCLS_DEBUG)
4997 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4998 "Could not lock system task entry");
5008 mBuf2 = mBuf->b_next;
5010 /* find out what kind of message this is */
5011 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5012 #ifdef SS_MEM_WL_DEBUG
5013 mtTskBuffer1 = mBuf2;
5015 mtTskBuffer2 = mBuf2->b_next;
5017 if(mInfo == 0x5050505)
5021 cmAnalyseBtInfo((PTR) mBuf,4);
5023 printf("\n In trouble .... \n");
5025 else if (mInfo == 0x2020202)
5028 cmAnalyseBtInfo((PTR) mBuf,1);
5029 printf("\n In trouble .... \n");
5031 #endif /* SS_MEM_WL_DEBUG */
5032 switch (mInfo->eventInfo.event)
5034 /* this is a termination event, we die */
5036 /* release the message */
5039 /* Unlock the system task entry and lock the system
5040 * task table to clean our entry up.
5042 SUnlock(&sTsk->lock);
5044 ret = SLock(&osCp.sTskTblLock);
5048 #if (ERRCLASS & ERRCLS_DEBUG)
5049 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5050 "Could not lock system task table");
5052 /* what to do here? */
5056 /* clean up the system task entry */
5059 /* mt003.301 Modifications - SDeRegTTsk */
5060 /* sTsk->numTTsks = 0; */
5061 SDestroyLock(&sTsk->lock);
5062 ssDestroyDmndQ(&sTsk->dQ);
5064 /* lock for current executing TAPA task ID */
5066 /* make this entry available in the system task table */
5067 sTsk->nxt = osCp.nxtSTskEntry;
5068 for (i = 0; i < SS_MAX_STSKS; i++)
5070 if (sTsk == &osCp.sTskTbl[i])
5072 osCp.nxtSTskEntry = i;
5079 /* unlock the system task table */
5080 SUnlock(&osCp.sTskTblLock);
5085 /* this is a data message or a permanent task keep-alive message */
5087 case SS_EVNT_PERMTICK:
5088 /* message to a task. find the destination task */
5089 /* mt028.201: modification: multiple procs support related changes */
5090 #ifdef SS_MULTIPLE_PROCS
5091 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5093 if (procIdIdx == SS_INV_PROCID_IDX)
5099 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5100 #else /* SS_MULTIPLE_PROCS */
5101 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5102 #endif /* SS_MULTIPLE_PROCS */
5104 /* verify that it hasn't been deregistered */
5105 if (idx == SS_TSKNC)
5111 /* verify that this system task is still running it */
5112 tTsk = &osCp.tTskTbl[idx];
5113 if (tTsk->sTsk != sTsk)
5119 /* set the current executing TAPA task ID */
5120 sTsk->dep.ent = mInfo->pst.dstEnt;
5121 sTsk->dep.inst = mInfo->pst.dstInst;
5123 /* copy the Pst structure into a local duplicate */
5124 for (i = 0; i < (S16) sizeof(Pst); i++)
5125 *(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
5127 /* Give the message to the task activation function. If
5128 * its a normal data message, we pass it, if this is a
5129 * keep-alive message for a permanent task then we pass
5130 * NULLP in place of the message to the task activation
5133 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5135 #ifndef RGL_SPECIFIC_CHANGES
5136 #ifdef SS_TSKLOG_ENABLE
5137 U32 t = MacGetTick();
5140 /* mt003.301 Modifications */
5141 #if SS_THREAD_PROFILE
5142 tTsk->curEvent = nPst.event;
5144 #endif /* SS_THREAD_PROFILE */
5145 tTsk->actvTsk(&nPst, mBuf);
5146 #ifndef RGL_SPECIFIC_CHANGES
5147 #ifdef SS_TSKLOG_ENABLE
5148 SStopTask(t,PID_SSI_TSK);
5151 #if SS_THREAD_PROFILE
5153 tTsk->curEvtTime = (U32)(et2 - et1);
5154 tTsk->totTime += (U64)tTsk->curEvtTime;
5155 #endif /* SS_THREAD_PROFILE */
5159 #if (ERRCLASS & ERRCLS_DEBUG)
5160 /* this message should only come to a permanent task */
5161 if (tTsk->tskType != SS_TSK_PERMANENT)
5163 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5167 tTsk->actvTsk(&nPst, NULLP);
5169 /* We need to re-send this message back to ourselves so
5170 * the permanent task continues to run.
5172 /* Check if this task got deregistered or detached
5173 * by the activation function; if so, there's nothing
5174 * more to do here, otherwise go ahead.
5177 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5179 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5180 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5184 /* failure here is a real problem */
5187 #if (ERRCLASS & ERRCLS_DEBUG)
5188 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5189 "Could not write to demand queue");
5195 /* unset the current executing TAPA task ID */
5196 sTsk->dep.ent = ENTNC;
5197 sTsk->dep.inst = INSTNC;
5202 /* timer event. find the timer entry */
5203 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5205 /* lock the timer table, coz we're going to peek in it */
5206 ret = SLock(&osCp.tmrTblLock);
5210 #if (ERRCLASS & ERRCLS_DEBUG)
5211 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5212 "Could not lock timer table");
5218 /* Verify that this timer entry is still around and that it
5219 * belongs to our task.
5221 if (osCp.tmrTbl[idx].used == FALSE
5222 /* mt028.201: modification: multiple procs support related changes */
5223 #ifdef SS_MULTIPLE_PROCS
5224 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5225 #endif /* SS_MULTIPLE_PROCS */
5226 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5227 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5229 SUnlock(&osCp.tmrTblLock);
5234 /* mt005.21: addition */
5235 /* set the current executing TAPA task ID */
5236 sTsk->dep.ent = mInfo->pst.dstEnt;
5237 sTsk->dep.inst = mInfo->pst.dstInst;
5239 #ifndef SS_MULTIPLE_PROCS
5241 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5242 tmrActvFnMt = NULLP;
5243 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5245 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5251 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5254 /* unlock the timer table */
5255 SUnlock(&osCp.tmrTblLock);
5257 /* activate the timer function */
5258 /* mt028.201: modification: multiple procs support related changes */
5259 #ifndef SS_MULTIPLE_PROCS
5263 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5264 osCp.tmrTbl[idx].ownerInst);
5272 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5273 osCp.tmrTbl[idx].ownerInst);
5274 #endif /* SS_MULTIPLE_PROCS */
5276 /*mt005.21: addition */
5277 /* unset the current executing TAPA task ID */
5278 sTsk->dep.ent = ENTNC;
5279 sTsk->dep.inst = INSTNC;
5282 /* return the message buffer */
5286 * mt003.301 - SDeRegTTsk fix
5288 case SS_EVNT_TTSK_TERM:
5289 #ifdef SS_MULTIPLE_PROCS
5290 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5292 if (procIdIdx == SS_INV_PROCID_IDX)
5298 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5299 #else /* SS_MULTIPLE_PROCS */
5300 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5301 #endif /* SS_MULTIPLE_PROCS */
5303 /* verify that it hasn't been deregistered */
5304 if (idx == SS_TSKNC)
5310 /* verify that this system task is still running it */
5311 tTsk = &osCp.tTskTbl[idx];
5312 if (tTsk->sTsk != sTsk)
5317 #ifdef SS_MULTIPLE_PROCS
5318 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5320 ssdProcTTskTerm(tTsk, idx);
5326 #if (ERRCLASS & ERRCLS_DEBUG)
5327 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5334 } while (mBuf != NULLP);
5337 /* unlock the system task entry */
5338 SUnlock(&sTsk->lock);
5341 /* yield for other threads */
5342 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5351 * Fun: mtTmrHdlrPublic
5354 PUBLIC Void mtTmrHdlrPublic
5358 PUBLIC Void mtTmrHdlrPublic()
5361 if (SLock(&osCp.tmrTblLock) != ROK)
5363 #if (ERRCLASS & ERRCLS_DEBUG)
5364 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5368 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5369 /* unlock the timer table */
5370 SUnlock(&osCp.tmrTblLock);
5378 * Desc: The timer handler thread function. Counts time
5379 * and invokes the common timer function on each
5382 * Ret: (thread function)
5389 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5391 PRIVATE Void *mtTmrHdlr
5393 void *parm /* unused */
5396 /* mt009.21: addition */
5397 PRIVATE Void *mtTmrHdlr(parm)
5398 void *parm; /* unused */
5401 /*mt004.301-addede new region*/
5402 /* mt010.301 Removed SS_FAP portion and
5403 * enabled oroginal code in function mtTmrHdlr */
5407 U32 i, cnt, oldTicks, newTicks;
5408 struct timeval tv1,tv2;
5409 /* mt038.201 added return */
5411 /* mt039.201 changes for nanosleep */
5412 struct timespec tsN;
5413 PRIVATE U32 err_in_usec;
5415 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5420 /* mt027.201 - Modification for SRegCfgTmr support */
5421 /* check SS_TICKS_SEC */
5422 if (SS_1MS < SS_TICKS_SEC)
5424 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5427 /* mt025.201 - Addition to stop timer handler till task registration is done */
5428 /* wait for SS to come up */
5429 /* mt038.201 changed how sem_wait is called */
5430 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5433 /* mt027.201 - Modification for SRegCfgTmr support */
5434 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5436 ts.tv_nsec = (MT_TICK_CNT * 1000);
5437 /* mt039.201 changes for nanosleep */
5443 if (gettimeofday(&tv1, NULL) == -1)
5445 #if (ERRCLASS & ERRCLS_DEBUG)
5446 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5447 "Error in clock_gettime");
5457 #ifndef STUB_TTI_HANDLING_5GTF
5458 printf("Returning from mtTmrHdlr()\n");
5463 /* mt039.201 changes for nanosleep */
5464 /* sleep for MT_TICK_CNT milli seconds */
5465 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5466 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5468 ts.tv_nsec = tsN.tv_nsec;
5473 if (gettimeofday(&tv2,NULL) == -1)
5475 #if (ERRCLASS & ERRCLS_DEBUG)
5476 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5477 "Error in clock_gettime");
5481 /*mt013.301 : changed check while calculating timer to fix
5482 * diffrence between MTSS time and real unix time
5484 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5486 time_int = (tv2.tv_usec - tv1.tv_usec);
5488 else if (tv2.tv_sec > tv1.tv_sec)
5490 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5492 else /* ts2 < ts1, this will not happen in normal scenario */
5494 /* to make sure cnt = 1 */
5496 time_int = MT_TICK_CNT;
5499 oldTicks = osCp.dep.sysTicks;
5500 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5501 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5502 newTicks = osCp.dep.sysTicks;
5503 tv1.tv_usec = tv2.tv_usec;
5504 tv1.tv_sec = tv2.tv_sec;
5506 cnt = newTicks - oldTicks;
5508 while(err_in_usec >= MT_TICK_CNT)
5511 err_in_usec -= MT_TICK_CNT;
5513 if( cnt >= MT_MAX_TICK_CNT_VAL)
5514 cnt = MT_MIN_TICK_CNT_VAL;
5515 /* call the common timer tick handler */
5516 for (i = 0; i < cnt; i++)
5518 /* mt008.301: cmPrcTmr is guarded with a lock */
5519 /* lock the timer table */
5520 if (SLock(&osCp.tmrTblLock) != ROK)
5522 #if (ERRCLASS & ERRCLS_DEBUG)
5523 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5527 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5528 /* unlock the timer table */
5529 SUnlock(&osCp.tmrTblLock);
5533 /* mt009.21: addition */
5534 RETVALUE( (Void *) NULLP);
5535 /* will not reach here */
5543 * Desc: Process timer event. Called from the common timer
5544 * code when a timeout occurs.
5554 PUBLIC Void mtTimeout
5556 PTR tCb, /* control block */
5557 S16 evnt /* event */
5560 PUBLIC Void mtTimeout(tCb, evnt)
5561 PTR tCb; /* control block */
5562 S16 evnt; /* event */
5571 #ifndef TENB_RTLIN_CHANGES
5574 /* mt028.201: modification: multiple procs support related changes */
5575 #ifdef SS_MULTIPLE_PROCS
5577 #endif /* SS_MULTIPLE_PROCS */
5578 #ifdef RGL_SPECIFIC_CHANGES
5579 #ifdef MSPD_MLOG_NEW
5580 U32 t = GetTIMETICK();
5587 /* get the timer entry */
5588 tEnt = (SsTmrEntry *) tCb;
5591 /* if the timer was deleted, this will be NULL, so drop it */
5597 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5600 /* Hmmmm, the timer might have been deleted while we've been
5601 * working at getting here, so we just skip this.
5603 if (tEnt->used == FALSE)
5609 /* Set up and send a timer message to the destination tasks'
5612 #ifndef SS_MULTICORE_SUPPORT
5613 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5615 #ifdef RGL_SPECIFIC_CHANGES
5616 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5618 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5623 #if (ERRCLASS & ERRCLS_DEBUG)
5624 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5630 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5631 mInfo->eventInfo.event = SS_EVNT_TIMER;
5632 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5634 mInfo->pst.dstEnt = tEnt->ownerEnt;
5635 mInfo->pst.dstInst = tEnt->ownerInst;
5636 mInfo->pst.srcEnt = tEnt->ownerEnt;
5637 mInfo->pst.srcInst = tEnt->ownerInst;
5638 /* mt028.201: modification: multiple procs support related changes */
5639 #ifndef SS_MULTIPLE_PROCS
5640 mInfo->pst.dstProcId = SFndProcId();
5641 mInfo->pst.srcProcId = SFndProcId();
5642 #else /* SS_MULTIPLE_PROCS */
5643 mInfo->pst.dstProcId = tEnt->ownerProc;
5644 mInfo->pst.srcProcId = tEnt->ownerProc;
5645 #endif /* SS_MULTIPLE_PROCS */
5646 mInfo->pst.selector = SEL_LC_NEW;
5647 #ifndef SS_MULTICORE_SUPPORT
5648 mInfo->pst.region = DFLT_REGION;
5651 mInfo->pst.pool = DFLT_POOL;
5652 mInfo->pst.prior = PRIOR0;
5653 mInfo->pst.route = RTESPEC;
5654 mInfo->pst.event = 0;
5657 #ifndef TENB_RTLIN_CHANGES
5658 /* get a semaphore for the TAPA task table */
5659 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5664 #if (ERRCLASS & ERRCLS_DEBUG)
5665 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5673 /* find the owner TAPA task */
5674 /* mt028.201: modification: multiple procs support related changes */
5675 #ifdef SS_MULTIPLE_PROCS
5676 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5677 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5678 #else /* SS_MULTIPLE_PROCS */
5679 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5680 #endif /* SS_MULTIPLE_PROCS */
5681 if (idx == SS_TSKNC)
5683 #ifndef TENB_RTLIN_CHANGES
5684 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5691 /* ensure that the TAPA task is hale and hearty */
5692 tTsk = &osCp.tTskTbl[idx];
5695 #ifndef TENB_RTLIN_CHANGES
5696 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5701 /* Klock work fix ccpu00148484 */
5702 /* write the timer message to the queue of the destination task */
5703 /* mt008.301 : check sTsk before putting into it's DQ */
5704 if (tTsk->sTsk == NULLP)
5706 #ifndef TENB_RTLIN_CHANGES
5707 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5711 #if (ERRCLASS & ERRCLS_DEBUG)
5712 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5713 "Could not write to demand queue");
5718 #ifdef SS_LOCKLESS_MEMORY
5719 mInfo->pst.region = tTsk->sTsk->region;
5720 mInfo->region = tTsk->sTsk->region;
5721 #endif /* SS_LOCKLESS_MEMORY */
5722 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5723 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5725 #ifndef TENB_RTLIN_CHANGES
5726 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5730 #if (ERRCLASS & ERRCLS_DEBUG)
5731 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5732 "Could not write to demand queue");
5737 /* Fix for ccpu00130657 */
5738 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5739 if (tTsk->sTsk->tskPrior == PRIOR0)
5742 WLS_WakeUp(mtGetWlsHdl());
5749 /* release the semaphore for the TAPA task table */
5750 #ifndef TENB_RTLIN_CHANGES
5751 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5755 /* restart the timer */
5756 arg.tq = osCp.dep.tmrTq;
5757 arg.tqCp = &osCp.dep.tmrTqCp;
5758 arg.timers = tEnt->dep.timers;
5759 arg.cb = (PTR) tEnt;
5763 arg.max = TMR_DEF_MAX;
5764 arg.wait = tEnt->interval;
5766 #ifdef RGL_SPECIFIC_CHANGES
5767 #ifdef MSPD_MLOG_NEW
5768 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5780 * Desc: This thread reads the console and hands over any
5781 * data read to a user function.
5783 * Ret: (thread function)
5791 PRIVATE Void *mtConHdlr
5793 Ptr parm /* unused */
5796 /* mt009.21: addition */
5797 PRIVATE Void *mtConHdlr(parm)
5798 Ptr parm; /* unused */
5805 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5811 /* check if we have a console input file handle */
5812 if (osCp.dep.conInFp == NULLP)
5818 fd = fileno(osCp.dep.conInFp);
5823 if ((read(fd, &data, 1)) != 1)
5829 /* call rdConQ, defined by the system service user */
5839 #ifdef SS_DRVR_SUPPORT
5842 * Fun: Interrupt service task handler
5844 * Desc: This is the interrupt service task handler. It blocks
5845 * on a pipe from which it reads an isFlag structure. The
5846 * structure indicates which interrupt service task is to
5847 * be executed. The thread identifies the task, calls the
5848 * isTsk function and sends itself a message to repeat
5849 * this operation until it receives a message to cease.
5859 /* mt009.21: addition */
5860 PRIVATE Void *mtIsTskHdlr
5862 Ptr tskPtr /* pointer to task entry */
5865 /* mt009.21: addition */
5866 PRIVATE Void *mtIsTskHdlr(tskPtr)
5867 Ptr tskPtr; /* pointer to task entry */
5870 #if (ERRCLASS & ERRCLS_DEBUG)
5881 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5886 switch (isFlag.action)
5889 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5891 /* call the interrupt service task activation function */
5892 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5894 /* send self a message to keep doing this */
5895 isFlag.action = MT_IS_RESET;
5897 #if (ERRCLASS & ERRCLS_DEBUG)
5898 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5899 if (ret != sizeof(isFlag))
5901 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5902 "write() to pipe failed");
5905 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5912 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5917 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5919 /* call the interrupt service task activation function */
5920 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5922 #if (ERRCLASS & ERRCLS_DEBUG)
5923 /* send self a message to do this again */
5924 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5926 if (ret != sizeof(isFlag))
5928 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5929 "write() to pipe failed");
5932 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5940 /* where did THIS come from?? */
5944 /* mt009.21: addition */
5945 RETVALUE( (Void *) NULLP);
5949 #endif /* SS_DRVR_SUPPORT */
5950 #endif /* L2_L3_SPLIT */
5952 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5956 * Fun: mtIntSigHndlr
5958 * Desc: Exit function, shuts down.
5968 PUBLIC Void mtIntSigHndlr
5973 PUBLIC Void mtIntSigHndlr(arg)
5978 TRC0(mtIntSigHndlr);
5980 osCp.dep.sigEvnt=TRUE;
5983 #ifdef TENB_RTLIN_CHANGES
5991 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5996 * Desc: function, shuts down.
6006 PUBLIC Void mtExitClnup
6011 PUBLIC Void mtExitClnup()
6020 SGetSysTime(&ticks);
6022 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
6024 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
6026 #ifdef SS_HISTOGRAM_SUPPORT
6030 osCp.dep.sigEvnt=FALSE;
6032 if (osCp.dep.fileOutFp)
6034 fclose(osCp.dep.fileOutFp);
6042 Void SIncrementTtiCount(Void)
6047 Ticks SGetTtiCount(Void)
6056 * Desc: This function displays a string to a given output
6061 * Notes: Buffer should be null terminated.
6063 * channel 0 is reserved for backwards compatibility
6072 S16 chan, /* channel */
6073 Txt *buf /* buffer */
6076 PUBLIC S16 SDisplay(chan, buf)
6077 S16 chan; /* channel */
6078 Txt *buf; /* buffer */
6083 /* mt020.201 - Fixed typo */
6084 #if (ERRCLASS & ERRCLS_INT_PAR)
6087 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6092 #ifndef XEON_SPECIFIC_CHANGES
6093 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6094 ssMemlog(buf, strlen(buf));
6099 /* mt012.301 :FIX for LOG RELATED ISSUE */
6107 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6113 if (osCp.dep.fileOutFp)
6114 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6115 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6118 fflush(osCp.dep.fileOutFp);
6131 * Desc: function, shuts down.
6151 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6152 a loop to overcome the child processes being killed upon exiting the
6154 #ifdef SS_LINUX /* this should have already been defined */
6155 /* mt010.301 removed flag SLES9_PLUS */
6156 /* wait forever for children */
6160 if(osCp.dep.sigEvnt==TRUE)
6167 pthread_exit(NULLP);
6173 * Fun: Set date and time
6175 * Desc: This function is used to set the calendar
6180 * Notes: Unimplemented
6186 PUBLIC S16 SSetDateTime
6188 REG1 DateTime *dt /* date and time */
6191 PUBLIC S16 SSetDateTime(dt)
6192 REG1 DateTime *dt; /* date and time */
6207 * Fun: Get date and time
6209 * Desc: This function is used to determine the calendar
6210 * date and time. This information may be used for
6211 * some management functions.
6222 PUBLIC S16 SGetDateTime
6224 REG1 DateTime *dt /* date and time */
6227 PUBLIC S16 SGetDateTime(dt)
6228 REG1 DateTime *dt; /* date and time */
6231 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6234 struct timespec ptime;
6236 struct timeval ptime;
6245 #if (ERRCLASS & ERRCLS_INT_PAR)
6248 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6257 localtime_r(&tt, &tme);
6260 clock_gettime(CLOCK_REALTIME, &ptime);
6262 gettimeofday(&ptime, NULL);
6264 localtime_r(&ptime.tv_sec, &tme);
6266 dt->month = (U8) tme.tm_mon + 1;
6267 dt->day = (U8) tme.tm_mday;
6268 dt->year = (U8) tme.tm_year;
6269 dt->hour = (U8) tme.tm_hour;
6270 dt->min = (U8) tme.tm_min;
6271 dt->sec = (U8) tme.tm_sec;
6274 #ifdef SS_DATETIME_USEC
6276 dt->usec = ptime.tv_nsec / 1000;
6278 dt->usec = ptime.tv_usec;
6280 #endif /*-- SS_DATETIME_USEC --*/
6286 * Get time from epoch in milliseconds
6288 * Fun: Get time from epoch in milliseconds
6290 * Desc: This function is used to get the time from epoch in milli seconds.
6291 * This information may be used for calculating a layer's activation function
6292 * execution time used for thread profiling.
6301 /* mt003.301 Modifications */
6303 PUBLIC S16 SGetEpcTime
6305 EpcTime *et /* date and time */
6308 PUBLIC S16 SGetEpcTime(et)
6309 EpcTime *et; /* date and time */
6312 /* mt003.301 Modifications */
6314 U64 to_sec = 1000000;
6317 struct timespec ptime;
6319 struct timeval ptime;
6325 #if (ERRCLASS & ERRCLS_INT_PAR)
6334 clock_gettime(CLOCK_REALTIME, &ptime);
6336 gettimeofday(&ptime, NULL);
6337 #endif /* SS_LINUX */
6339 now = (ptime.tv_sec * to_sec);
6342 now += (ptime.tv_nsec / to_nsec);
6343 #else /* SS_LINUX */
6344 now += (ptime.tv_usec);
6346 #endif /* SS_LINUX */
6347 now = (now / to_nsec);
6358 * Fun: Get system time
6360 * Desc: This function is used to determine the system time.
6364 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6370 PUBLIC S16 SGetSysTime
6372 Ticks *sysTime /* system time */
6375 PUBLIC S16 SGetSysTime(sysTime)
6376 Ticks *sysTime; /* system time */
6382 #if (ERRCLASS & ERRCLS_INT_PAR)
6383 if (sysTime == NULLP)
6385 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6391 *sysTime = osCp.dep.sysTicks;
6397 /* mt021.201 - Addition of SGetRefTime function */
6400 * Fun: Get referenced time
6402 * Desc: This function is used to determine the time in seconds
6403 * and microseconds from a reference time. The reference
6404 * time is expressed in seconds from UTC EPOC, January 1,
6410 * Notes: Macros are defined for reference times:
6411 * SS_REFTIME_01_01_1970
6412 * SS_REFTIME_01_01_2002
6418 PUBLIC S16 SGetRefTime
6420 U32 refTime, /* reference time */
6425 PUBLIC S16 SGetRefTime(refTime, sec, usec)
6426 U32 refTime; /* reference time */
6433 struct timespec ptime;
6435 struct timeval ptime;
6441 clock_gettime(CLOCK_REALTIME, &ptime);
6443 gettimeofday(&ptime, NULL);
6446 #if (ERRCLASS & ERRCLS_INT_PAR)
6447 if (sec == NULLP || usec == NULLP)
6449 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6452 /* mt022.201 - Modification to fix compile warning */
6453 if (refTime > (U32)(ptime.tv_sec))
6455 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6460 *sec = ptime.tv_sec - refTime;
6462 *usec = ptime.tv_nsec / 1000;
6464 *usec = ptime.tv_usec;
6474 * Fun: Get Random Number
6476 * Desc: Invoked by layer when a pseudorandom number is required.
6480 * Notes: Suggested approach uses shuffled Linear Congruential
6481 * Operators as described in Byte magazine October
6482 * 1984; "Generating and Testing Pseudorandom Numbers"
6490 Random *value /* random number */
6493 PUBLIC S16 SRandom(value)
6494 Random *value; /* random number */
6500 #if (ERRCLASS & ERRCLS_INT_PAR)
6503 /* mt011.21: addition */
6504 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6510 *value = (Random) rand_r(&osCp.dep.randSeed);
6521 * Desc: This function exits from a task.
6525 * Notes: Currently does nothing.
6536 PUBLIC S16 SExitTsk()
6548 * Fun: Exit Interrupt
6550 * Desc: This function exits from an interrupt.
6554 * Notes: Currently does nothing.
6565 PUBLIC S16 SExitInt()
6577 * Fun: Hold Interrupt
6579 * Desc: This function prohibits interrupts from being enabled until
6580 * release interrupt. This function should be called when
6581 * interrupts are disabled and prior to any call to system
6582 * services either by entry to an interrupt service routine or
6583 * by explicit call to disable interrupt.
6587 * Notes: Currently does nothing
6598 PUBLIC S16 SHoldInt()
6610 * Fun: Release Interrupt
6612 * Desc: This function allows interrupts to be enabled.
6616 * Notes: Currently does nothing.
6627 PUBLIC S16 SRelInt()
6641 * Desc: Enable interrupts
6643 * Ret: ROK on success
6646 * Notes: Currently does nothing.
6652 PUBLIC INLINE S16 SEnbInt
6657 PUBLIC INLINE S16 SEnbInt()
6671 * Desc: Disable interrupts
6673 * Ret: ROK on success
6676 * Notes: Currently does nothing.
6682 PUBLIC INLINE S16 SDisInt
6687 PUBLIC INLINE S16 SDisInt()
6701 * Desc: This function gets the function address stored at the
6702 * specified interrupt vector.
6706 * Notes: Currently does nothing.
6714 VectNmb vectNmb, /* vector number */
6715 PIF *vectFnct /* vector function */
6718 PUBLIC S16 SGetVect(vectNmb, vectFnct)
6719 VectNmb vectNmb; /* vector number */
6720 PIF *vectFnct; /* vector function */
6738 * Desc: This function installs the specified function at the
6739 * specified interrupt vector.
6743 * Notes: Currently does nothing.
6751 VectNmb vectNmb, /* vector number */
6752 PIF vectFnct /* vector function */
6755 PUBLIC S16 SPutVect(vectNmb, vectFnct)
6756 VectNmb vectNmb; /* vector number */
6757 PIF vectFnct; /* vector function */
6770 /* mt028.201: modification: multiple procs support related changes */
6771 #ifndef SS_MULTIPLE_PROCS
6777 * Desc: This function gets the current entity and instance.
6780 * RFAILED - failed, general (optional)
6782 * Notes: This function may be called by the OS or Layer 1
6789 PUBLIC S16 SGetEntInst
6791 Ent *ent, /* entity */
6792 Inst *inst /* instance */
6795 PUBLIC S16 SGetEntInst(ent, inst)
6796 Ent *ent; /* entity */
6797 Inst *inst; /* instance */
6809 #if (ERRCLASS & ERRCLS_INT_PAR)
6810 /* check pointers */
6811 if (ent == NULLP || inst == NULLP)
6813 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6819 /* get the thread id */
6820 tId = pthread_self();
6823 /* find the system task in whose context we're running */
6825 ret = SLock(&osCp.sTskTblLock);
6830 for (i = 0; i < SS_MAX_STSKS; i++)
6832 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6834 sTsk = &osCp.sTskTbl[i];
6840 *ent = sTsk->dep.ent;
6841 *inst = sTsk->dep.inst;
6843 SUnlock(&osCp.sTskTblLock);
6846 RETVALUE(ret == ROK ? ROK : RFAILED);
6854 * Desc: This function sets the current entity and instance.
6864 PUBLIC S16 SSetEntInst
6866 Ent ent, /* entity */
6867 Inst inst /* instance */
6870 PUBLIC S16 SSetEntInst(ent, inst)
6871 Ent ent; /* entity */
6872 Inst inst; /* instance */
6884 #if (ERRCLASS & ERRCLS_INT_PAR)
6885 /* check entity and instance IDs */
6886 if (ent >= ENTNC || inst >= INSTNC)
6888 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6894 /* get the thread id */
6895 tId = pthread_self();
6898 /* find the system task in whose context we're running */
6900 ret = SLock(&osCp.sTskTblLock);
6905 for (i = 0; i < SS_MAX_STSKS; i++)
6907 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6909 sTsk = &osCp.sTskTbl[i];
6915 sTsk->dep.ent = ent;
6916 sTsk->dep.inst = inst;
6918 SUnlock(&osCp.sTskTblLock);
6921 RETVALUE(ret == ROK ? ROK : RFAILED);
6924 #endif /* SS_MULTIPLE_PROCS */
6926 #ifdef SS_DRVR_SUPPORT
6932 * Desc: Set interrupt pending flag
6934 * Ret: ROK on success
6943 PUBLIC INLINE S16 SSetIntPend
6945 U16 id, /* driver task identifier */
6946 Bool flag /* flag */
6949 PUBLIC INLINE S16 SSetIntPend(id, flag)
6950 U16 id; /* driver task identifier */
6951 Bool flag; /* flag */
6960 #if (ERRCLASS & ERRCLS_INT_PAR)
6961 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6963 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6970 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6972 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6980 #endif /* SS_DRVR_SUPPORT */
6983 #ifdef SS_LOCKLESS_MEMORY
6986 * Fun: SGlobMemInfoShow
6988 * Desc: This function displays the memory usage information
6989 * for the destined region. It will show the usage of
6990 * each configured bucket and the heap for the specified region.
6993 * RFAILED Region not registered
6999 PUBLIC S16 SGlobMemInfoShow
7004 PUBLIC S16 SGlobMemInfoShow()
7009 CmMmGlobRegCb *globReg;
7011 TRC1(SGlobMemInfoShow);
7013 globReg = osCp.globRegCb;
7015 sprintf(prntBuf, "--------------------------------------------------------------\n");
7016 SDisplay(0, prntBuf);
7017 sprintf(prntBuf, "Global Region Bucket Information\n");
7018 SDisplay(0, prntBuf);
7019 sprintf(prntBuf, "====================================================\n");
7020 SDisplay(0, prntBuf);
7021 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
7022 SDisplay(0, prntBuf);
7023 sprintf(prntBuf, "====================================================\n");
7024 SDisplay(0, prntBuf);
7027 for (idx = 0; idx < globReg->numBkts; idx++)
7029 #ifdef XEON_SPECIFIC_CHANGES
7030 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
7031 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7034 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
7035 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7037 sprintf(prntBuf, "%2u %12u %8u %9u\n",
7038 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7041 SDisplay(0, prntBuf);
7043 sprintf(prntBuf, "--------------------------------------------------------------\n");
7044 SDisplay(0, prntBuf);
7049 #endif /* SS_LOCKLESS_MEMORY */
7052 Bool IsMemoryThresholdHit(Region reg, Pool pool)
7054 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
7056 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
7059 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
7060 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
7067 /* mt022.201 - Addition of SRegInfoShow function */
7072 * Desc: This function displays the memory usage information
7073 * for the destined region. It will show the usage of
7074 * each configured bucket and the heap for the specified region.
7077 * RFAILED Region not registered
7079 * Notes: A Sample Output from the function
7080 * Bucket Memory: region 1
7081 * ====================================================
7082 * Bucket Number of Blks configured Size Allocated
7083 * ====================================================
7091 * Heap Memory: region 1
7094 * Heap Segmented blocks: 0
7101 PUBLIC S16 SRegInfoShow
7107 PUBLIC S16 SRegInfoShow(region, availmem)
7117 #if (ERRCLASS & ERRCLS_INT_PAR)
7118 if (region > (SS_MAX_REGS-1) )
7120 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7127 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7128 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7129 SDisplay(0, prntBuf);
7130 sprintf(prntBuf, "====================================================\n");
7131 SDisplay(0, prntBuf);
7132 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7133 SDisplay(0, prntBuf);
7134 sprintf(prntBuf, "====================================================\n");
7135 SDisplay(0, prntBuf);
7139 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7141 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7143 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7144 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7145 mtCMMRegCb[region]->bktTbl[idx].size,
7146 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7147 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7149 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7150 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7151 mtCMMRegCb[region]->bktTbl[idx].size,
7152 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7153 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7156 /*mt009.301 Fixed 64BIT compilation warnings*/
7158 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7159 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7160 mtCMMRegCb[region]->bktTbl[idx].size,
7161 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7163 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7164 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7165 mtCMMRegCb[region]->bktTbl[idx].size,
7166 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7168 #endif /* not TENB_RTLIN_CHANGES */
7169 SDisplay(0, prntBuf);
7170 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7171 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7172 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7174 sprintf(prntBuf, "\n---------------\n");
7175 SDisplay(0, prntBuf);
7176 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7177 SDisplay(0, prntBuf);
7178 /*mt009.301 Fixed 64BIT compilation warnings*/
7180 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7182 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7184 SDisplay(0, prntBuf);
7185 /*mt009.301 Fixed 64BIT compilation warnings*/
7187 sprintf(prntBuf, "Heap Allocated: %u\n",
7188 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7190 sprintf(prntBuf, "Heap Allocated: %lu\n",
7191 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7193 SDisplay(0, prntBuf);
7194 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7195 #if (ERRCLASS & ERRCLS_DEBUG)
7196 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7197 mtCMMRegCb[region]->heapCb.numFragBlk);
7198 SDisplay(0, prntBuf);
7203 #ifdef XEON_SPECIFIC_CHANGES
7204 #define SSI_MAX_BKT_THRESHOLD 6
7205 #define SSI_MAX_REG_THRESHOLD 2
7206 U32 SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7207 U32 SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7208 U32 SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7211 PRIVATE Void SInitMemThreshold
7217 PRIVATE Void SInitMemThreshold(region, maxBkt)
7223 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7225 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7226 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7227 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7228 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7233 PUBLIC S16 SRegReachedMemThreshold
7239 PUBLIC S16 SRegReachedMemThreshold(region, maxBkt)
7246 PRIVATE U8 initFlag = 1;
7250 SInitMemThreshold(region, maxBkt);
7253 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7255 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7260 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7264 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7269 RETVALUE(memStatus);
7272 /* mt033.201 - addition of API to return the memory statistical data */
7277 * Desc: This function returns the memory usage information
7278 * for the destined region. It will return the usage of
7279 * each configured bucket and the heap for the specified region.
7282 * RFAILED Region not registered
7290 PUBLIC S16 SGetRegInfo
7293 SsMemDbgInfo *dbgInfo
7296 PUBLIC S16 SGetRegInfo(region, dbgInfo)
7298 SsMemDbgInfo *dbgInfo;
7305 #if (ERRCLASS & ERRCLS_INT_PAR)
7306 if (region >= mtMemoCfg.numRegions )
7308 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7313 dbgInfo->availmem = 0;
7315 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7316 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7318 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7320 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7322 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7323 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7324 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7326 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7327 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7328 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7331 dbgInfo->region = region;
7333 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7335 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7336 mtCMMRegCb[region]->heapCb.avlSize);
7338 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7340 #if (ERRCLASS & ERRCLS_DEBUG)
7341 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7348 PUBLIC S16 SGetRegPoolInfo
7354 PUBLIC S16 SGetRegPoolInfo(numRegion, numPool)
7359 /* Send number of Region available */
7360 *numRegion = mtMemoCfg.numRegions;
7361 /* Send number of Pools available */
7362 *numPool = cfgRegInfo[0].numPools;
7367 /* mt033.201 - addition of APIs to print the memory statistical data
7368 * as defined by SSI enhancements
7370 #ifdef SSI_DEBUG_LEVEL1
7373 * Fun: SPrintRegMemStatusInfo
7375 * Desc: This function displays the memory usage information
7376 * for the destined region. It will show the total memory
7377 * used for static and dynamic memory if typeFlag is
7378 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7379 * memory block allocated for a particular size if typeFlag
7380 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7381 * calling SRegPrintMemStats.
7391 PUBLIC S16 SPrintRegMemStatusInfo
7397 PUBLIC S16 SPrintRegMemStatusInfo(region, typeFlag)
7407 TRC1(SPrintRegMemStatusInfo);
7409 #if (ERRCLASS & ERRCLS_INT_PAR)
7410 if (region >= mtMemoCfg.numRegions )
7412 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7417 /* initialize the counters*/
7421 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7423 /* total static and dynamic memory allocated from all the buckets in region requested */
7424 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7425 SDisplay(0, prntBuf);
7426 sprintf(prntBuf, "===========================================\n");
7427 SDisplay(0, prntBuf);
7428 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7429 SDisplay(0, prntBuf);
7430 sprintf(prntBuf, "===========================================\n");
7431 SDisplay(0, prntBuf);
7432 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7434 /*mt009.301 Fixed 64BIT compilation warnings*/
7436 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7437 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7438 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7440 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7441 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7442 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7444 SDisplay(0, prntBuf);
7445 /* update the total count */
7446 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7447 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7450 /*mt009.301 Fixed 64BIT compilation warnings*/
7452 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7453 SDisplay(0, prntBuf);
7454 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7456 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7457 SDisplay(0, prntBuf);
7458 /*mt010.301 fix for compilation error*/
7459 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7461 SDisplay(0, prntBuf);
7463 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7464 SDisplay(0, prntBuf);
7465 /*mt009.301 Fixed 64BIT compilation warnings*/
7467 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7468 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7470 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7471 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7473 SDisplay(0, prntBuf);
7475 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7477 /* Bucket Memory allocation Statistics */
7478 RETVALUE(SPrintRegMemStats(region));
7483 sprintf(prntBuf, "\n Invalid choice \n");
7484 SDisplay(0, prntBuf);
7492 * Fun: SPrintRegMemStats
7494 * Desc: This function displays the memory usage information for
7495 * the destined region. It will show the number of memory
7496 * block allocated for a particular size from the hash list.
7506 PRIVATE S16 SPrintRegMemStats
7511 PRIVATE S16 SPrintRegMemStats(region)
7515 CmMmHashListCp *hashListCp;
7520 TRC1(SPrintRegMemStats);
7522 hashListCp = &mtCMMRegCb[region]->hashListCp;
7524 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7525 SDisplay(0, prntBuf);
7526 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7527 hashListCp->numOfbins, hashListCp->numOfEntries);
7528 SDisplay(0, prntBuf);
7529 sprintf(prntBuf, "===================================\n");
7530 SDisplay(0, prntBuf);
7531 sprintf(prntBuf, "Block Size Total number of requests\n");
7532 SDisplay(0, prntBuf);
7533 sprintf(prntBuf, "===================================\n");
7534 SDisplay(0, prntBuf);
7536 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7537 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7539 if (hashListCp->hashList[idx].numAttempts)
7542 /*mt009.301 Fixed 64BIT compilation warnings*/
7544 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7545 hashListCp->hashList[idx].numAttempts);
7547 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7548 hashListCp->hashList[idx].numAttempts);
7550 SDisplay(0, prntBuf);
7554 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7555 SDisplay(0, prntBuf);
7556 sprintf(prntBuf, "=================================================\n");
7557 SDisplay(0, prntBuf);
7558 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7559 SDisplay(0, prntBuf);
7560 sprintf(prntBuf, "=================================================\n");
7561 SDisplay(0, prntBuf);
7563 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7564 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7566 /*mt009.301 Fixed 64BIT compilation warnings*/
7568 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7569 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7570 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7572 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7573 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7574 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7576 SDisplay(0, prntBuf);
7578 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7579 SDisplay(0, prntBuf);
7580 /*mt009.301 Fixed 64BIT compilation warnings*/
7582 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7583 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7584 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7586 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7587 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7588 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7590 SDisplay(0, prntBuf);
7591 sprintf(prntBuf, "\n");
7592 SDisplay(0, prntBuf);
7599 * Fun: SRegMemErrHdlr
7601 * Desc: This function handles the errors returned from the memory
7602 * related functions. Customers are suggested to modify this
7603 * API according to their specific requirement.
7613 PUBLIC Void SRegMemErrHdlr
7620 PUBLIC Void SRegMemErrHdlr(region, ptr, errCode)
7628 TRC1(SRegMemErrHdlr);
7630 if (errCode == RDBLFREE)
7632 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7633 SDisplay(0, prntBuf);
7635 else if (errCode == RTRAMPLINGNOK)
7637 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7638 SDisplay(0, prntBuf);
7646 * Fun: SPrintRegMemProfile
7648 * Desc: This function displays the memory profile information
7649 * for the destined region. This function prints for:
7650 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7651 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7661 PUBLIC S16 SPrintRegMemProfile
7666 PUBLIC S16 SPrintRegMemProfile(region)
7672 CmMmBlkHdr *curBktBlk;
7674 Size offsetToNxtBlk;
7681 TRC1(SPrintRegMemProfile);
7683 #if (ERRCLASS & ERRCLS_INT_PAR)
7684 if (region >= mtMemoCfg.numRegions )
7686 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7691 regCb = mtCMMRegCb[region];
7693 /* memory profile */
7694 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7695 SDisplay(0, prntBuf);
7697 /* bucket profile */
7698 sprintf(prntBuf, "\nBucket Profile\n");
7699 SDisplay(0, prntBuf);
7701 for (idx = 0; idx < regCb->numBkts; idx++)
7704 /*mt009.301 Fixed 64BIT compilation warnings*/
7706 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7707 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7709 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7710 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7712 SDisplay(0, prntBuf);
7714 sprintf(prntBuf, "==========================================================================\n");
7715 SDisplay(0, prntBuf);
7716 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7717 SDisplay(0, prntBuf);
7718 sprintf(prntBuf, "==========================================================================\n");
7719 SDisplay(0, prntBuf);
7721 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7723 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7724 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7725 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7727 /*mt009.301 Fixed 64BIT compilation warnings*/
7729 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7731 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7733 SDisplay(0, prntBuf);
7734 /* check if it is a sane block, elxe jump to next block */
7735 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7737 sprintf(prntBuf, " Trampled \n");
7738 SDisplay(0, prntBuf);
7743 if (CMM_IS_STATIC(curBktBlk->memFlags))
7745 /*mt009.301 Fixed 64BIT compilation warnings*/
7747 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7749 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7751 SDisplay(0, prntBuf);
7753 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7755 /*mt009.301 Fixed 64BIT compilation warnings*/
7757 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7759 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7761 SDisplay(0, prntBuf);
7763 else if (CMM_IS_FREE(curBktBlk->memFlags))
7765 /*mt009.301 Fixed 64BIT compilation warnings*/
7767 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7769 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7771 SDisplay(0, prntBuf);
7775 sprintf(prntBuf, " Trampled \n");
7776 SDisplay(0, prntBuf);
7782 sprintf(prntBuf, "\nHeap Profile\n");
7783 SDisplay(0, prntBuf);
7785 /* point to heapCb */
7786 heapCb = &(regCb->heapCb);
7788 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7789 SDisplay(0, prntBuf);
7790 sprintf(prntBuf, "==========================================================================\n");
7791 SDisplay(0, prntBuf);
7792 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7793 SDisplay(0, prntBuf);
7794 sprintf(prntBuf, "==========================================================================\n");
7795 SDisplay(0, prntBuf);
7797 /* traverse the entire heap to output the heap profile */
7798 hdrSize = sizeof(CmHEntry);
7799 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7800 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7802 /*mt009.301 Fixed 64BIT compilation warnings*/
7804 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7806 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7808 SDisplay(0, prntBuf);
7810 /* check if it is a sane block, elxe jump to next block */
7811 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7813 sprintf(prntBuf, " Trampled \n");
7814 SDisplay(0, prntBuf);
7816 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7817 SDisplay(0, prntBuf);
7820 * To go to next block in the heap we do not have any offset value
7821 * other than curHBlk->size. As the block is already trampled
7822 * we cannot rely on this size. So it is better to stop here unless there
7823 * exists any other mechanism(?) to know the offset to next block.
7828 /*mt009.301 Fixed 64BIT compilation warnings*/
7830 sprintf(prntBuf, " %8u", curHBlk->size);
7832 sprintf(prntBuf, " %8lu", curHBlk->size);
7834 SDisplay(0, prntBuf);
7836 if (CMM_IS_STATIC(curHBlk->memFlags))
7838 /*mt009.301 Fixed 64BIT compilation warnings*/
7840 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7842 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7844 SDisplay(0, prntBuf);
7846 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7848 /*mt009.301 Fixed 64BIT compilation warnings*/
7850 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7852 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7854 SDisplay(0, prntBuf);
7856 else if (CMM_IS_FREE(curHBlk->memFlags))
7858 /*mt009.301 Fixed 64BIT compilation warnings*/
7860 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7862 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7864 SDisplay(0, prntBuf);
7868 sprintf(prntBuf, " Trampled \n");
7869 SDisplay(0, prntBuf);
7871 /* goto next block in the heap */
7872 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7878 #endif /* SSI_DEBUG_LEVEL1 */
7880 /*-- mt035.201 : Added new API for timestamp --*/
7883 * Fun: Get TimeStamp
7885 * Desc: This function is used to Get TimeStamp in micro seconds
7896 PUBLIC S16 SGetTimeStamp
7901 PUBLIC S16 SGetTimeStamp(ts)
7907 struct timespec ptime;
7909 struct timeval ptime;
7916 TRC1(SGetTimeStamp);
7919 clock_gettime(CLOCK_REALTIME, &ptime);
7921 gettimeofday(&ptime, NULL);
7924 /* Obtain the time of day, and convert it to a tm struct. --*/
7925 ptm = localtime (&ptime.tv_sec);
7926 /* Klock work fix ccpu00148484 */
7929 /* Format the date and time, down to a single second. --*/
7930 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7933 /* Compute microseconds. --*/
7935 microseconds = ptime.tv_nsec / 1000;
7937 microseconds = ptime.tv_usec;
7940 /* Print the formatted time, in seconds, followed by a decimal point
7941 and the microseconds. --*/
7942 /*mt009.301 Fixed 64BIT compilation warnings*/
7944 sprintf(ts, "%s.%03d", time_string, microseconds);
7946 sprintf(ts, "%s.%03ld", time_string, microseconds);
7952 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7955 * Fun: Get SGetSystemTsk
7957 * Desc: This function is used to Get sytem task id
7967 PUBLIC U32 SGetSystemTsk
7972 PUBLIC U32 SGetSystemTsk()
7975 TRC1(SGetSystemTskS);
7977 RETVALUE(pthread_self());
7979 } /* end of SGetSystemTsk */
7981 #ifdef SS_MULTICORE_SUPPORT
7984 * Fun: Add Timer thread into system task table
7986 * Desc: This function is used to add the system task
7987 * associated with Timer thread.
7997 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void)
7999 PRIVATE SsSTskEntry* ssdAddTmrSTsk()
8005 TRC1(ssdAddTmrSTsk);
8007 /* lock the system task table */
8008 ret = SLock(&osCp.sTskTblLock);
8012 #if (ERRCLASS & ERRCLS_DEBUG)
8013 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8014 "Could not lock system task table");
8020 /* check count of system tasks */
8021 if (osCp.numSTsks == SS_MAX_STSKS)
8024 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8026 #if (ERRCLASS & ERRCLS_DEBUG)
8027 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
8028 "Could not give the Semaphore");
8033 #if (ERRCLASS & ERRCLS_ADD_RES)
8034 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
8041 /* initialize the system task entry with the information we have */
8042 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
8044 /* store the system task priority */
8045 sTsk->tskPrior = SS_NORM_TSK_PRI;
8047 /* initialize the demand queue */
8048 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8051 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8053 #if (ERRCLASS & ERRCLS_DEBUG)
8054 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8055 "Could not give the Semaphore");
8060 #if (ERRCLASS & ERRCLS_DEBUG)
8061 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8062 "Could not initialize demand queue");
8068 /* initialize the system task entry lock */
8069 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8071 ssDestroyDmndQ(&sTsk->dQ);
8073 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8075 #if (ERRCLASS & ERRCLS_DEBUG)
8076 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8077 "Could not give the Semaphore");
8082 #if (ERRCLASS & ERRCLS_DEBUG)
8083 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8084 "Could not initialize system task entry lock");
8091 /* success, update the table */
8092 sTsk->tskId = osCp.nxtSTskEntry;
8094 sTsk->termPend = FALSE;
8095 osCp.nxtSTskEntry = sTsk->nxt;
8098 /* unlock the system task table */
8100 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8102 #if (ERRCLASS & ERRCLS_DEBUG)
8103 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8104 "Could not give the Semaphore");
8111 #endif /* SS_MULTICORE_SUPPORT */
8112 /* mt003.301 Readwrite lock and recursive mutex additions */
8113 #ifdef SS_LOCK_SUPPORT
8116 * Fun: ssdInitLockNew
8118 * Desc: This function is used to initialise lock/mutex
8128 PUBLIC S16 ssdInitLockNew
8134 PUBLIC S16 ssdInitLockNew(lockId, lockType)
8140 #ifdef SS_REC_LOCK_SUPPORT
8141 pthread_mutexattr_t attr;
8142 #endif /* SS_REC_LOCK_SUPPORT */
8143 Txt prntBuf[PRNTSZE];
8146 TRC1(ssdInitLockNew);
8150 #ifdef SS_RDWR_LOCK_SUPPORT
8153 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8155 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8156 SDisplay(0, prntBuf);
8161 #endif /* SS_RDWR_LOCK_SUPPORT */
8162 #ifdef SS_REC_LOCK_SUPPORT
8165 retVal = pthread_mutexattr_init(&attr);
8169 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8174 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8176 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8180 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8181 pthread_mutexattr_destroy(&attr);
8185 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8188 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8189 pthread_mutexattr_destroy(&attr);
8195 #endif /* SS_REC_LOCK_SUPPORT */
8198 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8199 SDisplay(0, prntBuf);
8209 * Desc: This function is used to aquire the read write lock
8219 PUBLIC S16 ssdLockNew
8225 PUBLIC S16 ssdLockNew(lockId, lockType)
8231 Txt prntBuf[PRNTSZE];
8238 #ifdef SS_RDWR_LOCK_SUPPORT
8241 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8243 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8244 SDisplay(0, prntBuf);
8251 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8253 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8254 SDisplay(0, prntBuf);
8261 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8263 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8264 SDisplay(0, prntBuf);
8271 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8273 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8274 SDisplay(0, prntBuf);
8279 #endif /* SS_RDWR_LOCK_SUPPORT */
8280 #ifdef SS_REC_LOCK_SUPPORT
8283 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8285 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8286 SDisplay(0, prntBuf);
8291 #endif /* SS_REC_LOCK_SUPPORT */
8294 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8295 SDisplay(0, prntBuf);
8308 * Desc: This function is used to Unlock the read write lock
8318 PUBLIC S16 ssdUnlockNew
8324 PUBLIC S16 ssdUnlockNew(lockId, lockType)
8330 Txt prntBuf[PRNTSZE];
8337 #ifdef SS_RDWR_LOCK_SUPPORT
8340 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8342 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8343 SDisplay(0, prntBuf);
8348 #endif /* SS_RDWR_LOCK_SUPPORT */
8349 #ifdef SS_REC_LOCK_SUPPORT
8352 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8354 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8355 SDisplay(0, prntBuf);
8360 #endif /* SS_REC_LOCK_SUPPORT */
8363 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8364 SDisplay(0, prntBuf);
8373 * Fun: ssdDestroyLockNew
8375 * Desc: This function is used to destroy the read write lock
8385 PUBLIC S16 ssdDestroyLockNew
8391 PUBLIC S16 ssdDestroyLockNew(lockId, lockType)
8396 Txt prntBuf[PRNTSZE];
8399 TRC1(ssdDestroyLockNew);
8403 #ifdef SS_RDWR_LOCK_SUPPORT
8406 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8408 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8409 SDisplay(0, prntBuf);
8414 #endif /* SS_RDWR_LOCK_SUPPORT */
8415 #ifdef SS_REC_LOCK_SUPPORT
8418 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8420 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8421 SDisplay(0, prntBuf);
8426 #endif /* SS_REC_LOCK_SUPPORT */
8429 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8430 SDisplay(0, prntBuf);
8436 #endif /* SS_LOCK_SUPPORT */
8438 /* mt005.301 : Cavium Changes */
8439 #ifdef SS_SEUM_CAVIUM
8443 * Fun: ssInitRcvWork
8445 * Desc: This is the initializtion function of receive
8449 * RFAILED - failed, general (optional)
8451 * Notes: Function to initialize the work queue packet
8452 * receiving thread. This creates the new thread to
8453 * receive the work and sets the affinity.
8459 PUBLIC S16 ssInitRcvWork
8464 PUBLIC S16 ssInitRcvWork()
8467 pthread_attr_t attr;
8470 TRC1(ssInitRcvWork);
8472 /* set the required attributes */
8473 pthread_attr_init(&attr);
8474 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8475 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8476 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8478 /* Create a new thread to receive the work queue messages */
8479 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8481 pthread_attr_destroy(&attr);
8486 pthread_attr_destroy(&attr);
8490 }/* ssInitRcvWork */
8497 * Desc: This is the handler function of receive
8501 * RFAILED - failed, general (optional)
8503 * Notes:The handler function of the work queue receiver task.
8504 * This will be waiting for the work and after receiving
8505 * it, work will converted and posted to that entityt
8512 PRIVATE void *workRcvTsk
8517 PRIVATE void *workRcvTsk (ptr)
8522 cvmx_wqe_t *workPtr;
8523 Buffer *mBuf, *rcvdBuf;
8524 SsMsgInfo *minfoPtr;
8534 /* get the work if its avilable */
8535 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8537 if ( workPtr == NULLP )
8539 /* If there is no work then sleep for 10 usec */
8541 ts.tv_nsec = 500000;
8543 nanosleep(&ts, NULLP);
8547 switch(workPtr->tag)
8549 /* Switch over according to the tag value */
8550 case SS_CVMX_MBUF_TAG:
8552 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8554 /* Convert the physical address to Pointers */
8555 ret = SConvPhyPtr(&rcvdBuf);
8558 /* mt011.301: Cavium 32 bit changes */
8559 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8563 /* Copy the buffer to this region */
8564 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8567 /* mt011.301: Cavium 32 bit changes */
8568 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8572 /* mt011.301: Cavium 32 bit changes */
8573 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8575 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8577 /* Get the post strucutre and Post the message */
8578 if ( minfoPtr != NULLP)
8580 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8582 (Void)SPstTsk(&pst, mBuf);
8584 /* Free the buffer allocated if it cannot be sent */
8593 /* Invalid tag value, drop the work */
8594 /* mt011.301: Cavium 32 bit changes */
8595 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8604 #endif /* SS_SEUM_CAVIUM */
8606 #ifdef TENB_RTLIN_CHANGES
8607 PUBLIC S16 SInitLock(SLockId *l, U8 t)
8610 pthread_mutexattr_t prior;
8611 pthread_mutexattr_init(&prior);
8612 #ifndef RGL_SPECIFIC_CHANGES
8613 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8615 r = pthread_mutex_init(l, &prior);
8616 pthread_mutexattr_destroy(&prior);
8620 #ifdef SS_THR_REG_MAP
8623 * Fun: ssRegMainThread
8625 * Desc: This function is used to add the memory region
8626 * mapping for the main thread.
8628 * Ret: VOID (Always successful)
8636 PUBLIC Void ssRegMainThread(Void)
8639 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8641 printf("not able to get different Id for main thread\n");
8644 /* Here the default region is added as we dont have any region associated with
8645 * Main thread. The thread should not perform any allocation except
8646 * the initial configuratin
8648 #ifdef XEON_SPECIFIC_CHANGES
8649 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8651 SS_GET_THREAD_MEM_REGION() =
8658 * Fun: ssCheckAndAddMemoryRegionMap
8660 * Desc: This function is used to add the memory region
8661 * mapping for the provided sTsk associated thread.
8662 * If the threadId can be placed in the thread memory
8663 * region mapping table and returns success if it is able
8664 * to place. If not, it keeps the thread ID in the static
8665 * local array and increments the count. Once thread Id
8666 * is successfully placed in the thread memory region mapping
8667 * table, pthread_cancel is sent for all the previous threads
8668 * which are failed to place in table.
8670 * Ret: TRUE - Thread ID successfully placed in thread memory region
8672 * FALSE - If thread Id is not placed in thread memory region
8675 * Notes:mapping tablemapping tablng tablee
8680 PUBLIC S32 ssCheckAndAddMemoryRegionMap
8682 pthread_t threadId, /* Thread Id of system task */
8683 Region region /* Region associated with thread */
8686 PRIVATE U32 createdThreads;
8687 PRIVATE pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8690 TRC1(ssCheckAndAddMemoryRegionMap);
8692 /* Here 0xFF is considered as invalid region and if the mapping table
8693 * contains 0xFF, that mapping entry is free
8695 if(SS_INVALID_THREAD_REG_MAP !=
8696 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8698 /* Klock work fix ccpu00148484 */
8699 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8701 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8702 printf("Not able to get the different thread ID, exiting\n");
8705 createdThreadIds[createdThreads++] = threadId;
8708 /* If we found free mapping table entry, place the region and send pthread_cancel
8709 * for all the thread Ids which are created before this
8711 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8712 #ifdef XEON_SPECIFIC_CHANGES
8713 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8714 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8715 SS_MAX_THREAD_REGION_MAP), region);
8717 for(indx = 0; indx < createdThreads; indx++)
8719 #ifdef XEON_SPECIFIC_CHANGES
8720 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8722 pthread_cancel(createdThreadIds[indx]);
8728 } /* ssCheckAndAddMemoryRegionMap */
8732 * Fun: ssCheckAndDelMemoryRegionMap
8734 * Desc: This function is used to add the memory region
8735 * mapping for the provided sTsk associated thread.
8736 * If the threadId can be placed in the thread memory
8737 * region mapping table and returns success if it is able
8738 * to place. If not, it keeps the thread ID in the static
8739 * local array and increments the count. Once thread Id
8740 * is successfully placed in the thread memory region mapping
8741 * table, pthread_cancel is sent for all the previous threads
8742 * which are failed to place in table.
8744 * Ret: TRUE - Thread ID successfully placed in thread memory region
8746 * FALSE - If thread Id is not placed in thread memory region
8749 * Notes:mapping tablemapping tablng tablee
8754 PUBLIC S32 ssCheckAndDelMemoryRegionMap
8756 pthread_t threadId /* Thread Id of system task */
8760 TRC1(ssCheckAndDelMemoryRegionMap);
8762 /* Raghu To-Do Check with team, is it necessary to acquire lock
8763 * as del and add may go parallel */
8764 /* Here 0xFF is considered as invalid region and if the mapping table
8765 * contains 0xFF, that mapping entry is free
8767 if(SS_INVALID_THREAD_REG_MAP ==
8768 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8771 printf("Invalid Thread ID (%ld)\n", (U32)threadId);
8773 printf("Invalid Thread ID (%d)\n", (U32)threadId);
8777 /* If we found free mapping table entry, place the region and send pthread_cancel
8778 * for all the thread Ids which are created before this
8780 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8784 } /* ssCheckAndAddMemoryRegionMap */
8788 #ifdef SS_TSKLOG_ENABLE
8793 * Desc: This function will return current time through input parameter.
8796 * RFAILED - failed, general (optional)
8803 PUBLIC S16 SStartTask
8805 VOLATILE U32 *startTime,
8809 PUBLIC S16 SStartTask(startTime, taskId)
8810 VOLATILE U32 *startTime;
8814 #ifdef MSPD_MLOG_NEW
8815 *startTime = GetTIMETICK();
8824 * Desc: This function will return current time through input parameter.
8825 * and take the difference of start time provided as input parameter
8829 * RFAILED - failed, general (optional)
8836 PUBLIC S16 SStopTask
8838 VOLATILE U32 startTime,
8842 PUBLIC S16 SStopTask(startTime, taskId)
8843 VOLATILE U32 startTime;
8850 case PID_MAC_HARQ_IND:
8851 case PID_SCH_TTI_IND:
8853 case PID_MAC_DAT_IND:
8854 case PID_MAC_SF_ALLOC_REQ:
8855 case PID_MAC_STA_RSP:
8856 case PID_MAC_DL_SCHD:
8857 case PID_MAC_DL_CQI_IND:
8858 case PID_MAC_UL_CQI_IND:
8859 case PID_MAC_UL_SCHD:
8860 case PID_MAC_TTI_IND:
8861 case PID_CL_RCV_PHY_MSG:
8862 case PID_CL_HARQ_STA_IND:
8863 case PID_MAC_AM_HARQ_RLS:
8864 case PID_CL_DL_BATCH_PROC:
8865 case PID_CL_DLM_PRC_TTI_IND:
8866 case PID_CRC_IND_REAL:
8867 case PID_CRC_IND_DUMMY:
8868 case PID_TTI_LATENCY:
8869 case PID_RECPREQ_PROC:
8872 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8874 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8877 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8885 PUBLIC S16 SStartTask
8887 VOLATILE U32 * startTime,
8891 PUBLIC S16 SStartTask(startTime, taskId)
8892 VOLATILE U32 * startTime;
8901 PUBLIC S16 SStopTask
8903 VOLATILE U32 startTime,
8907 PUBLIC S16 SStopTask(startTime, taskId)
8908 VOLATILE U32 startTime;
8915 #endif /*#ifdef SS_TSKLOG_ENABLE */
8916 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8918 * This primitive is used to calculate the CPU Utilization per Core
8923 * @return Void - function is always success
8926 PUBLIC Void UpdateSocCpuInfo
8928 CmCpuStatsInfo *cpuInfo,
8932 PUBLIC Void UpdateSocCpuInfo(*cpuInfo, idx)
8933 CmCpuStatsInfo *cpuInfo;
8938 S8 mipsStr[MIPS_STRING_LEN];
8945 /* Open the file which holds the MIPS available value */
8946 mipsFd = fopen(MIPS_FILE, "r");
8953 /* Get the free mips available value from the file */
8954 if(NULLP == fgets(mipsStr, 24, mipsFd))
8956 printf("fgets to get the free mips available failed\n");
8961 strtok(mipsStr, " ");
8963 strPart = strtok(NULLP, " ");
8965 if(idx == CM_L2_CPU_UTIL)
8967 if(strPart != NULLP)
8969 l2FreeCpu = atoi(strPart);
8970 l2CpuUsed = 100 - l2FreeCpu;
8971 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8972 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);;
8973 cpuInfo->cpuUtil[0].numSamples++;
8976 if(idx == CM_L3_CPU_UTIL)
8978 strPart = strtok(NULLP, " ");
8979 if(strPart != NULLP)
8981 l3FreeCpu = atoi(strPart);
8982 l3CpuUsed = 100 - l3FreeCpu;
8983 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8984 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);;
8985 cpuInfo->cpuUtil[0].numSamples++;
8988 if(idx == CM_L2_CPU_UTIL)
8990 cpuInfo->numCores = CM_NUM_L2_CORES ;
8992 else if(idx == CM_L3_CPU_UTIL)
8994 cpuInfo->numCores = CM_NUM_L3_CORES ;
9000 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
9001 #ifdef SS_MULTICORE_SUPPORT
9004 * Fun: Add Timer thread into system task table
9006 * Desc: This function is used to add the system task
9007 * associated with Timer thread.
9017 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(
9021 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(idx)
9028 TRC1(ssdReAddTmrSTsk);
9030 /* lock the system task table */
9031 ret = SLock(&osCp.sTskTblLock);
9035 #if (ERRCLASS & ERRCLS_DEBUG)
9036 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
9037 "Could not lock system task table");
9043 /* initialize the system task entry with the information we have */
9044 sTsk = &osCp.sTskTbl[idx];
9049 SDestroyLock(&sTsk->lock);
9050 ssDestroyDmndQ(&sTsk->dQ);
9053 /* store the system task priority */
9054 sTsk->tskPrior = SS_NORM_TSK_PRI;
9056 /* initialize the demand queue */
9057 if (ssInitDmndQ(&sTsk->dQ) != ROK)
9060 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9062 #if (ERRCLASS & ERRCLS_DEBUG)
9063 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
9064 "Could not give the Semaphore");
9069 #if (ERRCLASS & ERRCLS_DEBUG)
9070 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
9071 "Could not initialize demand queue");
9077 /* initialize the system task entry lock */
9078 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
9080 ssDestroyDmndQ(&sTsk->dQ);
9082 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9084 #if (ERRCLASS & ERRCLS_DEBUG)
9085 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
9086 "Could not give the Semaphore");
9091 #if (ERRCLASS & ERRCLS_DEBUG)
9092 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9093 "Could not initialize system task entry lock");
9100 /* success, update the table */
9101 sTsk->tskId = idx + 1;
9103 sTsk->termPend = FALSE;
9105 /* unlock the system task table */
9107 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9109 #if (ERRCLASS & ERRCLS_DEBUG)
9110 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9111 "Could not give the Semaphore");
9118 #endif /* SS_MULTICORE_SUPPORT */
9123 * Fun: Initialize timer table
9125 * Desc: This function initializes MTSS-specific information
9126 * in the timer table.
9136 PUBLIC S16 ssdReInitTmr
9141 PUBLIC S16 ssdReInitTmr()
9144 pthread_attr_t attr;
9145 struct sched_param param_sched;
9146 #ifndef XEON_SPECIFIC_CHANGES
9149 #ifdef SS_MULTICORE_SUPPORT
9151 #endif /* SS_MULTICORE_SUPPORT */
9152 #ifdef SS_THR_REG_MAP
9153 U32 threadCreated = FALSE;
9154 #endif /* SS_THR_REG_MAP */
9158 #ifndef XEON_SPECIFIC_CHANGES
9159 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9162 #if (ERRCLASS & ERRCLS_DEBUG)
9163 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9164 "Could not give the Semaphore");
9170 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9171 /* mt010.21: addition */
9173 #ifdef SS_MULTICORE_SUPPORT
9174 sTsk = ssdReAddTmrSTsk(0);
9179 #endif /* SS_MULTICORE_SUPPORT */
9180 /* create the timer handler thread */
9182 pthread_attr_init(&attr);
9183 /* mt021.201 - Addition to set stack size */
9184 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9185 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9186 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9187 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9188 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9189 pthread_attr_setschedparam(&attr, ¶m_sched);
9192 #ifdef SS_THR_REG_MAP
9193 /* When the thread is created, we check for the memory mapping table if
9194 * threadId can be placed in thread memory map table. If it is not able to place
9195 * threadId is stored in tmporary array. Once thread is created successful,
9196 * thread_cancel is sent for each thread which are created before. All the
9197 * threads are made to wait on sema which is cancel point for thread.
9199 while(threadCreated == FALSE)
9202 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9204 /* mt020.201 - Addition for destroying thread attribute object attr */
9205 pthread_attr_destroy(&attr);
9210 #ifdef SS_THR_REG_MAP
9211 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9214 #endif /* SS_THR_REG_MAP */
9215 #ifdef SS_MEM_WL_DEBUG
9216 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9219 /* mt020.201 - Addition for destroying thread attribute object attr */
9220 pthread_attr_destroy(&attr);
9221 sem_post(&osCp.dep.ssStarted);
9225 /**********************************************************************
9227 **********************************************************************/