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 */
635 #else /* Page boundary alignment */
636 {256, 491520}, /* 60 pages of 2M*/
637 {512, 12288}, /* 3 pages of 2M */
638 {2048, 99328}, /* 97 Pages of 2M */
639 {8192, 75008}, /* 293 Pages of 2M */
640 {16384, 4096} /* 32 pages of 2M */
646 #ifndef SS_LOCKLESS_MEMORY
648 SS_DFLT_REGION + 1, /* region id */
649 MT_MAX_BKTS, /* number of buckets */
650 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
652 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
653 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
654 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
655 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
663 #endif /* SS_LOCKLESS_MEMORY */
664 #endif /* INTEL_WLS */
665 #ifdef SS_LOCKLESS_MEMORY
667 SS_DFLT_REGION + 1, /* region id */
668 MT_MAX_BKTS, /* number of buckets */
669 MT_HEAP_SIZE, /* heap size */
671 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
672 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
673 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
674 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
678 SS_DFLT_REGION + 2, /* region id */
679 MT_MAX_BKTS, /* number of buckets */
680 MT_HEAP_SIZE, /* heap size */
682 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
683 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
684 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
685 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
689 SS_DFLT_REGION + 3, /* region id */
690 MT_MAX_BKTS, /* number of buckets */
691 MT_HEAP_SIZE, /* heap size */
693 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
694 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
695 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
696 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
699 #endif /* SS_LOCKLESS_MEMORY */
703 /* mt003.301 Modifications - File Based task registration made
704 * common for both MULTICORE and NON-MULTICORE
705 * bucket info, as different regions may request for different no.
708 PUBLIC MtBktCfg mtBktInfo[MT_MAX_BKTS];
709 PUBLIC S16 msArgc; /* argc */
710 PUBLIC Txt **msArgv; /* argv */
711 PUBLIC S16 msOptInd; /* SGetOpt vars */
712 PUBLIC S8 *msOptArg; /* SGetOpt vars */
716 typedef struct _MtRegMemSz
722 PRIVATE MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
726 /* private variable declarations */
727 /* mt018.201 - change mtCMMRegCfg as array of pointers */
728 PRIVATE CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
729 PRIVATE CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
730 /* mt003.301 - Fixed compilation warnings */
731 /*mt004.301-addede new veriable for FAP*/
732 /*mt010.301 - removed veriable defined for FA*/
738 void mtSetNtlHdl(unsigned int hdl)
743 unsigned int mtGetNtlHdl()
745 return(osCp.ntl.hdl);
752 RETVALUE(osCp.wls.intf);
755 #ifdef XEON_MULTIPLE_CELL_CHANGES
756 EXTERN S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
757 EXTERN S16 smWrReadWlsConfigParams (Void);
760 PRIVATE int SOpenWlsIntf()
763 #define WLS_DEVICE_NAME "/dev/wls"
765 #ifdef XEON_SPECIFIC_CHANGES
766 #ifdef XEON_MULTIPLE_CELL_CHANGES
767 hdl = WLS_Open(gWrWlsDeviceName, 1);
769 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
772 hdl = WLS_Open(WLS_DEVICE_NAME, 0);
779 printf("Could not open WLS Interface \n");
794 * Desc: This function is the entry point for the final binary. It
795 * calls SInit() in the common code. It can be replaced by a
796 * user function if required (SInit() must still be called).
798 * Ret: none on success
809 int argc, /* argument count */
810 char **argv /* argument vector */
813 PUBLIC int main(argc, argv)
814 int argc; /* argument count */
815 char **argv; /* argument vector */
820 #ifdef XEON_MULTIPLE_CELL_CHANGES
821 /* Read the WLS parameters from the file and copy into global control block */
822 if(smWrReadWlsConfigParams() != ROK)
824 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
826 } /* end of if statement */
832 #endif /* INTEL_WLS */
836 /* mt003.301 Modifications */
839 printf("\n SInit failed, SSI could not start \n");
840 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
844 /*mt010.301 cleanup part exposed to user*/
855 * Desc: This function is the entry point for the final binary. It
856 * calls SInit() in the common code. It can be replaced by a
857 * user function if required (SInit() must still be called).
859 * Ret: none on success
870 int argc, /* argument count */
871 char **argv /* argument vector */
874 PUBLIC int ssMain(argc, argv)
875 int argc; /* argument count */
876 char **argv; /* argument vector */
893 * initialization functions
898 * Fun: Initialize OS control point
900 * Desc: This function initializes MTSS-specific information
901 * in the OS control point.
911 PUBLIC S16 ssdInitGen
916 PUBLIC S16 ssdInitGen()
919 struct sigaction act;
921 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
927 /*mt014.301 : 4GMX release related changes*/
931 /* mt005.301 : Cavium changes */
932 #ifdef SS_SEUM_CAVIUM
933 /* set group mask for the core */
934 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
935 #endif /* SS_SEUM_CAVIUM */
937 osCp.dep.sysTicks = 0;
939 /* mt020.201 - Addition for no command line available */
941 /* parse command line */
943 /* mt003.301 Additions */
944 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
946 printf("\n File Based Memory configuration failed \n");
951 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
952 #ifndef SS_LOCKLESS_MEMORY
953 #ifdef SS_MULTICORE_SUPPORT
954 if(memConfigured == FALSE)
960 /* initialize the started semaphore */
961 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
966 /* mt028.201 added compile time flag to allow not to mask signals */
968 /* mask all signals in the main thread */
970 sigdelset(&set, SIGINT);
971 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
972 sigdelset(&set, SIGSEGV);
973 sigdelset(&set, SIGUSR2);
974 sigdelset(&set, SIGILL);
975 #ifdef XEON_SPECIFIC_CHANGES
976 sigdelset(&set, SIGABRT);
977 sigdelset(&set, SIGTERM);
978 sigdelset(&set, SIGHUP);
981 pthread_sigmask(SIG_SETMASK, &set, NULLP);
982 #endif /* UNMASK_SIG */
984 /* install a SIGINT handler to shutdown */
985 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
987 /*Initialize SIGSEGV Signal */
988 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
990 memset(&sa, 0, sizeof(struct sigaction));
991 sigemptyset(&sa.sa_mask);
992 sa.sa_sigaction = signal_segv;
993 sa.sa_flags = SA_SIGINFO;
994 #ifndef XEON_SPECIFIC_CHANGES
995 sigaction(SIGSEGV, &sa, NULL);
997 memset(&sa, 0, sizeof(struct sigaction));
998 sigemptyset(&sa.sa_mask);
999 sa.sa_sigaction = signal_segv;
1000 sa.sa_flags = SA_SIGINFO;
1002 sigaction(SIGILL, &sa, NULL);
1004 if(sigaction(SIGILL, &sa, NULL) != 0)
1006 printf("Failed to process sigaction for the SIGILL\n");
1009 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1011 printf("Failed to process sigaction for the SIGSEGV\n");
1014 if(sigaction(SIGABRT, &sa, NULL) != 0)
1016 printf("Failed to process sigaction for the SIGABRT\n");
1019 if(sigaction(SIGTERM, &sa, NULL) != 0)
1021 printf("Failed to process sigaction for the SIGTERM\n");
1024 if(sigaction(SIGHUP, &sa, NULL) != 0)
1026 printf("Failed to process sigaction for the SIGHUP\n");
1031 signal (SIGSEGV, mtSigSegvHndlr);
1032 signal (SIGKILL, mtSigSegvHndlr);
1033 signal (SIGUSR2, mtSigUsr2Hndlr);
1038 signal (SIGINT, mtStopHndlr);
1041 act.sa_handler = mtIntSigHndlr;
1042 sigfillset(&act.sa_mask);
1044 if (sigaction(SIGINT, &act, NULLP) != 0)
1050 /* mt040.201 initialise random seed */
1051 osCp.dep.randSeed = time(NULLP);
1059 * Fun: De-initialize OS control point
1061 * Desc: This function reverses the initialization in ssdInitGen().
1071 PUBLIC Void ssdDeinitGen
1076 PUBLIC Void ssdDeinitGen()
1082 sem_destroy(&osCp.dep.ssStarted);
1087 #ifdef SS_LOCKLESS_MEMORY
1091 * Fun: ssPutDynMemBlkSet
1093 * Desc: Returns the set of dynamic Blocks into the global region
1096 * Ret: ROK - successful,
1097 * RFAILED - unsuccessful.
1105 PUBLIC S16 ssPutDynMemBlkSet
1107 U8 bktIdx, /* Index to bucket list */
1108 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1109 added to global region */
1112 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1113 U8 bktIdx; /* Index to bucket list */
1114 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1115 added to global region */
1118 CmMmGlobRegCb *globReg;
1119 CmMmGlobalBktCb *bktCb;
1123 globReg = osCp.globRegCb;
1125 #if (ERRCLASS & ERRCLS_INT_PAR)
1126 if(bktIdx >= globReg->numBkts)
1130 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1132 bktCb = &(globReg->bktTbl[bktIdx]);
1134 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1136 blkPtr = dynMemSetElem->nextBktPtr;
1137 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1138 free((Void *)blkPtr);
1141 dynMemSetElem->nextBktPtr = NULLP;
1142 dynMemSetElem->numFreeBlks = 0;
1149 * Fun: ssGetDynMemBlkSet
1151 * Desc: Gets the set of dynamic memory blocks from the global region
1154 * Ret: ROK - successful,
1155 * RFAILED - unsuccessful.
1163 PUBLIC S16 ssGetDynMemBlkSet
1165 U8 bktIdx, /* Index to bucket list */
1166 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1167 with new set values */
1170 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1171 U8 bktIdx; /* Index to bucket list */
1172 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1173 with new set values */
1177 CmMmGlobRegCb *globReg;
1178 CmMmGlobalBktCb *bktCb;
1183 globReg = osCp.globRegCb;
1185 #if (ERRCLASS & ERRCLS_INT_PAR)
1186 if(bktIdx >= globReg->numBkts)
1190 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1192 bktCb = &(globReg->bktTbl[bktIdx]);
1193 basePtr = &(dynMemSetElem->nextBktPtr);
1195 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1197 blkPtr = (Data *)malloc(bktCb->size);
1199 basePtr = (CmMmEntry **)blkPtr;
1202 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1206 } /* ssGetDynMemBlkSet */
1211 * Fun: ssPutDynMemBlkSet
1213 * Desc: Returns the set of dynamic Blocks into the global region
1216 * Ret: ROK - successful,
1217 * RFAILED - unsuccessful.
1225 PUBLIC S16 ssPutDynMemBlkSet
1227 U8 bktIdx, /* Index to bucket list */
1228 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1229 added to global region */
1230 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1233 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1234 U8 bktIdx; /* Index to bucket list */
1235 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1236 added to global region */
1237 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1240 CmMmGlobRegCb *globReg;
1241 CmMmGlobalBktCb *bktCb;
1243 CmMmBlkSetElement *globMemNode;
1246 TRC1(ssPutDynMemBlkSet);
1248 globReg = osCp.globRegCb;
1250 #if (ERRCLASS & ERRCLS_INT_PAR)
1251 if(bktIdx >= globReg->numBkts)
1255 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1257 bktCb = &(globReg->bktTbl[bktIdx]);
1259 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1260 try lock is used as it is not required to block as it will be taken
1261 in the next go else it will be blocked for lock as we have to get the
1264 SLock(&(bktCb->bucketLock));
1270 /* Get a free node from the free node linked list */
1271 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1272 if(lstNode == NULLP)
1274 SUnlock(&(bktCb->bucketLock));
1278 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1280 /* Copy the content of the received element information on to free node
1281 * and add it to valid linked list */
1282 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1283 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1284 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1285 dynMemSetElem->numFreeBlks = 0;
1286 dynMemSetElem->nextBktPtr = NULLP;
1288 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1290 SUnlock(&(bktCb->bucketLock));
1298 * Fun: ssGetDynMemBlkSet
1300 * Desc: Gets the set of dynamic memory blocks from the global region
1303 * Ret: ROK - successful,
1304 * RFAILED - unsuccessful.
1306 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1313 PUBLIC S16 ssGetDynMemBlkSet
1315 U8 bktIdx, /* Index to bucket list */
1316 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1317 with new set values */
1318 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1321 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1322 U8 bktIdx; /* Index to bucket list */
1323 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1324 with new set values */
1325 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1328 CmMmGlobRegCb *globReg;
1329 CmMmGlobalBktCb *bktCb;
1331 CmMmBlkSetElement *globMemNode;
1334 TRC1(ssGetDynMemBlkSet);
1336 globReg = osCp.globRegCb;
1338 #if (ERRCLASS & ERRCLS_INT_PAR)
1339 if(bktIdx >= globReg->numBkts)
1343 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1345 bktCb = &(globReg->bktTbl[bktIdx]);
1347 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1348 try lock is used as it is not required to block as it will be taken
1349 in the next go else it will be blocked for lock as we have to get the
1352 SLock(&(bktCb->bucketLock));
1357 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1359 if(lstNode == NULLP)
1361 SUnlock(&(bktCb->bucketLock));
1365 /* Delete the node from the valid linked list and copy the values of the
1366 * elements of structrues into pointer */
1367 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1368 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1369 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1370 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1372 /* Add this node to the free node linked list */
1373 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1375 SUnlock(&(bktCb->bucketLock));
1379 } /* ssGetDynMemBlkSet */
1382 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1384 PRIVATE U32 memoryCheckCounter;
1387 PUBLIC U32 isMemThreshReached(
1391 PUBLIC U32 isMemThreshReached(reg)
1395 CmMmGlobRegCb *globReg;
1396 CmMmGlobalBktCb *bktCb;
1399 TRC3(isMemThreshReached)
1401 globReg = osCp.globRegCb;
1403 #if (ERRCLASS & ERRCLS_INT_PAR)
1404 if(bktIdx >= globReg->numBkts)
1408 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1410 bktCb = &(globReg->bktTbl[bktIdx]);
1412 if(gDynMemAlrm[bktIdx])
1414 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1415 SLock(&(bktCb->bucketLock));
1416 if(bktCb->listValidBktSet.count > 25)
1418 gDynMemAlrm[bktIdx] = FALSE;
1419 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1421 SUnlock(&(bktCb->bucketLock));
1427 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1429 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1430 SLock(&(bktCb->bucketLock));
1431 if(bktCb->listValidBktSet.count < 15 )
1432 gDynMemAlrm[bktIdx] = TRUE;
1433 memoryCheckCounter = 0;
1434 SUnlock(&(bktCb->bucketLock));
1440 #endif /* USE_MALLOC */
1441 #endif /* SS_LOCKLESS_MEMORY */
1443 #ifdef SS_USE_ICC_MEMORY
1446 * Fun: Initialize region/pool tables
1448 * Desc: This function initializes MTSS-specific information
1449 * in the region/pool tables and configures the common
1450 * memory manager for use.
1460 PUBLIC Void * ssGetIccHdl
1465 PUBLIC Void * ssGetIccHdl()
1469 CmMmDynRegCb *dynRegCb;
1471 /* Klock work fix ccpu00148484 */
1472 if(!(region < SS_MAX_REGS))
1477 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1479 RETVALUE(dynRegCb->iccHdl);
1481 #endif /* SS_USE_ICC_MEMORY */
1483 #ifdef T2K_MEM_LEAK_DBG
1484 extern RegionMemLeakInfo regMemLeakInfo;
1485 #endif /* T2K_MEM_LEAK_DBG */
1489 PUBLIC S16 SPartitionWlsMemory()
1494 U64 pageSize[1], hugePageSize;
1497 long int pageSize[1], hugePageSize;
1500 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1502 U8 *regMemStrtAddr = (U8 *)osCp.wls.allocAddr;
1504 gethugepagesizes(pageSize,1);
1505 hugePageSize = pageSize[0];
1506 for (i = 0; i < 1; i++)
1508 mtRegMemSz[i].startAddr = regMemStrtAddr;
1509 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1511 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1512 reqdSz = numHugePg * hugePageSize;
1513 regMemStrtAddr += reqdSz;
1514 #ifdef T2K_MEM_LEAK_DBG
1515 /* Since wls is region 0 */
1516 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1517 regMemLeakInfo.numActvRegions++;
1518 #endif /* T2K_MEM_LEAK_DBG */
1520 //Store last region addr for validation
1521 mtRegMemSz[i].startAddr = regMemStrtAddr;
1525 #ifdef SS_MEM_WL_DEBUG
1526 PUBLIC Void SChkAddrValid(int type, int region, PTR ptr)
1528 char *tryPtr = NULL;
1529 if(type == 0) //Global
1531 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1532 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1534 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1540 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1542 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1548 #endif /* SS_MEM_WL_DEBUG */
1550 PUBLIC S16 SPartitionStaticMemory(U8 *startAddr)
1555 U8 *regMemStrtAddr = (U8 *)startAddr;
1558 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1559 for (i = 1; i < mtMemoCfg.numRegions; i++)
1561 mtRegMemSz[i].startAddr = regMemStrtAddr;
1562 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1563 regMemStrtAddr += reqdSz;
1564 #ifdef T2K_MEM_LEAK_DBG
1565 { /* Since region 1 onwards are used for non wls */
1566 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1567 regMemLeakInfo.numActvRegions++;
1569 #endif /* T2K_MEM_LEAK_DBG */
1573 PUBLIC S16 SAllocateWlsMem()
1581 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1582 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1584 for (i = 0; i < 1; i++)
1586 /* allocate space for the region */
1587 region = &mtMemoCfg.region[i];
1588 reqdMemSz += region->heapsize;
1589 mtRegMemSz[i].reqdSz += region->heapsize;
1591 for (j = 0; j < region->numBkts; j++)
1593 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1594 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1597 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1598 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1600 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1602 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1604 SPartitionWlsMemory();
1607 PUBLIC S16 SAllocateStaticMem()
1616 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1618 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1619 for (i = 1; i < mtMemoCfg.numRegions; i++)
1621 /* allocate space for the region */
1622 region = &mtMemoCfg.region[i];
1623 reqdMemSz += region->heapsize;
1624 mtRegMemSz[i].reqdSz += region->heapsize;
1626 for (j = 0; j < region->numBkts; j++)
1628 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1629 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1633 startAddr = malloc(reqdMemSz + (1024 * 10));
1635 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1637 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1639 SPartitionStaticMemory(startAddr);
1642 #endif /* INTEL_WLS */
1648 * Fun: Initialize region/pool tables
1650 * Desc: This function initializes MTSS-specific information
1651 * in the region/pool tables and configures the common
1652 * memory manager for use.
1662 PUBLIC S16 ssdInitMem
1667 PUBLIC S16 ssdInitMem()
1670 /* mt018.201 - added local variable */
1675 Txt errMsg[256] = {'\0'};
1676 #ifdef SS_LOCKLESS_MEMORY
1677 CmMmDynRegCb *dynRegCb;
1678 #ifdef SS_USE_ICC_MEMORY
1680 CmMmGlobRegCb *globReg;
1683 #endif /* SS_LOCKLESS_MEMORY */
1687 /* Use the default SSI memory manager if the ICC memory manager is not
1688 * avilable. If ICC memory manager is avilable, it will be used for
1689 * all sharable memory allocation and de-allocation */
1690 #ifdef SS_LOCKLESS_MEMORY
1691 #ifdef SS_USE_ICC_MEMORY
1692 #ifndef YS_PHY_3_8_2
1694 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1696 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1697 if(dynRegCb == NULLP)
1701 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1703 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1705 dynRegCb->region = i;
1706 cmMmDynRegInit(dynRegCb);
1707 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1710 /* ysIccHdl = dynRegCb->iccHdl; */
1713 /* Initialize the global region first */
1714 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1716 if(osCp.globRegCb == NULLP)
1721 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1723 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1725 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1727 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1729 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1731 if(globReg->bktTbl[i].startAddr == NULLP)
1735 globReg->bktTbl[i].poolId = i;
1736 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1737 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1738 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1741 globReg->numBkts = mtGlobMemoCfg.numBkts;
1742 cmMmGlobRegInit(globReg);
1744 /* Initialize the dynamic task regions and sanity check for the theshold
1746 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1748 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1749 if(dynRegCb == NULLP)
1753 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1755 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1756 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1757 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1758 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1760 #ifdef XEON_SPECIFIC_CHANGES
1765 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1766 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1767 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1768 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1769 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1771 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1774 dynRegCb->region = i;
1775 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1776 cmMmDynRegInit(dynRegCb);
1778 #endif /* SS_USE_ICC_MEMORY */
1779 #endif /* SS_LOCKLESS_MEMORY */
1781 #ifdef T2K_MEM_LEAK_DBG
1783 /* Initailize mem leak tool memorys for debguing */
1784 regMemLeakInfo.numActvRegions=0;
1785 for(reg=0; reg <SS_MAX_REGS; reg++)
1787 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1788 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1789 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1790 regMemLeakInfo.regStartAddr[reg] = 0;
1793 regMemLeakInfo.regStartAddr[reg] = 0;
1794 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1796 printf("\n mutex init failed\n");
1802 /* Now allocate WLS memory */
1804 SAllocateStaticMem();
1806 /* mt018.201 - CMM Initialization */
1807 for (i = 0; i < mtMemoCfg.numRegions; i++)
1809 /* allocate space for the region control block */
1810 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1811 #ifdef TENB_RTLIN_CHANGES
1812 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1814 if (mtCMMRegCb[i] == NULLP)
1816 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1817 for the Region:%d control block\n",i);
1819 for (k = 0; k < i; k++)
1821 cmMmRegDeInit(mtCMMRegCb[k]);
1822 free(mtCMMRegCfg[k]->vAddr);
1823 free(mtCMMRegCb[k]);
1824 free(mtCMMRegCfg[k]);
1829 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1830 #ifdef TENB_RTLIN_CHANGES
1831 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1833 if (mtCMMRegCfg[i] == NULLP)
1835 for (k = 0; k < i; k++)
1837 cmMmRegDeInit(mtCMMRegCb[k]);
1838 free(mtCMMRegCfg[k]->vAddr);
1839 free(mtCMMRegCb[k]);
1840 free(mtCMMRegCfg[k]);
1842 free(mtCMMRegCb[i]);
1847 /* allocate space for the region */
1848 region = &mtMemoCfg.region[i];
1849 mtCMMRegCfg[i]->size = region->heapsize;
1850 for (j = 0; j < region->numBkts; j++)
1852 /* mt033.201 - addition for including the header size while computing the total size */
1853 #ifdef SSI_DEBUG_LEVEL1
1854 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1855 (region->bkt[j].numBlks);
1857 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1858 #endif /* SSI_DEBUG_LEVEL1 */
1861 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1863 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1866 #ifdef XEON_SPECIFIC_CHANGES
1867 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1868 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1870 #ifdef TENB_RTLIN_CHANGES
1871 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1874 if (mtCMMRegCfg[i]->vAddr == NULLP)
1876 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1877 for the Region:%d \n",i);
1879 for (k = 0; k < i; k++)
1881 cmMmRegDeInit(mtCMMRegCb[k]);
1882 free(mtCMMRegCfg[k]->vAddr);
1883 free(mtCMMRegCb[k]);
1884 free(mtCMMRegCfg[k]);
1886 free(mtCMMRegCb[i]);
1887 free(mtCMMRegCfg[i]);
1892 /* set up the CMM configuration structure */
1893 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1894 mtCMMRegCfg[i]->chFlag = 0;
1895 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1896 mtCMMRegCfg[i]->numBkts = region->numBkts;
1898 for (j = 0; j < region->numBkts; j++)
1900 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1901 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1904 /* initialize the CMM */
1905 #ifdef SS_LOCKLESS_MEMORY
1906 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1908 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1909 #endif /* SS_LOCKLESS_MEMORY */
1911 for (k = 0; k < i; k++)
1913 cmMmRegDeInit(mtCMMRegCb[k]);
1914 free(mtCMMRegCfg[k]->vAddr);
1915 free(mtCMMRegCb[k]);
1916 free(mtCMMRegCfg[k]);
1918 free(mtCMMRegCfg[i]->vAddr);
1919 free(mtCMMRegCb[i]);
1920 free(mtCMMRegCfg[i]);
1925 /* initialize the STREAMS module */
1926 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1927 if (region->regionId == 0)
1929 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
1931 for (k = 0; k < i; k++)
1933 cmMmRegDeInit(mtCMMRegCb[k]);
1934 free(mtCMMRegCfg[k]->vAddr);
1935 free(mtCMMRegCb[k]);
1936 free(mtCMMRegCfg[k]);
1938 cmMmRegDeInit(mtCMMRegCb[i]);
1939 free(mtCMMRegCfg[i]->vAddr);
1940 free(mtCMMRegCb[i]);
1941 free(mtCMMRegCfg[i]);
1946 /* mt001.301 : Additions */
1947 #ifdef SS_MEM_LEAK_STS
1949 #endif /* SS_MEM_LEAK_STS */
1958 * Fun: De-initialize region/pool tables
1960 * Desc: This function reverses the initialization in ssdInitMem().
1970 PUBLIC Void ssdDeinitMem
1975 PUBLIC Void ssdDeinitMem()
1978 /* mt018.201 - added local variables */
1982 /* mt008.301 Additions */
1983 #ifdef SS_MEM_LEAK_STS
1984 cmDeinitMemLeakMdl();
1985 #endif /* SS_MEM_LEAK_STS */
1987 for (i = 0; i < mtMemoCfg.numRegions; i++)
1989 cmMmRegDeInit(mtCMMRegCb[i]);
1990 free(mtCMMRegCfg[i]->vAddr);
1991 free(mtCMMRegCb[i]);
1992 free(mtCMMRegCfg[i]);
2001 * Fun: Initialize task table
2003 * Desc: This function initializes MTSS-specific information
2004 * in the task table.
2014 PUBLIC S16 ssdInitTsk
2019 PUBLIC S16 ssdInitTsk()
2022 /* mt001.301 : Additions */
2023 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2024 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2026 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2031 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2032 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2033 /* initialize system task information */
2034 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2036 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2038 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2045 * Fun: Deinitialize task table
2047 * Desc: This function reverses the initialization perfomed in
2058 PUBLIC Void ssdDeinitTsk
2063 PUBLIC Void ssdDeinitTsk()
2072 #ifdef SS_DRVR_SUPPORT
2075 * Fun: Initialize driver task table
2077 * Desc: This function initializes MTSS-specific information
2078 * in the driver task table.
2088 PUBLIC S16 ssdInitDrvr
2093 PUBLIC S16 ssdInitDrvr()
2098 pthread_attr_t attr;
2104 /* initialize the dependent portion of the driver task entries */
2105 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2107 osCp.drvrTskTbl[i].dep.flag = FALSE;
2111 /* create pipe for communication between SSetIntPend() and
2112 * the isTskHdlr thread.
2114 if (pipe(osCp.dep.isFildes) != 0)
2120 /* create the isTskHdlr thread */
2121 pthread_attr_init(&attr);
2122 /* mt021.201 - Addition to set stack size */
2123 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2124 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2125 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2126 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2128 /* mt020.201 - Addition for destroying thread attribute object attr */
2129 pthread_attr_destroy(&attr);
2135 /*mt014.301 : 4GMX release related changes*/
2136 #ifdef SS_4GMX_UCORE
2144 /* mt020.201 - Addition for destroying thread attribute object attr */
2145 pthread_attr_destroy(&attr);
2154 * Fun: Deinitialize driver information
2156 * Desc: This function reverses the initialization performed in
2167 PUBLIC Void ssdDeinitDrvr
2172 PUBLIC Void ssdDeinitDrvr()
2175 TRC0(ssdDeinitDrvr);
2176 /* mt008.301: Terminate the Driver Task on exit */
2177 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2180 TL_Close(AppContext.hUAII);
2181 if (clusterMode == RADIO_CLUSTER_MODE)
2183 TL_Close(AppContext.hUAII_second);
2189 #endif /* SS_DRVR_SUPPORT */
2194 * Fun: Initialize timer table
2196 * Desc: This function initializes MTSS-specific information
2197 * in the timer table.
2207 PUBLIC S16 ssdInitTmr
2212 PUBLIC S16 ssdInitTmr()
2215 pthread_attr_t attr;
2216 struct sched_param param_sched;
2217 /* mt010.21: addition */
2219 #ifdef SS_MULTICORE_SUPPORT
2221 #endif /* SS_MULTICORE_SUPPORT */
2222 #ifdef SS_THR_REG_MAP
2223 U32 threadCreated = FALSE;
2224 #endif /* SS_THR_REG_MAP */
2229 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2230 /* mt010.21: addition */
2231 osCp.dep.tmrTqCp.nxtEnt = 0;
2232 for (i=0; i< SS_MAX_TMRS; i++)
2234 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2237 #ifdef SS_MULTICORE_SUPPORT
2238 sTsk = ssdAddTmrSTsk();
2243 #endif /* SS_MULTICORE_SUPPORT */
2244 /* create the timer handler thread */
2245 pthread_attr_init(&attr);
2246 /* mt021.201 - Addition to set stack size */
2247 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2248 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2249 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2250 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2251 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2252 pthread_attr_setschedparam(&attr, ¶m_sched);
2255 #ifdef SS_THR_REG_MAP
2256 /* When the thread is created, we check for the memory mapping table if
2257 * threadId can be placed in thread memory map table. If it is not able to place
2258 * threadId is stored in tmporary array. Once thread is created successful,
2259 * thread_cancel is sent for each thread which are created before. All the
2260 * threads are made to wait on sema which is cancel point for thread.
2262 while(threadCreated == FALSE)
2265 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2267 /* mt020.201 - Addition for destroying thread attribute object attr */
2268 pthread_attr_destroy(&attr);
2273 #ifdef SS_THR_REG_MAP
2274 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2277 #endif /* SS_THR_REG_MAP */
2278 #ifdef SS_MEM_WL_DEBUG
2279 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2282 /* mt020.201 - Addition for destroying thread attribute object attr */
2283 pthread_attr_destroy(&attr);
2292 * Fun: Deinitialize timer table
2294 * Desc: This function reverses the initialization performed in
2305 PUBLIC Void ssdDeinitTmr
2310 PUBLIC Void ssdDeinitTmr()
2313 #ifdef SS_MULTICORE_SUPPORT
2316 #endif /* SS_MULTICORE_SUPPORT */
2320 #ifdef SS_MULTICORE_SUPPORT
2321 ret = SLock(&osCp.sTskTblLock);
2325 #if (ERRCLASS & ERRCLS_DEBUG)
2326 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2327 "Could not lock system task table");
2331 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2332 /* clean up the system task entry */
2336 SDestroyLock(&sTsk->lock);
2337 ssDestroyDmndQ(&sTsk->dQ);
2340 /* make this entry available in the system task table */
2341 sTsk->nxt = osCp.nxtSTskEntry;
2342 osCp.nxtSTskEntry = 0;
2346 /* unlock the system task table */
2347 SUnlock(&osCp.sTskTblLock);
2349 #endif /* SS_MULTICORE_SUPPORT */
2350 /* mt008.301: Terminate the timer thread on exit */
2351 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2361 * Desc: Pre-tst() initialization.
2371 PUBLIC S16 ssdInitLog
2376 PUBLIC S16 ssdInitLog()
2379 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2383 pthread_attr_t attr;
2386 #endif /* CONSTDIO */
2391 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2397 osCp.dep.conInFp = (FILE *) stdin;
2398 osCp.dep.conOutFp = (FILE *) stdout;
2399 /* added compile time flag CONRD: mt017.21 */
2403 /* disable canonical input processing */
2404 fd = fileno(osCp.dep.conInFp);
2405 if ((tcgetattr(fd, &tio)) != 0)
2407 printf("Error: disable canonical input processing\n");
2411 tio.c_lflag &= ~ICANON;
2412 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2413 tio.c_cc[VTIME] = 0;
2414 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2416 printf("Error: while tcsetattr() processing\n");
2420 #endif /* CONSTDIO */
2423 /* set up the input fd to block when no data is available */
2424 fd = fileno(osCp.dep.conInFp);
2425 flags = fcntl(fd, F_GETFL, &flags);
2426 flags &= ~O_NONBLOCK;
2427 if (fcntl(fd, F_SETFL, flags) == -1)
2429 printf("Error: while fcntl processing\n");
2434 /* create the console handler thread */
2435 pthread_attr_init(&attr);
2436 /* mt021.201 - Addition to set stack size */
2437 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2438 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2439 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2442 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2444 /* mt020.201 - Addition for destroying thread attribute object attr */
2445 pthread_attr_destroy(&attr);
2447 printf("Error: Logging Thread creation failed \n");
2451 /* mt020.201 - Addition for destroying thread attribute object attr */
2452 pthread_attr_destroy(&attr);
2466 * Desc: This function reverses the initialization performed in
2476 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2478 PUBLIC Void ssdDeinitLog
2483 PUBLIC Void ssdDeinitLog()
2486 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2490 /* mt008.301: Terminate the console reader on exit */
2491 while(pthread_cancel(osCp.dep.conHdlrTID));
2497 /* mt001.301 : Additions */
2502 PUBLIC S16 ssdInitWatchDog
2507 PUBLIC S16 ssdInitWatchDog(port)
2512 Txt prntBuf[PRNTSZE];
2515 #ifdef SS_WATCHDOG_IPV6
2516 struct sockaddr_in6 tmpaddr;
2518 struct sockaddr_in tmpaddr;
2519 #endif /* SS_WATCHDOG_IPV6 */
2520 #ifdef SS_MULTIPLE_PROCS
2521 ProcId procId = SS_WD_WDPROC;
2522 if (SAddProcIdLst(1, &procId) != ROK)
2526 #endif /* SS_MULTIPLE_PROCS */
2528 TRC0(ssdInitWatchDog);
2530 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2532 /* Create a watch dog system task */
2533 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2535 /* Create a watch dog reveiver system task */
2536 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2538 /* Register and attach watch dog TAPA task */
2539 #ifdef SS_MULTIPLE_PROCS
2540 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2541 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2543 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2544 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2545 #endif /* SS_MULTIPLE_PROCS */
2546 /* Register and attach watch dog receiver TAPA task */
2547 #ifdef SS_MULTIPLE_PROCS
2548 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2549 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2551 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2552 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2553 #endif /* SS_MULTIPLE_PROCS */
2555 #ifndef SS_MULTIPLE_PROCS
2556 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2557 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2559 osCp.wdCp.watchDgPst.srcProcId = procId;
2560 osCp.wdCp.watchDgPst.dstProcId = procId;
2561 #endif /* SS_MULTIPLE_PROCS */
2563 /* Initialise the pst structure */
2564 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2565 /* Initialize the watch dog timer resolution default is 1 sec */
2567 cmInitTimers(osCp.wdCp.watchDgTmr, (U8)1);
2568 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2569 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2570 for(idx = 0; idx < 1; idx++)
2572 osCp.wdCp.watchDgTs[idx].first = NULLP;
2573 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2575 #ifdef SS_MULTIPLE_PROCS
2576 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2578 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2579 #endif /* SS_MULTIPLE_PROCS */
2581 /* Create the watch dog receiver socket */
2582 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2583 if(osCp.wdCp.globWd.sock == -1)
2585 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2589 #ifdef SS_WATCHDOG_IPV6
2590 tmpaddr.sin6_len = sizeof(tmpadDr);
2591 tmpaddr.sin6_family = AF_INET6;
2592 tmpaddr.sin6_addr = in6addr_any;
2593 tmpaddr.sin6_port = htons(port);
2595 tmpaddr.sin_family = AF_INET;
2596 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2597 tmpaddr.sin_port = htons(port);
2598 #endif /* SS_WATCHDOG_IPV6 */
2600 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2603 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2607 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2611 #ifndef SS_MULTIPLE_PROCS
2612 pst.srcProcId = SFndProcId();
2613 pst.dstProcId = SFndProcId();
2615 pst.srcProcId = procId;
2616 pst.dstProcId = procId;
2617 #endif /* SS_MULTIPLE_PROCS */
2618 pst.event = EVTSSHRTBTREQ;
2619 ssdInitWatchDgPst(&pst);
2620 SPstTsk(&pst, mBuf);
2626 PUBLIC S16 ssdInitWatchDgPst
2631 PUBLIC S16 ssdInitWatchDgPst(pst)
2635 TRC1(ssInitWatchDgPst);
2637 pst->selector = SS_LOOSE_COUPLING;
2639 pst->region = DFLT_REGION; /* region */
2640 pst->pool = DFLT_POOL; /* pool */
2642 pst->prior = PRIOR0; /* priority */
2643 pst->route = RTESPEC; /* route */
2645 pst->dstEnt = ENTHB; /* destination entity */
2647 pst->srcEnt = ENTDW; /* source entity */
2653 #ifdef SS_MULTIPLE_PROCS
2655 PUBLIC S16 ssdWatchDgActvTmr
2662 PUBLIC S16 ssdWatchDgActvTmr(proc, ent, inst)
2666 PUBLIC S16 ssdWatchDgActvTmr
2671 PUBLIC S16 ssdWatchDgActvTmr()
2673 #endif /* SS_MULTIPLE_PROCS */
2675 TRC3(ssWatchDgActvTmr);
2677 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2683 PUBLIC Void ssdWatchDgTmrEvt
2685 PTR cb, /* control block */
2686 S16 event /* timer number */
2689 PUBLIC Void ssdWatchDgTmrEvt(cb, event)
2690 PTR cb; /* control block */
2691 S16 event; /* timer number */
2694 /* mt003.301 Fixed warings */
2698 Txt prntBuf[PRNTSZE];
2702 TRC2(ssWatchDgTmrEvt);
2708 SPrint("Timer Heartbeat Request Expired");
2710 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2715 SLock(&osCp.wdCp.wdLock);
2716 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2718 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2720 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2722 if(osCp.wdCp.globWd.callback != 0)
2724 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2728 SUnlock(&osCp.wdCp.wdLock);
2730 if(!osCp.wdCp.globWd.watchdogStop)
2732 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2733 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2744 PUBLIC Void ssdStartWatchDgTmr
2751 PUBLIC Void ssdStartWatchDgTmr(cb, event, wait)
2761 Txt prntBuf[PRNTSZE];
2765 TRC2(ssStartWatchDgTmr)
2766 /* mt003.301 Modifications */
2769 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2770 if(event == SS_TMR_HRTBT)
2772 SPrint("\nSTART SS_TMR_HRTBT");
2779 SLock(&osCp.wdCp.wdLock);
2780 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2782 osCp.wdCp.globWd.wdsta[i].status = 0;
2784 SUnlock(&osCp.wdCp.wdLock);
2786 arg.tq = osCp.wdCp.watchDgTs;
2787 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2788 arg.timers = osCp.wdCp.watchDgTmr;
2789 arg.cb = (PTR)NULLP;
2791 arg.wait = osCp.wdCp.globWd.timeout = wait;
2800 PUBLIC Void ssdStopWatchDgTmr
2806 PUBLIC Void ssdStopWatchDgTmr(cb, event)
2814 Txt prntBuf[PRNTSZE];
2818 TRC2(ssStopWatchDgTmr)
2819 /* mt003.301 Modifications */
2822 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2823 if(event == SS_TMR_HRTBT)
2825 SPrint("STOP SS_TMR_HRTBT");
2829 SLock(&osCp.wdCp.wdLock);
2830 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2832 osCp.wdCp.globWd.wdsta[i].status = 0;
2834 SUnlock(&osCp.wdCp.wdLock);
2837 arg.tq = osCp.wdCp.watchDgTs;
2838 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2839 arg.timers = osCp.wdCp.watchDgTmr;
2840 arg.cb = (PTR)NULLP;
2851 PUBLIC S16 ssdSndHrtBtMsg
2857 PUBLIC S16 ssdSndHrtBtMsg(restart, type)
2865 Txt prntBuf[PRNTSZE];
2867 struct sockaddr_in tmpaddr;
2868 char hbMsg[SS_WD_HB_MSG_SIZE];
2872 TRC2(ssdSndHrtBtReq)
2876 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2880 /* Pack the message */
2881 strcpy(hbMsg, "<HB>REQ</HB>");
2883 /* Send the heartbeat messages to all the configured nodes */
2884 SLock(&osCp.wdCp.wdLock);
2885 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2887 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2892 /* Identify the destination node */
2893 #ifdef SS_WATCHDOG_IPV6
2894 tmpaddr.sin6_len = sizeof(tmpaddr);
2895 tmpaddr.sin6_family = AF_INET6;
2896 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2897 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2899 tmpaddr.sin_family = AF_INET;
2900 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2901 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2902 #endif /* SS_WATCHDOG_IPV6 */
2904 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2908 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2909 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2916 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2921 SUnlock(&osCp.wdCp.wdLock);
2926 #endif /* SS_WATCHDOG */
2930 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2936 * Desc: This function gets command line options.
2946 PRIVATE Void mtGetOpts
2951 PRIVATE Void mtGetOpts()
2959 FILE *memOpt; /* memory options file pointer */
2962 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2968 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2970 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2976 #ifdef SS_LOCKLESS_MEMORY
2992 osCp.dep.fileOutFp = (FILE *)NULLP;
2994 /* initialize memOpt */
2995 memOpt = (FILE *) NULLP;
3002 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
3007 /* mt001.301 : Additions */
3008 #ifdef SS_MEM_LEAK_STS
3010 cmMemOpenMemLkFile(msOptArg);
3014 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3017 fileBasedMemCfg = TRUE;
3018 memOpt = fopen(msOptArg, "r");
3020 /* if file does not exist or could not be opened then use the
3021 * default memory configuration as defined in mt_ss.h
3023 if (memOpt == (FILE *) NULLP)
3025 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3026 be opened, using default mem configuration\n", msOptArg);
3031 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3033 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3039 case 0: /*** INPUT: Number of regions ***/
3040 sscanf(line, "%ld", (long *) &numReg);
3041 mtMemoCfg.numRegions = numReg;
3042 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3044 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3050 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3051 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3052 if(numBkts > MT_MAX_BKTS)
3054 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3058 if(numPools > SS_MAX_POOLS_PER_REG)
3060 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3065 * Delay updation from local variable to global
3066 * structure of number of regions and heap data to
3067 * counter error conditions present above.
3069 for(idx = 0; idx < cfgNumRegs; idx++)
3071 mtMemoCfg.region[idx].numBkts = numBkts;
3072 cfgRegInfo[idx].region = idx;
3073 cfgRegInfo[idx].numPools = numPools;
3075 * Initialize the pool info as static type with size zero
3077 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3079 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3080 cfgRegInfo[idx].pools[poolIdx].size = 0;
3085 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3086 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3088 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3090 if(bktIdx >= numBkts)
3092 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3097 mtBktInfo[bktIdx].blkSize = bktSz;
3099 if(bktUpdtCnt == numBkts)
3101 i++; /*done reading bkt info, start reading individual region info*/
3105 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3106 sscanf(line,"%ld",(long *) ®Id);
3107 if(regId >= mtMemoCfg.numRegions)
3109 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3110 #ifndef XEON_SPECIFIC_CHANGES
3115 mtMemoCfg.region[regId].regionId = regId;
3118 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3119 if(bktUpdtCnt < numBkts)
3121 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3122 if(bktIdx >= numBkts)
3124 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3129 if(bktIdx < MT_MAX_BKTS)
3131 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3132 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3133 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3134 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3137 if(bktUpdtCnt == numBkts)
3144 case 5: /* INPUT: Heapsize ***/
3145 sscanf(line, "%ld", (long *) &heapSz);
3146 mtMemoCfg.region[regId].heapsize = heapSz;
3148 if(regUpdtCnt != mtMemoCfg.numRegions)
3157 #ifdef SS_LOCKLESS_MEMORY
3159 sscanf(line, "%ld", (long *) &numBkts);
3160 mtGlobMemoCfg.numBkts = numBkts;
3161 #ifndef XEON_SPECIFIC_CHANGES
3162 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3165 #ifdef XEON_SPECIFIC_CHANGES
3166 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3167 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3168 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3170 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3173 mtDynMemoCfg.region[idx].regionId = idx;
3174 mtDynMemoCfg.region[idx].numBkts = numBkts;
3182 if(bktUpdtCnt < numBkts)
3184 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3185 (long *) &bktSz, (long *) &bktNum,
3186 (long *) &bktSetSize, (long *) &bktRelThr,
3187 (long *) &bktAqurThr);
3188 /* Klock work fix ccpu00148484 */
3189 if(bktIdx < SS_MAX_POOLS_PER_REG)
3191 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3192 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3193 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3194 #ifdef XEON_SPECIFIC_CHANGES
3195 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3196 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3197 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3199 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3201 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3207 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3209 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3210 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3211 #ifdef XEON_SPECIFIC_CHANGES
3212 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3213 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3214 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3220 #ifdef XEON_SPECIFIC_CHANGES
3221 if(bktUpdtCnt == numBkts)
3227 case 8: /* INPUT: Global Heapsize ***/
3228 sscanf(line, "%ld", (long *) &heapSz);
3229 mtGlobMemoCfg.heapSize = heapSz;
3230 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3238 memConfigured = FALSE;
3242 memConfigured = TRUE;
3250 /* mt028.201: modification: multiple procs support related changes */
3251 #ifndef SS_MULTIPLE_PROCS
3254 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3256 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3259 #else /* SS_MULTIPLE_PROCS */
3263 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3265 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3267 SAddProcIdLst(1, &procId);
3270 #endif /* SS_MULTIPLE_PROCS */
3274 osCp.configFilePath = msOptArg;
3298 * Desc: Get options from command line
3300 * Ret: option - success
3302 * EOF - end of options
3304 * Notes: Handles command lines like the following
3307 * then command line should look like this...
3308 * -a foo -b foo1 -c -d foo
3312 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3317 * nloops = atoi(msArgv[msOptInd]);
3320 * state1 = atoi(msArgv[msOptInd]);
3333 int argc, /* argument count */
3334 char **argv, /* argument value */
3335 char *opts /* options */
3338 PUBLIC S16 SGetOpt(argc, argv, opts)
3339 int argc; /* argument count */
3340 char **argv; /* argument value */
3341 char *opts; /* options */
3344 /* mt020.201 - Removed for no command line */
3353 /* mt020.201 - Addition for no command line */
3365 /*mt013.301 : Changes as per coding standards*/
3366 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3372 if (!strcmp(argv[msOptInd], "--"))
3377 else if (argv[msOptInd][0] != '-')
3385 c = argv[msOptInd][sp];
3386 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3388 if (argv[msOptInd][++sp] == '\0')
3399 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3402 if (++msOptInd >= (S16) argc)
3407 else msOptArg = argv[msOptInd++];
3414 if (argv[msOptInd][++sp] == '\0')
3426 #endif /* NOCMDLINE */
3434 * Desc: This function starts system services execution; the
3435 * permanent tasks are started and the system enters a
3446 PUBLIC Void ssdStart
3451 PUBLIC Void ssdStart()
3460 /* mt025.201 - Modification for adding lock to timer handler */
3461 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3463 sem_post(&osCp.dep.ssStarted);
3472 * indirect interface functions to system services service user
3478 * Fun: ssdAttachTTsk
3480 * Desc: This function sends the initial tick message to a TAPA
3481 * task if the task is a permanent task.
3491 PUBLIC S16 ssdAttachTTsk
3493 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3496 PUBLIC S16 ssdAttachTTsk(tTsk)
3497 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3505 TRC0(ssdAttachTTsk);
3508 if (tTsk->tskType == SS_TSK_PERMANENT)
3510 /* Send a permanent tick message to this task, to start
3513 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3516 #if (ERRCLASS & ERRCLS_DEBUG)
3517 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3522 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3523 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3525 /* set up post structure */
3526 /* mt028.201: modification: multiple procs support related changes */
3527 #ifndef SS_MULTIPLE_PROCS
3528 mInfo->pst.dstProcId = SFndProcId();
3529 mInfo->pst.srcProcId = SFndProcId();
3530 #else /* SS_MULTIPLE_PROCS */
3531 mInfo->pst.dstProcId = tTsk->proc;
3532 mInfo->pst.srcProcId = tTsk->proc;
3533 #endif /* SS_MULTIPLE_PROCS */
3534 mInfo->pst.selector = SEL_LC_NEW;
3535 mInfo->pst.region = DFLT_REGION;
3536 mInfo->pst.pool = DFLT_POOL;
3537 mInfo->pst.prior = PRIOR3;
3538 mInfo->pst.route = RTESPEC;
3539 mInfo->pst.event = 0;
3540 mInfo->pst.dstEnt = tTsk->ent;
3541 mInfo->pst.dstInst = tTsk->inst;
3542 mInfo->pst.srcEnt = tTsk->ent;
3543 mInfo->pst.srcInst = tTsk->inst;
3545 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3546 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3552 #if (ERRCLASS & ERRCLS_DEBUG)
3553 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3554 "Could not write to demand queue");
3567 * Fun: ssdDetachTTsk
3569 * Desc: Does nothing.
3579 PUBLIC S16 ssdDetachTTsk
3581 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3584 PUBLIC S16 ssdDetachTTsk(tTsk)
3585 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3588 TRC0(ssdDetachTTsk);
3597 * Fun: ssdCreateSTsk
3599 * Desc: This function creates a system task. A thread is started
3600 * on the system task handler function defined later.
3610 PUBLIC S16 ssdCreateSTsk
3612 SsSTskEntry *sTsk /* pointer to system task entry */
3615 PUBLIC S16 ssdCreateSTsk(sTsk)
3616 SsSTskEntry *sTsk; /* pointer to system task entry */
3619 pthread_attr_t attr;
3620 /* struct sched_param param_sched;*/
3622 #ifdef SS_THR_REG_MAP
3623 U32 threadCreated = FALSE;
3626 TRC0(ssdCreateSTsk);
3629 #ifdef SS_SINGLE_THREADED
3630 /* mt001.301 : Additions */
3632 #ifdef SS_MULTICORE_SUPPORT
3633 if (osCp.numSTsks > 1)
3635 if (osCp.numSTsks > 0)
3636 #endif /* SS_MULTICORE_SUPPORT */
3638 #ifdef SS_MULTICORE_SUPPORT
3639 if (osCp.numSTsks > 3)
3641 if (osCp.numSTsks > 2)
3642 #endif /* SS_MULTICORE_SUPPORT */
3643 #endif /* SS_WATCHDOG */
3650 /* set the current executing entity and instance IDs to
3651 * 'not configured'. create the lock to access them.
3653 sTsk->dep.ent = ENTNC;
3654 sTsk->dep.inst = INSTNC;
3657 /* create the thread */
3658 pthread_attr_init(&attr);
3659 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3661 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3662 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3663 if (sTsk->tskPrior == 0)
3665 printf("Creating RT thread #######################\n");
3666 #ifdef SS_THR_REG_MAP
3667 /* When the thread is created, we check for the memory mapping table if
3668 * threadId can be placed in thread memory map table. If it is not able to place
3669 * threadId is stored in tmporary array. Once thread is created successful,
3670 * thread_cancel is sent for each thread which are created before. All the
3671 * threads are made to wait on sema which is cancel point for thread.
3673 while(threadCreated == FALSE)
3676 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlrT2kL2, (Ptr)sTsk)) != 0)
3679 pthread_attr_destroy(&attr);
3681 #if (ERRCLASS & ERRCLS_DEBUG)
3682 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3687 #ifdef SS_THR_REG_MAP
3688 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3696 #ifdef SS_THR_REG_MAP
3697 /* When the thread is created, we check for the memory mapping table if
3698 * threadId can be placed in thread memory map table. If it is not able to place
3699 * threadId is stored in tmporary array. Once thread is created successful,
3700 * thread_cancel is sent for each thread which are created before. All the
3701 * threads are made to wait on sema which is cancel point for thread.
3703 while(threadCreated == FALSE)
3706 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk)) != 0)
3709 /* mt020.201 - Addition for destroying thread attribute object attr */
3710 pthread_attr_destroy(&attr);
3712 #if (ERRCLASS & ERRCLS_DEBUG)
3713 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3718 #ifdef SS_THR_REG_MAP
3719 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3726 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3727 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3729 static U32 stLwpId = 3;
3730 sTsk->dep.lwpId = ++stLwpId;
3732 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3734 /* mt020.201 - Addition for destroying thread attribute object attr */
3735 pthread_attr_destroy(&attr);
3742 PUBLIC int SCreatePThread
3745 pthread_attr_t* attr,
3746 void *(*start_routine) (void *),
3750 PUBLIC int SCreatePThread(tid, attr, start_routine, arg)
3752 pthread_attr_t* attr;
3753 void *(*start_routine) (void *);
3758 #ifdef SS_THR_REG_MAP
3759 U32 threadCreated = FALSE;
3762 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3763 /* Klock work fix ccpu00148484 */
3764 if(threadArg == NULLP)
3768 threadArg->argument = arg;
3769 threadArg->start_routine = start_routine;
3771 TRC0(SCreatePThread);
3773 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3775 #ifdef SS_THR_REG_MAP
3776 /* When the thread is created, we check for the memory mapping table if
3777 * threadId can be placed in thread memory map table. If it is not able to place
3778 * threadId is stored in tmporary array. Once thread is created successful,
3779 * thread_cancel is sent for each thread which are created before. All the
3780 * threads are made to wait on sema which is cancel point for thread.
3782 while(threadCreated == FALSE)
3785 /*pthreadCreateHdlr */
3786 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3791 #ifdef SS_THR_REG_MAP
3792 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3803 * Fun: Set Pthread Attributes
3805 * Desc: This function is used to set various explicit
3806 * pthread attributes like, priority scheduling,etc
3817 PRIVATE S16 ssdSetPthreadAttr
3820 pthread_attr_t *attr
3823 PRIVATE S16 ssdSetPthreadAttr(sTsk, attr)
3825 pthread_attr_t *attr
3828 struct sched_param param;
3830 TRC0 (ssdSetPthreadAttr)
3832 SMemSet(¶m, 0, sizeof(param));
3834 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3835 param.sched_priority = 100 - 1 - tskPrior;
3837 param.sched_priority = 100 - 10 - tskPrior;
3840 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3841 /* TODO:: This can be avoided by reducing the priority
3842 * of iccserv thread in l1_master.sh*/
3844 if (clusterMode == RADIO_CLUSTER_MODE)
3846 if(tskPrior == PRIOR1)
3848 param.sched_priority = 91;
3855 printf("Set priority %u\n", param.sched_priority);
3857 /* Set Scheduler to explicit, without this non of the below
3858 pthread attr works */
3859 #ifdef TENB_RTLIN_CHANGES
3860 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3863 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3864 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3865 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3866 #ifdef TENB_RTLIN_CHANGES
3867 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3869 pthread_attr_setschedparam(attr, ¶m);
3873 } /* ssdSetPthreadAttr */
3875 /************* multi-core support **************/
3876 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3877 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3881 * Fun: Get the current core/cpu affinity for a thread/lwp
3883 * Desc: This function is used to get the current processor/core
3884 * affinity for a a system task (thread/lwp). It sets the
3885 * affinity based on the mode supplied by the caller.
3888 * RFAILED - failed, general (optional)
3896 PUBLIC S16 ssdGetAffinity
3898 SSTskId *tskId, /* filled in with system task ID */
3899 U32 *coreId /* the core/processor id to which the affinity is set */
3902 PUBLIC S16 ssdGetAffinity(tskId, coreId)
3903 SSTskId *tskId; /* filled in with system task ID */
3904 U32 *coreId; /* the core/processor id to which the affinity is set */
3915 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3921 TRC0(ssdGetAffinity);
3923 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3925 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3927 tId = osCp.sTskTbl[tskInd].dep.tId;
3932 /* if tskId is not found in the tskTbl */
3933 if (tskInd == SS_MAX_STSKS)
3935 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3940 /* initialize the cpu mask */
3943 /* set thread affinity for linux */
3944 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3946 #if (ERRCLASS & ERRCLS_DEBUG)
3947 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3950 } /* end if pthread_setaffinity fails */
3952 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3954 if (CPU_ISSET (cpuInd, & cpuSet))
3963 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3965 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3967 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3972 /* if tskId is not found in the tskTbl */
3973 if (tskInd == SS_MAX_STSKS)
3975 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3979 /* set thread affinity for Solaris */
3980 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3982 #if (ERRCLASS & ERRCLS_DEBUG)
3983 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3986 } /* end if processor_bind fails */
3989 #endif /* SS_LINUX */
3993 } /* ssdGetAffinity */
3998 * Fun: Set the core/cpu affinity for a thread/lwp
4000 * Desc: This function is used to set processor/core affinity for a
4001 * a system task (thread/lwp). It sets the affinity based on the
4002 * mode supplied by the caller.
4005 * RFAILED - failed, general (optional)
4013 PUBLIC S16 ssdSetAffinity
4015 SSTskId *tskId, /* filled in with system task ID */
4016 U32 coreId /* the core/processor id to which the affinity has to be set */
4019 PUBLIC S16 ssdSetAffinity(tskId, coreId)
4020 SSTskId *tskId; /* filled in with system task ID */
4021 U32 coreId; /* the core/processor id to which the affinity has to be set */
4030 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4037 TRC0(ssdSetAffinity)
4040 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4042 /* Here tskId can not be used as index as the task may be terminated if
4043 there is a TERM even for that tsk, thus breaking the task Id numbering
4045 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4047 tId = osCp.sTskTbl[tskInd].dep.tId;
4052 /* if tskId is not found in the tskTbl */
4053 if (tskInd == SS_MAX_STSKS)
4055 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4059 /* initialize the cpu mask */
4062 /* set the cpu mask */
4063 CPU_SET(coreId, &cpuSet);
4065 /* set thread affinity for linux */
4066 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4068 #if (ERRCLASS & ERRCLS_DEBUG)
4069 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4072 } /* end if pthread_setaffinity fails */
4076 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4078 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4079 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4081 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4086 /* if tskId is not found in the tskTbl */
4087 if (tskInd == SS_MAX_STSKS)
4089 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4093 /* set thread affinity for Solaris */
4094 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4096 #if (ERRCLASS & ERRCLS_DEBUG)
4097 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4100 } /* end if processor_bind fails */
4103 #endif /* SS_LINUX */
4105 } /* ssdSetAffinity */
4107 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4108 /************ end multi-core support *************/
4113 * Fun: ssdDestroySTsk
4115 * Desc: This function destroys a system task. A terminate
4116 * event message is sent to the thread function.
4126 PUBLIC S16 ssdDestroySTsk
4128 SsSTskEntry *sTsk /* pointer to system task entry */
4131 PUBLIC S16 ssdDestroySTsk(sTsk)
4132 SsSTskEntry *sTsk; /* pointer to system task entry */
4139 TRC0(ssdDestroySTsk);
4142 /* we send a message to this system task to tell it to die */
4143 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4146 #if (ERRCLASS & ERRCLASS_DEBUG)
4147 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4153 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4154 mInfo->eventInfo.event = SS_EVNT_TERM;
4156 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4160 #if (ERRCLASS & ERRCLASS_DEBUG)
4161 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4162 "Could not write to demand queue");
4172 /* mt023.201 - Added SThreadYield function to yield CPU
4176 * Desc: This function defers thread execution to any other ready
4188 PUBLIC S16 SThreadYield
4193 PUBLIC S16 SThreadYield()
4199 /* mt024.201 - seperated Linux and other UNIX implementations
4205 /* Set sleep value to 0 to yield CPU */
4209 RETVALUE(select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4211 #else /* other UNICes */
4213 RETVALUE(sleep(0) == 0 ? ROK : RFAILED);
4215 #endif /* SS_LINUX */
4222 * Fun: Register timer
4224 * Desc: This function is used to register a timer
4225 * function for the service user. System services
4226 * will invoke the timer activation function
4227 * passed to it at the specified intervals.
4231 * Notes: Timing is handled by the common timers. The
4232 * ticks are handled by a thread that uses
4233 * nanosleep() and thus timing precision will not
4240 PUBLIC S16 ssdRegTmr
4242 SsTmrEntry *tmr /* pointer to timer entry */
4245 PUBLIC S16 ssdRegTmr(tmr)
4246 SsTmrEntry *tmr; /* pointer to timer entry */
4255 /* initialize common timers */
4256 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4259 /* start the timer */
4260 arg.tq = osCp.dep.tmrTq;
4261 arg.tqCp = &osCp.dep.tmrTqCp;
4262 arg.timers = tmr->dep.timers;
4267 arg.max = TMR_DEF_MAX;
4268 arg.wait = tmr->interval;
4278 * Fun: Deregister timer
4280 * Desc: This function is used to deregister a timer function.
4290 PUBLIC S16 ssdDeregTmr
4292 SsTmrEntry *tmr /* pointer to timer entry */
4295 PUBLIC S16 ssdDeregTmr(tmr)
4296 SsTmrEntry *tmr; /* pointer to timer entry */
4305 /* stop the timer */
4306 arg.tq = osCp.dep.tmrTq;
4307 arg.tqCp = &osCp.dep.tmrTqCp;
4308 arg.timers = tmr->dep.timers;
4313 arg.max = TMR_DEF_MAX;
4314 arg.wait = tmr->interval;
4324 * Fun: Critical error
4326 * Desc: This function is called when a critical error occurs.
4338 Seq seq, /* sequence number */
4339 Reason reason /* reset reason */
4342 PUBLIC S16 ssdError(seq, reason)
4343 Seq seq; /* sequence number */
4344 Reason reason; /* reset reason */
4355 /* get calling task ID */
4356 tId = pthread_self();
4359 /* set up the message to display */
4360 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4361 "reason = %d\n\n", (U8)tId, seq, reason);
4365 /* delete all system tasks */
4366 for (i = 0; i < SS_MAX_STSKS; i++)
4368 if (osCp.sTskTbl[i].used
4369 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4371 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4377 pthread_exit(NULLP);
4380 /* won't reach here */
4389 * Desc: This function is called to log an error.
4399 PUBLIC Void ssdLogError
4401 Ent ent, /* Calling layer's entity id */
4402 Inst inst, /* Calling layer's instance id */
4403 ProcId procId, /* Calling layer's processor id */
4404 Txt *file, /* file name where error occured */
4405 S32 line, /* line in file where error occured */
4406 ErrCls errCls, /* error class */
4407 ErrCode errCode, /* layer unique error code */
4408 ErrVal errVal, /* error value */
4409 Txt *errDesc /* description of error */
4412 PUBLIC Void ssdLogError(ent, inst, procId, file, line,
4413 errCls, errCode, errVal, errDesc)
4414 Ent ent; /* Calling layer's entity id */
4415 Inst inst; /* Calling layer's instance id */
4416 ProcId procId; /* Calling layer's processor id */
4417 Txt *file; /* file name where error occured */
4418 S32 line; /* line in file where error occured */
4419 ErrCls errCls; /* error class */
4420 ErrCode errCode; /* layer unique error code */
4421 ErrVal errVal; /* error value */
4422 Txt *errDesc; /* description of error */
4436 /* get calling task ID */
4438 tId = pthread_self();
4444 case ERRCLS_ADD_RES:
4445 errClsMsg = "ERRCLS_ADD_RES";
4448 case ERRCLS_INT_PAR:
4449 errClsMsg = "ERRCLS_INT_PAR";
4453 errClsMsg = "ERRCLS_DEBUG";
4456 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4458 errClsMsg = "ERRCLS_FTHA";
4462 errClsMsg = "INVALID ERROR CLASS!";
4467 /*mt009.301 Fixed 64BIT compilation warnings*/
4470 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4471 "file: %s line: %03d errcode: %05d errcls: %s\n"
4472 "errval: %05d errdesc: %s\n",
4473 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4476 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4477 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4478 "errval: %05ld errdesc: %s\n",
4479 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4481 SDisplay(0, errBuf);
4482 /* mt001.301 : Additions */
4483 #ifdef SS_LOGGER_SUPPORT
4485 #endif /* SS_LOGGER_SUPPORT */
4489 /* debug errors halt the system */
4490 if (errCls == ERRCLS_DEBUG)
4492 /* mt001.301 : Additions */
4493 #ifdef SS_LOGGER_SUPPORT
4495 #endif /* SS_LOGGER_SUPPORT */
4496 /* delete all system tasks */
4497 for (i = 0; i < SS_MAX_STSKS; i++)
4499 if (osCp.sTskTbl[i].used
4500 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4502 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4508 pthread_exit(NULLP);
4520 * Fun: Register driver task
4522 * Desc: This function is called to register the handlers for a
4533 PUBLIC S16 ssdRegDrvrTsk
4535 SsDrvrTskEntry *drvrTsk /* driver task entry */
4538 PUBLIC S16 ssdRegDrvrTsk(drvrTsk)
4539 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4542 TRC0(ssdRegDrvrTsk);
4547 /* mt001.30 : Additions */
4550 * Fun: Deregister driver task
4552 * Desc: This function is called to deregister the handlers for a
4563 PUBLIC S16 ssdDeregDrvrTsk
4565 SsDrvrTskEntry *drvrTsk /* driver task entry */
4568 PUBLIC S16 ssdDeregDrvrTsk(drvrTsk)
4569 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4572 TRC0(ssdDeregDrvrTsk);
4583 * mt003.301 Additions - SDeRegTTsk fix
4585 #ifdef SS_MULTIPLE_PROCS
4587 PUBLIC S16 ssdProcTTskTerm
4594 PUBLIC S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4599 #else /*SS_MULTIPLE_PROCS*/
4601 PUBLIC S16 ssdProcTTskTerm
4607 PUBLIC S16 ssdProcTTskTerm(tTsk, idx)
4611 #endif /*SS_MULTIPLE_PROCS*/
4613 #ifdef SS_MULTIPLE_PROCS
4622 TRC0(ssdProcTTskTerm);
4627 /* We check the sTsk element; if it is not NULLP, the
4628 * task is attached. So we have to detach it before
4629 * deregistering the task.
4631 ret = SLock(&osCp.sTskTblLock);
4634 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4637 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4640 #if (ERRCLASS & ERRCLS_DEBUG)
4641 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4643 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4645 #if (ERRCLASS & ERRCLS_DEBUG)
4646 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4654 #ifdef SS_MULTIPLE_PROCS
4656 if (tTsk->initTsk != NULLP)
4659 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4662 &(osCp.tTskTbl[idx].xxCb));
4664 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4667 &(osCp.tTskTbl[idx].xxCb));
4668 #endif /* USE_MEMCAL */
4670 #endif /* SS_MULTIPLE_PROCS */
4672 if (tTsk->sTsk != NULLP)
4676 sTsk->dep.ent = ent;
4677 sTsk->dep.inst = inst;
4679 for (n = 0; n < SS_MAX_TTSKS; n++)
4681 if (sTsk->tTsks[n] == idx)
4683 sTsk->tTsks[n] = SS_INVALID_IDX;
4689 /* call the implementation to detach the task */
4690 ssdDetachTTsk(tTsk);
4692 sTsk->dep.ent = ENTNC;
4693 sTsk->dep.inst = INSTNC;
4696 /* Now we empty the entry for this task and update the table
4699 #ifdef SS_MULTIPLE_PROCS
4700 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4701 #else /* SS_MULTIPLE_PROCS */
4702 osCp.tTskIds[ent][inst] = SS_TSKNC;
4703 #endif /* SS_MULTIPLE_PROCS */
4706 #ifdef SS_MULTIPLE_PROCS
4707 tTsk->proc = PROCNC;
4708 #endif /* SS_MULTIPLE_PROCS */
4710 tTsk->inst = INSTNC;
4711 tTsk->tskType = TTUND;
4712 tTsk->initTsk = NULLP;
4713 tTsk->actvTsk = NULLP;
4716 tTsk->nxt = osCp.nxtTTskEntry;
4717 osCp.nxtTTskEntry = idx;
4720 #ifdef SS_MULTIPLE_PROCS
4721 /* mark the control block for this task as invalid */
4722 osCp.tTskTbl[idx].xxCb = NULLP;
4725 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4726 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4728 #if (ERRCLASS & ERRCLS_DEBUG)
4729 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4736 //#ifndef SPLIT_RLC_DL_TASK
4737 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4738 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4739 EXTERN Void ysMtTskHdlr(Void);
4740 EXTERN Void ysMtPollPhyMsg(U8 region);
4741 EXTERN Void ysMtRcvPhyMsg(Void);
4743 PUBLIC Void *mtTskHdlrT2kL2
4745 Ptr tskPtr /* pointer to task entry */
4748 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4749 Ptr tskPtr; /* pointer to task entry */
4755 /* wait for SS to come up */
4756 /* It is required to block on this semaphore before starting actual processing of
4757 the thread becasue the creator of this thread might want to cance it without
4758 doing any processing. When this semaphore is released, means the creator gives
4759 the go ahead for actual processing and we should never come back to this point */
4760 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4769 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4770 * (processes L1 msgs) */
4776 EXTERN Void ysMtTskHdlr(Void);
4777 EXTERN Void YsPhyRecvMsg();
4779 PUBLIC Void *mtTskHdlrT2kL2
4781 Ptr tskPtr /* pointer to task entry */
4784 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4785 Ptr tskPtr; /* pointer to task entry */
4791 /* get out the system task entry from the parameter */
4792 sTsk = (SsSTskEntry *) tskPtr;
4794 /* wait for SS to come up */
4795 /* It is required to block on this semaphore before starting actual processing of
4796 the thread becasue the creator of this thread might want to cance it without
4797 doing any processing. When this semaphore is released, means the creator gives
4798 the go ahead for actual processing and we should never come back to this point */
4799 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4802 #ifndef RGL_SPECIFIC_CHANGES
4810 #ifdef V5GTF_SPECIFIC_CHANGES
4813 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4814 * (processes L1 msgs) */
4816 /* get a message from the demand queue */
4818 #ifdef RLC_MAC_DAT_REQ_RBUF
4819 rgDlDatReqBatchProc();
4822 ret = mtTskHdlMsg(sTsk);
4825 /* exit the for loop here */
4828 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4835 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4839 PUBLIC void *pthreadCreateHdlr
4844 PUBLIC void *pthreadCreateHdlr(pthreadCreateArg)
4849 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4850 /* mt038.201 changed how sem_wait is called */
4851 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4854 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4862 * Desc: This is the system task handler function. It blocks on
4863 * the system task's demand queue. On receiving a message,
4864 * it identifies the target TAPA task, verifies that the
4865 * TAPA task belongs to this system task and if so, calls
4866 * the activation function of that TAPA task with the
4867 * received message. The task activation function or the
4868 * timer activation function may be called.
4870 * Ret: (thread function)
4878 PUBLIC Void *mtTskHdlr
4880 Ptr tskPtr /* pointer to task entry */
4883 PUBLIC Void *mtTskHdlr(tskPtr)
4884 Ptr tskPtr; /* pointer to task entry */
4890 /* get out the system task entry from the parameter */
4891 sTsk = (SsSTskEntry *) tskPtr;
4894 /* wait for SS to come up */
4896 /* mt038.201 changed how sem_wait is called */
4897 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4899 #ifdef XEON_SPECIFIC_CHANGES
4900 printf("\n**********MT Task Handler********\n");
4904 /* Wait for a message from the demand queue */
4905 #ifdef SS_CDMNDQ_SUPPORT
4906 ret = ssCDmndQWait(&sTsk->dQ);
4908 ret = ssDmndQWait(&sTsk->dQ);
4913 ret = mtTskHdlMsg(sTsk);
4928 * Desc: This is the system task handler function. It blocks on
4929 * the system task's demand queue. On receiving a message,
4930 * it identifies the target TAPA task, verifies that the
4931 * TAPA task belongs to this system task and if so, calls
4932 * the activation function of that TAPA task with the
4933 * received message. The task activation function or the
4934 * timer activation function may be called.
4936 * Ret: (thread function)
4944 PUBLIC S16 mtTskHdlMsg
4949 PUBLIC S16 mtTskHdlMsg(sTsk)
4963 /* mt028.201: modification: multiple procs support related changes */
4964 #ifndef SS_MULTIPLE_PROCS
4966 PAIFTMRS16 tmrActvFnMt = NULLP;
4968 /* mt015.301 Initialized the timer activation functions with NULLP */
4969 PFS16 tmrActvFn = NULLP;
4971 PAIFTMRS16 tmrActvFn;
4973 #endif /* SS_MULTIPLE_PROCS */
4974 /* mt003.301 Modifications */
4975 #ifdef SS_THREAD_PROFILE
4977 #endif /* SS_THREAD_PROFILE */
4980 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4983 /* nothing to receive */
4987 /* if we can't lock this system task entry, return the message */
4988 ret = SLock(&sTsk->lock);
4992 #if (ERRCLASS & ERRCLS_DEBUG)
4993 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4994 "Could not lock system task entry");
5004 mBuf2 = mBuf->b_next;
5006 /* find out what kind of message this is */
5007 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5008 #ifdef SS_MEM_WL_DEBUG
5009 mtTskBuffer1 = mBuf2;
5011 mtTskBuffer2 = mBuf2->b_next;
5013 if(mInfo == 0x5050505)
5017 cmAnalyseBtInfo((PTR) mBuf,4);
5019 printf("\n In trouble .... \n");
5021 else if (mInfo == 0x2020202)
5024 cmAnalyseBtInfo((PTR) mBuf,1);
5025 printf("\n In trouble .... \n");
5027 #endif /* SS_MEM_WL_DEBUG */
5028 switch (mInfo->eventInfo.event)
5030 /* this is a termination event, we die */
5032 /* release the message */
5035 /* Unlock the system task entry and lock the system
5036 * task table to clean our entry up.
5038 SUnlock(&sTsk->lock);
5040 ret = SLock(&osCp.sTskTblLock);
5044 #if (ERRCLASS & ERRCLS_DEBUG)
5045 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5046 "Could not lock system task table");
5048 /* what to do here? */
5052 /* clean up the system task entry */
5055 /* mt003.301 Modifications - SDeRegTTsk */
5056 /* sTsk->numTTsks = 0; */
5057 SDestroyLock(&sTsk->lock);
5058 ssDestroyDmndQ(&sTsk->dQ);
5060 /* lock for current executing TAPA task ID */
5062 /* make this entry available in the system task table */
5063 sTsk->nxt = osCp.nxtSTskEntry;
5064 for (i = 0; i < SS_MAX_STSKS; i++)
5066 if (sTsk == &osCp.sTskTbl[i])
5068 osCp.nxtSTskEntry = i;
5075 /* unlock the system task table */
5076 SUnlock(&osCp.sTskTblLock);
5081 /* this is a data message or a permanent task keep-alive message */
5083 case SS_EVNT_PERMTICK:
5084 /* message to a task. find the destination task */
5085 /* mt028.201: modification: multiple procs support related changes */
5086 #ifdef SS_MULTIPLE_PROCS
5087 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5089 if (procIdIdx == SS_INV_PROCID_IDX)
5095 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5096 #else /* SS_MULTIPLE_PROCS */
5097 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5098 #endif /* SS_MULTIPLE_PROCS */
5100 /* verify that it hasn't been deregistered */
5101 if (idx == SS_TSKNC)
5107 /* verify that this system task is still running it */
5108 tTsk = &osCp.tTskTbl[idx];
5109 if (tTsk->sTsk != sTsk)
5115 /* set the current executing TAPA task ID */
5116 sTsk->dep.ent = mInfo->pst.dstEnt;
5117 sTsk->dep.inst = mInfo->pst.dstInst;
5119 /* copy the Pst structure into a local duplicate */
5120 for (i = 0; i < (S16) sizeof(Pst); i++)
5121 *(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
5123 /* Give the message to the task activation function. If
5124 * its a normal data message, we pass it, if this is a
5125 * keep-alive message for a permanent task then we pass
5126 * NULLP in place of the message to the task activation
5129 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5131 #ifndef RGL_SPECIFIC_CHANGES
5132 #ifdef SS_TSKLOG_ENABLE
5133 U32 t = MacGetTick();
5136 /* mt003.301 Modifications */
5137 #if SS_THREAD_PROFILE
5138 tTsk->curEvent = nPst.event;
5140 #endif /* SS_THREAD_PROFILE */
5141 tTsk->actvTsk(&nPst, mBuf);
5142 #ifndef RGL_SPECIFIC_CHANGES
5143 #ifdef SS_TSKLOG_ENABLE
5144 SStopTask(t,PID_SSI_TSK);
5147 #if SS_THREAD_PROFILE
5149 tTsk->curEvtTime = (U32)(et2 - et1);
5150 tTsk->totTime += (U64)tTsk->curEvtTime;
5151 #endif /* SS_THREAD_PROFILE */
5155 #if (ERRCLASS & ERRCLS_DEBUG)
5156 /* this message should only come to a permanent task */
5157 if (tTsk->tskType != SS_TSK_PERMANENT)
5159 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5163 tTsk->actvTsk(&nPst, NULLP);
5165 /* We need to re-send this message back to ourselves so
5166 * the permanent task continues to run.
5168 /* Check if this task got deregistered or detached
5169 * by the activation function; if so, there's nothing
5170 * more to do here, otherwise go ahead.
5173 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5175 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5176 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5180 /* failure here is a real problem */
5183 #if (ERRCLASS & ERRCLS_DEBUG)
5184 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5185 "Could not write to demand queue");
5191 /* unset the current executing TAPA task ID */
5192 sTsk->dep.ent = ENTNC;
5193 sTsk->dep.inst = INSTNC;
5198 /* timer event. find the timer entry */
5199 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5201 /* lock the timer table, coz we're going to peek in it */
5202 ret = SLock(&osCp.tmrTblLock);
5206 #if (ERRCLASS & ERRCLS_DEBUG)
5207 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5208 "Could not lock timer table");
5214 /* Verify that this timer entry is still around and that it
5215 * belongs to our task.
5217 if (osCp.tmrTbl[idx].used == FALSE
5218 /* mt028.201: modification: multiple procs support related changes */
5219 #ifdef SS_MULTIPLE_PROCS
5220 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5221 #endif /* SS_MULTIPLE_PROCS */
5222 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5223 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5225 SUnlock(&osCp.tmrTblLock);
5230 /* mt005.21: addition */
5231 /* set the current executing TAPA task ID */
5232 sTsk->dep.ent = mInfo->pst.dstEnt;
5233 sTsk->dep.inst = mInfo->pst.dstInst;
5235 #ifndef SS_MULTIPLE_PROCS
5237 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5238 tmrActvFnMt = NULLP;
5239 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5241 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5247 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5250 /* unlock the timer table */
5251 SUnlock(&osCp.tmrTblLock);
5253 /* activate the timer function */
5254 /* mt028.201: modification: multiple procs support related changes */
5255 #ifndef SS_MULTIPLE_PROCS
5259 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5260 osCp.tmrTbl[idx].ownerInst);
5268 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5269 osCp.tmrTbl[idx].ownerInst);
5270 #endif /* SS_MULTIPLE_PROCS */
5272 /*mt005.21: addition */
5273 /* unset the current executing TAPA task ID */
5274 sTsk->dep.ent = ENTNC;
5275 sTsk->dep.inst = INSTNC;
5278 /* return the message buffer */
5282 * mt003.301 - SDeRegTTsk fix
5284 case SS_EVNT_TTSK_TERM:
5285 #ifdef SS_MULTIPLE_PROCS
5286 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5288 if (procIdIdx == SS_INV_PROCID_IDX)
5294 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5295 #else /* SS_MULTIPLE_PROCS */
5296 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5297 #endif /* SS_MULTIPLE_PROCS */
5299 /* verify that it hasn't been deregistered */
5300 if (idx == SS_TSKNC)
5306 /* verify that this system task is still running it */
5307 tTsk = &osCp.tTskTbl[idx];
5308 if (tTsk->sTsk != sTsk)
5313 #ifdef SS_MULTIPLE_PROCS
5314 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5316 ssdProcTTskTerm(tTsk, idx);
5322 #if (ERRCLASS & ERRCLS_DEBUG)
5323 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5330 } while (mBuf != NULLP);
5333 /* unlock the system task entry */
5334 SUnlock(&sTsk->lock);
5337 /* yield for other threads */
5338 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5347 * Fun: mtTmrHdlrPublic
5350 PUBLIC Void mtTmrHdlrPublic
5354 PUBLIC Void mtTmrHdlrPublic()
5357 if (SLock(&osCp.tmrTblLock) != ROK)
5359 #if (ERRCLASS & ERRCLS_DEBUG)
5360 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5364 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5365 /* unlock the timer table */
5366 SUnlock(&osCp.tmrTblLock);
5374 * Desc: The timer handler thread function. Counts time
5375 * and invokes the common timer function on each
5378 * Ret: (thread function)
5385 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5387 PRIVATE Void *mtTmrHdlr
5389 void *parm /* unused */
5392 /* mt009.21: addition */
5393 PRIVATE Void *mtTmrHdlr(parm)
5394 void *parm; /* unused */
5397 /*mt004.301-addede new region*/
5398 /* mt010.301 Removed SS_FAP portion and
5399 * enabled oroginal code in function mtTmrHdlr */
5403 U32 i, cnt, oldTicks, newTicks;
5404 struct timeval tv1,tv2;
5405 /* mt038.201 added return */
5407 /* mt039.201 changes for nanosleep */
5408 struct timespec tsN;
5409 PRIVATE U32 err_in_usec;
5411 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5416 /* mt027.201 - Modification for SRegCfgTmr support */
5417 /* check SS_TICKS_SEC */
5418 if (SS_1MS < SS_TICKS_SEC)
5420 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5423 /* mt025.201 - Addition to stop timer handler till task registration is done */
5424 /* wait for SS to come up */
5425 /* mt038.201 changed how sem_wait is called */
5426 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5429 /* mt027.201 - Modification for SRegCfgTmr support */
5430 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5432 ts.tv_nsec = (MT_TICK_CNT * 1000);
5433 /* mt039.201 changes for nanosleep */
5439 if (gettimeofday(&tv1, NULL) == -1)
5441 #if (ERRCLASS & ERRCLS_DEBUG)
5442 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5443 "Error in clock_gettime");
5453 #ifndef STUB_TTI_HANDLING_5GTF
5454 printf("Returning from mtTmrHdlr()\n");
5459 /* mt039.201 changes for nanosleep */
5460 /* sleep for MT_TICK_CNT milli seconds */
5461 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5462 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5464 ts.tv_nsec = tsN.tv_nsec;
5469 if (gettimeofday(&tv2,NULL) == -1)
5471 #if (ERRCLASS & ERRCLS_DEBUG)
5472 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5473 "Error in clock_gettime");
5477 /*mt013.301 : changed check while calculating timer to fix
5478 * diffrence between MTSS time and real unix time
5480 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5482 time_int = (tv2.tv_usec - tv1.tv_usec);
5484 else if (tv2.tv_sec > tv1.tv_sec)
5486 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5488 else /* ts2 < ts1, this will not happen in normal scenario */
5490 /* to make sure cnt = 1 */
5492 time_int = MT_TICK_CNT;
5495 oldTicks = osCp.dep.sysTicks;
5496 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5497 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5498 newTicks = osCp.dep.sysTicks;
5499 tv1.tv_usec = tv2.tv_usec;
5500 tv1.tv_sec = tv2.tv_sec;
5502 cnt = newTicks - oldTicks;
5504 while(err_in_usec >= MT_TICK_CNT)
5507 err_in_usec -= MT_TICK_CNT;
5509 if( cnt >= MT_MAX_TICK_CNT_VAL)
5510 cnt = MT_MIN_TICK_CNT_VAL;
5511 /* call the common timer tick handler */
5512 for (i = 0; i < cnt; i++)
5514 /* mt008.301: cmPrcTmr is guarded with a lock */
5515 /* lock the timer table */
5516 if (SLock(&osCp.tmrTblLock) != ROK)
5518 #if (ERRCLASS & ERRCLS_DEBUG)
5519 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5523 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5524 /* unlock the timer table */
5525 SUnlock(&osCp.tmrTblLock);
5529 /* mt009.21: addition */
5530 RETVALUE( (Void *) NULLP);
5531 /* will not reach here */
5539 * Desc: Process timer event. Called from the common timer
5540 * code when a timeout occurs.
5550 PUBLIC Void mtTimeout
5552 PTR tCb, /* control block */
5553 S16 evnt /* event */
5556 PUBLIC Void mtTimeout(tCb, evnt)
5557 PTR tCb; /* control block */
5558 S16 evnt; /* event */
5567 #ifndef TENB_RTLIN_CHANGES
5570 /* mt028.201: modification: multiple procs support related changes */
5571 #ifdef SS_MULTIPLE_PROCS
5573 #endif /* SS_MULTIPLE_PROCS */
5574 #ifdef RGL_SPECIFIC_CHANGES
5575 #ifdef MSPD_MLOG_NEW
5576 U32 t = GetTIMETICK();
5583 /* get the timer entry */
5584 tEnt = (SsTmrEntry *) tCb;
5587 /* if the timer was deleted, this will be NULL, so drop it */
5593 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5596 /* Hmmmm, the timer might have been deleted while we've been
5597 * working at getting here, so we just skip this.
5599 if (tEnt->used == FALSE)
5605 /* Set up and send a timer message to the destination tasks'
5608 #ifndef SS_MULTICORE_SUPPORT
5609 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5611 #ifdef RGL_SPECIFIC_CHANGES
5612 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5614 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5619 #if (ERRCLASS & ERRCLS_DEBUG)
5620 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5626 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5627 mInfo->eventInfo.event = SS_EVNT_TIMER;
5628 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5630 mInfo->pst.dstEnt = tEnt->ownerEnt;
5631 mInfo->pst.dstInst = tEnt->ownerInst;
5632 mInfo->pst.srcEnt = tEnt->ownerEnt;
5633 mInfo->pst.srcInst = tEnt->ownerInst;
5634 /* mt028.201: modification: multiple procs support related changes */
5635 #ifndef SS_MULTIPLE_PROCS
5636 mInfo->pst.dstProcId = SFndProcId();
5637 mInfo->pst.srcProcId = SFndProcId();
5638 #else /* SS_MULTIPLE_PROCS */
5639 mInfo->pst.dstProcId = tEnt->ownerProc;
5640 mInfo->pst.srcProcId = tEnt->ownerProc;
5641 #endif /* SS_MULTIPLE_PROCS */
5642 mInfo->pst.selector = SEL_LC_NEW;
5643 #ifndef SS_MULTICORE_SUPPORT
5644 mInfo->pst.region = DFLT_REGION;
5647 mInfo->pst.pool = DFLT_POOL;
5648 mInfo->pst.prior = PRIOR0;
5649 mInfo->pst.route = RTESPEC;
5650 mInfo->pst.event = 0;
5653 #ifndef TENB_RTLIN_CHANGES
5654 /* get a semaphore for the TAPA task table */
5655 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5660 #if (ERRCLASS & ERRCLS_DEBUG)
5661 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5669 /* find the owner TAPA task */
5670 /* mt028.201: modification: multiple procs support related changes */
5671 #ifdef SS_MULTIPLE_PROCS
5672 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5673 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5674 #else /* SS_MULTIPLE_PROCS */
5675 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5676 #endif /* SS_MULTIPLE_PROCS */
5677 if (idx == SS_TSKNC)
5679 #ifndef TENB_RTLIN_CHANGES
5680 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5687 /* ensure that the TAPA task is hale and hearty */
5688 tTsk = &osCp.tTskTbl[idx];
5691 #ifndef TENB_RTLIN_CHANGES
5692 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5697 /* Klock work fix ccpu00148484 */
5698 /* write the timer message to the queue of the destination task */
5699 /* mt008.301 : check sTsk before putting into it's DQ */
5700 if (tTsk->sTsk == NULLP)
5702 #ifndef TENB_RTLIN_CHANGES
5703 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5707 #if (ERRCLASS & ERRCLS_DEBUG)
5708 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5709 "Could not write to demand queue");
5714 #ifdef SS_LOCKLESS_MEMORY
5715 mInfo->pst.region = tTsk->sTsk->region;
5716 mInfo->region = tTsk->sTsk->region;
5717 #endif /* SS_LOCKLESS_MEMORY */
5718 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5719 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5721 #ifndef TENB_RTLIN_CHANGES
5722 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5726 #if (ERRCLASS & ERRCLS_DEBUG)
5727 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5728 "Could not write to demand queue");
5733 /* Fix for ccpu00130657 */
5734 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5735 if (tTsk->sTsk->tskPrior == PRIOR0)
5738 WLS_WakeUp(mtGetWlsHdl());
5745 /* release the semaphore for the TAPA task table */
5746 #ifndef TENB_RTLIN_CHANGES
5747 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5751 /* restart the timer */
5752 arg.tq = osCp.dep.tmrTq;
5753 arg.tqCp = &osCp.dep.tmrTqCp;
5754 arg.timers = tEnt->dep.timers;
5755 arg.cb = (PTR) tEnt;
5759 arg.max = TMR_DEF_MAX;
5760 arg.wait = tEnt->interval;
5762 #ifdef RGL_SPECIFIC_CHANGES
5763 #ifdef MSPD_MLOG_NEW
5764 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5776 * Desc: This thread reads the console and hands over any
5777 * data read to a user function.
5779 * Ret: (thread function)
5787 PRIVATE Void *mtConHdlr
5789 Ptr parm /* unused */
5792 /* mt009.21: addition */
5793 PRIVATE Void *mtConHdlr(parm)
5794 Ptr parm; /* unused */
5801 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5807 /* check if we have a console input file handle */
5808 if (osCp.dep.conInFp == NULLP)
5814 fd = fileno(osCp.dep.conInFp);
5819 if ((read(fd, &data, 1)) != 1)
5825 /* call rdConQ, defined by the system service user */
5835 #ifdef SS_DRVR_SUPPORT
5838 * Fun: Interrupt service task handler
5840 * Desc: This is the interrupt service task handler. It blocks
5841 * on a pipe from which it reads an isFlag structure. The
5842 * structure indicates which interrupt service task is to
5843 * be executed. The thread identifies the task, calls the
5844 * isTsk function and sends itself a message to repeat
5845 * this operation until it receives a message to cease.
5855 /* mt009.21: addition */
5856 PRIVATE Void *mtIsTskHdlr
5858 Ptr tskPtr /* pointer to task entry */
5861 /* mt009.21: addition */
5862 PRIVATE Void *mtIsTskHdlr(tskPtr)
5863 Ptr tskPtr; /* pointer to task entry */
5866 #if (ERRCLASS & ERRCLS_DEBUG)
5877 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5882 switch (isFlag.action)
5885 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5887 /* call the interrupt service task activation function */
5888 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5890 /* send self a message to keep doing this */
5891 isFlag.action = MT_IS_RESET;
5893 #if (ERRCLASS & ERRCLS_DEBUG)
5894 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5895 if (ret != sizeof(isFlag))
5897 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5898 "write() to pipe failed");
5901 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5908 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5913 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5915 /* call the interrupt service task activation function */
5916 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5918 #if (ERRCLASS & ERRCLS_DEBUG)
5919 /* send self a message to do this again */
5920 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5922 if (ret != sizeof(isFlag))
5924 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5925 "write() to pipe failed");
5928 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5936 /* where did THIS come from?? */
5940 /* mt009.21: addition */
5941 RETVALUE( (Void *) NULLP);
5945 #endif /* SS_DRVR_SUPPORT */
5946 #endif /* L2_L3_SPLIT */
5948 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5952 * Fun: mtIntSigHndlr
5954 * Desc: Exit function, shuts down.
5964 PUBLIC Void mtIntSigHndlr
5969 PUBLIC Void mtIntSigHndlr(arg)
5974 TRC0(mtIntSigHndlr);
5976 osCp.dep.sigEvnt=TRUE;
5979 #ifdef TENB_RTLIN_CHANGES
5987 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5992 * Desc: function, shuts down.
6002 PUBLIC Void mtExitClnup
6007 PUBLIC Void mtExitClnup()
6016 SGetSysTime(&ticks);
6018 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
6020 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
6022 #ifdef SS_HISTOGRAM_SUPPORT
6026 osCp.dep.sigEvnt=FALSE;
6028 if (osCp.dep.fileOutFp)
6030 fclose(osCp.dep.fileOutFp);
6038 Void SIncrementTtiCount(Void)
6043 Ticks SGetTtiCount(Void)
6052 * Desc: This function displays a string to a given output
6057 * Notes: Buffer should be null terminated.
6059 * channel 0 is reserved for backwards compatibility
6068 S16 chan, /* channel */
6069 Txt *buf /* buffer */
6072 PUBLIC S16 SDisplay(chan, buf)
6073 S16 chan; /* channel */
6074 Txt *buf; /* buffer */
6079 /* mt020.201 - Fixed typo */
6080 #if (ERRCLASS & ERRCLS_INT_PAR)
6083 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6088 #ifndef XEON_SPECIFIC_CHANGES
6089 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6090 ssMemlog(buf, strlen(buf));
6095 /* mt012.301 :FIX for LOG RELATED ISSUE */
6103 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6109 if (osCp.dep.fileOutFp)
6110 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6111 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6114 fflush(osCp.dep.fileOutFp);
6127 * Desc: function, shuts down.
6147 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6148 a loop to overcome the child processes being killed upon exiting the
6150 #ifdef SS_LINUX /* this should have already been defined */
6151 /* mt010.301 removed flag SLES9_PLUS */
6152 /* wait forever for children */
6156 if(osCp.dep.sigEvnt==TRUE)
6163 pthread_exit(NULLP);
6169 * Fun: Set date and time
6171 * Desc: This function is used to set the calendar
6176 * Notes: Unimplemented
6182 PUBLIC S16 SSetDateTime
6184 REG1 DateTime *dt /* date and time */
6187 PUBLIC S16 SSetDateTime(dt)
6188 REG1 DateTime *dt; /* date and time */
6203 * Fun: Get date and time
6205 * Desc: This function is used to determine the calendar
6206 * date and time. This information may be used for
6207 * some management functions.
6218 PUBLIC S16 SGetDateTime
6220 REG1 DateTime *dt /* date and time */
6223 PUBLIC S16 SGetDateTime(dt)
6224 REG1 DateTime *dt; /* date and time */
6227 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6230 struct timespec ptime;
6232 struct timeval ptime;
6241 #if (ERRCLASS & ERRCLS_INT_PAR)
6244 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6253 localtime_r(&tt, &tme);
6256 clock_gettime(CLOCK_REALTIME, &ptime);
6258 gettimeofday(&ptime, NULL);
6260 localtime_r(&ptime.tv_sec, &tme);
6262 dt->month = (U8) tme.tm_mon + 1;
6263 dt->day = (U8) tme.tm_mday;
6264 dt->year = (U8) tme.tm_year;
6265 dt->hour = (U8) tme.tm_hour;
6266 dt->min = (U8) tme.tm_min;
6267 dt->sec = (U8) tme.tm_sec;
6270 #ifdef SS_DATETIME_USEC
6272 dt->usec = ptime.tv_nsec / 1000;
6274 dt->usec = ptime.tv_usec;
6276 #endif /*-- SS_DATETIME_USEC --*/
6282 * Get time from epoch in milliseconds
6284 * Fun: Get time from epoch in milliseconds
6286 * Desc: This function is used to get the time from epoch in milli seconds.
6287 * This information may be used for calculating a layer's activation function
6288 * execution time used for thread profiling.
6297 /* mt003.301 Modifications */
6299 PUBLIC S16 SGetEpcTime
6301 EpcTime *et /* date and time */
6304 PUBLIC S16 SGetEpcTime(et)
6305 EpcTime *et; /* date and time */
6308 /* mt003.301 Modifications */
6310 U64 to_sec = 1000000;
6313 struct timespec ptime;
6315 struct timeval ptime;
6321 #if (ERRCLASS & ERRCLS_INT_PAR)
6330 clock_gettime(CLOCK_REALTIME, &ptime);
6332 gettimeofday(&ptime, NULL);
6333 #endif /* SS_LINUX */
6335 now = (ptime.tv_sec * to_sec);
6338 now += (ptime.tv_nsec / to_nsec);
6339 #else /* SS_LINUX */
6340 now += (ptime.tv_usec);
6342 #endif /* SS_LINUX */
6343 now = (now / to_nsec);
6354 * Fun: Get system time
6356 * Desc: This function is used to determine the system time.
6360 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6366 PUBLIC S16 SGetSysTime
6368 Ticks *sysTime /* system time */
6371 PUBLIC S16 SGetSysTime(sysTime)
6372 Ticks *sysTime; /* system time */
6378 #if (ERRCLASS & ERRCLS_INT_PAR)
6379 if (sysTime == NULLP)
6381 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6387 *sysTime = osCp.dep.sysTicks;
6393 /* mt021.201 - Addition of SGetRefTime function */
6396 * Fun: Get referenced time
6398 * Desc: This function is used to determine the time in seconds
6399 * and microseconds from a reference time. The reference
6400 * time is expressed in seconds from UTC EPOC, January 1,
6406 * Notes: Macros are defined for reference times:
6407 * SS_REFTIME_01_01_1970
6408 * SS_REFTIME_01_01_2002
6414 PUBLIC S16 SGetRefTime
6416 U32 refTime, /* reference time */
6421 PUBLIC S16 SGetRefTime(refTime, sec, usec)
6422 U32 refTime; /* reference time */
6429 struct timespec ptime;
6431 struct timeval ptime;
6437 clock_gettime(CLOCK_REALTIME, &ptime);
6439 gettimeofday(&ptime, NULL);
6442 #if (ERRCLASS & ERRCLS_INT_PAR)
6443 if (sec == NULLP || usec == NULLP)
6445 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6448 /* mt022.201 - Modification to fix compile warning */
6449 if (refTime > (U32)(ptime.tv_sec))
6451 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6456 *sec = ptime.tv_sec - refTime;
6458 *usec = ptime.tv_nsec / 1000;
6460 *usec = ptime.tv_usec;
6470 * Fun: Get Random Number
6472 * Desc: Invoked by layer when a pseudorandom number is required.
6476 * Notes: Suggested approach uses shuffled Linear Congruential
6477 * Operators as described in Byte magazine October
6478 * 1984; "Generating and Testing Pseudorandom Numbers"
6486 Random *value /* random number */
6489 PUBLIC S16 SRandom(value)
6490 Random *value; /* random number */
6496 #if (ERRCLASS & ERRCLS_INT_PAR)
6499 /* mt011.21: addition */
6500 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6506 *value = (Random) rand_r(&osCp.dep.randSeed);
6517 * Desc: This function exits from a task.
6521 * Notes: Currently does nothing.
6532 PUBLIC S16 SExitTsk()
6544 * Fun: Exit Interrupt
6546 * Desc: This function exits from an interrupt.
6550 * Notes: Currently does nothing.
6561 PUBLIC S16 SExitInt()
6573 * Fun: Hold Interrupt
6575 * Desc: This function prohibits interrupts from being enabled until
6576 * release interrupt. This function should be called when
6577 * interrupts are disabled and prior to any call to system
6578 * services either by entry to an interrupt service routine or
6579 * by explicit call to disable interrupt.
6583 * Notes: Currently does nothing
6594 PUBLIC S16 SHoldInt()
6606 * Fun: Release Interrupt
6608 * Desc: This function allows interrupts to be enabled.
6612 * Notes: Currently does nothing.
6623 PUBLIC S16 SRelInt()
6637 * Desc: Enable interrupts
6639 * Ret: ROK on success
6642 * Notes: Currently does nothing.
6648 PUBLIC INLINE S16 SEnbInt
6653 PUBLIC INLINE S16 SEnbInt()
6667 * Desc: Disable interrupts
6669 * Ret: ROK on success
6672 * Notes: Currently does nothing.
6678 PUBLIC INLINE S16 SDisInt
6683 PUBLIC INLINE S16 SDisInt()
6697 * Desc: This function gets the function address stored at the
6698 * specified interrupt vector.
6702 * Notes: Currently does nothing.
6710 VectNmb vectNmb, /* vector number */
6711 PIF *vectFnct /* vector function */
6714 PUBLIC S16 SGetVect(vectNmb, vectFnct)
6715 VectNmb vectNmb; /* vector number */
6716 PIF *vectFnct; /* vector function */
6734 * Desc: This function installs the specified function at the
6735 * specified interrupt vector.
6739 * Notes: Currently does nothing.
6747 VectNmb vectNmb, /* vector number */
6748 PIF vectFnct /* vector function */
6751 PUBLIC S16 SPutVect(vectNmb, vectFnct)
6752 VectNmb vectNmb; /* vector number */
6753 PIF vectFnct; /* vector function */
6766 /* mt028.201: modification: multiple procs support related changes */
6767 #ifndef SS_MULTIPLE_PROCS
6773 * Desc: This function gets the current entity and instance.
6776 * RFAILED - failed, general (optional)
6778 * Notes: This function may be called by the OS or Layer 1
6785 PUBLIC S16 SGetEntInst
6787 Ent *ent, /* entity */
6788 Inst *inst /* instance */
6791 PUBLIC S16 SGetEntInst(ent, inst)
6792 Ent *ent; /* entity */
6793 Inst *inst; /* instance */
6805 #if (ERRCLASS & ERRCLS_INT_PAR)
6806 /* check pointers */
6807 if (ent == NULLP || inst == NULLP)
6809 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6815 /* get the thread id */
6816 tId = pthread_self();
6819 /* find the system task in whose context we're running */
6821 ret = SLock(&osCp.sTskTblLock);
6826 for (i = 0; i < SS_MAX_STSKS; i++)
6828 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6830 sTsk = &osCp.sTskTbl[i];
6836 *ent = sTsk->dep.ent;
6837 *inst = sTsk->dep.inst;
6839 SUnlock(&osCp.sTskTblLock);
6842 RETVALUE(ret == ROK ? ROK : RFAILED);
6850 * Desc: This function sets the current entity and instance.
6860 PUBLIC S16 SSetEntInst
6862 Ent ent, /* entity */
6863 Inst inst /* instance */
6866 PUBLIC S16 SSetEntInst(ent, inst)
6867 Ent ent; /* entity */
6868 Inst inst; /* instance */
6880 #if (ERRCLASS & ERRCLS_INT_PAR)
6881 /* check entity and instance IDs */
6882 if (ent >= ENTNC || inst >= INSTNC)
6884 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6890 /* get the thread id */
6891 tId = pthread_self();
6894 /* find the system task in whose context we're running */
6896 ret = SLock(&osCp.sTskTblLock);
6901 for (i = 0; i < SS_MAX_STSKS; i++)
6903 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6905 sTsk = &osCp.sTskTbl[i];
6911 sTsk->dep.ent = ent;
6912 sTsk->dep.inst = inst;
6914 SUnlock(&osCp.sTskTblLock);
6917 RETVALUE(ret == ROK ? ROK : RFAILED);
6920 #endif /* SS_MULTIPLE_PROCS */
6922 #ifdef SS_DRVR_SUPPORT
6928 * Desc: Set interrupt pending flag
6930 * Ret: ROK on success
6939 PUBLIC INLINE S16 SSetIntPend
6941 U16 id, /* driver task identifier */
6942 Bool flag /* flag */
6945 PUBLIC INLINE S16 SSetIntPend(id, flag)
6946 U16 id; /* driver task identifier */
6947 Bool flag; /* flag */
6956 #if (ERRCLASS & ERRCLS_INT_PAR)
6957 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6959 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6966 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6968 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6976 #endif /* SS_DRVR_SUPPORT */
6979 #ifdef SS_LOCKLESS_MEMORY
6982 * Fun: SGlobMemInfoShow
6984 * Desc: This function displays the memory usage information
6985 * for the destined region. It will show the usage of
6986 * each configured bucket and the heap for the specified region.
6989 * RFAILED Region not registered
6995 PUBLIC S16 SGlobMemInfoShow
7000 PUBLIC S16 SGlobMemInfoShow()
7005 CmMmGlobRegCb *globReg;
7007 TRC1(SGlobMemInfoShow);
7009 globReg = osCp.globRegCb;
7011 sprintf(prntBuf, "--------------------------------------------------------------\n");
7012 SDisplay(0, prntBuf);
7013 sprintf(prntBuf, "Global Region Bucket Information\n");
7014 SDisplay(0, prntBuf);
7015 sprintf(prntBuf, "====================================================\n");
7016 SDisplay(0, prntBuf);
7017 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
7018 SDisplay(0, prntBuf);
7019 sprintf(prntBuf, "====================================================\n");
7020 SDisplay(0, prntBuf);
7023 for (idx = 0; idx < globReg->numBkts; idx++)
7025 #ifdef XEON_SPECIFIC_CHANGES
7026 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
7027 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7030 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
7031 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7033 sprintf(prntBuf, "%2u %12u %8u %9u\n",
7034 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7037 SDisplay(0, prntBuf);
7039 sprintf(prntBuf, "--------------------------------------------------------------\n");
7040 SDisplay(0, prntBuf);
7045 #endif /* SS_LOCKLESS_MEMORY */
7048 Bool IsMemoryThresholdHit(Region reg, Pool pool)
7050 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
7052 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
7055 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
7056 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
7063 /* mt022.201 - Addition of SRegInfoShow function */
7068 * Desc: This function displays the memory usage information
7069 * for the destined region. It will show the usage of
7070 * each configured bucket and the heap for the specified region.
7073 * RFAILED Region not registered
7075 * Notes: A Sample Output from the function
7076 * Bucket Memory: region 1
7077 * ====================================================
7078 * Bucket Number of Blks configured Size Allocated
7079 * ====================================================
7087 * Heap Memory: region 1
7090 * Heap Segmented blocks: 0
7097 PUBLIC S16 SRegInfoShow
7103 PUBLIC S16 SRegInfoShow(region, availmem)
7113 #if (ERRCLASS & ERRCLS_INT_PAR)
7114 if (region > (SS_MAX_REGS-1) )
7116 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7123 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7124 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7125 SDisplay(0, prntBuf);
7126 sprintf(prntBuf, "====================================================\n");
7127 SDisplay(0, prntBuf);
7128 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7129 SDisplay(0, prntBuf);
7130 sprintf(prntBuf, "====================================================\n");
7131 SDisplay(0, prntBuf);
7135 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7137 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7139 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7140 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7141 mtCMMRegCb[region]->bktTbl[idx].size,
7142 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7143 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7145 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7146 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7147 mtCMMRegCb[region]->bktTbl[idx].size,
7148 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7149 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7152 /*mt009.301 Fixed 64BIT compilation warnings*/
7154 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7155 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7156 mtCMMRegCb[region]->bktTbl[idx].size,
7157 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7159 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7160 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7161 mtCMMRegCb[region]->bktTbl[idx].size,
7162 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7164 #endif /* not TENB_RTLIN_CHANGES */
7165 SDisplay(0, prntBuf);
7166 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7167 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7168 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7170 sprintf(prntBuf, "\n---------------\n");
7171 SDisplay(0, prntBuf);
7172 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7173 SDisplay(0, prntBuf);
7174 /*mt009.301 Fixed 64BIT compilation warnings*/
7176 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7178 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7180 SDisplay(0, prntBuf);
7181 /*mt009.301 Fixed 64BIT compilation warnings*/
7183 sprintf(prntBuf, "Heap Allocated: %u\n",
7184 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7186 sprintf(prntBuf, "Heap Allocated: %lu\n",
7187 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7189 SDisplay(0, prntBuf);
7190 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7191 #if (ERRCLASS & ERRCLS_DEBUG)
7192 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7193 mtCMMRegCb[region]->heapCb.numFragBlk);
7194 SDisplay(0, prntBuf);
7199 #ifdef XEON_SPECIFIC_CHANGES
7200 #define SSI_MAX_BKT_THRESHOLD 6
7201 #define SSI_MAX_REG_THRESHOLD 2
7202 U32 SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7203 U32 SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7204 U32 SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7207 PRIVATE Void SInitMemThreshold
7213 PRIVATE Void SInitMemThreshold(region, maxBkt)
7219 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7221 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7222 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7223 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7224 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7229 PUBLIC S16 SRegReachedMemThreshold
7235 PUBLIC S16 SRegReachedMemThreshold(region, maxBkt)
7242 PRIVATE U8 initFlag = 1;
7246 SInitMemThreshold(region, maxBkt);
7249 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7251 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7256 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7260 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7265 RETVALUE(memStatus);
7268 /* mt033.201 - addition of API to return the memory statistical data */
7273 * Desc: This function returns the memory usage information
7274 * for the destined region. It will return the usage of
7275 * each configured bucket and the heap for the specified region.
7278 * RFAILED Region not registered
7286 PUBLIC S16 SGetRegInfo
7289 SsMemDbgInfo *dbgInfo
7292 PUBLIC S16 SGetRegInfo(region, dbgInfo)
7294 SsMemDbgInfo *dbgInfo;
7301 #if (ERRCLASS & ERRCLS_INT_PAR)
7302 if (region >= mtMemoCfg.numRegions )
7304 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7309 dbgInfo->availmem = 0;
7311 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7312 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7314 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7316 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7318 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7319 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7320 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7322 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7323 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7324 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7327 dbgInfo->region = region;
7329 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7331 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7332 mtCMMRegCb[region]->heapCb.avlSize);
7334 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7336 #if (ERRCLASS & ERRCLS_DEBUG)
7337 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7344 PUBLIC S16 SGetRegPoolInfo
7350 PUBLIC S16 SGetRegPoolInfo(numRegion, numPool)
7355 /* Send number of Region available */
7356 *numRegion = mtMemoCfg.numRegions;
7357 /* Send number of Pools available */
7358 *numPool = cfgRegInfo[0].numPools;
7363 /* mt033.201 - addition of APIs to print the memory statistical data
7364 * as defined by SSI enhancements
7366 #ifdef SSI_DEBUG_LEVEL1
7369 * Fun: SPrintRegMemStatusInfo
7371 * Desc: This function displays the memory usage information
7372 * for the destined region. It will show the total memory
7373 * used for static and dynamic memory if typeFlag is
7374 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7375 * memory block allocated for a particular size if typeFlag
7376 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7377 * calling SRegPrintMemStats.
7387 PUBLIC S16 SPrintRegMemStatusInfo
7393 PUBLIC S16 SPrintRegMemStatusInfo(region, typeFlag)
7403 TRC1(SPrintRegMemStatusInfo);
7405 #if (ERRCLASS & ERRCLS_INT_PAR)
7406 if (region >= mtMemoCfg.numRegions )
7408 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7413 /* initialize the counters*/
7417 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7419 /* total static and dynamic memory allocated from all the buckets in region requested */
7420 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7421 SDisplay(0, prntBuf);
7422 sprintf(prntBuf, "===========================================\n");
7423 SDisplay(0, prntBuf);
7424 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7425 SDisplay(0, prntBuf);
7426 sprintf(prntBuf, "===========================================\n");
7427 SDisplay(0, prntBuf);
7428 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7430 /*mt009.301 Fixed 64BIT compilation warnings*/
7432 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7433 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7434 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7436 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7437 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7438 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7440 SDisplay(0, prntBuf);
7441 /* update the total count */
7442 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7443 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7446 /*mt009.301 Fixed 64BIT compilation warnings*/
7448 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7449 SDisplay(0, prntBuf);
7450 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7452 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7453 SDisplay(0, prntBuf);
7454 /*mt010.301 fix for compilation error*/
7455 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7457 SDisplay(0, prntBuf);
7459 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7460 SDisplay(0, prntBuf);
7461 /*mt009.301 Fixed 64BIT compilation warnings*/
7463 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7464 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7466 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7467 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7469 SDisplay(0, prntBuf);
7471 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7473 /* Bucket Memory allocation Statistics */
7474 RETVALUE(SPrintRegMemStats(region));
7479 sprintf(prntBuf, "\n Invalid choice \n");
7480 SDisplay(0, prntBuf);
7488 * Fun: SPrintRegMemStats
7490 * Desc: This function displays the memory usage information for
7491 * the destined region. It will show the number of memory
7492 * block allocated for a particular size from the hash list.
7502 PRIVATE S16 SPrintRegMemStats
7507 PRIVATE S16 SPrintRegMemStats(region)
7511 CmMmHashListCp *hashListCp;
7516 TRC1(SPrintRegMemStats);
7518 hashListCp = &mtCMMRegCb[region]->hashListCp;
7520 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7521 SDisplay(0, prntBuf);
7522 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7523 hashListCp->numOfbins, hashListCp->numOfEntries);
7524 SDisplay(0, prntBuf);
7525 sprintf(prntBuf, "===================================\n");
7526 SDisplay(0, prntBuf);
7527 sprintf(prntBuf, "Block Size Total number of requests\n");
7528 SDisplay(0, prntBuf);
7529 sprintf(prntBuf, "===================================\n");
7530 SDisplay(0, prntBuf);
7532 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7533 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7535 if (hashListCp->hashList[idx].numAttempts)
7538 /*mt009.301 Fixed 64BIT compilation warnings*/
7540 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7541 hashListCp->hashList[idx].numAttempts);
7543 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7544 hashListCp->hashList[idx].numAttempts);
7546 SDisplay(0, prntBuf);
7550 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7551 SDisplay(0, prntBuf);
7552 sprintf(prntBuf, "=================================================\n");
7553 SDisplay(0, prntBuf);
7554 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7555 SDisplay(0, prntBuf);
7556 sprintf(prntBuf, "=================================================\n");
7557 SDisplay(0, prntBuf);
7559 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7560 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7562 /*mt009.301 Fixed 64BIT compilation warnings*/
7564 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7565 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7566 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7568 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7569 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7570 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7572 SDisplay(0, prntBuf);
7574 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7575 SDisplay(0, prntBuf);
7576 /*mt009.301 Fixed 64BIT compilation warnings*/
7578 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7579 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7580 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7582 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7583 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7584 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7586 SDisplay(0, prntBuf);
7587 sprintf(prntBuf, "\n");
7588 SDisplay(0, prntBuf);
7595 * Fun: SRegMemErrHdlr
7597 * Desc: This function handles the errors returned from the memory
7598 * related functions. Customers are suggested to modify this
7599 * API according to their specific requirement.
7609 PUBLIC Void SRegMemErrHdlr
7616 PUBLIC Void SRegMemErrHdlr(region, ptr, errCode)
7624 TRC1(SRegMemErrHdlr);
7626 if (errCode == RDBLFREE)
7628 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7629 SDisplay(0, prntBuf);
7631 else if (errCode == RTRAMPLINGNOK)
7633 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7634 SDisplay(0, prntBuf);
7642 * Fun: SPrintRegMemProfile
7644 * Desc: This function displays the memory profile information
7645 * for the destined region. This function prints for:
7646 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7647 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7657 PUBLIC S16 SPrintRegMemProfile
7662 PUBLIC S16 SPrintRegMemProfile(region)
7668 CmMmBlkHdr *curBktBlk;
7670 Size offsetToNxtBlk;
7677 TRC1(SPrintRegMemProfile);
7679 #if (ERRCLASS & ERRCLS_INT_PAR)
7680 if (region >= mtMemoCfg.numRegions )
7682 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7687 regCb = mtCMMRegCb[region];
7689 /* memory profile */
7690 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7691 SDisplay(0, prntBuf);
7693 /* bucket profile */
7694 sprintf(prntBuf, "\nBucket Profile\n");
7695 SDisplay(0, prntBuf);
7697 for (idx = 0; idx < regCb->numBkts; idx++)
7700 /*mt009.301 Fixed 64BIT compilation warnings*/
7702 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7703 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7705 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7706 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7708 SDisplay(0, prntBuf);
7710 sprintf(prntBuf, "==========================================================================\n");
7711 SDisplay(0, prntBuf);
7712 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7713 SDisplay(0, prntBuf);
7714 sprintf(prntBuf, "==========================================================================\n");
7715 SDisplay(0, prntBuf);
7717 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7719 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7720 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7721 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7723 /*mt009.301 Fixed 64BIT compilation warnings*/
7725 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7727 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7729 SDisplay(0, prntBuf);
7730 /* check if it is a sane block, elxe jump to next block */
7731 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7733 sprintf(prntBuf, " Trampled \n");
7734 SDisplay(0, prntBuf);
7739 if (CMM_IS_STATIC(curBktBlk->memFlags))
7741 /*mt009.301 Fixed 64BIT compilation warnings*/
7743 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7745 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7747 SDisplay(0, prntBuf);
7749 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7751 /*mt009.301 Fixed 64BIT compilation warnings*/
7753 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7755 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7757 SDisplay(0, prntBuf);
7759 else if (CMM_IS_FREE(curBktBlk->memFlags))
7761 /*mt009.301 Fixed 64BIT compilation warnings*/
7763 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7765 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7767 SDisplay(0, prntBuf);
7771 sprintf(prntBuf, " Trampled \n");
7772 SDisplay(0, prntBuf);
7778 sprintf(prntBuf, "\nHeap Profile\n");
7779 SDisplay(0, prntBuf);
7781 /* point to heapCb */
7782 heapCb = &(regCb->heapCb);
7784 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7785 SDisplay(0, prntBuf);
7786 sprintf(prntBuf, "==========================================================================\n");
7787 SDisplay(0, prntBuf);
7788 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7789 SDisplay(0, prntBuf);
7790 sprintf(prntBuf, "==========================================================================\n");
7791 SDisplay(0, prntBuf);
7793 /* traverse the entire heap to output the heap profile */
7794 hdrSize = sizeof(CmHEntry);
7795 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7796 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7798 /*mt009.301 Fixed 64BIT compilation warnings*/
7800 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7802 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7804 SDisplay(0, prntBuf);
7806 /* check if it is a sane block, elxe jump to next block */
7807 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7809 sprintf(prntBuf, " Trampled \n");
7810 SDisplay(0, prntBuf);
7812 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7813 SDisplay(0, prntBuf);
7816 * To go to next block in the heap we do not have any offset value
7817 * other than curHBlk->size. As the block is already trampled
7818 * we cannot rely on this size. So it is better to stop here unless there
7819 * exists any other mechanism(?) to know the offset to next block.
7824 /*mt009.301 Fixed 64BIT compilation warnings*/
7826 sprintf(prntBuf, " %8u", curHBlk->size);
7828 sprintf(prntBuf, " %8lu", curHBlk->size);
7830 SDisplay(0, prntBuf);
7832 if (CMM_IS_STATIC(curHBlk->memFlags))
7834 /*mt009.301 Fixed 64BIT compilation warnings*/
7836 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7838 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7840 SDisplay(0, prntBuf);
7842 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7844 /*mt009.301 Fixed 64BIT compilation warnings*/
7846 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7848 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7850 SDisplay(0, prntBuf);
7852 else if (CMM_IS_FREE(curHBlk->memFlags))
7854 /*mt009.301 Fixed 64BIT compilation warnings*/
7856 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7858 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7860 SDisplay(0, prntBuf);
7864 sprintf(prntBuf, " Trampled \n");
7865 SDisplay(0, prntBuf);
7867 /* goto next block in the heap */
7868 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7874 #endif /* SSI_DEBUG_LEVEL1 */
7876 /*-- mt035.201 : Added new API for timestamp --*/
7879 * Fun: Get TimeStamp
7881 * Desc: This function is used to Get TimeStamp in micro seconds
7892 PUBLIC S16 SGetTimeStamp
7897 PUBLIC S16 SGetTimeStamp(ts)
7903 struct timespec ptime;
7905 struct timeval ptime;
7912 TRC1(SGetTimeStamp);
7915 clock_gettime(CLOCK_REALTIME, &ptime);
7917 gettimeofday(&ptime, NULL);
7920 /* Obtain the time of day, and convert it to a tm struct. --*/
7921 ptm = localtime (&ptime.tv_sec);
7922 /* Klock work fix ccpu00148484 */
7925 /* Format the date and time, down to a single second. --*/
7926 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7929 /* Compute microseconds. --*/
7931 microseconds = ptime.tv_nsec / 1000;
7933 microseconds = ptime.tv_usec;
7936 /* Print the formatted time, in seconds, followed by a decimal point
7937 and the microseconds. --*/
7938 /*mt009.301 Fixed 64BIT compilation warnings*/
7940 sprintf(ts, "%s.%03d", time_string, microseconds);
7942 sprintf(ts, "%s.%03ld", time_string, microseconds);
7948 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7951 * Fun: Get SGetSystemTsk
7953 * Desc: This function is used to Get sytem task id
7963 PUBLIC U32 SGetSystemTsk
7968 PUBLIC U32 SGetSystemTsk()
7971 TRC1(SGetSystemTskS);
7973 RETVALUE(pthread_self());
7975 } /* end of SGetSystemTsk */
7977 #ifdef SS_MULTICORE_SUPPORT
7980 * Fun: Add Timer thread into system task table
7982 * Desc: This function is used to add the system task
7983 * associated with Timer thread.
7993 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void)
7995 PRIVATE SsSTskEntry* ssdAddTmrSTsk()
8001 TRC1(ssdAddTmrSTsk);
8003 /* lock the system task table */
8004 ret = SLock(&osCp.sTskTblLock);
8008 #if (ERRCLASS & ERRCLS_DEBUG)
8009 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8010 "Could not lock system task table");
8016 /* check count of system tasks */
8017 if (osCp.numSTsks == SS_MAX_STSKS)
8020 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8022 #if (ERRCLASS & ERRCLS_DEBUG)
8023 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
8024 "Could not give the Semaphore");
8029 #if (ERRCLASS & ERRCLS_ADD_RES)
8030 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
8037 /* initialize the system task entry with the information we have */
8038 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
8040 /* store the system task priority */
8041 sTsk->tskPrior = SS_NORM_TSK_PRI;
8043 /* initialize the demand queue */
8044 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8047 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8049 #if (ERRCLASS & ERRCLS_DEBUG)
8050 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8051 "Could not give the Semaphore");
8056 #if (ERRCLASS & ERRCLS_DEBUG)
8057 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8058 "Could not initialize demand queue");
8064 /* initialize the system task entry lock */
8065 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8067 ssDestroyDmndQ(&sTsk->dQ);
8069 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8071 #if (ERRCLASS & ERRCLS_DEBUG)
8072 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8073 "Could not give the Semaphore");
8078 #if (ERRCLASS & ERRCLS_DEBUG)
8079 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8080 "Could not initialize system task entry lock");
8087 /* success, update the table */
8088 sTsk->tskId = osCp.nxtSTskEntry;
8090 sTsk->termPend = FALSE;
8091 osCp.nxtSTskEntry = sTsk->nxt;
8094 /* unlock the system task table */
8096 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8098 #if (ERRCLASS & ERRCLS_DEBUG)
8099 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8100 "Could not give the Semaphore");
8107 #endif /* SS_MULTICORE_SUPPORT */
8108 /* mt003.301 Readwrite lock and recursive mutex additions */
8109 #ifdef SS_LOCK_SUPPORT
8112 * Fun: ssdInitLockNew
8114 * Desc: This function is used to initialise lock/mutex
8124 PUBLIC S16 ssdInitLockNew
8130 PUBLIC S16 ssdInitLockNew(lockId, lockType)
8136 #ifdef SS_REC_LOCK_SUPPORT
8137 pthread_mutexattr_t attr;
8138 #endif /* SS_REC_LOCK_SUPPORT */
8139 Txt prntBuf[PRNTSZE];
8142 TRC1(ssdInitLockNew);
8146 #ifdef SS_RDWR_LOCK_SUPPORT
8149 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8151 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8152 SDisplay(0, prntBuf);
8157 #endif /* SS_RDWR_LOCK_SUPPORT */
8158 #ifdef SS_REC_LOCK_SUPPORT
8161 retVal = pthread_mutexattr_init(&attr);
8165 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8170 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8172 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8176 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8177 pthread_mutexattr_destroy(&attr);
8181 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8184 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8185 pthread_mutexattr_destroy(&attr);
8191 #endif /* SS_REC_LOCK_SUPPORT */
8194 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8195 SDisplay(0, prntBuf);
8205 * Desc: This function is used to aquire the read write lock
8215 PUBLIC S16 ssdLockNew
8221 PUBLIC S16 ssdLockNew(lockId, lockType)
8227 Txt prntBuf[PRNTSZE];
8234 #ifdef SS_RDWR_LOCK_SUPPORT
8237 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8239 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8240 SDisplay(0, prntBuf);
8247 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8249 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8250 SDisplay(0, prntBuf);
8257 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8259 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8260 SDisplay(0, prntBuf);
8267 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8269 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8270 SDisplay(0, prntBuf);
8275 #endif /* SS_RDWR_LOCK_SUPPORT */
8276 #ifdef SS_REC_LOCK_SUPPORT
8279 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8281 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8282 SDisplay(0, prntBuf);
8287 #endif /* SS_REC_LOCK_SUPPORT */
8290 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8291 SDisplay(0, prntBuf);
8304 * Desc: This function is used to Unlock the read write lock
8314 PUBLIC S16 ssdUnlockNew
8320 PUBLIC S16 ssdUnlockNew(lockId, lockType)
8326 Txt prntBuf[PRNTSZE];
8333 #ifdef SS_RDWR_LOCK_SUPPORT
8336 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8338 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8339 SDisplay(0, prntBuf);
8344 #endif /* SS_RDWR_LOCK_SUPPORT */
8345 #ifdef SS_REC_LOCK_SUPPORT
8348 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8350 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8351 SDisplay(0, prntBuf);
8356 #endif /* SS_REC_LOCK_SUPPORT */
8359 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8360 SDisplay(0, prntBuf);
8369 * Fun: ssdDestroyLockNew
8371 * Desc: This function is used to destroy the read write lock
8381 PUBLIC S16 ssdDestroyLockNew
8387 PUBLIC S16 ssdDestroyLockNew(lockId, lockType)
8392 Txt prntBuf[PRNTSZE];
8395 TRC1(ssdDestroyLockNew);
8399 #ifdef SS_RDWR_LOCK_SUPPORT
8402 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8404 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8405 SDisplay(0, prntBuf);
8410 #endif /* SS_RDWR_LOCK_SUPPORT */
8411 #ifdef SS_REC_LOCK_SUPPORT
8414 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8416 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8417 SDisplay(0, prntBuf);
8422 #endif /* SS_REC_LOCK_SUPPORT */
8425 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8426 SDisplay(0, prntBuf);
8432 #endif /* SS_LOCK_SUPPORT */
8434 /* mt005.301 : Cavium Changes */
8435 #ifdef SS_SEUM_CAVIUM
8439 * Fun: ssInitRcvWork
8441 * Desc: This is the initializtion function of receive
8445 * RFAILED - failed, general (optional)
8447 * Notes: Function to initialize the work queue packet
8448 * receiving thread. This creates the new thread to
8449 * receive the work and sets the affinity.
8455 PUBLIC S16 ssInitRcvWork
8460 PUBLIC S16 ssInitRcvWork()
8463 pthread_attr_t attr;
8466 TRC1(ssInitRcvWork);
8468 /* set the required attributes */
8469 pthread_attr_init(&attr);
8470 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8471 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8472 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8474 /* Create a new thread to receive the work queue messages */
8475 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8477 pthread_attr_destroy(&attr);
8482 pthread_attr_destroy(&attr);
8486 }/* ssInitRcvWork */
8493 * Desc: This is the handler function of receive
8497 * RFAILED - failed, general (optional)
8499 * Notes:The handler function of the work queue receiver task.
8500 * This will be waiting for the work and after receiving
8501 * it, work will converted and posted to that entityt
8508 PRIVATE void *workRcvTsk
8513 PRIVATE void *workRcvTsk (ptr)
8518 cvmx_wqe_t *workPtr;
8519 Buffer *mBuf, *rcvdBuf;
8520 SsMsgInfo *minfoPtr;
8530 /* get the work if its avilable */
8531 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8533 if ( workPtr == NULLP )
8535 /* If there is no work then sleep for 10 usec */
8537 ts.tv_nsec = 500000;
8539 nanosleep(&ts, NULLP);
8543 switch(workPtr->tag)
8545 /* Switch over according to the tag value */
8546 case SS_CVMX_MBUF_TAG:
8548 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8550 /* Convert the physical address to Pointers */
8551 ret = SConvPhyPtr(&rcvdBuf);
8554 /* mt011.301: Cavium 32 bit changes */
8555 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8559 /* Copy the buffer to this region */
8560 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8563 /* mt011.301: Cavium 32 bit changes */
8564 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8568 /* mt011.301: Cavium 32 bit changes */
8569 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8571 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8573 /* Get the post strucutre and Post the message */
8574 if ( minfoPtr != NULLP)
8576 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8578 (Void)SPstTsk(&pst, mBuf);
8580 /* Free the buffer allocated if it cannot be sent */
8589 /* Invalid tag value, drop the work */
8590 /* mt011.301: Cavium 32 bit changes */
8591 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8600 #endif /* SS_SEUM_CAVIUM */
8602 #ifdef TENB_RTLIN_CHANGES
8603 PUBLIC S16 SInitLock(SLockId *l, U8 t)
8606 pthread_mutexattr_t prior;
8607 pthread_mutexattr_init(&prior);
8608 #ifndef RGL_SPECIFIC_CHANGES
8609 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8611 r = pthread_mutex_init(l, &prior);
8612 pthread_mutexattr_destroy(&prior);
8616 #ifdef SS_THR_REG_MAP
8619 * Fun: ssRegMainThread
8621 * Desc: This function is used to add the memory region
8622 * mapping for the main thread.
8624 * Ret: VOID (Always successful)
8632 PUBLIC Void ssRegMainThread(Void)
8637 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8640 printf("not able to get different Id for main thread\n");
8643 /* Here the default region is added as we dont have any region associated with
8644 * Main thread. The thread should not perform any allocation except
8645 * the initial configuratin
8649 #ifdef XEON_SPECIFIC_CHANGES
8650 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8652 SS_GET_THREAD_MEM_REGION() =
8660 * Fun: ssCheckAndAddMemoryRegionMap
8662 * Desc: This function is used to add the memory region
8663 * mapping for the provided sTsk associated thread.
8664 * If the threadId can be placed in the thread memory
8665 * region mapping table and returns success if it is able
8666 * to place. If not, it keeps the thread ID in the static
8667 * local array and increments the count. Once thread Id
8668 * is successfully placed in the thread memory region mapping
8669 * table, pthread_cancel is sent for all the previous threads
8670 * which are failed to place in table.
8672 * Ret: TRUE - Thread ID successfully placed in thread memory region
8674 * FALSE - If thread Id is not placed in thread memory region
8677 * Notes:mapping tablemapping tablng tablee
8682 PUBLIC S32 ssCheckAndAddMemoryRegionMap
8684 pthread_t threadId, /* Thread Id of system task */
8685 Region region /* Region associated with thread */
8688 PRIVATE U32 createdThreads;
8689 PRIVATE pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8692 TRC1(ssCheckAndAddMemoryRegionMap);
8694 /* Here 0xFF is considered as invalid region and if the mapping table
8695 * contains 0xFF, that mapping entry is free
8699 if(SS_INVALID_THREAD_REG_MAP !=
8700 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8703 /* Klock work fix ccpu00148484 */
8704 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8706 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8707 printf("Not able to get the different thread ID, exiting\n");
8710 createdThreadIds[createdThreads++] = threadId;
8713 /* If we found free mapping table entry, place the region and send pthread_cancel
8714 * for all the thread Ids which are created before this
8718 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8719 #ifdef XEON_SPECIFIC_CHANGES
8720 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8721 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8722 SS_MAX_THREAD_REGION_MAP), region);
8725 for(indx = 0; indx < createdThreads; indx++)
8727 #ifdef XEON_SPECIFIC_CHANGES
8728 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8730 pthread_cancel(createdThreadIds[indx]);
8736 } /* ssCheckAndAddMemoryRegionMap */
8740 * Fun: ssCheckAndDelMemoryRegionMap
8742 * Desc: This function is used to add the memory region
8743 * mapping for the provided sTsk associated thread.
8744 * If the threadId can be placed in the thread memory
8745 * region mapping table and returns success if it is able
8746 * to place. If not, it keeps the thread ID in the static
8747 * local array and increments the count. Once thread Id
8748 * is successfully placed in the thread memory region mapping
8749 * table, pthread_cancel is sent for all the previous threads
8750 * which are failed to place in table.
8752 * Ret: TRUE - Thread ID successfully placed in thread memory region
8754 * FALSE - If thread Id is not placed in thread memory region
8757 * Notes:mapping tablemapping tablng tablee
8762 PUBLIC S32 ssCheckAndDelMemoryRegionMap
8764 pthread_t threadId /* Thread Id of system task */
8768 TRC1(ssCheckAndDelMemoryRegionMap);
8770 /* Raghu To-Do Check with team, is it necessary to acquire lock
8771 * as del and add may go parallel */
8772 /* Here 0xFF is considered as invalid region and if the mapping table
8773 * contains 0xFF, that mapping entry is free
8775 if(SS_INVALID_THREAD_REG_MAP ==
8776 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8779 printf("Invalid Thread ID (%ld)\n", (U32)threadId);
8781 printf("Invalid Thread ID (%d)\n", (U32)threadId);
8785 /* If we found free mapping table entry, place the region and send pthread_cancel
8786 * for all the thread Ids which are created before this
8788 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8792 } /* ssCheckAndAddMemoryRegionMap */
8796 #ifdef SS_TSKLOG_ENABLE
8801 * Desc: This function will return current time through input parameter.
8804 * RFAILED - failed, general (optional)
8811 PUBLIC S16 SStartTask
8813 VOLATILE U32 *startTime,
8817 PUBLIC S16 SStartTask(startTime, taskId)
8818 VOLATILE U32 *startTime;
8822 #ifdef MSPD_MLOG_NEW
8823 *startTime = GetTIMETICK();
8832 * Desc: This function will return current time through input parameter.
8833 * and take the difference of start time provided as input parameter
8837 * RFAILED - failed, general (optional)
8844 PUBLIC S16 SStopTask
8846 VOLATILE U32 startTime,
8850 PUBLIC S16 SStopTask(startTime, taskId)
8851 VOLATILE U32 startTime;
8858 case PID_MAC_HARQ_IND:
8859 case PID_SCH_TTI_IND:
8861 case PID_MAC_DAT_IND:
8862 case PID_MAC_SF_ALLOC_REQ:
8863 case PID_MAC_STA_RSP:
8864 case PID_MAC_DL_SCHD:
8865 case PID_MAC_DL_CQI_IND:
8866 case PID_MAC_UL_CQI_IND:
8867 case PID_MAC_UL_SCHD:
8868 case PID_MAC_TTI_IND:
8869 case PID_CL_RCV_PHY_MSG:
8870 case PID_CL_HARQ_STA_IND:
8871 case PID_MAC_AM_HARQ_RLS:
8872 case PID_CL_DL_BATCH_PROC:
8873 case PID_CL_DLM_PRC_TTI_IND:
8874 case PID_CRC_IND_REAL:
8875 case PID_CRC_IND_DUMMY:
8876 case PID_TTI_LATENCY:
8877 case PID_RECPREQ_PROC:
8880 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8882 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8885 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8893 PUBLIC S16 SStartTask
8895 VOLATILE U32 * startTime,
8899 PUBLIC S16 SStartTask(startTime, taskId)
8900 VOLATILE U32 * startTime;
8909 PUBLIC S16 SStopTask
8911 VOLATILE U32 startTime,
8915 PUBLIC S16 SStopTask(startTime, taskId)
8916 VOLATILE U32 startTime;
8923 #endif /*#ifdef SS_TSKLOG_ENABLE */
8924 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8926 * This primitive is used to calculate the CPU Utilization per Core
8931 * @return Void - function is always success
8934 PUBLIC Void UpdateSocCpuInfo
8936 CmCpuStatsInfo *cpuInfo,
8940 PUBLIC Void UpdateSocCpuInfo(*cpuInfo, idx)
8941 CmCpuStatsInfo *cpuInfo;
8946 S8 mipsStr[MIPS_STRING_LEN];
8953 /* Open the file which holds the MIPS available value */
8954 mipsFd = fopen(MIPS_FILE, "r");
8961 /* Get the free mips available value from the file */
8962 if(NULLP == fgets(mipsStr, 24, mipsFd))
8964 printf("fgets to get the free mips available failed\n");
8969 strtok(mipsStr, " ");
8971 strPart = strtok(NULLP, " ");
8973 if(idx == CM_L2_CPU_UTIL)
8975 if(strPart != NULLP)
8977 l2FreeCpu = atoi(strPart);
8978 l2CpuUsed = 100 - l2FreeCpu;
8979 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8980 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);;
8981 cpuInfo->cpuUtil[0].numSamples++;
8984 if(idx == CM_L3_CPU_UTIL)
8986 strPart = strtok(NULLP, " ");
8987 if(strPart != NULLP)
8989 l3FreeCpu = atoi(strPart);
8990 l3CpuUsed = 100 - l3FreeCpu;
8991 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8992 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);;
8993 cpuInfo->cpuUtil[0].numSamples++;
8996 if(idx == CM_L2_CPU_UTIL)
8998 cpuInfo->numCores = CM_NUM_L2_CORES ;
9000 else if(idx == CM_L3_CPU_UTIL)
9002 cpuInfo->numCores = CM_NUM_L3_CORES ;
9008 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
9009 #ifdef SS_MULTICORE_SUPPORT
9012 * Fun: Add Timer thread into system task table
9014 * Desc: This function is used to add the system task
9015 * associated with Timer thread.
9025 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(
9029 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(idx)
9036 TRC1(ssdReAddTmrSTsk);
9038 /* lock the system task table */
9039 ret = SLock(&osCp.sTskTblLock);
9043 #if (ERRCLASS & ERRCLS_DEBUG)
9044 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
9045 "Could not lock system task table");
9051 /* initialize the system task entry with the information we have */
9052 sTsk = &osCp.sTskTbl[idx];
9057 SDestroyLock(&sTsk->lock);
9058 ssDestroyDmndQ(&sTsk->dQ);
9061 /* store the system task priority */
9062 sTsk->tskPrior = SS_NORM_TSK_PRI;
9064 /* initialize the demand queue */
9065 if (ssInitDmndQ(&sTsk->dQ) != ROK)
9068 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9070 #if (ERRCLASS & ERRCLS_DEBUG)
9071 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
9072 "Could not give the Semaphore");
9077 #if (ERRCLASS & ERRCLS_DEBUG)
9078 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
9079 "Could not initialize demand queue");
9085 /* initialize the system task entry lock */
9086 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
9088 ssDestroyDmndQ(&sTsk->dQ);
9090 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9092 #if (ERRCLASS & ERRCLS_DEBUG)
9093 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
9094 "Could not give the Semaphore");
9099 #if (ERRCLASS & ERRCLS_DEBUG)
9100 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9101 "Could not initialize system task entry lock");
9108 /* success, update the table */
9109 sTsk->tskId = idx + 1;
9111 sTsk->termPend = FALSE;
9113 /* unlock the system task table */
9115 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9117 #if (ERRCLASS & ERRCLS_DEBUG)
9118 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9119 "Could not give the Semaphore");
9126 #endif /* SS_MULTICORE_SUPPORT */
9131 * Fun: Initialize timer table
9133 * Desc: This function initializes MTSS-specific information
9134 * in the timer table.
9144 PUBLIC S16 ssdReInitTmr
9149 PUBLIC S16 ssdReInitTmr()
9152 pthread_attr_t attr;
9153 struct sched_param param_sched;
9154 #ifndef XEON_SPECIFIC_CHANGES
9157 #ifdef SS_MULTICORE_SUPPORT
9159 #endif /* SS_MULTICORE_SUPPORT */
9160 #ifdef SS_THR_REG_MAP
9161 U32 threadCreated = FALSE;
9162 #endif /* SS_THR_REG_MAP */
9166 #ifndef XEON_SPECIFIC_CHANGES
9167 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9170 #if (ERRCLASS & ERRCLS_DEBUG)
9171 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9172 "Could not give the Semaphore");
9178 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9179 /* mt010.21: addition */
9181 #ifdef SS_MULTICORE_SUPPORT
9182 sTsk = ssdReAddTmrSTsk(0);
9187 #endif /* SS_MULTICORE_SUPPORT */
9188 /* create the timer handler thread */
9190 pthread_attr_init(&attr);
9191 /* mt021.201 - Addition to set stack size */
9192 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9193 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9194 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9195 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9196 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9197 pthread_attr_setschedparam(&attr, ¶m_sched);
9200 #ifdef SS_THR_REG_MAP
9201 /* When the thread is created, we check for the memory mapping table if
9202 * threadId can be placed in thread memory map table. If it is not able to place
9203 * threadId is stored in tmporary array. Once thread is created successful,
9204 * thread_cancel is sent for each thread which are created before. All the
9205 * threads are made to wait on sema which is cancel point for thread.
9207 while(threadCreated == FALSE)
9210 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9212 /* mt020.201 - Addition for destroying thread attribute object attr */
9213 pthread_attr_destroy(&attr);
9218 #ifdef SS_THR_REG_MAP
9219 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9222 #endif /* SS_THR_REG_MAP */
9223 #ifdef SS_MEM_WL_DEBUG
9224 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9227 /* mt020.201 - Addition for destroying thread attribute object attr */
9228 pthread_attr_destroy(&attr);
9229 sem_post(&osCp.dep.ssStarted);
9233 /**********************************************************************
9235 **********************************************************************/