1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: Multi-threaded System Services - Solaris
25 Desc: C source code for the MTSS-Solaris implementation of
30 *********************************************************************21*/
35 #ifndef _POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE 199309L
38 /* mt003.301 moved env files to use the __USE_UNIX98 flag in sys includes */
39 #include "envopt.h" /* environment options */
40 #include "envdep.h" /* environment dependent */
41 #include "envind.h" /* environment independent */
48 #include <sys/types.h>
53 /* mt003.301: included sys/time.h
54 * for both solaris and linux
57 /* mt008.21: addition */
62 /* header include files (.h) */
65 #include "gen.h" /* general layer */
66 #include "ssi.h" /* system services */
68 #include "cm5.h" /* common timers */
70 #include "mt_ss.h" /* MTSS specific */
71 #include "mt_err.h" /* MTSS error defines */
73 #include "ss_queue.h" /* queues */
74 #include "ss_task.h" /* tasking */
75 #include "ss_msg.h" /* messaging */
76 #include "ss_mem.h" /* memory management interface */
77 #include "ss_gen.h" /* general */
78 /* mt003.301 Additions - Task deregistration */
79 #include "ss_err.h" /* error */
80 #include "cm_mem.h" /* common memory manager */
81 #include "cm_lte.h" /* common lte param */
82 /* mt001.301 : Additions */
83 #ifdef SS_THREAD_PROFILE
86 #ifdef SS_LOCKLESS_MEMORY
91 /* multi-core support enhancement */
92 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
93 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
99 #include <sys/types.h>
100 #include <sys/processor.h>
101 #include <sys/procset.h>
103 #endif /* SS_LINUX */
104 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
105 /* mt001.301 : Additions */
107 #include <sys/types.h>
108 #include <sys/socket.h>
109 #include <netinet/in.h>
110 #include <arpa/inet.h>
111 #endif /* SS_WATCHDOG */
113 /* header/extern include files (.x) */
115 #include "gen.x" /* general layer */
116 #include "ssi.x" /* system services */
118 #include "cm5.x" /* common timers */
120 #include "mt_ss.x" /* MTSS specific */
121 #ifdef SS_LOCKLESS_MEMORY
122 #include "mt_ss_wl.x" /* MTSS specific */
123 #endif /* SS_LOCKLESS_MEMORY */
125 #include "ss_queue.x" /* queues */
126 #include "ss_task.x" /* tasking */
127 #include "ss_timer.x" /* timers */
128 #include "ss_strm.x" /* STREAMS */
129 #include "ss_msg.x" /* messaging */
130 #include "ss_mem.x" /* memory management interface */
131 #include "ss_drvr.x" /* driver tasks */
132 #include "ss_gen.x" /* general */
133 #ifdef SS_LOCKLESS_MEMORY
134 #include "cm_llist.x"
136 #include "cm_mem_wl.x" /* common memory manager */
138 #include "cm_mem.x" /* common memory manager */
139 #endif /* SS_LOCKLESS_MEMORY */
140 #include "cm_lte.x" /* common memory manager */
141 /* mt001.301 : Additions */
142 #ifdef SS_LOGGER_SUPPORT
144 #endif /* SS_LOGGER_SUPPORT */
146 /*mt005.301: Cavium Changes */
147 #ifdef SS_SEUM_CAVIUM
148 /* cvmx includes files */
149 #include "cvmx-config.h"
151 #include "cvmx-pow.h"
152 #include "cvmx-tim.h"
153 #include "cvmx-fpa.h"
154 #include "cvmx-helper-fpa.h"
155 #include "cvmx-malloc.h"
156 #endif /* SS_SEUM_CAVIUM */
159 #include "mt_plat_t33.h"
160 #include "mt_plat_t33.x"
161 #include "sys/syscall.h"
164 #ifdef RGL_SPECIFIC_CHANGES
166 #include <hugetlbfs.h>
169 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
170 EXTERN S16 rgBatchProc (Void);
172 #ifdef RLC_MAC_DAT_REQ_RBUF
173 EXTERN S16 rgDlDatReqBatchProc ARGS((
176 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
177 EXTERN S16 rgBatchProc ARGS((
181 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
182 /* general purpose debug zone */
183 char my_buffer2[4096 * 4] = { 0 };
184 char my_buffer[4096] = { 0 };
185 int my_buffer_idx = 0;
189 #define sigsegv_print(x, ...) my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
191 struct sigcontext my_uc_mcontext = { 0 };
196 #include <ucontext.h>
200 #define SIGSEGV_STACK_GENERIC
201 #define REGFORMAT "%x\n"
203 #ifdef XEON_SPECIFIC_CHANGES
204 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
207 void dump_external(void);
210 PRIVATE Void mtDelSigals
215 PRIVATE Void mtDelSignals()
220 memset(&sa, 0, sizeof(struct sigaction));
221 sigemptyset(&sa.sa_mask);
222 sa.sa_handler = SIG_DFL;
223 sigaction(SIGSEGV, &sa, NULL);
225 memset(&sa, 0, sizeof(struct sigaction));
226 sigemptyset(&sa.sa_mask);
227 sa.sa_handler = SIG_DFL;
228 sigaction(SIGILL, &sa, NULL);
232 static void signal_segv(int signum, siginfo_t * info, void *ptr)
234 static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
237 ucontext_t *ucontext = (ucontext_t *) ptr;
238 #ifdef XEON_SPECIFIC_CHANGES
240 int *p32 = (int *) 0x2fff0000;
245 printf("segv ooops @ %p\n", info->si_addr);
248 printf("Segmentation Fault!\n");
249 printf("info.si_signo = %d\n", signum);
250 printf("info.si_errno = %d\n", info->si_errno);
251 printf("info.si_code = %d (%s)\n", info->si_code, si_codes[info->si_code]);
252 printf("info.si_addr = %p\n", info->si_addr);
254 memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
257 #ifndef RGL_SPECIFIC_CHANGES
258 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
259 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
260 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
261 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
262 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
263 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
264 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
265 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
266 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
267 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
268 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
269 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
270 printf("reg[%02d] = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
271 printf("reg[sp] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
272 printf("reg[lr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
273 printf("reg[pc] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
274 printf("reg[cpsr] = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
277 printf("Stack trace (non-dedicated):\n");
279 sz = backtrace(buffer, 50);
280 strings = backtrace_symbols(buffer, sz);
281 for (i = 0; i < sz; ++i)
282 printf("%s\n", strings[i]);
284 printf("End of stack trace.");
286 #ifdef XEON_SPECIFIC_CHANGES
291 /* Lets first print our debug information */
292 printf("Before dumping our Debug info\n");
294 printf("After dumping our Debug info\n");
296 /* Disable the signal and make the enodeb to dump. This will make
297 * eNB to generate the core with dumping the ccpu log
304 /* End printing debug information */
309 /*** TBD: IMPORTANT ***
310 *** The following definition is temporary. This must be removed
311 *** when all products have been updated with latest ssi.h file OR
312 *** all ssi.h files have been updated to contain this definitions
314 /* New error class for FTHA added */
316 #define ERRCLS_FTHA 0x8
317 #endif /* ERRCLS_FTHA */
319 typedef struct _SPThreadCreateArg
321 void *argument; /* argument that is to be passed to the actual pthread */
322 void *(*start_routine) (void *); /* function from which pthread starts */
325 PUBLIC void *pthreadCreateHdlr(void* arg);
327 #ifdef SS_LOCKLESS_MEMORY
328 PUBLIC Buffer *mtTskBuffer1;
329 PUBLIC Buffer *mtTskBuffer2;
331 EXTERN pthread_t tmpRegTidMap[20];
332 EXTERN U8 stopBtInfo;
333 EXTERN S16 SGlobMemInfoShow(void);
334 #endif /* SS_LOCKLESS_MEMORY */
337 EXTERN APP_CONTEXT AppContext;
338 EXTERN S32 clusterMode;
341 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
342 EXTERN unsigned int tlPost(void *handle);
345 /* forward references */
346 /* mt003.301 Modifications - Moved to ss_gen.x */
347 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
348 PUBLIC Void *mtTskHdlrT2kL2 ARGS((Void*));
349 PUBLIC void mtSigSegvHndlr ARGS((void));
350 PUBLIC void mtSigUsr2Hndlr ARGS((void));
353 PRIVATE S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
354 PRIVATE Void *mtTskHdlr ARGS((void *));
355 PRIVATE S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
357 PRIVATE Void *mtTmrHdlr ARGS((void *));
358 PRIVATE Void mtTimeout ARGS((PTR tCb, S16 evnt));
360 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
361 PRIVATE Void mtIntSigHndlr ARGS((int));
362 PRIVATE Void mtExitClnup ARGS((void));
365 PRIVATE Void *mtConHdlr ARGS((void *));
369 #ifdef SS_DRVR_SUPPORT
370 PRIVATE Void *mtIsTskHdlr ARGS((void *));
374 /* mt020.201 - Addition for no command line available */
376 PRIVATE Void mtGetOpts ARGS((void));
377 /* mt003.301 Additions - File Based task registration made
378 * common for both MULTICORE and NON-MULTICORE
380 PRIVATE Bool fileBasedMemCfg = FALSE;
383 /* mt033.201 - addition of local function to print the statistics such as
384 * (size vs. numAttempts) and (allocations vs. deallocations)
386 #ifdef SSI_DEBUG_LEVEL1
387 PRIVATE S16 SPrintRegMemStats ARGS((Region region));
388 #endif /* SSI_DEBUG_LEVEL1 */
390 #ifdef SS_MULTICORE_SUPPORT
391 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void);
392 PRIVATE SsSTskEntry* ssdReAddTmrSTsk ARGS((U8 idx));
393 #ifndef SS_LOCKLESS_MEMORY
394 #ifndef RGL_SPECIFIC_CHANGES
395 PRIVATE S16 ssdInitMemInfo ARGS((void));
400 /* mt005.301: Cavium changes */
401 #ifdef SS_SEUM_CAVIUM
402 PRIVATE Void *workRcvTsk ARGS((void *));
403 #endif /* SS_SEUM_CAVIUM */
405 #ifdef SS_THR_REG_MAP
406 PUBLIC S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t threadId,
408 PUBLIC S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t threadId));
409 #endif /* SS_THR_REG_MAP */
411 /* type declarations */
413 #ifdef SS_DRVR_SUPPORT
414 typedef struct mtIsFlag
424 /* public variable declarations */
426 PUBLIC Cntr cfgNumRegs = SS_MAX_REGS;
427 /* Set memory configuration as false.
428 * Set to true if memory configuration through file is successfull.
430 PUBLIC Bool memConfigured = FALSE;
431 /* mt022.201 - Modification for shared memory relay region and memcal tool */
432 PUBLIC SsRegCfg cfgRegInfo[SS_MAX_REGS] =
435 SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
437 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
438 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
439 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
440 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
441 { SS_POOL_STATIC, 0 }
447 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
449 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
450 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
451 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
452 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
453 { SS_POOL_STATIC, 0 }
456 #endif /* INTEL_WLS */
458 #ifdef SS_LOCKLESS_MEMORY
461 SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
463 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
464 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
465 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
466 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
467 { SS_POOL_STATIC, 0 }
471 SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
473 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
474 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
475 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
476 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
477 { SS_POOL_STATIC, 0 }
481 SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
483 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
484 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
485 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
486 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
487 { SS_POOL_STATIC, 0 }
491 SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
493 { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
494 { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
495 { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
496 { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
497 { SS_POOL_STATIC, 0 }
500 #endif /* SS_LOCKLESS_MEMORY */
502 /* mt003.301 Modifications - File Based task registration made
503 * common for both MULTICORE and NON-MULTICORE
506 #ifdef SS_LOCKLESS_MEMORY
507 PUBLIC MtDynMemCfg mtDynMemoCfg =
509 SS_MAX_REGS, /* number of regions */
512 SS_DFLT_REGION, /* region id */
513 MT_MAX_BKTS, /* number of buckets */
515 /* block size, no. of blocks, Upper threshold, lower threshold */
516 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
517 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
518 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
519 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
523 SS_DFLT_REGION + 1, /* region id */
524 MT_MAX_BKTS, /* number of buckets */
526 /* block size, no. of blocks, Upper threshold, lower threshold */
527 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
528 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
529 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
530 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
534 SS_DFLT_REGION + 2, /* region id */
535 MT_MAX_BKTS, /* number of buckets */
537 /* block size, no. of blocks, Upper threshold, lower threshold */
538 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
539 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
540 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
541 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
545 SS_DFLT_REGION + 3, /* region id */
546 MT_MAX_BKTS, /* number of buckets */
548 /* block size, no. of blocks, Upper threshold, lower threshold */
549 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
550 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
551 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
552 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
556 SS_DFLT_REGION + 4, /* region id */
557 MT_MAX_BKTS, /* number of buckets */
559 /* block size, no. of blocks, Upper threshold, lower threshold */
560 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
561 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
562 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
563 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
566 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
569 SS_DFLT_REGION + 4, /* region id */
570 MT_MAX_BKTS, /* number of buckets */
572 /* block size, no. of blocks, Upper threshold, lower threshold */
573 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
574 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
575 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
576 {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
584 PUBLIC MtGlobMemCfg mtGlobMemoCfg =
586 MT_MAX_BKTS, /* number of buckets */
589 /* block size, no. of blocks, Upper threshold, lower threshold */
590 {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
591 {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
592 {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
593 {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
595 {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
596 {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
597 {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
598 {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
602 #endif /* SS_LOCKLESS_MEMORY */
604 /* mt022.201 - Modification for memory calculator tool */
605 /* mt018.201 - added memory configuration matrix */
606 PUBLIC MtMemCfg mtMemoCfg =
609 SS_MAX_REGS - 1, /* number of regions */
611 #ifndef XEON_SPECIFIC_CHANGES
612 SS_MAX_REGS, /* number of regions */
619 SS_DFLT_REGION, /* region id */
620 MT_MAX_BKTS, /* number of buckets */
621 MT_HEAP_SIZE, /* heap size */
623 #ifndef XEON_SPECIFIC_CHANGES
624 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
625 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
626 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
627 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
629 {256, 491520}, /* 60 pages of 2M*/
630 {512, 12288}, /* 3 pages of 2M */
631 {2048, 99328}, /* 97 Pages of 2M */
632 {8192, 75008}, /* 293 Pages of 2M */
633 {16384, 4096} /* 32 pages of 2M */
638 #ifndef SS_LOCKLESS_MEMORY
640 SS_DFLT_REGION + 1, /* region id */
641 MT_MAX_BKTS, /* number of buckets */
642 /*MT_HEAP_SIZE 7194304 */ 10485760, /* heap size */
644 //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
645 //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
646 //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
647 //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
655 #endif /* SS_LOCKLESS_MEMORY */
656 #endif /* INTEL_WLS */
657 #ifdef SS_LOCKLESS_MEMORY
659 SS_DFLT_REGION + 1, /* region id */
660 MT_MAX_BKTS, /* number of buckets */
661 MT_HEAP_SIZE, /* heap size */
663 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
664 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
665 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
666 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
670 SS_DFLT_REGION + 2, /* region id */
671 MT_MAX_BKTS, /* number of buckets */
672 MT_HEAP_SIZE, /* heap size */
674 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
675 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
676 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
677 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
681 SS_DFLT_REGION + 3, /* region id */
682 MT_MAX_BKTS, /* number of buckets */
683 MT_HEAP_SIZE, /* heap size */
685 {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */
686 {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */
687 {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */
688 {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS} /* block size, no. of blocks */
691 #endif /* SS_LOCKLESS_MEMORY */
695 /* mt003.301 Modifications - File Based task registration made
696 * common for both MULTICORE and NON-MULTICORE
697 * bucket info, as different regions may request for different no.
700 PUBLIC MtBktCfg mtBktInfo[MT_MAX_BKTS];
701 PUBLIC S16 msArgc; /* argc */
702 PUBLIC Txt **msArgv; /* argv */
703 PUBLIC S16 msOptInd; /* SGetOpt vars */
704 PUBLIC S8 *msOptArg; /* SGetOpt vars */
708 typedef struct _MtRegMemSz
714 PRIVATE MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
718 /* private variable declarations */
719 /* mt018.201 - change mtCMMRegCfg as array of pointers */
720 PRIVATE CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
721 PRIVATE CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
722 /* mt003.301 - Fixed compilation warnings */
723 /*mt004.301-addede new veriable for FAP*/
724 /*mt010.301 - removed veriable defined for FA*/
730 void mtSetNtlHdl(unsigned int hdl)
735 unsigned int mtGetNtlHdl()
737 return(osCp.ntl.hdl);
744 RETVALUE(osCp.wls.intf);
747 #ifdef XEON_MULTIPLE_CELL_CHANGES
748 EXTERN S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
749 EXTERN S16 smWrReadWlsConfigParams (Void);
752 PRIVATE int SOpenWlsIntf()
755 #define WLS_DEVICE_NAME "/dev/wls"
757 #ifdef XEON_SPECIFIC_CHANGES
758 #ifdef XEON_MULTIPLE_CELL_CHANGES
759 hdl = WLS_Open(gWrWlsDeviceName, 1);
761 hdl = WLS_Open(WLS_DEVICE_NAME, 1);
764 hdl = WLS_Open(WLS_DEVICE_NAME, 0);
771 printf("Could not open WLS Interface \n");
786 * Desc: This function is the entry point for the final binary. It
787 * calls SInit() in the common code. It can be replaced by a
788 * user function if required (SInit() must still be called).
790 * Ret: none on success
801 int argc, /* argument count */
802 char **argv /* argument vector */
805 PUBLIC int main(argc, argv)
806 int argc; /* argument count */
807 char **argv; /* argument vector */
812 #ifdef XEON_MULTIPLE_CELL_CHANGES
813 /* Read the WLS parameters from the file and copy into global control block */
814 if(smWrReadWlsConfigParams() != ROK)
816 fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
818 } /* end of if statement */
824 #endif /* INTEL_WLS */
828 /* mt003.301 Modifications */
831 printf("\n SInit failed, SSI could not start \n");
832 /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
836 /*mt010.301 cleanup part exposed to user*/
847 * Desc: This function is the entry point for the final binary. It
848 * calls SInit() in the common code. It can be replaced by a
849 * user function if required (SInit() must still be called).
851 * Ret: none on success
862 int argc, /* argument count */
863 char **argv /* argument vector */
866 PUBLIC int ssMain(argc, argv)
867 int argc; /* argument count */
868 char **argv; /* argument vector */
885 * initialization functions
890 * Fun: Initialize OS control point
892 * Desc: This function initializes MTSS-specific information
893 * in the OS control point.
903 PUBLIC S16 ssdInitGen
908 PUBLIC S16 ssdInitGen()
911 struct sigaction act;
913 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
919 /*mt014.301 : 4GMX release related changes*/
923 /* mt005.301 : Cavium changes */
924 #ifdef SS_SEUM_CAVIUM
925 /* set group mask for the core */
926 cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
927 #endif /* SS_SEUM_CAVIUM */
929 osCp.dep.sysTicks = 0;
931 /* mt020.201 - Addition for no command line available */
933 /* parse command line */
935 /* mt003.301 Additions */
936 if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
938 printf("\n File Based Memory configuration failed \n");
943 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
944 #ifndef SS_LOCKLESS_MEMORY
945 #ifdef SS_MULTICORE_SUPPORT
946 if(memConfigured == FALSE)
952 /* initialize the started semaphore */
953 if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
958 /* mt028.201 added compile time flag to allow not to mask signals */
960 /* mask all signals in the main thread */
962 sigdelset(&set, SIGINT);
963 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
964 sigdelset(&set, SIGSEGV);
965 sigdelset(&set, SIGUSR2);
966 sigdelset(&set, SIGILL);
967 #ifdef XEON_SPECIFIC_CHANGES
968 sigdelset(&set, SIGABRT);
969 sigdelset(&set, SIGTERM);
970 sigdelset(&set, SIGHUP);
973 pthread_sigmask(SIG_SETMASK, &set, NULLP);
974 #endif /* UNMASK_SIG */
976 /* install a SIGINT handler to shutdown */
977 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
979 /*Initialize SIGSEGV Signal */
980 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
982 memset(&sa, 0, sizeof(struct sigaction));
983 sigemptyset(&sa.sa_mask);
984 sa.sa_sigaction = signal_segv;
985 sa.sa_flags = SA_SIGINFO;
986 #ifndef XEON_SPECIFIC_CHANGES
987 sigaction(SIGSEGV, &sa, NULL);
989 memset(&sa, 0, sizeof(struct sigaction));
990 sigemptyset(&sa.sa_mask);
991 sa.sa_sigaction = signal_segv;
992 sa.sa_flags = SA_SIGINFO;
994 sigaction(SIGILL, &sa, NULL);
996 if(sigaction(SIGILL, &sa, NULL) != 0)
998 printf("Failed to process sigaction for the SIGILL\n");
1001 if(sigaction(SIGSEGV, &sa, NULL) != 0)
1003 printf("Failed to process sigaction for the SIGSEGV\n");
1006 if(sigaction(SIGABRT, &sa, NULL) != 0)
1008 printf("Failed to process sigaction for the SIGABRT\n");
1011 if(sigaction(SIGTERM, &sa, NULL) != 0)
1013 printf("Failed to process sigaction for the SIGTERM\n");
1016 if(sigaction(SIGHUP, &sa, NULL) != 0)
1018 printf("Failed to process sigaction for the SIGHUP\n");
1023 signal (SIGSEGV, mtSigSegvHndlr);
1024 signal (SIGKILL, mtSigSegvHndlr);
1025 signal (SIGUSR2, mtSigUsr2Hndlr);
1030 signal (SIGINT, mtStopHndlr);
1033 act.sa_handler = mtIntSigHndlr;
1034 sigfillset(&act.sa_mask);
1036 if (sigaction(SIGINT, &act, NULLP) != 0)
1042 /* mt040.201 initialise random seed */
1043 osCp.dep.randSeed = time(NULLP);
1051 * Fun: De-initialize OS control point
1053 * Desc: This function reverses the initialization in ssdInitGen().
1063 PUBLIC Void ssdDeinitGen
1068 PUBLIC Void ssdDeinitGen()
1074 sem_destroy(&osCp.dep.ssStarted);
1079 #ifdef SS_LOCKLESS_MEMORY
1083 * Fun: ssPutDynMemBlkSet
1085 * Desc: Returns the set of dynamic Blocks into the global region
1088 * Ret: ROK - successful,
1089 * RFAILED - unsuccessful.
1097 PUBLIC S16 ssPutDynMemBlkSet
1099 U8 bktIdx, /* Index to bucket list */
1100 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is needs to be
1101 added to global region */
1104 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1105 U8 bktIdx; /* Index to bucket list */
1106 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1107 added to global region */
1110 CmMmGlobRegCb *globReg;
1111 CmMmGlobalBktCb *bktCb;
1115 globReg = osCp.globRegCb;
1117 #if (ERRCLASS & ERRCLS_INT_PAR)
1118 if(bktIdx >= globReg->numBkts)
1122 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1124 bktCb = &(globReg->bktTbl[bktIdx]);
1126 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1128 blkPtr = dynMemSetElem->nextBktPtr;
1129 dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1130 free((Void *)blkPtr);
1133 dynMemSetElem->nextBktPtr = NULLP;
1134 dynMemSetElem->numFreeBlks = 0;
1141 * Fun: ssGetDynMemBlkSet
1143 * Desc: Gets the set of dynamic memory blocks from the global region
1146 * Ret: ROK - successful,
1147 * RFAILED - unsuccessful.
1155 PUBLIC S16 ssGetDynMemBlkSet
1157 U8 bktIdx, /* Index to bucket list */
1158 CmMmBlkSetElement *dynMemSetElem /* Memory set element which is updated
1159 with new set values */
1162 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1163 U8 bktIdx; /* Index to bucket list */
1164 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1165 with new set values */
1169 CmMmGlobRegCb *globReg;
1170 CmMmGlobalBktCb *bktCb;
1175 globReg = osCp.globRegCb;
1177 #if (ERRCLASS & ERRCLS_INT_PAR)
1178 if(bktIdx >= globReg->numBkts)
1182 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1184 bktCb = &(globReg->bktTbl[bktIdx]);
1185 basePtr = &(dynMemSetElem->nextBktPtr);
1187 for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1189 blkPtr = (Data *)malloc(bktCb->size);
1191 basePtr = (CmMmEntry **)blkPtr;
1194 dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1198 } /* ssGetDynMemBlkSet */
1203 * Fun: ssPutDynMemBlkSet
1205 * Desc: Returns the set of dynamic Blocks into the global region
1208 * Ret: ROK - successful,
1209 * RFAILED - unsuccessful.
1217 PUBLIC S16 ssPutDynMemBlkSet
1219 U8 bktIdx, /* Index to bucket list */
1220 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is needs to be
1221 added to global region */
1222 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1225 PUBLIC S16 ssPutDynMemBlkSet(bktIdx, dynMemSetElem)
1226 U8 bktIdx; /* Index to bucket list */
1227 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is needs to be
1228 added to global region */
1229 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1232 CmMmGlobRegCb *globReg;
1233 CmMmGlobalBktCb *bktCb;
1235 CmMmBlkSetElement *globMemNode;
1238 TRC1(ssPutDynMemBlkSet);
1240 globReg = osCp.globRegCb;
1242 #if (ERRCLASS & ERRCLS_INT_PAR)
1243 if(bktIdx >= globReg->numBkts)
1247 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1249 bktCb = &(globReg->bktTbl[bktIdx]);
1251 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1252 try lock is used as it is not required to block as it will be taken
1253 in the next go else it will be blocked for lock as we have to get the
1256 SLock(&(bktCb->bucketLock));
1262 /* Get a free node from the free node linked list */
1263 lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1264 if(lstNode == NULLP)
1266 SUnlock(&(bktCb->bucketLock));
1270 cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1272 /* Copy the content of the received element information on to free node
1273 * and add it to valid linked list */
1274 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1275 globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1276 globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1277 dynMemSetElem->numFreeBlks = 0;
1278 dynMemSetElem->nextBktPtr = NULLP;
1280 cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1282 SUnlock(&(bktCb->bucketLock));
1290 * Fun: ssGetDynMemBlkSet
1292 * Desc: Gets the set of dynamic memory blocks from the global region
1295 * Ret: ROK - successful,
1296 * RFAILED - unsuccessful.
1298 * Notes: The parameter doNotBlockForLock specifies whether to block for lock
1305 PUBLIC S16 ssGetDynMemBlkSet
1307 U8 bktIdx, /* Index to bucket list */
1308 CmMmBlkSetElement *dynMemSetElem, /* Memory set element which is updated
1309 with new set values */
1310 U32 doNotBlockForLock /* Boolean whether to block for lock or not */
1313 PUBLIC S16 ssGetDynMemBlkSet(bktIdx, dynMemSetElem)
1314 U8 bktIdx; /* Index to bucket list */
1315 CmMmBlkSetElement *dynMemSetElem; /* Memory set element which is updated
1316 with new set values */
1317 U32 doNotBlockForLock; /* Boolean whether to block for lock or not */
1320 CmMmGlobRegCb *globReg;
1321 CmMmGlobalBktCb *bktCb;
1323 CmMmBlkSetElement *globMemNode;
1326 TRC1(ssGetDynMemBlkSet);
1328 globReg = osCp.globRegCb;
1330 #if (ERRCLASS & ERRCLS_INT_PAR)
1331 if(bktIdx >= globReg->numBkts)
1335 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1337 bktCb = &(globReg->bktTbl[bktIdx]);
1339 /* Lock the global region first. If the doNotBlockForLock is non-zero, the
1340 try lock is used as it is not required to block as it will be taken
1341 in the next go else it will be blocked for lock as we have to get the
1344 SLock(&(bktCb->bucketLock));
1349 lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1351 if(lstNode == NULLP)
1353 SUnlock(&(bktCb->bucketLock));
1357 /* Delete the node from the valid linked list and copy the values of the
1358 * elements of structrues into pointer */
1359 cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1360 globMemNode = (CmMmBlkSetElement *)lstNode->node;
1361 dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1362 dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1364 /* Add this node to the free node linked list */
1365 cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1367 SUnlock(&(bktCb->bucketLock));
1371 } /* ssGetDynMemBlkSet */
1374 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1376 PRIVATE U32 memoryCheckCounter;
1379 PUBLIC U32 isMemThreshReached(
1383 PUBLIC U32 isMemThreshReached(reg)
1387 CmMmGlobRegCb *globReg;
1388 CmMmGlobalBktCb *bktCb;
1391 TRC3(isMemThreshReached)
1393 globReg = osCp.globRegCb;
1395 #if (ERRCLASS & ERRCLS_INT_PAR)
1396 if(bktIdx >= globReg->numBkts)
1400 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1402 bktCb = &(globReg->bktTbl[bktIdx]);
1404 if(gDynMemAlrm[bktIdx])
1406 // printf ("under memory bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1407 SLock(&(bktCb->bucketLock));
1408 if(bktCb->listValidBktSet.count > 25)
1410 gDynMemAlrm[bktIdx] = FALSE;
1411 // printf ("recoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1413 SUnlock(&(bktCb->bucketLock));
1419 if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1421 // printf ("CHECK bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1422 SLock(&(bktCb->bucketLock));
1423 if(bktCb->listValidBktSet.count < 15 )
1424 gDynMemAlrm[bktIdx] = TRUE;
1425 memoryCheckCounter = 0;
1426 SUnlock(&(bktCb->bucketLock));
1432 #endif /* USE_MALLOC */
1433 #endif /* SS_LOCKLESS_MEMORY */
1435 #ifdef SS_USE_ICC_MEMORY
1438 * Fun: Initialize region/pool tables
1440 * Desc: This function initializes MTSS-specific information
1441 * in the region/pool tables and configures the common
1442 * memory manager for use.
1452 PUBLIC Void * ssGetIccHdl
1457 PUBLIC Void * ssGetIccHdl()
1461 CmMmDynRegCb *dynRegCb;
1463 /* Klock work fix ccpu00148484 */
1464 if(!(region < SS_MAX_REGS))
1469 dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb;
1471 RETVALUE(dynRegCb->iccHdl);
1473 #endif /* SS_USE_ICC_MEMORY */
1475 #ifdef T2K_MEM_LEAK_DBG
1476 extern RegionMemLeakInfo regMemLeakInfo;
1477 #endif /* T2K_MEM_LEAK_DBG */
1481 PUBLIC S16 SPartitionWlsMemory()
1486 U64 pageSize[1], hugePageSize;
1489 long int pageSize[1], hugePageSize;
1492 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1494 U8 *regMemStrtAddr = (U8 *)osCp.wls.allocAddr;
1496 gethugepagesizes(pageSize,1);
1497 hugePageSize = pageSize[0];
1498 for (i = 0; i < 1; i++)
1500 mtRegMemSz[i].startAddr = regMemStrtAddr;
1501 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1503 numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1504 reqdSz = numHugePg * hugePageSize;
1505 regMemStrtAddr += reqdSz;
1506 #ifdef T2K_MEM_LEAK_DBG
1507 /* Since wls is region 0 */
1508 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1509 regMemLeakInfo.numActvRegions++;
1510 #endif /* T2K_MEM_LEAK_DBG */
1512 //Store last region addr for validation
1513 mtRegMemSz[i].startAddr = regMemStrtAddr;
1517 #ifdef SS_MEM_WL_DEBUG
1518 PUBLIC Void SChkAddrValid(int type, int region, PTR ptr)
1520 char *tryPtr = NULL;
1521 if(type == 0) //Global
1523 if(ptr < mtRegMemSz[0].startAddr || ptr >=
1524 (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1526 printf("****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1532 if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1534 printf("****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1540 #endif /* SS_MEM_WL_DEBUG */
1542 PUBLIC S16 SPartitionStaticMemory(U8 *startAddr)
1547 U8 *regMemStrtAddr = (U8 *)startAddr;
1550 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1551 for (i = 1; i < mtMemoCfg.numRegions; i++)
1553 mtRegMemSz[i].startAddr = regMemStrtAddr;
1554 reqdSz = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1555 regMemStrtAddr += reqdSz;
1556 #ifdef T2K_MEM_LEAK_DBG
1557 { /* Since region 1 onwards are used for non wls */
1558 regMemLeakInfo.regStartAddr[i] = (U64)mtRegMemSz[i].startAddr;
1559 regMemLeakInfo.numActvRegions++;
1561 #endif /* T2K_MEM_LEAK_DBG */
1565 PUBLIC S16 SAllocateWlsMem()
1573 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1574 memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1576 for (i = 0; i < 1; i++)
1578 /* allocate space for the region */
1579 region = &mtMemoCfg.region[i];
1580 reqdMemSz += region->heapsize;
1581 mtRegMemSz[i].reqdSz += region->heapsize;
1583 for (j = 0; j < region->numBkts; j++)
1585 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1586 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1589 osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1590 //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1592 printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz);
1594 printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1596 SPartitionWlsMemory();
1599 PUBLIC S16 SAllocateStaticMem()
1608 //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1610 //for (i = 0; i < mtMemoCfg.numRegions; i++)
1611 for (i = 1; i < mtMemoCfg.numRegions; i++)
1613 /* allocate space for the region */
1614 region = &mtMemoCfg.region[i];
1615 reqdMemSz += region->heapsize;
1616 mtRegMemSz[i].reqdSz += region->heapsize;
1618 for (j = 0; j < region->numBkts; j++)
1620 reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1621 mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1625 startAddr = malloc(reqdMemSz + (1024 * 10));
1627 printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz);
1629 printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz);
1631 SPartitionStaticMemory(startAddr);
1634 #endif /* INTEL_WLS */
1640 * Fun: Initialize region/pool tables
1642 * Desc: This function initializes MTSS-specific information
1643 * in the region/pool tables and configures the common
1644 * memory manager for use.
1654 PUBLIC S16 ssdInitMem
1659 PUBLIC S16 ssdInitMem()
1662 /* mt018.201 - added local variable */
1667 Txt errMsg[256] = {'\0'};
1668 #ifdef SS_LOCKLESS_MEMORY
1669 CmMmDynRegCb *dynRegCb;
1670 #ifdef SS_USE_ICC_MEMORY
1672 CmMmGlobRegCb *globReg;
1675 #endif /* SS_LOCKLESS_MEMORY */
1679 /* Use the default SSI memory manager if the ICC memory manager is not
1680 * avilable. If ICC memory manager is avilable, it will be used for
1681 * all sharable memory allocation and de-allocation */
1682 #ifdef SS_LOCKLESS_MEMORY
1683 #ifdef SS_USE_ICC_MEMORY
1684 #ifndef YS_PHY_3_8_2
1686 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1688 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1689 if(dynRegCb == NULLP)
1693 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1695 dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1697 dynRegCb->region = i;
1698 cmMmDynRegInit(dynRegCb);
1699 printf("iccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1702 /* ysIccHdl = dynRegCb->iccHdl; */
1705 /* Initialize the global region first */
1706 osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1708 if(osCp.globRegCb == NULLP)
1713 globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1715 for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1717 memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1719 globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1721 globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1723 if(globReg->bktTbl[i].startAddr == NULLP)
1727 globReg->bktTbl[i].poolId = i;
1728 globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1729 globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1730 globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1733 globReg->numBkts = mtGlobMemoCfg.numBkts;
1734 cmMmGlobRegInit(globReg);
1736 /* Initialize the dynamic task regions and sanity check for the theshold
1738 for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1740 dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1741 if(dynRegCb == NULLP)
1745 for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1747 if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold <
1748 mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1749 (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1750 (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1752 #ifdef XEON_SPECIFIC_CHANGES
1757 dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1758 dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1759 dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1760 dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1761 if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1763 dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1766 dynRegCb->region = i;
1767 dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1768 cmMmDynRegInit(dynRegCb);
1770 #endif /* SS_USE_ICC_MEMORY */
1771 #endif /* SS_LOCKLESS_MEMORY */
1773 #ifdef T2K_MEM_LEAK_DBG
1775 /* Initailize mem leak tool memorys for debguing */
1776 regMemLeakInfo.numActvRegions=0;
1777 for(reg=0; reg <SS_MAX_REGS; reg++)
1779 regMemLeakInfo.gMemLeakInfo[reg] = malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1780 memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1781 sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1782 regMemLeakInfo.regStartAddr[reg] = 0;
1785 regMemLeakInfo.regStartAddr[reg] = 0;
1786 if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1788 printf("\n mutex init failed\n");
1794 /* Now allocate WLS memory */
1796 SAllocateStaticMem();
1798 /* mt018.201 - CMM Initialization */
1799 for (i = 0; i < mtMemoCfg.numRegions; i++)
1801 /* allocate space for the region control block */
1802 mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1803 #ifdef TENB_RTLIN_CHANGES
1804 mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1806 if (mtCMMRegCb[i] == NULLP)
1808 sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1809 for the Region:%d control block\n",i);
1811 for (k = 0; k < i; k++)
1813 cmMmRegDeInit(mtCMMRegCb[k]);
1814 free(mtCMMRegCfg[k]->vAddr);
1815 free(mtCMMRegCb[k]);
1816 free(mtCMMRegCfg[k]);
1821 mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1822 #ifdef TENB_RTLIN_CHANGES
1823 mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1825 if (mtCMMRegCfg[i] == NULLP)
1827 for (k = 0; k < i; k++)
1829 cmMmRegDeInit(mtCMMRegCb[k]);
1830 free(mtCMMRegCfg[k]->vAddr);
1831 free(mtCMMRegCb[k]);
1832 free(mtCMMRegCfg[k]);
1834 free(mtCMMRegCb[i]);
1839 /* allocate space for the region */
1840 region = &mtMemoCfg.region[i];
1841 mtCMMRegCfg[i]->size = region->heapsize;
1842 for (j = 0; j < region->numBkts; j++)
1844 /* mt033.201 - addition for including the header size while computing the total size */
1845 #ifdef SSI_DEBUG_LEVEL1
1846 mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1847 (region->bkt[j].numBlks);
1849 mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1850 #endif /* SSI_DEBUG_LEVEL1 */
1853 mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1855 mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1858 #ifdef XEON_SPECIFIC_CHANGES
1859 CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n",
1860 i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1862 #ifdef TENB_RTLIN_CHANGES
1863 mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1866 if (mtCMMRegCfg[i]->vAddr == NULLP)
1868 sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1869 for the Region:%d \n",i);
1871 for (k = 0; k < i; k++)
1873 cmMmRegDeInit(mtCMMRegCb[k]);
1874 free(mtCMMRegCfg[k]->vAddr);
1875 free(mtCMMRegCb[k]);
1876 free(mtCMMRegCfg[k]);
1878 free(mtCMMRegCb[i]);
1879 free(mtCMMRegCfg[i]);
1884 /* set up the CMM configuration structure */
1885 mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
1886 mtCMMRegCfg[i]->chFlag = 0;
1887 mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
1888 mtCMMRegCfg[i]->numBkts = region->numBkts;
1890 for (j = 0; j < region->numBkts; j++)
1892 mtCMMRegCfg[i]->bktCfg[j].size = region->bkt[j].blkSize;
1893 mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
1896 /* initialize the CMM */
1897 #ifdef SS_LOCKLESS_MEMORY
1898 if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1900 if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
1901 #endif /* SS_LOCKLESS_MEMORY */
1903 for (k = 0; k < i; k++)
1905 cmMmRegDeInit(mtCMMRegCb[k]);
1906 free(mtCMMRegCfg[k]->vAddr);
1907 free(mtCMMRegCb[k]);
1908 free(mtCMMRegCfg[k]);
1910 free(mtCMMRegCfg[i]->vAddr);
1911 free(mtCMMRegCb[i]);
1912 free(mtCMMRegCfg[i]);
1917 /* initialize the STREAMS module */
1918 /* mt019.201: STREAMS module will only apply to DFLT_REGION */
1919 if (region->regionId == 0)
1921 if (ssStrmCfg(region->regionId, region->regionId) != ROK)
1923 for (k = 0; k < i; k++)
1925 cmMmRegDeInit(mtCMMRegCb[k]);
1926 free(mtCMMRegCfg[k]->vAddr);
1927 free(mtCMMRegCb[k]);
1928 free(mtCMMRegCfg[k]);
1930 cmMmRegDeInit(mtCMMRegCb[i]);
1931 free(mtCMMRegCfg[i]->vAddr);
1932 free(mtCMMRegCb[i]);
1933 free(mtCMMRegCfg[i]);
1938 /* mt001.301 : Additions */
1939 #ifdef SS_MEM_LEAK_STS
1941 #endif /* SS_MEM_LEAK_STS */
1950 * Fun: De-initialize region/pool tables
1952 * Desc: This function reverses the initialization in ssdInitMem().
1962 PUBLIC Void ssdDeinitMem
1967 PUBLIC Void ssdDeinitMem()
1970 /* mt018.201 - added local variables */
1974 /* mt008.301 Additions */
1975 #ifdef SS_MEM_LEAK_STS
1976 cmDeinitMemLeakMdl();
1977 #endif /* SS_MEM_LEAK_STS */
1979 for (i = 0; i < mtMemoCfg.numRegions; i++)
1981 cmMmRegDeInit(mtCMMRegCb[i]);
1982 free(mtCMMRegCfg[i]->vAddr);
1983 free(mtCMMRegCb[i]);
1984 free(mtCMMRegCfg[i]);
1993 * Fun: Initialize task table
1995 * Desc: This function initializes MTSS-specific information
1996 * in the task table.
2006 PUBLIC S16 ssdInitTsk
2011 PUBLIC S16 ssdInitTsk()
2014 /* mt001.301 : Additions */
2015 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2016 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2018 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2023 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
2024 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2025 /* initialize system task information */
2026 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
2028 osCp.sTskTbl[tskInd].dep.lwpId = 0;
2030 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2037 * Fun: Deinitialize task table
2039 * Desc: This function reverses the initialization perfomed in
2050 PUBLIC Void ssdDeinitTsk
2055 PUBLIC Void ssdDeinitTsk()
2064 #ifdef SS_DRVR_SUPPORT
2067 * Fun: Initialize driver task table
2069 * Desc: This function initializes MTSS-specific information
2070 * in the driver task table.
2080 PUBLIC S16 ssdInitDrvr
2085 PUBLIC S16 ssdInitDrvr()
2090 pthread_attr_t attr;
2096 /* initialize the dependent portion of the driver task entries */
2097 for (i = 0; i < SS_MAX_DRVRTSKS; i++)
2099 osCp.drvrTskTbl[i].dep.flag = FALSE;
2103 /* create pipe for communication between SSetIntPend() and
2104 * the isTskHdlr thread.
2106 if (pipe(osCp.dep.isFildes) != 0)
2112 /* create the isTskHdlr thread */
2113 pthread_attr_init(&attr);
2114 /* mt021.201 - Addition to set stack size */
2115 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2116 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2117 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2118 if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2120 /* mt020.201 - Addition for destroying thread attribute object attr */
2121 pthread_attr_destroy(&attr);
2127 /*mt014.301 : 4GMX release related changes*/
2128 #ifdef SS_4GMX_UCORE
2136 /* mt020.201 - Addition for destroying thread attribute object attr */
2137 pthread_attr_destroy(&attr);
2146 * Fun: Deinitialize driver information
2148 * Desc: This function reverses the initialization performed in
2159 PUBLIC Void ssdDeinitDrvr
2164 PUBLIC Void ssdDeinitDrvr()
2167 TRC0(ssdDeinitDrvr);
2168 /* mt008.301: Terminate the Driver Task on exit */
2169 while(pthread_cancel(osCp.dep.isTskHdlrTID));
2172 TL_Close(AppContext.hUAII);
2173 if (clusterMode == RADIO_CLUSTER_MODE)
2175 TL_Close(AppContext.hUAII_second);
2181 #endif /* SS_DRVR_SUPPORT */
2186 * Fun: Initialize timer table
2188 * Desc: This function initializes MTSS-specific information
2189 * in the timer table.
2199 PUBLIC S16 ssdInitTmr
2204 PUBLIC S16 ssdInitTmr()
2207 pthread_attr_t attr;
2208 struct sched_param param_sched;
2209 /* mt010.21: addition */
2211 #ifdef SS_MULTICORE_SUPPORT
2213 #endif /* SS_MULTICORE_SUPPORT */
2214 #ifdef SS_THR_REG_MAP
2215 U32 threadCreated = FALSE;
2216 #endif /* SS_THR_REG_MAP */
2221 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2222 /* mt010.21: addition */
2223 osCp.dep.tmrTqCp.nxtEnt = 0;
2224 for (i=0; i< SS_MAX_TMRS; i++)
2226 osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2229 #ifdef SS_MULTICORE_SUPPORT
2230 sTsk = ssdAddTmrSTsk();
2235 #endif /* SS_MULTICORE_SUPPORT */
2236 /* create the timer handler thread */
2237 pthread_attr_init(&attr);
2238 /* mt021.201 - Addition to set stack size */
2239 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2240 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2241 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2242 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2243 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2244 pthread_attr_setschedparam(&attr, ¶m_sched);
2247 #ifdef SS_THR_REG_MAP
2248 /* When the thread is created, we check for the memory mapping table if
2249 * threadId can be placed in thread memory map table. If it is not able to place
2250 * threadId is stored in tmporary array. Once thread is created successful,
2251 * thread_cancel is sent for each thread which are created before. All the
2252 * threads are made to wait on sema which is cancel point for thread.
2254 while(threadCreated == FALSE)
2257 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2259 /* mt020.201 - Addition for destroying thread attribute object attr */
2260 pthread_attr_destroy(&attr);
2265 #ifdef SS_THR_REG_MAP
2266 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
2269 #endif /* SS_THR_REG_MAP */
2270 #ifdef SS_MEM_WL_DEBUG
2271 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2274 /* mt020.201 - Addition for destroying thread attribute object attr */
2275 pthread_attr_destroy(&attr);
2284 * Fun: Deinitialize timer table
2286 * Desc: This function reverses the initialization performed in
2297 PUBLIC Void ssdDeinitTmr
2302 PUBLIC Void ssdDeinitTmr()
2305 #ifdef SS_MULTICORE_SUPPORT
2308 #endif /* SS_MULTICORE_SUPPORT */
2312 #ifdef SS_MULTICORE_SUPPORT
2313 ret = SLock(&osCp.sTskTblLock);
2317 #if (ERRCLASS & ERRCLS_DEBUG)
2318 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2319 "Could not lock system task table");
2323 sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2324 /* clean up the system task entry */
2328 SDestroyLock(&sTsk->lock);
2329 ssDestroyDmndQ(&sTsk->dQ);
2332 /* make this entry available in the system task table */
2333 sTsk->nxt = osCp.nxtSTskEntry;
2334 osCp.nxtSTskEntry = 0;
2338 /* unlock the system task table */
2339 SUnlock(&osCp.sTskTblLock);
2341 #endif /* SS_MULTICORE_SUPPORT */
2342 /* mt008.301: Terminate the timer thread on exit */
2343 while(pthread_cancel(osCp.dep.tmrHdlrTID));
2353 * Desc: Pre-tst() initialization.
2363 PUBLIC S16 ssdInitLog
2368 PUBLIC S16 ssdInitLog()
2371 /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2375 pthread_attr_t attr;
2378 #endif /* CONSTDIO */
2383 /* mt008.301: ssdInitFinal changed to ssdInitLog */
2389 osCp.dep.conInFp = (FILE *) stdin;
2390 osCp.dep.conOutFp = (FILE *) stdout;
2391 /* added compile time flag CONRD: mt017.21 */
2395 /* disable canonical input processing */
2396 fd = fileno(osCp.dep.conInFp);
2397 if ((tcgetattr(fd, &tio)) != 0)
2399 printf("Error: disable canonical input processing\n");
2403 tio.c_lflag &= ~ICANON;
2404 tio.c_cc[VMIN] = 1; /* wait for a minimum of 1 character input */
2405 tio.c_cc[VTIME] = 0;
2406 if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2408 printf("Error: while tcsetattr() processing\n");
2412 #endif /* CONSTDIO */
2415 /* set up the input fd to block when no data is available */
2416 fd = fileno(osCp.dep.conInFp);
2417 flags = fcntl(fd, F_GETFL, &flags);
2418 flags &= ~O_NONBLOCK;
2419 if (fcntl(fd, F_SETFL, flags) == -1)
2421 printf("Error: while fcntl processing\n");
2426 /* create the console handler thread */
2427 pthread_attr_init(&attr);
2428 /* mt021.201 - Addition to set stack size */
2429 pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2430 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2431 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2434 if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2436 /* mt020.201 - Addition for destroying thread attribute object attr */
2437 pthread_attr_destroy(&attr);
2439 printf("Error: Logging Thread creation failed \n");
2443 /* mt020.201 - Addition for destroying thread attribute object attr */
2444 pthread_attr_destroy(&attr);
2458 * Desc: This function reverses the initialization performed in
2468 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2470 PUBLIC Void ssdDeinitLog
2475 PUBLIC Void ssdDeinitLog()
2478 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2482 /* mt008.301: Terminate the console reader on exit */
2483 while(pthread_cancel(osCp.dep.conHdlrTID));
2489 /* mt001.301 : Additions */
2494 PUBLIC S16 ssdInitWatchDog
2499 PUBLIC S16 ssdInitWatchDog(port)
2504 Txt prntBuf[PRNTSZE];
2507 #ifdef SS_WATCHDOG_IPV6
2508 struct sockaddr_in6 tmpaddr;
2510 struct sockaddr_in tmpaddr;
2511 #endif /* SS_WATCHDOG_IPV6 */
2512 #ifdef SS_MULTIPLE_PROCS
2513 ProcId procId = SS_WD_WDPROC;
2514 if (SAddProcIdLst(1, &procId) != ROK)
2518 #endif /* SS_MULTIPLE_PROCS */
2520 TRC0(ssdInitWatchDog);
2522 SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2524 /* Create a watch dog system task */
2525 SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2527 /* Create a watch dog reveiver system task */
2528 SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2530 /* Register and attach watch dog TAPA task */
2531 #ifdef SS_MULTIPLE_PROCS
2532 SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2533 SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2535 SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2536 SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2537 #endif /* SS_MULTIPLE_PROCS */
2538 /* Register and attach watch dog receiver TAPA task */
2539 #ifdef SS_MULTIPLE_PROCS
2540 SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2541 SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2543 SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2544 SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2545 #endif /* SS_MULTIPLE_PROCS */
2547 #ifndef SS_MULTIPLE_PROCS
2548 osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2549 osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2551 osCp.wdCp.watchDgPst.srcProcId = procId;
2552 osCp.wdCp.watchDgPst.dstProcId = procId;
2553 #endif /* SS_MULTIPLE_PROCS */
2555 /* Initialise the pst structure */
2556 ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2557 /* Initialize the watch dog timer resolution default is 1 sec */
2559 cmInitTimers(osCp.wdCp.watchDgTmr, (U8)1);
2560 osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2561 osCp.wdCp.watchDgTqCp.tmrLen = 1;
2562 for(idx = 0; idx < 1; idx++)
2564 osCp.wdCp.watchDgTs[idx].first = NULLP;
2565 osCp.wdCp.watchDgTs[idx].tail = NULLP;
2567 #ifdef SS_MULTIPLE_PROCS
2568 SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2570 SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2571 #endif /* SS_MULTIPLE_PROCS */
2573 /* Create the watch dog receiver socket */
2574 osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2575 if(osCp.wdCp.globWd.sock == -1)
2577 sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2581 #ifdef SS_WATCHDOG_IPV6
2582 tmpaddr.sin6_len = sizeof(tmpadDr);
2583 tmpaddr.sin6_family = AF_INET6;
2584 tmpaddr.sin6_addr = in6addr_any;
2585 tmpaddr.sin6_port = htons(port);
2587 tmpaddr.sin_family = AF_INET;
2588 tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2589 tmpaddr.sin_port = htons(port);
2590 #endif /* SS_WATCHDOG_IPV6 */
2592 if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2595 sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2599 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2603 #ifndef SS_MULTIPLE_PROCS
2604 pst.srcProcId = SFndProcId();
2605 pst.dstProcId = SFndProcId();
2607 pst.srcProcId = procId;
2608 pst.dstProcId = procId;
2609 #endif /* SS_MULTIPLE_PROCS */
2610 pst.event = EVTSSHRTBTREQ;
2611 ssdInitWatchDgPst(&pst);
2612 SPstTsk(&pst, mBuf);
2618 PUBLIC S16 ssdInitWatchDgPst
2623 PUBLIC S16 ssdInitWatchDgPst(pst)
2627 TRC1(ssInitWatchDgPst);
2629 pst->selector = SS_LOOSE_COUPLING;
2631 pst->region = DFLT_REGION; /* region */
2632 pst->pool = DFLT_POOL; /* pool */
2634 pst->prior = PRIOR0; /* priority */
2635 pst->route = RTESPEC; /* route */
2637 pst->dstEnt = ENTHB; /* destination entity */
2639 pst->srcEnt = ENTDW; /* source entity */
2645 #ifdef SS_MULTIPLE_PROCS
2647 PUBLIC S16 ssdWatchDgActvTmr
2654 PUBLIC S16 ssdWatchDgActvTmr(proc, ent, inst)
2658 PUBLIC S16 ssdWatchDgActvTmr
2663 PUBLIC S16 ssdWatchDgActvTmr()
2665 #endif /* SS_MULTIPLE_PROCS */
2667 TRC3(ssWatchDgActvTmr);
2669 cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2675 PUBLIC Void ssdWatchDgTmrEvt
2677 PTR cb, /* control block */
2678 S16 event /* timer number */
2681 PUBLIC Void ssdWatchDgTmrEvt(cb, event)
2682 PTR cb; /* control block */
2683 S16 event; /* timer number */
2686 /* mt003.301 Fixed warings */
2690 Txt prntBuf[PRNTSZE];
2694 TRC2(ssWatchDgTmrEvt);
2700 SPrint("Timer Heartbeat Request Expired");
2702 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2707 SLock(&osCp.wdCp.wdLock);
2708 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2710 if(osCp.wdCp.globWd.wdsta[i].status == 0)
2712 sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2714 if(osCp.wdCp.globWd.callback != 0)
2716 osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2720 SUnlock(&osCp.wdCp.wdLock);
2722 if(!osCp.wdCp.globWd.watchdogStop)
2724 ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2725 ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2736 PUBLIC Void ssdStartWatchDgTmr
2743 PUBLIC Void ssdStartWatchDgTmr(cb, event, wait)
2753 Txt prntBuf[PRNTSZE];
2757 TRC2(ssStartWatchDgTmr)
2758 /* mt003.301 Modifications */
2761 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2762 if(event == SS_TMR_HRTBT)
2764 SPrint("\nSTART SS_TMR_HRTBT");
2771 SLock(&osCp.wdCp.wdLock);
2772 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2774 osCp.wdCp.globWd.wdsta[i].status = 0;
2776 SUnlock(&osCp.wdCp.wdLock);
2778 arg.tq = osCp.wdCp.watchDgTs;
2779 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2780 arg.timers = osCp.wdCp.watchDgTmr;
2781 arg.cb = (PTR)NULLP;
2783 arg.wait = osCp.wdCp.globWd.timeout = wait;
2792 PUBLIC Void ssdStopWatchDgTmr
2798 PUBLIC Void ssdStopWatchDgTmr(cb, event)
2806 Txt prntBuf[PRNTSZE];
2810 TRC2(ssStopWatchDgTmr)
2811 /* mt003.301 Modifications */
2814 sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2815 if(event == SS_TMR_HRTBT)
2817 SPrint("STOP SS_TMR_HRTBT");
2821 SLock(&osCp.wdCp.wdLock);
2822 for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2824 osCp.wdCp.globWd.wdsta[i].status = 0;
2826 SUnlock(&osCp.wdCp.wdLock);
2829 arg.tq = osCp.wdCp.watchDgTs;
2830 arg.tqCp = &osCp.wdCp.watchDgTqCp;
2831 arg.timers = osCp.wdCp.watchDgTmr;
2832 arg.cb = (PTR)NULLP;
2843 PUBLIC S16 ssdSndHrtBtMsg
2849 PUBLIC S16 ssdSndHrtBtMsg(restart, type)
2857 Txt prntBuf[PRNTSZE];
2859 struct sockaddr_in tmpaddr;
2860 char hbMsg[SS_WD_HB_MSG_SIZE];
2864 TRC2(ssdSndHrtBtReq)
2868 sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2872 /* Pack the message */
2873 strcpy(hbMsg, "<HB>REQ</HB>");
2875 /* Send the heartbeat messages to all the configured nodes */
2876 SLock(&osCp.wdCp.wdLock);
2877 for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2879 if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2884 /* Identify the destination node */
2885 #ifdef SS_WATCHDOG_IPV6
2886 tmpaddr.sin6_len = sizeof(tmpaddr);
2887 tmpaddr.sin6_family = AF_INET6;
2888 tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2889 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2891 tmpaddr.sin_family = AF_INET;
2892 tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2893 tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2894 #endif /* SS_WATCHDOG_IPV6 */
2896 err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2900 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2901 inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2908 sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2913 SUnlock(&osCp.wdCp.wdLock);
2918 #endif /* SS_WATCHDOG */
2922 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2928 * Desc: This function gets command line options.
2938 PRIVATE Void mtGetOpts
2943 PRIVATE Void mtGetOpts()
2951 FILE *memOpt; /* memory options file pointer */
2954 /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2960 /*KWORK_FIX: Initializing the variable for avoidning corruption */
2962 /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2968 #ifdef SS_LOCKLESS_MEMORY
2984 osCp.dep.fileOutFp = (FILE *)NULLP;
2986 /* initialize memOpt */
2987 memOpt = (FILE *) NULLP;
2994 while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2999 /* mt001.301 : Additions */
3000 #ifdef SS_MEM_LEAK_STS
3002 cmMemOpenMemLkFile(msOptArg);
3006 osCp.dep.fileOutFp = fopen(msOptArg, "w");
3009 fileBasedMemCfg = TRUE;
3010 memOpt = fopen(msOptArg, "r");
3012 /* if file does not exist or could not be opened then use the
3013 * default memory configuration as defined in mt_ss.h
3015 if (memOpt == (FILE *) NULLP)
3017 sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
3018 be opened, using default mem configuration\n", msOptArg);
3023 while (fgets((Txt *)line, 256, memOpt) != NULLP)
3025 if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3031 case 0: /*** INPUT: Number of regions ***/
3032 sscanf(line, "%ld", (long *) &numReg);
3033 mtMemoCfg.numRegions = numReg;
3034 if(mtMemoCfg.numRegions > SS_MAX_REGS)
3036 printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3042 case 1: /*** INPUT: Number of buckets and number of Pools ***/
3043 sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3044 if(numBkts > MT_MAX_BKTS)
3046 printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3050 if(numPools > SS_MAX_POOLS_PER_REG)
3052 printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3057 * Delay updation from local variable to global
3058 * structure of number of regions and heap data to
3059 * counter error conditions present above.
3061 for(idx = 0; idx < cfgNumRegs; idx++)
3063 mtMemoCfg.region[idx].numBkts = numBkts;
3064 cfgRegInfo[idx].region = idx;
3065 cfgRegInfo[idx].numPools = numPools;
3067 * Initialize the pool info as static type with size zero
3069 for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3071 cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3072 cfgRegInfo[idx].pools[poolIdx].size = 0;
3077 case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3078 if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3080 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3082 if(bktIdx >= numBkts)
3084 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3089 mtBktInfo[bktIdx].blkSize = bktSz;
3091 if(bktUpdtCnt == numBkts)
3093 i++; /*done reading bkt info, start reading individual region info*/
3097 case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3098 sscanf(line,"%ld",(long *) ®Id);
3099 if(regId >= mtMemoCfg.numRegions)
3101 printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3102 #ifndef XEON_SPECIFIC_CHANGES
3107 mtMemoCfg.region[regId].regionId = regId;
3110 case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3111 if(bktUpdtCnt < numBkts)
3113 sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3114 if(bktIdx >= numBkts)
3116 printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3121 if(bktIdx < MT_MAX_BKTS)
3123 mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3124 mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3125 cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3126 cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3129 if(bktUpdtCnt == numBkts)
3136 case 5: /* INPUT: Heapsize ***/
3137 sscanf(line, "%ld", (long *) &heapSz);
3138 mtMemoCfg.region[regId].heapsize = heapSz;
3140 if(regUpdtCnt != mtMemoCfg.numRegions)
3149 #ifdef SS_LOCKLESS_MEMORY
3151 sscanf(line, "%ld", (long *) &numBkts);
3152 mtGlobMemoCfg.numBkts = numBkts;
3153 #ifndef XEON_SPECIFIC_CHANGES
3154 mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3157 #ifdef XEON_SPECIFIC_CHANGES
3158 CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3159 mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3160 for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3162 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3165 mtDynMemoCfg.region[idx].regionId = idx;
3166 mtDynMemoCfg.region[idx].numBkts = numBkts;
3174 if(bktUpdtCnt < numBkts)
3176 sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3177 (long *) &bktSz, (long *) &bktNum,
3178 (long *) &bktSetSize, (long *) &bktRelThr,
3179 (long *) &bktAqurThr);
3180 /* Klock work fix ccpu00148484 */
3181 if(bktIdx < SS_MAX_POOLS_PER_REG)
3183 mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3184 mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3185 mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3186 #ifdef XEON_SPECIFIC_CHANGES
3187 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3188 bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3189 mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize);
3191 if(bktIdx >= SS_MAX_POOLS_PER_REG)
3193 printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3199 for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3201 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3202 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3203 #ifdef XEON_SPECIFIC_CHANGES
3204 CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3205 bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3206 mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3212 #ifdef XEON_SPECIFIC_CHANGES
3213 if(bktUpdtCnt == numBkts)
3219 case 8: /* INPUT: Global Heapsize ***/
3220 sscanf(line, "%ld", (long *) &heapSz);
3221 mtGlobMemoCfg.heapSize = heapSz;
3222 CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3230 memConfigured = FALSE;
3234 memConfigured = TRUE;
3242 /* mt028.201: modification: multiple procs support related changes */
3243 #ifndef SS_MULTIPLE_PROCS
3246 osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3248 osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3251 #else /* SS_MULTIPLE_PROCS */
3255 procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3257 procId = (ProcId) strtol(msOptArg, NULLP, 0);
3259 SAddProcIdLst(1, &procId);
3262 #endif /* SS_MULTIPLE_PROCS */
3266 osCp.configFilePath = msOptArg;
3290 * Desc: Get options from command line
3292 * Ret: option - success
3294 * EOF - end of options
3296 * Notes: Handles command lines like the following
3299 * then command line should look like this...
3300 * -a foo -b foo1 -c -d foo
3304 * while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3309 * nloops = atoi(msArgv[msOptInd]);
3312 * state1 = atoi(msArgv[msOptInd]);
3325 int argc, /* argument count */
3326 char **argv, /* argument value */
3327 char *opts /* options */
3330 PUBLIC S16 SGetOpt(argc, argv, opts)
3331 int argc; /* argument count */
3332 char **argv; /* argument value */
3333 char *opts; /* options */
3336 /* mt020.201 - Removed for no command line */
3345 /* mt020.201 - Addition for no command line */
3357 /*mt013.301 : Changes as per coding standards*/
3358 if (msOptInd >= (S16) argc || argv[msOptInd][0] == '\0')
3364 if (!strcmp(argv[msOptInd], "--"))
3369 else if (argv[msOptInd][0] != '-')
3377 c = argv[msOptInd][sp];
3378 if (c == ':' || (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3380 if (argv[msOptInd][++sp] == '\0')
3391 if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3394 if (++msOptInd >= (S16) argc)
3399 else msOptArg = argv[msOptInd++];
3406 if (argv[msOptInd][++sp] == '\0')
3418 #endif /* NOCMDLINE */
3426 * Desc: This function starts system services execution; the
3427 * permanent tasks are started and the system enters a
3438 PUBLIC Void ssdStart
3443 PUBLIC Void ssdStart()
3452 /* mt025.201 - Modification for adding lock to timer handler */
3453 for (i = 0; i <= SS_MAX_STSKS + 5; i++)
3455 sem_post(&osCp.dep.ssStarted);
3464 * indirect interface functions to system services service user
3470 * Fun: ssdAttachTTsk
3472 * Desc: This function sends the initial tick message to a TAPA
3473 * task if the task is a permanent task.
3483 PUBLIC S16 ssdAttachTTsk
3485 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3488 PUBLIC S16 ssdAttachTTsk(tTsk)
3489 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3497 TRC0(ssdAttachTTsk);
3500 if (tTsk->tskType == SS_TSK_PERMANENT)
3502 /* Send a permanent tick message to this task, to start
3505 ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3508 #if (ERRCLASS & ERRCLS_DEBUG)
3509 MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3514 mInfo = (SsMsgInfo *)mBuf->b_rptr;
3515 mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3517 /* set up post structure */
3518 /* mt028.201: modification: multiple procs support related changes */
3519 #ifndef SS_MULTIPLE_PROCS
3520 mInfo->pst.dstProcId = SFndProcId();
3521 mInfo->pst.srcProcId = SFndProcId();
3522 #else /* SS_MULTIPLE_PROCS */
3523 mInfo->pst.dstProcId = tTsk->proc;
3524 mInfo->pst.srcProcId = tTsk->proc;
3525 #endif /* SS_MULTIPLE_PROCS */
3526 mInfo->pst.selector = SEL_LC_NEW;
3527 mInfo->pst.region = DFLT_REGION;
3528 mInfo->pst.pool = DFLT_POOL;
3529 mInfo->pst.prior = PRIOR3;
3530 mInfo->pst.route = RTESPEC;
3531 mInfo->pst.event = 0;
3532 mInfo->pst.dstEnt = tTsk->ent;
3533 mInfo->pst.dstInst = tTsk->inst;
3534 mInfo->pst.srcEnt = tTsk->ent;
3535 mInfo->pst.srcInst = tTsk->inst;
3537 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3538 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3544 #if (ERRCLASS & ERRCLS_DEBUG)
3545 MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3546 "Could not write to demand queue");
3559 * Fun: ssdDetachTTsk
3561 * Desc: Does nothing.
3571 PUBLIC S16 ssdDetachTTsk
3573 SsTTskEntry *tTsk /* pointer to TAPA task entry */
3576 PUBLIC S16 ssdDetachTTsk(tTsk)
3577 SsTTskEntry *tTsk; /* pointer to TAPA task entry */
3580 TRC0(ssdDetachTTsk);
3589 * Fun: ssdCreateSTsk
3591 * Desc: This function creates a system task. A thread is started
3592 * on the system task handler function defined later.
3602 PUBLIC S16 ssdCreateSTsk
3604 SsSTskEntry *sTsk /* pointer to system task entry */
3607 PUBLIC S16 ssdCreateSTsk(sTsk)
3608 SsSTskEntry *sTsk; /* pointer to system task entry */
3611 pthread_attr_t attr;
3612 /* struct sched_param param_sched;*/
3614 #ifdef SS_THR_REG_MAP
3615 U32 threadCreated = FALSE;
3618 TRC0(ssdCreateSTsk);
3621 #ifdef SS_SINGLE_THREADED
3622 /* mt001.301 : Additions */
3624 #ifdef SS_MULTICORE_SUPPORT
3625 if (osCp.numSTsks > 1)
3627 if (osCp.numSTsks > 0)
3628 #endif /* SS_MULTICORE_SUPPORT */
3630 #ifdef SS_MULTICORE_SUPPORT
3631 if (osCp.numSTsks > 3)
3633 if (osCp.numSTsks > 2)
3634 #endif /* SS_MULTICORE_SUPPORT */
3635 #endif /* SS_WATCHDOG */
3642 /* set the current executing entity and instance IDs to
3643 * 'not configured'. create the lock to access them.
3645 sTsk->dep.ent = ENTNC;
3646 sTsk->dep.inst = INSTNC;
3649 /* create the thread */
3650 pthread_attr_init(&attr);
3651 ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3653 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3654 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3655 if (sTsk->tskPrior == 0)
3657 printf("Creating RT thread #######################\n");
3658 #ifdef SS_THR_REG_MAP
3659 /* When the thread is created, we check for the memory mapping table if
3660 * threadId can be placed in thread memory map table. If it is not able to place
3661 * threadId is stored in tmporary array. Once thread is created successful,
3662 * thread_cancel is sent for each thread which are created before. All the
3663 * threads are made to wait on sema which is cancel point for thread.
3665 while(threadCreated == FALSE)
3668 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlrT2kL2, (Ptr)sTsk)) != 0)
3671 pthread_attr_destroy(&attr);
3673 #if (ERRCLASS & ERRCLS_DEBUG)
3674 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3679 #ifdef SS_THR_REG_MAP
3680 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3688 #ifdef SS_THR_REG_MAP
3689 /* When the thread is created, we check for the memory mapping table if
3690 * threadId can be placed in thread memory map table. If it is not able to place
3691 * threadId is stored in tmporary array. Once thread is created successful,
3692 * thread_cancel is sent for each thread which are created before. All the
3693 * threads are made to wait on sema which is cancel point for thread.
3695 while(threadCreated == FALSE)
3698 if ((pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk)) != 0)
3701 /* mt020.201 - Addition for destroying thread attribute object attr */
3702 pthread_attr_destroy(&attr);
3704 #if (ERRCLASS & ERRCLS_DEBUG)
3705 MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3710 #ifdef SS_THR_REG_MAP
3711 threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId,
3718 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3719 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3721 static U32 stLwpId = 3;
3722 sTsk->dep.lwpId = ++stLwpId;
3724 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3726 /* mt020.201 - Addition for destroying thread attribute object attr */
3727 pthread_attr_destroy(&attr);
3734 PUBLIC int SCreatePThread
3737 pthread_attr_t* attr,
3738 void *(*start_routine) (void *),
3742 PUBLIC int SCreatePThread(tid, attr, start_routine, arg)
3744 pthread_attr_t* attr;
3745 void *(*start_routine) (void *);
3750 #ifdef SS_THR_REG_MAP
3751 U32 threadCreated = FALSE;
3754 SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3755 /* Klock work fix ccpu00148484 */
3756 if(threadArg == NULLP)
3760 threadArg->argument = arg;
3761 threadArg->start_routine = start_routine;
3763 TRC0(SCreatePThread);
3765 printf("Creating thread here %s %d\n", __FILE__, __LINE__);
3767 #ifdef SS_THR_REG_MAP
3768 /* When the thread is created, we check for the memory mapping table if
3769 * threadId can be placed in thread memory map table. If it is not able to place
3770 * threadId is stored in tmporary array. Once thread is created successful,
3771 * thread_cancel is sent for each thread which are created before. All the
3772 * threads are made to wait on sema which is cancel point for thread.
3774 while(threadCreated == FALSE)
3777 /*pthreadCreateHdlr */
3778 if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3783 #ifdef SS_THR_REG_MAP
3784 threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3795 * Fun: Set Pthread Attributes
3797 * Desc: This function is used to set various explicit
3798 * pthread attributes like, priority scheduling,etc
3809 PRIVATE S16 ssdSetPthreadAttr
3812 pthread_attr_t *attr
3815 PRIVATE S16 ssdSetPthreadAttr(sTsk, attr)
3817 pthread_attr_t *attr
3820 struct sched_param param;
3822 TRC0 (ssdSetPthreadAttr)
3824 SMemSet(¶m, 0, sizeof(param));
3826 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3827 param.sched_priority = 100 - 1 - tskPrior;
3829 param.sched_priority = 100 - 10 - tskPrior;
3832 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3833 /* TODO:: This can be avoided by reducing the priority
3834 * of iccserv thread in l1_master.sh*/
3836 if (clusterMode == RADIO_CLUSTER_MODE)
3838 if(tskPrior == PRIOR1)
3840 param.sched_priority = 91;
3847 printf("Set priority %u\n", param.sched_priority);
3849 /* Set Scheduler to explicit, without this non of the below
3850 pthread attr works */
3851 #ifdef TENB_RTLIN_CHANGES
3852 pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3855 pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3856 pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3857 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3858 #ifdef TENB_RTLIN_CHANGES
3859 pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3861 pthread_attr_setschedparam(attr, ¶m);
3865 } /* ssdSetPthreadAttr */
3867 /************* multi-core support **************/
3868 /*mt013.301 :Added SS_AFFINITY_SUPPORT */
3869 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3873 * Fun: Get the current core/cpu affinity for a thread/lwp
3875 * Desc: This function is used to get the current processor/core
3876 * affinity for a a system task (thread/lwp). It sets the
3877 * affinity based on the mode supplied by the caller.
3880 * RFAILED - failed, general (optional)
3888 PUBLIC S16 ssdGetAffinity
3890 SSTskId *tskId, /* filled in with system task ID */
3891 U32 *coreId /* the core/processor id to which the affinity is set */
3894 PUBLIC S16 ssdGetAffinity(tskId, coreId)
3895 SSTskId *tskId; /* filled in with system task ID */
3896 U32 *coreId; /* the core/processor id to which the affinity is set */
3907 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3913 TRC0(ssdGetAffinity);
3915 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3917 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3919 tId = osCp.sTskTbl[tskInd].dep.tId;
3924 /* if tskId is not found in the tskTbl */
3925 if (tskInd == SS_MAX_STSKS)
3927 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3932 /* initialize the cpu mask */
3935 /* set thread affinity for linux */
3936 if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3938 #if (ERRCLASS & ERRCLS_DEBUG)
3939 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3942 } /* end if pthread_setaffinity fails */
3944 for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3946 if (CPU_ISSET (cpuInd, & cpuSet))
3955 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
3957 if (osCp.sTskTbl[tskInd].tskId == *tskId)
3959 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3964 /* if tskId is not found in the tskTbl */
3965 if (tskInd == SS_MAX_STSKS)
3967 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3971 /* set thread affinity for Solaris */
3972 if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3974 #if (ERRCLASS & ERRCLS_DEBUG)
3975 MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3978 } /* end if processor_bind fails */
3981 #endif /* SS_LINUX */
3985 } /* ssdGetAffinity */
3990 * Fun: Set the core/cpu affinity for a thread/lwp
3992 * Desc: This function is used to set processor/core affinity for a
3993 * a system task (thread/lwp). It sets the affinity based on the
3994 * mode supplied by the caller.
3997 * RFAILED - failed, general (optional)
4005 PUBLIC S16 ssdSetAffinity
4007 SSTskId *tskId, /* filled in with system task ID */
4008 U32 coreId /* the core/processor id to which the affinity has to be set */
4011 PUBLIC S16 ssdSetAffinity(tskId, coreId)
4012 SSTskId *tskId; /* filled in with system task ID */
4013 U32 coreId; /* the core/processor id to which the affinity has to be set */
4022 /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
4029 TRC0(ssdSetAffinity)
4032 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4034 /* Here tskId can not be used as index as the task may be terminated if
4035 there is a TERM even for that tsk, thus breaking the task Id numbering
4037 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4039 tId = osCp.sTskTbl[tskInd].dep.tId;
4044 /* if tskId is not found in the tskTbl */
4045 if (tskInd == SS_MAX_STSKS)
4047 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4051 /* initialize the cpu mask */
4054 /* set the cpu mask */
4055 CPU_SET(coreId, &cpuSet);
4057 /* set thread affinity for linux */
4058 if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
4060 #if (ERRCLASS & ERRCLS_DEBUG)
4061 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4064 } /* end if pthread_setaffinity fails */
4068 for (tskInd = 0; tskInd < SS_MAX_STSKS; tskInd++)
4070 /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable in dep */
4071 if (osCp.sTskTbl[tskInd].tskId == *tskId)
4073 lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
4078 /* if tskId is not found in the tskTbl */
4079 if (tskInd == SS_MAX_STSKS)
4081 MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
4085 /* set thread affinity for Solaris */
4086 if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4088 #if (ERRCLASS & ERRCLS_DEBUG)
4089 MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4092 } /* end if processor_bind fails */
4095 #endif /* SS_LINUX */
4097 } /* ssdSetAffinity */
4099 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4100 /************ end multi-core support *************/
4105 * Fun: ssdDestroySTsk
4107 * Desc: This function destroys a system task. A terminate
4108 * event message is sent to the thread function.
4118 PUBLIC S16 ssdDestroySTsk
4120 SsSTskEntry *sTsk /* pointer to system task entry */
4123 PUBLIC S16 ssdDestroySTsk(sTsk)
4124 SsSTskEntry *sTsk; /* pointer to system task entry */
4131 TRC0(ssdDestroySTsk);
4134 /* we send a message to this system task to tell it to die */
4135 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4138 #if (ERRCLASS & ERRCLASS_DEBUG)
4139 MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4145 mInfo = (SsMsgInfo *)mBuf->b_rptr;
4146 mInfo->eventInfo.event = SS_EVNT_TERM;
4148 if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4152 #if (ERRCLASS & ERRCLASS_DEBUG)
4153 MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4154 "Could not write to demand queue");
4164 /* mt023.201 - Added SThreadYield function to yield CPU
4168 * Desc: This function defers thread execution to any other ready
4180 PUBLIC S16 SThreadYield
4185 PUBLIC S16 SThreadYield()
4191 /* mt024.201 - seperated Linux and other UNIX implementations
4197 /* Set sleep value to 0 to yield CPU */
4201 RETVALUE(select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4203 #else /* other UNICes */
4205 RETVALUE(sleep(0) == 0 ? ROK : RFAILED);
4207 #endif /* SS_LINUX */
4214 * Fun: Register timer
4216 * Desc: This function is used to register a timer
4217 * function for the service user. System services
4218 * will invoke the timer activation function
4219 * passed to it at the specified intervals.
4223 * Notes: Timing is handled by the common timers. The
4224 * ticks are handled by a thread that uses
4225 * nanosleep() and thus timing precision will not
4232 PUBLIC S16 ssdRegTmr
4234 SsTmrEntry *tmr /* pointer to timer entry */
4237 PUBLIC S16 ssdRegTmr(tmr)
4238 SsTmrEntry *tmr; /* pointer to timer entry */
4247 /* initialize common timers */
4248 cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4251 /* start the timer */
4252 arg.tq = osCp.dep.tmrTq;
4253 arg.tqCp = &osCp.dep.tmrTqCp;
4254 arg.timers = tmr->dep.timers;
4259 arg.max = TMR_DEF_MAX;
4260 arg.wait = tmr->interval;
4270 * Fun: Deregister timer
4272 * Desc: This function is used to deregister a timer function.
4282 PUBLIC S16 ssdDeregTmr
4284 SsTmrEntry *tmr /* pointer to timer entry */
4287 PUBLIC S16 ssdDeregTmr(tmr)
4288 SsTmrEntry *tmr; /* pointer to timer entry */
4297 /* stop the timer */
4298 arg.tq = osCp.dep.tmrTq;
4299 arg.tqCp = &osCp.dep.tmrTqCp;
4300 arg.timers = tmr->dep.timers;
4305 arg.max = TMR_DEF_MAX;
4306 arg.wait = tmr->interval;
4316 * Fun: Critical error
4318 * Desc: This function is called when a critical error occurs.
4330 Seq seq, /* sequence number */
4331 Reason reason /* reset reason */
4334 PUBLIC S16 ssdError(seq, reason)
4335 Seq seq; /* sequence number */
4336 Reason reason; /* reset reason */
4347 /* get calling task ID */
4348 tId = pthread_self();
4351 /* set up the message to display */
4352 sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4353 "reason = %d\n\n", (U8)tId, seq, reason);
4357 /* delete all system tasks */
4358 for (i = 0; i < SS_MAX_STSKS; i++)
4360 if (osCp.sTskTbl[i].used
4361 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4363 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4369 pthread_exit(NULLP);
4372 /* won't reach here */
4381 * Desc: This function is called to log an error.
4391 PUBLIC Void ssdLogError
4393 Ent ent, /* Calling layer's entity id */
4394 Inst inst, /* Calling layer's instance id */
4395 ProcId procId, /* Calling layer's processor id */
4396 Txt *file, /* file name where error occured */
4397 S32 line, /* line in file where error occured */
4398 ErrCls errCls, /* error class */
4399 ErrCode errCode, /* layer unique error code */
4400 ErrVal errVal, /* error value */
4401 Txt *errDesc /* description of error */
4404 PUBLIC Void ssdLogError(ent, inst, procId, file, line,
4405 errCls, errCode, errVal, errDesc)
4406 Ent ent; /* Calling layer's entity id */
4407 Inst inst; /* Calling layer's instance id */
4408 ProcId procId; /* Calling layer's processor id */
4409 Txt *file; /* file name where error occured */
4410 S32 line; /* line in file where error occured */
4411 ErrCls errCls; /* error class */
4412 ErrCode errCode; /* layer unique error code */
4413 ErrVal errVal; /* error value */
4414 Txt *errDesc; /* description of error */
4428 /* get calling task ID */
4430 tId = pthread_self();
4436 case ERRCLS_ADD_RES:
4437 errClsMsg = "ERRCLS_ADD_RES";
4440 case ERRCLS_INT_PAR:
4441 errClsMsg = "ERRCLS_INT_PAR";
4445 errClsMsg = "ERRCLS_DEBUG";
4448 /* mt028.201 : Addition - ERRCLS_FTHA changes */
4450 errClsMsg = "ERRCLS_FTHA";
4454 errClsMsg = "INVALID ERROR CLASS!";
4459 /*mt009.301 Fixed 64BIT compilation warnings*/
4462 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4463 "file: %s line: %03d errcode: %05d errcls: %s\n"
4464 "errval: %05d errdesc: %s\n",
4465 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4468 "\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
4469 "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4470 "errval: %05ld errdesc: %s\n",
4471 ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4473 SDisplay(0, errBuf);
4474 /* mt001.301 : Additions */
4475 #ifdef SS_LOGGER_SUPPORT
4477 #endif /* SS_LOGGER_SUPPORT */
4481 /* debug errors halt the system */
4482 if (errCls == ERRCLS_DEBUG)
4484 /* mt001.301 : Additions */
4485 #ifdef SS_LOGGER_SUPPORT
4487 #endif /* SS_LOGGER_SUPPORT */
4488 /* delete all system tasks */
4489 for (i = 0; i < SS_MAX_STSKS; i++)
4491 if (osCp.sTskTbl[i].used
4492 && !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4494 pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4500 pthread_exit(NULLP);
4512 * Fun: Register driver task
4514 * Desc: This function is called to register the handlers for a
4525 PUBLIC S16 ssdRegDrvrTsk
4527 SsDrvrTskEntry *drvrTsk /* driver task entry */
4530 PUBLIC S16 ssdRegDrvrTsk(drvrTsk)
4531 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4534 TRC0(ssdRegDrvrTsk);
4539 /* mt001.30 : Additions */
4542 * Fun: Deregister driver task
4544 * Desc: This function is called to deregister the handlers for a
4555 PUBLIC S16 ssdDeregDrvrTsk
4557 SsDrvrTskEntry *drvrTsk /* driver task entry */
4560 PUBLIC S16 ssdDeregDrvrTsk(drvrTsk)
4561 SsDrvrTskEntry *drvrTsk; /* driver task entry */
4564 TRC0(ssdDeregDrvrTsk);
4575 * mt003.301 Additions - SDeRegTTsk fix
4577 #ifdef SS_MULTIPLE_PROCS
4579 PUBLIC S16 ssdProcTTskTerm
4586 PUBLIC S16 ssdProcTTskTerm(procIdx, tTsk, idx)
4591 #else /*SS_MULTIPLE_PROCS*/
4593 PUBLIC S16 ssdProcTTskTerm
4599 PUBLIC S16 ssdProcTTskTerm(tTsk, idx)
4603 #endif /*SS_MULTIPLE_PROCS*/
4605 #ifdef SS_MULTIPLE_PROCS
4614 TRC0(ssdProcTTskTerm);
4619 /* We check the sTsk element; if it is not NULLP, the
4620 * task is attached. So we have to detach it before
4621 * deregistering the task.
4623 ret = SLock(&osCp.sTskTblLock);
4626 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4629 SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4632 #if (ERRCLASS & ERRCLS_DEBUG)
4633 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4635 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4637 #if (ERRCLASS & ERRCLS_DEBUG)
4638 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4646 #ifdef SS_MULTIPLE_PROCS
4648 if (tTsk->initTsk != NULLP)
4651 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4654 &(osCp.tTskTbl[idx].xxCb));
4656 (Void)(*(tTsk->initTsk))(proc, ent, inst,
4659 &(osCp.tTskTbl[idx].xxCb));
4660 #endif /* USE_MEMCAL */
4662 #endif /* SS_MULTIPLE_PROCS */
4664 if (tTsk->sTsk != NULLP)
4668 sTsk->dep.ent = ent;
4669 sTsk->dep.inst = inst;
4671 for (n = 0; n < SS_MAX_TTSKS; n++)
4673 if (sTsk->tTsks[n] == idx)
4675 sTsk->tTsks[n] = SS_INVALID_IDX;
4681 /* call the implementation to detach the task */
4682 ssdDetachTTsk(tTsk);
4684 sTsk->dep.ent = ENTNC;
4685 sTsk->dep.inst = INSTNC;
4688 /* Now we empty the entry for this task and update the table
4691 #ifdef SS_MULTIPLE_PROCS
4692 osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4693 #else /* SS_MULTIPLE_PROCS */
4694 osCp.tTskIds[ent][inst] = SS_TSKNC;
4695 #endif /* SS_MULTIPLE_PROCS */
4698 #ifdef SS_MULTIPLE_PROCS
4699 tTsk->proc = PROCNC;
4700 #endif /* SS_MULTIPLE_PROCS */
4702 tTsk->inst = INSTNC;
4703 tTsk->tskType = TTUND;
4704 tTsk->initTsk = NULLP;
4705 tTsk->actvTsk = NULLP;
4708 tTsk->nxt = osCp.nxtTTskEntry;
4709 osCp.nxtTTskEntry = idx;
4712 #ifdef SS_MULTIPLE_PROCS
4713 /* mark the control block for this task as invalid */
4714 osCp.tTskTbl[idx].xxCb = NULLP;
4717 SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4718 if ( SUnlock(&osCp.sTskTblLock) != ROK)
4720 #if (ERRCLASS & ERRCLS_DEBUG)
4721 MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4728 //#ifndef SPLIT_RLC_DL_TASK
4729 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4730 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK)
4731 EXTERN Void ysMtTskHdlr(Void);
4732 EXTERN Void ysMtPollPhyMsg(U8 region);
4733 EXTERN Void ysMtRcvPhyMsg(Void);
4735 PUBLIC Void *mtTskHdlrT2kL2
4737 Ptr tskPtr /* pointer to task entry */
4740 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4741 Ptr tskPtr; /* pointer to task entry */
4747 /* wait for SS to come up */
4748 /* It is required to block on this semaphore before starting actual processing of
4749 the thread becasue the creator of this thread might want to cance it without
4750 doing any processing. When this semaphore is released, means the creator gives
4751 the go ahead for actual processing and we should never come back to this point */
4752 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4761 ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4762 * (processes L1 msgs) */
4768 EXTERN Void ysMtTskHdlr(Void);
4769 EXTERN Void YsPhyRecvMsg();
4771 PUBLIC Void *mtTskHdlrT2kL2
4773 Ptr tskPtr /* pointer to task entry */
4776 PUBLIC Void *mtTskHdlrT2kL2(tskPtr)
4777 Ptr tskPtr; /* pointer to task entry */
4783 /* get out the system task entry from the parameter */
4784 sTsk = (SsSTskEntry *) tskPtr;
4786 /* wait for SS to come up */
4787 /* It is required to block on this semaphore before starting actual processing of
4788 the thread becasue the creator of this thread might want to cance it without
4789 doing any processing. When this semaphore is released, means the creator gives
4790 the go ahead for actual processing and we should never come back to this point */
4791 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4794 #ifndef RGL_SPECIFIC_CHANGES
4802 #ifdef V5GTF_SPECIFIC_CHANGES
4805 ysMtTskHdlr(); /* blocks, waiting for messages for L2
4806 * (processes L1 msgs) */
4808 /* get a message from the demand queue */
4810 #ifdef RLC_MAC_DAT_REQ_RBUF
4811 rgDlDatReqBatchProc();
4814 ret = mtTskHdlMsg(sTsk);
4817 /* exit the for loop here */
4820 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4827 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4831 PUBLIC void *pthreadCreateHdlr
4836 PUBLIC void *pthreadCreateHdlr(pthreadCreateArg)
4841 SPThreadCreateArg* pthreadCreateArg = (SPThreadCreateArg*)arg;
4842 /* mt038.201 changed how sem_wait is called */
4843 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4846 pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4854 * Desc: This is the system task handler function. It blocks on
4855 * the system task's demand queue. On receiving a message,
4856 * it identifies the target TAPA task, verifies that the
4857 * TAPA task belongs to this system task and if so, calls
4858 * the activation function of that TAPA task with the
4859 * received message. The task activation function or the
4860 * timer activation function may be called.
4862 * Ret: (thread function)
4870 PUBLIC Void *mtTskHdlr
4872 Ptr tskPtr /* pointer to task entry */
4875 PUBLIC Void *mtTskHdlr(tskPtr)
4876 Ptr tskPtr; /* pointer to task entry */
4882 /* get out the system task entry from the parameter */
4883 sTsk = (SsSTskEntry *) tskPtr;
4886 /* wait for SS to come up */
4888 /* mt038.201 changed how sem_wait is called */
4889 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4891 #ifdef XEON_SPECIFIC_CHANGES
4892 printf("\n**********MT Task Handler********\n");
4896 /* Wait for a message from the demand queue */
4897 #ifdef SS_CDMNDQ_SUPPORT
4898 ret = ssCDmndQWait(&sTsk->dQ);
4900 ret = ssDmndQWait(&sTsk->dQ);
4905 ret = mtTskHdlMsg(sTsk);
4920 * Desc: This is the system task handler function. It blocks on
4921 * the system task's demand queue. On receiving a message,
4922 * it identifies the target TAPA task, verifies that the
4923 * TAPA task belongs to this system task and if so, calls
4924 * the activation function of that TAPA task with the
4925 * received message. The task activation function or the
4926 * timer activation function may be called.
4928 * Ret: (thread function)
4936 PUBLIC S16 mtTskHdlMsg
4941 PUBLIC S16 mtTskHdlMsg(sTsk)
4955 /* mt028.201: modification: multiple procs support related changes */
4956 #ifndef SS_MULTIPLE_PROCS
4958 PAIFTMRS16 tmrActvFnMt = NULLP;
4960 /* mt015.301 Initialized the timer activation functions with NULLP */
4961 PFS16 tmrActvFn = NULLP;
4963 PAIFTMRS16 tmrActvFn;
4965 #endif /* SS_MULTIPLE_PROCS */
4966 /* mt003.301 Modifications */
4967 #ifdef SS_THREAD_PROFILE
4969 #endif /* SS_THREAD_PROFILE */
4972 ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4975 /* nothing to receive */
4979 /* if we can't lock this system task entry, return the message */
4980 ret = SLock(&sTsk->lock);
4984 #if (ERRCLASS & ERRCLS_DEBUG)
4985 MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4986 "Could not lock system task entry");
4996 mBuf2 = mBuf->b_next;
4998 /* find out what kind of message this is */
4999 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5000 #ifdef SS_MEM_WL_DEBUG
5001 mtTskBuffer1 = mBuf2;
5003 mtTskBuffer2 = mBuf2->b_next;
5005 if(mInfo == 0x5050505)
5009 cmAnalyseBtInfo((PTR) mBuf,4);
5011 printf("\n In trouble .... \n");
5013 else if (mInfo == 0x2020202)
5016 cmAnalyseBtInfo((PTR) mBuf,1);
5017 printf("\n In trouble .... \n");
5019 #endif /* SS_MEM_WL_DEBUG */
5020 switch (mInfo->eventInfo.event)
5022 /* this is a termination event, we die */
5024 /* release the message */
5027 /* Unlock the system task entry and lock the system
5028 * task table to clean our entry up.
5030 SUnlock(&sTsk->lock);
5032 ret = SLock(&osCp.sTskTblLock);
5036 #if (ERRCLASS & ERRCLS_DEBUG)
5037 MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
5038 "Could not lock system task table");
5040 /* what to do here? */
5044 /* clean up the system task entry */
5047 /* mt003.301 Modifications - SDeRegTTsk */
5048 /* sTsk->numTTsks = 0; */
5049 SDestroyLock(&sTsk->lock);
5050 ssDestroyDmndQ(&sTsk->dQ);
5052 /* lock for current executing TAPA task ID */
5054 /* make this entry available in the system task table */
5055 sTsk->nxt = osCp.nxtSTskEntry;
5056 for (i = 0; i < SS_MAX_STSKS; i++)
5058 if (sTsk == &osCp.sTskTbl[i])
5060 osCp.nxtSTskEntry = i;
5067 /* unlock the system task table */
5068 SUnlock(&osCp.sTskTblLock);
5073 /* this is a data message or a permanent task keep-alive message */
5075 case SS_EVNT_PERMTICK:
5076 /* message to a task. find the destination task */
5077 /* mt028.201: modification: multiple procs support related changes */
5078 #ifdef SS_MULTIPLE_PROCS
5079 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5081 if (procIdIdx == SS_INV_PROCID_IDX)
5087 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5088 #else /* SS_MULTIPLE_PROCS */
5089 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5090 #endif /* SS_MULTIPLE_PROCS */
5092 /* verify that it hasn't been deregistered */
5093 if (idx == SS_TSKNC)
5099 /* verify that this system task is still running it */
5100 tTsk = &osCp.tTskTbl[idx];
5101 if (tTsk->sTsk != sTsk)
5107 /* set the current executing TAPA task ID */
5108 sTsk->dep.ent = mInfo->pst.dstEnt;
5109 sTsk->dep.inst = mInfo->pst.dstInst;
5111 /* copy the Pst structure into a local duplicate */
5112 for (i = 0; i < (S16) sizeof(Pst); i++)
5113 *(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
5115 /* Give the message to the task activation function. If
5116 * its a normal data message, we pass it, if this is a
5117 * keep-alive message for a permanent task then we pass
5118 * NULLP in place of the message to the task activation
5121 if (mInfo->eventInfo.event == SS_EVNT_DATA)
5123 #ifndef RGL_SPECIFIC_CHANGES
5124 #ifdef SS_TSKLOG_ENABLE
5125 U32 t = MacGetTick();
5128 /* mt003.301 Modifications */
5129 #if SS_THREAD_PROFILE
5130 tTsk->curEvent = nPst.event;
5132 #endif /* SS_THREAD_PROFILE */
5133 tTsk->actvTsk(&nPst, mBuf);
5134 #ifndef RGL_SPECIFIC_CHANGES
5135 #ifdef SS_TSKLOG_ENABLE
5136 SStopTask(t,PID_SSI_TSK);
5139 #if SS_THREAD_PROFILE
5141 tTsk->curEvtTime = (U32)(et2 - et1);
5142 tTsk->totTime += (U64)tTsk->curEvtTime;
5143 #endif /* SS_THREAD_PROFILE */
5147 #if (ERRCLASS & ERRCLS_DEBUG)
5148 /* this message should only come to a permanent task */
5149 if (tTsk->tskType != SS_TSK_PERMANENT)
5151 MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
5155 tTsk->actvTsk(&nPst, NULLP);
5157 /* We need to re-send this message back to ourselves so
5158 * the permanent task continues to run.
5160 /* Check if this task got deregistered or detached
5161 * by the activation function; if so, there's nothing
5162 * more to do here, otherwise go ahead.
5165 if (tTsk->used == TRUE && tTsk->sTsk != NULLP)
5167 ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5168 ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
5172 /* failure here is a real problem */
5175 #if (ERRCLASS & ERRCLS_DEBUG)
5176 MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
5177 "Could not write to demand queue");
5183 /* unset the current executing TAPA task ID */
5184 sTsk->dep.ent = ENTNC;
5185 sTsk->dep.inst = INSTNC;
5190 /* timer event. find the timer entry */
5191 idx = mInfo->eventInfo.u.tmr.tmrIdx;
5193 /* lock the timer table, coz we're going to peek in it */
5194 ret = SLock(&osCp.tmrTblLock);
5198 #if (ERRCLASS & ERRCLS_DEBUG)
5199 MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5200 "Could not lock timer table");
5206 /* Verify that this timer entry is still around and that it
5207 * belongs to our task.
5209 if (osCp.tmrTbl[idx].used == FALSE
5210 /* mt028.201: modification: multiple procs support related changes */
5211 #ifdef SS_MULTIPLE_PROCS
5212 || osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5213 #endif /* SS_MULTIPLE_PROCS */
5214 || osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5215 || osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5217 SUnlock(&osCp.tmrTblLock);
5222 /* mt005.21: addition */
5223 /* set the current executing TAPA task ID */
5224 sTsk->dep.ent = mInfo->pst.dstEnt;
5225 sTsk->dep.inst = mInfo->pst.dstInst;
5227 #ifndef SS_MULTIPLE_PROCS
5229 /*mt006.301 Adding Initializing the tmrActvFnMt*/
5230 tmrActvFnMt = NULLP;
5231 if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5233 tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5239 tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5242 /* unlock the timer table */
5243 SUnlock(&osCp.tmrTblLock);
5245 /* activate the timer function */
5246 /* mt028.201: modification: multiple procs support related changes */
5247 #ifndef SS_MULTIPLE_PROCS
5251 tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5252 osCp.tmrTbl[idx].ownerInst);
5260 tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5261 osCp.tmrTbl[idx].ownerInst);
5262 #endif /* SS_MULTIPLE_PROCS */
5264 /*mt005.21: addition */
5265 /* unset the current executing TAPA task ID */
5266 sTsk->dep.ent = ENTNC;
5267 sTsk->dep.inst = INSTNC;
5270 /* return the message buffer */
5274 * mt003.301 - SDeRegTTsk fix
5276 case SS_EVNT_TTSK_TERM:
5277 #ifdef SS_MULTIPLE_PROCS
5278 procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5280 if (procIdIdx == SS_INV_PROCID_IDX)
5286 idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5287 #else /* SS_MULTIPLE_PROCS */
5288 idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5289 #endif /* SS_MULTIPLE_PROCS */
5291 /* verify that it hasn't been deregistered */
5292 if (idx == SS_TSKNC)
5298 /* verify that this system task is still running it */
5299 tTsk = &osCp.tTskTbl[idx];
5300 if (tTsk->sTsk != sTsk)
5305 #ifdef SS_MULTIPLE_PROCS
5306 ssdProcTTskTerm(procIdIdx, tTsk, idx);
5308 ssdProcTTskTerm(tTsk, idx);
5314 #if (ERRCLASS & ERRCLS_DEBUG)
5315 MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5322 } while (mBuf != NULLP);
5325 /* unlock the system task entry */
5326 SUnlock(&sTsk->lock);
5329 /* yield for other threads */
5330 /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5339 * Fun: mtTmrHdlrPublic
5342 PUBLIC Void mtTmrHdlrPublic
5346 PUBLIC Void mtTmrHdlrPublic()
5349 if (SLock(&osCp.tmrTblLock) != ROK)
5351 #if (ERRCLASS & ERRCLS_DEBUG)
5352 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5356 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5357 /* unlock the timer table */
5358 SUnlock(&osCp.tmrTblLock);
5366 * Desc: The timer handler thread function. Counts time
5367 * and invokes the common timer function on each
5370 * Ret: (thread function)
5377 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5379 PRIVATE Void *mtTmrHdlr
5381 void *parm /* unused */
5384 /* mt009.21: addition */
5385 PRIVATE Void *mtTmrHdlr(parm)
5386 void *parm; /* unused */
5389 /*mt004.301-addede new region*/
5390 /* mt010.301 Removed SS_FAP portion and
5391 * enabled oroginal code in function mtTmrHdlr */
5395 U32 i, cnt, oldTicks, newTicks;
5396 struct timeval tv1,tv2;
5397 /* mt038.201 added return */
5399 /* mt039.201 changes for nanosleep */
5400 struct timespec tsN;
5401 PRIVATE U32 err_in_usec;
5403 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5408 /* mt027.201 - Modification for SRegCfgTmr support */
5409 /* check SS_TICKS_SEC */
5410 if (SS_1MS < SS_TICKS_SEC)
5412 MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5415 /* mt025.201 - Addition to stop timer handler till task registration is done */
5416 /* wait for SS to come up */
5417 /* mt038.201 changed how sem_wait is called */
5418 while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5421 /* mt027.201 - Modification for SRegCfgTmr support */
5422 /* set up parameter to nanosleep() for SS_TICKS_SEC */
5424 ts.tv_nsec = (MT_TICK_CNT * 1000);
5425 /* mt039.201 changes for nanosleep */
5431 if (gettimeofday(&tv1, NULL) == -1)
5433 #if (ERRCLASS & ERRCLS_DEBUG)
5434 MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5435 "Error in clock_gettime");
5445 #ifndef STUB_TTI_HANDLING_5GTF
5446 printf("Returning from mtTmrHdlr()\n");
5451 /* mt039.201 changes for nanosleep */
5452 /* sleep for MT_TICK_CNT milli seconds */
5453 ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5454 while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5456 ts.tv_nsec = tsN.tv_nsec;
5461 if (gettimeofday(&tv2,NULL) == -1)
5463 #if (ERRCLASS & ERRCLS_DEBUG)
5464 MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5465 "Error in clock_gettime");
5469 /*mt013.301 : changed check while calculating timer to fix
5470 * diffrence between MTSS time and real unix time
5472 if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5474 time_int = (tv2.tv_usec - tv1.tv_usec);
5476 else if (tv2.tv_sec > tv1.tv_sec)
5478 time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5480 else /* ts2 < ts1, this will not happen in normal scenario */
5482 /* to make sure cnt = 1 */
5484 time_int = MT_TICK_CNT;
5487 oldTicks = osCp.dep.sysTicks;
5488 osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5489 err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5490 newTicks = osCp.dep.sysTicks;
5491 tv1.tv_usec = tv2.tv_usec;
5492 tv1.tv_sec = tv2.tv_sec;
5494 cnt = newTicks - oldTicks;
5496 while(err_in_usec >= MT_TICK_CNT)
5499 err_in_usec -= MT_TICK_CNT;
5501 if( cnt >= MT_MAX_TICK_CNT_VAL)
5502 cnt = MT_MIN_TICK_CNT_VAL;
5503 /* call the common timer tick handler */
5504 for (i = 0; i < cnt; i++)
5506 /* mt008.301: cmPrcTmr is guarded with a lock */
5507 /* lock the timer table */
5508 if (SLock(&osCp.tmrTblLock) != ROK)
5510 #if (ERRCLASS & ERRCLS_DEBUG)
5511 MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5515 cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5516 /* unlock the timer table */
5517 SUnlock(&osCp.tmrTblLock);
5521 /* mt009.21: addition */
5522 RETVALUE( (Void *) NULLP);
5523 /* will not reach here */
5531 * Desc: Process timer event. Called from the common timer
5532 * code when a timeout occurs.
5542 PUBLIC Void mtTimeout
5544 PTR tCb, /* control block */
5545 S16 evnt /* event */
5548 PUBLIC Void mtTimeout(tCb, evnt)
5549 PTR tCb; /* control block */
5550 S16 evnt; /* event */
5559 #ifndef TENB_RTLIN_CHANGES
5562 /* mt028.201: modification: multiple procs support related changes */
5563 #ifdef SS_MULTIPLE_PROCS
5565 #endif /* SS_MULTIPLE_PROCS */
5566 #ifdef RGL_SPECIFIC_CHANGES
5567 #ifdef MSPD_MLOG_NEW
5568 U32 t = GetTIMETICK();
5575 /* get the timer entry */
5576 tEnt = (SsTmrEntry *) tCb;
5579 /* if the timer was deleted, this will be NULL, so drop it */
5585 /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5588 /* Hmmmm, the timer might have been deleted while we've been
5589 * working at getting here, so we just skip this.
5591 if (tEnt->used == FALSE)
5597 /* Set up and send a timer message to the destination tasks'
5600 #ifndef SS_MULTICORE_SUPPORT
5601 if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5603 #ifdef RGL_SPECIFIC_CHANGES
5604 if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5606 if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5611 #if (ERRCLASS & ERRCLS_DEBUG)
5612 MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5618 mInfo = (SsMsgInfo *)mBuf->b_rptr;
5619 mInfo->eventInfo.event = SS_EVNT_TIMER;
5620 mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5622 mInfo->pst.dstEnt = tEnt->ownerEnt;
5623 mInfo->pst.dstInst = tEnt->ownerInst;
5624 mInfo->pst.srcEnt = tEnt->ownerEnt;
5625 mInfo->pst.srcInst = tEnt->ownerInst;
5626 /* mt028.201: modification: multiple procs support related changes */
5627 #ifndef SS_MULTIPLE_PROCS
5628 mInfo->pst.dstProcId = SFndProcId();
5629 mInfo->pst.srcProcId = SFndProcId();
5630 #else /* SS_MULTIPLE_PROCS */
5631 mInfo->pst.dstProcId = tEnt->ownerProc;
5632 mInfo->pst.srcProcId = tEnt->ownerProc;
5633 #endif /* SS_MULTIPLE_PROCS */
5634 mInfo->pst.selector = SEL_LC_NEW;
5635 #ifndef SS_MULTICORE_SUPPORT
5636 mInfo->pst.region = DFLT_REGION;
5639 mInfo->pst.pool = DFLT_POOL;
5640 mInfo->pst.prior = PRIOR0;
5641 mInfo->pst.route = RTESPEC;
5642 mInfo->pst.event = 0;
5645 #ifndef TENB_RTLIN_CHANGES
5646 /* get a semaphore for the TAPA task table */
5647 SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5652 #if (ERRCLASS & ERRCLS_DEBUG)
5653 MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5661 /* find the owner TAPA task */
5662 /* mt028.201: modification: multiple procs support related changes */
5663 #ifdef SS_MULTIPLE_PROCS
5664 procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5665 idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5666 #else /* SS_MULTIPLE_PROCS */
5667 idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5668 #endif /* SS_MULTIPLE_PROCS */
5669 if (idx == SS_TSKNC)
5671 #ifndef TENB_RTLIN_CHANGES
5672 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5679 /* ensure that the TAPA task is hale and hearty */
5680 tTsk = &osCp.tTskTbl[idx];
5683 #ifndef TENB_RTLIN_CHANGES
5684 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5689 /* Klock work fix ccpu00148484 */
5690 /* write the timer message to the queue of the destination task */
5691 /* mt008.301 : check sTsk before putting into it's DQ */
5692 if (tTsk->sTsk == NULLP)
5694 #ifndef TENB_RTLIN_CHANGES
5695 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5699 #if (ERRCLASS & ERRCLS_DEBUG)
5700 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5701 "Could not write to demand queue");
5706 #ifdef SS_LOCKLESS_MEMORY
5707 mInfo->pst.region = tTsk->sTsk->region;
5708 mInfo->region = tTsk->sTsk->region;
5709 #endif /* SS_LOCKLESS_MEMORY */
5710 if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5711 (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5713 #ifndef TENB_RTLIN_CHANGES
5714 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5718 #if (ERRCLASS & ERRCLS_DEBUG)
5719 MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5720 "Could not write to demand queue");
5725 /* Fix for ccpu00130657 */
5726 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5727 if (tTsk->sTsk->tskPrior == PRIOR0)
5730 WLS_WakeUp(mtGetWlsHdl());
5737 /* release the semaphore for the TAPA task table */
5738 #ifndef TENB_RTLIN_CHANGES
5739 SS_RELEASE_SEMA(&osCp.tTskTblSem);
5743 /* restart the timer */
5744 arg.tq = osCp.dep.tmrTq;
5745 arg.tqCp = &osCp.dep.tmrTqCp;
5746 arg.timers = tEnt->dep.timers;
5747 arg.cb = (PTR) tEnt;
5751 arg.max = TMR_DEF_MAX;
5752 arg.wait = tEnt->interval;
5754 #ifdef RGL_SPECIFIC_CHANGES
5755 #ifdef MSPD_MLOG_NEW
5756 MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5768 * Desc: This thread reads the console and hands over any
5769 * data read to a user function.
5771 * Ret: (thread function)
5779 PRIVATE Void *mtConHdlr
5781 Ptr parm /* unused */
5784 /* mt009.21: addition */
5785 PRIVATE Void *mtConHdlr(parm)
5786 Ptr parm; /* unused */
5793 /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5799 /* check if we have a console input file handle */
5800 if (osCp.dep.conInFp == NULLP)
5806 fd = fileno(osCp.dep.conInFp);
5811 if ((read(fd, &data, 1)) != 1)
5817 /* call rdConQ, defined by the system service user */
5827 #ifdef SS_DRVR_SUPPORT
5830 * Fun: Interrupt service task handler
5832 * Desc: This is the interrupt service task handler. It blocks
5833 * on a pipe from which it reads an isFlag structure. The
5834 * structure indicates which interrupt service task is to
5835 * be executed. The thread identifies the task, calls the
5836 * isTsk function and sends itself a message to repeat
5837 * this operation until it receives a message to cease.
5847 /* mt009.21: addition */
5848 PRIVATE Void *mtIsTskHdlr
5850 Ptr tskPtr /* pointer to task entry */
5853 /* mt009.21: addition */
5854 PRIVATE Void *mtIsTskHdlr(tskPtr)
5855 Ptr tskPtr; /* pointer to task entry */
5858 #if (ERRCLASS & ERRCLS_DEBUG)
5869 if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5874 switch (isFlag.action)
5877 osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5879 /* call the interrupt service task activation function */
5880 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5882 /* send self a message to keep doing this */
5883 isFlag.action = MT_IS_RESET;
5885 #if (ERRCLASS & ERRCLS_DEBUG)
5886 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5887 if (ret != sizeof(isFlag))
5889 MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5890 "write() to pipe failed");
5893 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5900 osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5905 if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5907 /* call the interrupt service task activation function */
5908 osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5910 #if (ERRCLASS & ERRCLS_DEBUG)
5911 /* send self a message to do this again */
5912 ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5914 if (ret != sizeof(isFlag))
5916 MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5917 "write() to pipe failed");
5920 write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5928 /* where did THIS come from?? */
5932 /* mt009.21: addition */
5933 RETVALUE( (Void *) NULLP);
5937 #endif /* SS_DRVR_SUPPORT */
5938 #endif /* L2_L3_SPLIT */
5940 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5944 * Fun: mtIntSigHndlr
5946 * Desc: Exit function, shuts down.
5956 PUBLIC Void mtIntSigHndlr
5961 PUBLIC Void mtIntSigHndlr(arg)
5966 TRC0(mtIntSigHndlr);
5968 osCp.dep.sigEvnt=TRUE;
5971 #ifdef TENB_RTLIN_CHANGES
5979 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5984 * Desc: function, shuts down.
5994 PUBLIC Void mtExitClnup
5999 PUBLIC Void mtExitClnup()
6008 SGetSysTime(&ticks);
6010 sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
6012 sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
6014 #ifdef SS_HISTOGRAM_SUPPORT
6018 osCp.dep.sigEvnt=FALSE;
6020 if (osCp.dep.fileOutFp)
6022 fclose(osCp.dep.fileOutFp);
6030 Void SIncrementTtiCount(Void)
6035 Ticks SGetTtiCount(Void)
6044 * Desc: This function displays a string to a given output
6049 * Notes: Buffer should be null terminated.
6051 * channel 0 is reserved for backwards compatibility
6060 S16 chan, /* channel */
6061 Txt *buf /* buffer */
6064 PUBLIC S16 SDisplay(chan, buf)
6065 S16 chan; /* channel */
6066 Txt *buf; /* buffer */
6071 /* mt020.201 - Fixed typo */
6072 #if (ERRCLASS & ERRCLS_INT_PAR)
6075 MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
6080 #ifndef XEON_SPECIFIC_CHANGES
6081 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6082 ssMemlog(buf, strlen(buf));
6087 /* mt012.301 :FIX for LOG RELATED ISSUE */
6095 if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
6101 if (osCp.dep.fileOutFp)
6102 fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
6103 /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
6106 fflush(osCp.dep.fileOutFp);
6119 * Desc: function, shuts down.
6139 /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
6140 a loop to overcome the child processes being killed upon exiting the
6142 #ifdef SS_LINUX /* this should have already been defined */
6143 /* mt010.301 removed flag SLES9_PLUS */
6144 /* wait forever for children */
6148 if(osCp.dep.sigEvnt==TRUE)
6155 pthread_exit(NULLP);
6161 * Fun: Set date and time
6163 * Desc: This function is used to set the calendar
6168 * Notes: Unimplemented
6174 PUBLIC S16 SSetDateTime
6176 REG1 DateTime *dt /* date and time */
6179 PUBLIC S16 SSetDateTime(dt)
6180 REG1 DateTime *dt; /* date and time */
6195 * Fun: Get date and time
6197 * Desc: This function is used to determine the calendar
6198 * date and time. This information may be used for
6199 * some management functions.
6210 PUBLIC S16 SGetDateTime
6212 REG1 DateTime *dt /* date and time */
6215 PUBLIC S16 SGetDateTime(dt)
6216 REG1 DateTime *dt; /* date and time */
6219 /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
6222 struct timespec ptime;
6224 struct timeval ptime;
6233 #if (ERRCLASS & ERRCLS_INT_PAR)
6236 MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
6245 localtime_r(&tt, &tme);
6248 clock_gettime(CLOCK_REALTIME, &ptime);
6250 gettimeofday(&ptime, NULL);
6252 localtime_r(&ptime.tv_sec, &tme);
6254 dt->month = (U8) tme.tm_mon + 1;
6255 dt->day = (U8) tme.tm_mday;
6256 dt->year = (U8) tme.tm_year;
6257 dt->hour = (U8) tme.tm_hour;
6258 dt->min = (U8) tme.tm_min;
6259 dt->sec = (U8) tme.tm_sec;
6262 #ifdef SS_DATETIME_USEC
6264 dt->usec = ptime.tv_nsec / 1000;
6266 dt->usec = ptime.tv_usec;
6268 #endif /*-- SS_DATETIME_USEC --*/
6274 * Get time from epoch in milliseconds
6276 * Fun: Get time from epoch in milliseconds
6278 * Desc: This function is used to get the time from epoch in milli seconds.
6279 * This information may be used for calculating a layer's activation function
6280 * execution time used for thread profiling.
6289 /* mt003.301 Modifications */
6291 PUBLIC S16 SGetEpcTime
6293 EpcTime *et /* date and time */
6296 PUBLIC S16 SGetEpcTime(et)
6297 EpcTime *et; /* date and time */
6300 /* mt003.301 Modifications */
6302 U64 to_sec = 1000000;
6305 struct timespec ptime;
6307 struct timeval ptime;
6313 #if (ERRCLASS & ERRCLS_INT_PAR)
6322 clock_gettime(CLOCK_REALTIME, &ptime);
6324 gettimeofday(&ptime, NULL);
6325 #endif /* SS_LINUX */
6327 now = (ptime.tv_sec * to_sec);
6330 now += (ptime.tv_nsec / to_nsec);
6331 #else /* SS_LINUX */
6332 now += (ptime.tv_usec);
6334 #endif /* SS_LINUX */
6335 now = (now / to_nsec);
6346 * Fun: Get system time
6348 * Desc: This function is used to determine the system time.
6352 * Notes: osCp.dep.sysTicks is updated by the timer thread.
6358 PUBLIC S16 SGetSysTime
6360 Ticks *sysTime /* system time */
6363 PUBLIC S16 SGetSysTime(sysTime)
6364 Ticks *sysTime; /* system time */
6370 #if (ERRCLASS & ERRCLS_INT_PAR)
6371 if (sysTime == NULLP)
6373 MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6379 *sysTime = osCp.dep.sysTicks;
6385 /* mt021.201 - Addition of SGetRefTime function */
6388 * Fun: Get referenced time
6390 * Desc: This function is used to determine the time in seconds
6391 * and microseconds from a reference time. The reference
6392 * time is expressed in seconds from UTC EPOC, January 1,
6398 * Notes: Macros are defined for reference times:
6399 * SS_REFTIME_01_01_1970
6400 * SS_REFTIME_01_01_2002
6406 PUBLIC S16 SGetRefTime
6408 U32 refTime, /* reference time */
6413 PUBLIC S16 SGetRefTime(refTime, sec, usec)
6414 U32 refTime; /* reference time */
6421 struct timespec ptime;
6423 struct timeval ptime;
6429 clock_gettime(CLOCK_REALTIME, &ptime);
6431 gettimeofday(&ptime, NULL);
6434 #if (ERRCLASS & ERRCLS_INT_PAR)
6435 if (sec == NULLP || usec == NULLP)
6437 MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6440 /* mt022.201 - Modification to fix compile warning */
6441 if (refTime > (U32)(ptime.tv_sec))
6443 MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6448 *sec = ptime.tv_sec - refTime;
6450 *usec = ptime.tv_nsec / 1000;
6452 *usec = ptime.tv_usec;
6462 * Fun: Get Random Number
6464 * Desc: Invoked by layer when a pseudorandom number is required.
6468 * Notes: Suggested approach uses shuffled Linear Congruential
6469 * Operators as described in Byte magazine October
6470 * 1984; "Generating and Testing Pseudorandom Numbers"
6478 Random *value /* random number */
6481 PUBLIC S16 SRandom(value)
6482 Random *value; /* random number */
6488 #if (ERRCLASS & ERRCLS_INT_PAR)
6491 /* mt011.21: addition */
6492 MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6498 *value = (Random) rand_r(&osCp.dep.randSeed);
6509 * Desc: This function exits from a task.
6513 * Notes: Currently does nothing.
6524 PUBLIC S16 SExitTsk()
6536 * Fun: Exit Interrupt
6538 * Desc: This function exits from an interrupt.
6542 * Notes: Currently does nothing.
6553 PUBLIC S16 SExitInt()
6565 * Fun: Hold Interrupt
6567 * Desc: This function prohibits interrupts from being enabled until
6568 * release interrupt. This function should be called when
6569 * interrupts are disabled and prior to any call to system
6570 * services either by entry to an interrupt service routine or
6571 * by explicit call to disable interrupt.
6575 * Notes: Currently does nothing
6586 PUBLIC S16 SHoldInt()
6598 * Fun: Release Interrupt
6600 * Desc: This function allows interrupts to be enabled.
6604 * Notes: Currently does nothing.
6615 PUBLIC S16 SRelInt()
6629 * Desc: Enable interrupts
6631 * Ret: ROK on success
6634 * Notes: Currently does nothing.
6640 PUBLIC INLINE S16 SEnbInt
6645 PUBLIC INLINE S16 SEnbInt()
6659 * Desc: Disable interrupts
6661 * Ret: ROK on success
6664 * Notes: Currently does nothing.
6670 PUBLIC INLINE S16 SDisInt
6675 PUBLIC INLINE S16 SDisInt()
6689 * Desc: This function gets the function address stored at the
6690 * specified interrupt vector.
6694 * Notes: Currently does nothing.
6702 VectNmb vectNmb, /* vector number */
6703 PIF *vectFnct /* vector function */
6706 PUBLIC S16 SGetVect(vectNmb, vectFnct)
6707 VectNmb vectNmb; /* vector number */
6708 PIF *vectFnct; /* vector function */
6726 * Desc: This function installs the specified function at the
6727 * specified interrupt vector.
6731 * Notes: Currently does nothing.
6739 VectNmb vectNmb, /* vector number */
6740 PIF vectFnct /* vector function */
6743 PUBLIC S16 SPutVect(vectNmb, vectFnct)
6744 VectNmb vectNmb; /* vector number */
6745 PIF vectFnct; /* vector function */
6758 /* mt028.201: modification: multiple procs support related changes */
6759 #ifndef SS_MULTIPLE_PROCS
6765 * Desc: This function gets the current entity and instance.
6768 * RFAILED - failed, general (optional)
6770 * Notes: This function may be called by the OS or Layer 1
6777 PUBLIC S16 SGetEntInst
6779 Ent *ent, /* entity */
6780 Inst *inst /* instance */
6783 PUBLIC S16 SGetEntInst(ent, inst)
6784 Ent *ent; /* entity */
6785 Inst *inst; /* instance */
6797 #if (ERRCLASS & ERRCLS_INT_PAR)
6798 /* check pointers */
6799 if (ent == NULLP || inst == NULLP)
6801 MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6807 /* get the thread id */
6808 tId = pthread_self();
6811 /* find the system task in whose context we're running */
6813 ret = SLock(&osCp.sTskTblLock);
6818 for (i = 0; i < SS_MAX_STSKS; i++)
6820 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6822 sTsk = &osCp.sTskTbl[i];
6828 *ent = sTsk->dep.ent;
6829 *inst = sTsk->dep.inst;
6831 SUnlock(&osCp.sTskTblLock);
6834 RETVALUE(ret == ROK ? ROK : RFAILED);
6842 * Desc: This function sets the current entity and instance.
6852 PUBLIC S16 SSetEntInst
6854 Ent ent, /* entity */
6855 Inst inst /* instance */
6858 PUBLIC S16 SSetEntInst(ent, inst)
6859 Ent ent; /* entity */
6860 Inst inst; /* instance */
6872 #if (ERRCLASS & ERRCLS_INT_PAR)
6873 /* check entity and instance IDs */
6874 if (ent >= ENTNC || inst >= INSTNC)
6876 MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6882 /* get the thread id */
6883 tId = pthread_self();
6886 /* find the system task in whose context we're running */
6888 ret = SLock(&osCp.sTskTblLock);
6893 for (i = 0; i < SS_MAX_STSKS; i++)
6895 if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6897 sTsk = &osCp.sTskTbl[i];
6903 sTsk->dep.ent = ent;
6904 sTsk->dep.inst = inst;
6906 SUnlock(&osCp.sTskTblLock);
6909 RETVALUE(ret == ROK ? ROK : RFAILED);
6912 #endif /* SS_MULTIPLE_PROCS */
6914 #ifdef SS_DRVR_SUPPORT
6920 * Desc: Set interrupt pending flag
6922 * Ret: ROK on success
6931 PUBLIC INLINE S16 SSetIntPend
6933 U16 id, /* driver task identifier */
6934 Bool flag /* flag */
6937 PUBLIC INLINE S16 SSetIntPend(id, flag)
6938 U16 id; /* driver task identifier */
6939 Bool flag; /* flag */
6948 #if (ERRCLASS & ERRCLS_INT_PAR)
6949 if (id >= SS_MAX_DRVRTSKS || osCp.drvrTskTbl[id].used == FALSE)
6951 MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6958 isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6960 if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6968 #endif /* SS_DRVR_SUPPORT */
6971 #ifdef SS_LOCKLESS_MEMORY
6974 * Fun: SGlobMemInfoShow
6976 * Desc: This function displays the memory usage information
6977 * for the destined region. It will show the usage of
6978 * each configured bucket and the heap for the specified region.
6981 * RFAILED Region not registered
6987 PUBLIC S16 SGlobMemInfoShow
6992 PUBLIC S16 SGlobMemInfoShow()
6997 CmMmGlobRegCb *globReg;
6999 TRC1(SGlobMemInfoShow);
7001 globReg = osCp.globRegCb;
7003 sprintf(prntBuf, "--------------------------------------------------------------\n");
7004 SDisplay(0, prntBuf);
7005 sprintf(prntBuf, "Global Region Bucket Information\n");
7006 SDisplay(0, prntBuf);
7007 sprintf(prntBuf, "====================================================\n");
7008 SDisplay(0, prntBuf);
7009 sprintf(prntBuf, "Bucket Id Set Size Free Sets Allocated\n");
7010 SDisplay(0, prntBuf);
7011 sprintf(prntBuf, "====================================================\n");
7012 SDisplay(0, prntBuf);
7015 for (idx = 0; idx < globReg->numBkts; idx++)
7017 #ifdef XEON_SPECIFIC_CHANGES
7018 sprintf(prntBuf, "%2u %12lu %12lu %8lu %9lu\n",
7019 idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7022 sprintf(prntBuf, "%2u %12lu %8lu %9lu\n",
7023 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7025 sprintf(prntBuf, "%2u %12u %8u %9u\n",
7026 idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
7029 SDisplay(0, prntBuf);
7031 sprintf(prntBuf, "--------------------------------------------------------------\n");
7032 SDisplay(0, prntBuf);
7037 #endif /* SS_LOCKLESS_MEMORY */
7040 Bool IsMemoryThresholdHit(Region reg, Pool pool)
7042 if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
7044 MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
7047 mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
7048 mtCMMRegCb[reg]->bktTbl[pool].numBlks);
7055 /* mt022.201 - Addition of SRegInfoShow function */
7060 * Desc: This function displays the memory usage information
7061 * for the destined region. It will show the usage of
7062 * each configured bucket and the heap for the specified region.
7065 * RFAILED Region not registered
7067 * Notes: A Sample Output from the function
7068 * Bucket Memory: region 1
7069 * ====================================================
7070 * Bucket Number of Blks configured Size Allocated
7071 * ====================================================
7079 * Heap Memory: region 1
7082 * Heap Segmented blocks: 0
7089 PUBLIC S16 SRegInfoShow
7095 PUBLIC S16 SRegInfoShow(region, availmem)
7105 #if (ERRCLASS & ERRCLS_INT_PAR)
7106 if (region > (SS_MAX_REGS-1) )
7108 MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
7115 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
7116 sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
7117 SDisplay(0, prntBuf);
7118 sprintf(prntBuf, "====================================================\n");
7119 SDisplay(0, prntBuf);
7120 sprintf(prntBuf, "Bucket Number of Blks configured Size Allocated\n");
7121 SDisplay(0, prntBuf);
7122 sprintf(prntBuf, "====================================================\n");
7123 SDisplay(0, prntBuf);
7127 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7129 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
7131 sprintf((char *)prntBuf, "%2u %8u %5u %8u %8u\n",
7132 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7133 mtCMMRegCb[region]->bktTbl[idx].size,
7134 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7135 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7137 sprintf((char *)prntBuf, "%2u %8lu %5lu %8lu %8lu\n",
7138 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7139 mtCMMRegCb[region]->bktTbl[idx].size,
7140 mtCMMRegCb[region]->bktTbl[idx].numAlloc,
7141 mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
7144 /*mt009.301 Fixed 64BIT compilation warnings*/
7146 sprintf(prntBuf, "%2u %8u %5u %8u\n",
7147 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7148 mtCMMRegCb[region]->bktTbl[idx].size,
7149 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7151 sprintf(prntBuf, "%2u %8lu %5lu %8lu\n",
7152 idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
7153 mtCMMRegCb[region]->bktTbl[idx].size,
7154 mtCMMRegCb[region]->bktTbl[idx].numAlloc);
7156 #endif /* not TENB_RTLIN_CHANGES */
7157 SDisplay(0, prntBuf);
7158 *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
7159 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7160 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7162 sprintf(prntBuf, "\n---------------\n");
7163 SDisplay(0, prntBuf);
7164 sprintf(prntBuf, "Heap Memory: region %d\n", region);
7165 SDisplay(0, prntBuf);
7166 /*mt009.301 Fixed 64BIT compilation warnings*/
7168 sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
7170 sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
7172 SDisplay(0, prntBuf);
7173 /*mt009.301 Fixed 64BIT compilation warnings*/
7175 sprintf(prntBuf, "Heap Allocated: %u\n",
7176 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7178 sprintf(prntBuf, "Heap Allocated: %lu\n",
7179 (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
7181 SDisplay(0, prntBuf);
7182 *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
7183 #if (ERRCLASS & ERRCLS_DEBUG)
7184 sprintf(prntBuf, "Heap Segmented blocks: %d\n",
7185 mtCMMRegCb[region]->heapCb.numFragBlk);
7186 SDisplay(0, prntBuf);
7191 #ifdef XEON_SPECIFIC_CHANGES
7192 #define SSI_MAX_BKT_THRESHOLD 6
7193 #define SSI_MAX_REG_THRESHOLD 2
7194 U32 SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7195 U32 SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7196 U32 SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
7199 PRIVATE Void SInitMemThreshold
7205 PRIVATE Void SInitMemThreshold(region, maxBkt)
7211 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7213 SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
7214 SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
7215 SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
7216 printf("REGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
7221 PUBLIC S16 SRegReachedMemThreshold
7227 PUBLIC S16 SRegReachedMemThreshold(region, maxBkt)
7234 PRIVATE U8 initFlag = 1;
7238 SInitMemThreshold(region, maxBkt);
7241 for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
7243 if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
7248 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
7252 else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
7257 RETVALUE(memStatus);
7260 /* mt033.201 - addition of API to return the memory statistical data */
7265 * Desc: This function returns the memory usage information
7266 * for the destined region. It will return the usage of
7267 * each configured bucket and the heap for the specified region.
7270 * RFAILED Region not registered
7278 PUBLIC S16 SGetRegInfo
7281 SsMemDbgInfo *dbgInfo
7284 PUBLIC S16 SGetRegInfo(region, dbgInfo)
7286 SsMemDbgInfo *dbgInfo;
7293 #if (ERRCLASS & ERRCLS_INT_PAR)
7294 if (region >= mtMemoCfg.numRegions )
7296 MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
7301 dbgInfo->availmem = 0;
7303 if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
7304 dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
7306 dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
7308 for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
7310 dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
7311 dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
7312 dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
7314 dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
7315 (mtCMMRegCb[region]->bktTbl[idx].numBlks - \
7316 mtCMMRegCb[region]->bktTbl[idx].numAlloc));
7319 dbgInfo->region = region;
7321 dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
7323 dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
7324 mtCMMRegCb[region]->heapCb.avlSize);
7326 dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
7328 #if (ERRCLASS & ERRCLS_DEBUG)
7329 dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
7336 PUBLIC S16 SGetRegPoolInfo
7342 PUBLIC S16 SGetRegPoolInfo(numRegion, numPool)
7347 /* Send number of Region available */
7348 *numRegion = mtMemoCfg.numRegions;
7349 /* Send number of Pools available */
7350 *numPool = cfgRegInfo[0].numPools;
7355 /* mt033.201 - addition of APIs to print the memory statistical data
7356 * as defined by SSI enhancements
7358 #ifdef SSI_DEBUG_LEVEL1
7361 * Fun: SPrintRegMemStatusInfo
7363 * Desc: This function displays the memory usage information
7364 * for the destined region. It will show the total memory
7365 * used for static and dynamic memory if typeFlag is
7366 * SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
7367 * memory block allocated for a particular size if typeFlag
7368 * is SS_MEM_BLK_SIZE_PROFILE from the hash list by
7369 * calling SRegPrintMemStats.
7379 PUBLIC S16 SPrintRegMemStatusInfo
7385 PUBLIC S16 SPrintRegMemStatusInfo(region, typeFlag)
7395 TRC1(SPrintRegMemStatusInfo);
7397 #if (ERRCLASS & ERRCLS_INT_PAR)
7398 if (region >= mtMemoCfg.numRegions )
7400 MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
7405 /* initialize the counters*/
7409 if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
7411 /* total static and dynamic memory allocated from all the buckets in region requested */
7412 sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
7413 SDisplay(0, prntBuf);
7414 sprintf(prntBuf, "===========================================\n");
7415 SDisplay(0, prntBuf);
7416 sprintf(prntBuf, "Bucket Static Memory Dynamic Memory\n");
7417 SDisplay(0, prntBuf);
7418 sprintf(prntBuf, "===========================================\n");
7419 SDisplay(0, prntBuf);
7420 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7422 /*mt009.301 Fixed 64BIT compilation warnings*/
7424 sprintf(prntBuf, "%2u %8u %8u\n", idx,
7425 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7426 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7428 sprintf(prntBuf, "%2lu %8lu %8lu\n", idx,
7429 mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7430 mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7432 SDisplay(0, prntBuf);
7433 /* update the total count */
7434 statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7435 dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7438 /*mt009.301 Fixed 64BIT compilation warnings*/
7440 sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7441 SDisplay(0, prntBuf);
7442 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7444 sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7445 SDisplay(0, prntBuf);
7446 /*mt010.301 fix for compilation error*/
7447 sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7449 SDisplay(0, prntBuf);
7451 sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7452 SDisplay(0, prntBuf);
7453 /*mt009.301 Fixed 64BIT compilation warnings*/
7455 sprintf(prntBuf, "STATIC MEMORY: %u DYNAMIC MEMORY:%u \n",
7456 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7458 sprintf(prntBuf, "STATIC MEMORY: %lu DYNAMIC MEMORY:%lu \n",
7459 mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7461 SDisplay(0, prntBuf);
7463 else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7465 /* Bucket Memory allocation Statistics */
7466 RETVALUE(SPrintRegMemStats(region));
7471 sprintf(prntBuf, "\n Invalid choice \n");
7472 SDisplay(0, prntBuf);
7480 * Fun: SPrintRegMemStats
7482 * Desc: This function displays the memory usage information for
7483 * the destined region. It will show the number of memory
7484 * block allocated for a particular size from the hash list.
7494 PRIVATE S16 SPrintRegMemStats
7499 PRIVATE S16 SPrintRegMemStats(region)
7503 CmMmHashListCp *hashListCp;
7508 TRC1(SPrintRegMemStats);
7510 hashListCp = &mtCMMRegCb[region]->hashListCp;
7512 sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7513 SDisplay(0, prntBuf);
7514 sprintf(prntBuf, "Maximum Entries: %u Current Entries: %u\n",
7515 hashListCp->numOfbins, hashListCp->numOfEntries);
7516 SDisplay(0, prntBuf);
7517 sprintf(prntBuf, "===================================\n");
7518 SDisplay(0, prntBuf);
7519 sprintf(prntBuf, "Block Size Total number of requests\n");
7520 SDisplay(0, prntBuf);
7521 sprintf(prntBuf, "===================================\n");
7522 SDisplay(0, prntBuf);
7524 for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7525 (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7527 if (hashListCp->hashList[idx].numAttempts)
7530 /*mt009.301 Fixed 64BIT compilation warnings*/
7532 sprintf(prntBuf, "%8u %8u\n", hashListCp->hashList[idx].size,
7533 hashListCp->hashList[idx].numAttempts);
7535 sprintf(prntBuf, "%8lu %8lu\n", hashListCp->hashList[idx].size,
7536 hashListCp->hashList[idx].numAttempts);
7538 SDisplay(0, prntBuf);
7542 sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7543 SDisplay(0, prntBuf);
7544 sprintf(prntBuf, "=================================================\n");
7545 SDisplay(0, prntBuf);
7546 sprintf(prntBuf, "Bucket Num of Alloc Attempts Num of De-alloc Attempts\n");
7547 SDisplay(0, prntBuf);
7548 sprintf(prntBuf, "=================================================\n");
7549 SDisplay(0, prntBuf);
7551 /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7552 for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7554 /*mt009.301 Fixed 64BIT compilation warnings*/
7556 sprintf(prntBuf, "%4u %8u %8u\n", idx,
7557 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7558 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7560 sprintf(prntBuf, "%4lu %8lu %8lu\n", idx,
7561 mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7562 mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7564 SDisplay(0, prntBuf);
7566 sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7567 SDisplay(0, prntBuf);
7568 /*mt009.301 Fixed 64BIT compilation warnings*/
7570 sprintf(prntBuf, "Num of Alloc Attempts: %u Num of De-alloc Attempts: %u\n",
7571 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7572 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7574 sprintf(prntBuf, "Num of Alloc Attempts: %lu Num of De-alloc Attempts: %lu\n",
7575 mtCMMRegCb[region]->heapCb.numAllocAttempts,
7576 mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7578 SDisplay(0, prntBuf);
7579 sprintf(prntBuf, "\n");
7580 SDisplay(0, prntBuf);
7587 * Fun: SRegMemErrHdlr
7589 * Desc: This function handles the errors returned from the memory
7590 * related functions. Customers are suggested to modify this
7591 * API according to their specific requirement.
7601 PUBLIC Void SRegMemErrHdlr
7608 PUBLIC Void SRegMemErrHdlr(region, ptr, errCode)
7616 TRC1(SRegMemErrHdlr);
7618 if (errCode == RDBLFREE)
7620 sprintf(prntBuf, "\nDouble free attempted at location:%8p in region:%d\n", ptr, region);
7621 SDisplay(0, prntBuf);
7623 else if (errCode == RTRAMPLINGNOK)
7625 sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7626 SDisplay(0, prntBuf);
7634 * Fun: SPrintRegMemProfile
7636 * Desc: This function displays the memory profile information
7637 * for the destined region. This function prints for:
7638 * 1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7639 * 2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7649 PUBLIC S16 SPrintRegMemProfile
7654 PUBLIC S16 SPrintRegMemProfile(region)
7660 CmMmBlkHdr *curBktBlk;
7662 Size offsetToNxtBlk;
7669 TRC1(SPrintRegMemProfile);
7671 #if (ERRCLASS & ERRCLS_INT_PAR)
7672 if (region >= mtMemoCfg.numRegions )
7674 MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7679 regCb = mtCMMRegCb[region];
7681 /* memory profile */
7682 sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7683 SDisplay(0, prntBuf);
7685 /* bucket profile */
7686 sprintf(prntBuf, "\nBucket Profile\n");
7687 SDisplay(0, prntBuf);
7689 for (idx = 0; idx < regCb->numBkts; idx++)
7692 /*mt009.301 Fixed 64BIT compilation warnings*/
7694 sprintf(prntBuf, "\nBucket number:%4u of Size:%u Num of Blocks: %u\n",
7695 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7697 sprintf(prntBuf, "\nBucket number:%4lu of Size:%lu Num of Blocks: %lu\n",
7698 idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7700 SDisplay(0, prntBuf);
7702 sprintf(prntBuf, "==========================================================================\n");
7703 SDisplay(0, prntBuf);
7704 sprintf(prntBuf, " Block Location Free/Allocated Static/dynamic Size requested\n");
7705 SDisplay(0, prntBuf);
7706 sprintf(prntBuf, "==========================================================================\n");
7707 SDisplay(0, prntBuf);
7709 offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7711 for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7712 ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7713 curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7715 /*mt009.301 Fixed 64BIT compilation warnings*/
7717 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curBktBlk);
7719 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curBktBlk);
7721 SDisplay(0, prntBuf);
7722 /* check if it is a sane block, elxe jump to next block */
7723 if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7725 sprintf(prntBuf, " Trampled \n");
7726 SDisplay(0, prntBuf);
7731 if (CMM_IS_STATIC(curBktBlk->memFlags))
7733 /*mt009.301 Fixed 64BIT compilation warnings*/
7735 sprintf(prntBuf, " Allocated Static %8u\n", curBktBlk->requestedSize);
7737 sprintf(prntBuf, " Allocated Static %8lu\n", curBktBlk->requestedSize);
7739 SDisplay(0, prntBuf);
7741 else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7743 /*mt009.301 Fixed 64BIT compilation warnings*/
7745 sprintf(prntBuf, " Allocated Dynamic %8u\n", curBktBlk->requestedSize);
7747 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curBktBlk->requestedSize);
7749 SDisplay(0, prntBuf);
7751 else if (CMM_IS_FREE(curBktBlk->memFlags))
7753 /*mt009.301 Fixed 64BIT compilation warnings*/
7755 sprintf(prntBuf, " Free %8u\n", curBktBlk->requestedSize);
7757 sprintf(prntBuf, " Free %8lu\n", curBktBlk->requestedSize);
7759 SDisplay(0, prntBuf);
7763 sprintf(prntBuf, " Trampled \n");
7764 SDisplay(0, prntBuf);
7770 sprintf(prntBuf, "\nHeap Profile\n");
7771 SDisplay(0, prntBuf);
7773 /* point to heapCb */
7774 heapCb = &(regCb->heapCb);
7776 sprintf(prntBuf, "\nHeap Start: %8p Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7777 SDisplay(0, prntBuf);
7778 sprintf(prntBuf, "==========================================================================\n");
7779 SDisplay(0, prntBuf);
7780 sprintf(prntBuf, " Block Location Size Free/Allocated Static/dynamic Size requested\n");
7781 SDisplay(0, prntBuf);
7782 sprintf(prntBuf, "==========================================================================\n");
7783 SDisplay(0, prntBuf);
7785 /* traverse the entire heap to output the heap profile */
7786 hdrSize = sizeof(CmHEntry);
7787 for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7788 ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7790 /*mt009.301 Fixed 64BIT compilation warnings*/
7792 sprintf(prntBuf, "%6u %8p", blkCnt, (void *)curHBlk);
7794 sprintf(prntBuf, "%6lu %8p", blkCnt, (void *)curHBlk);
7796 SDisplay(0, prntBuf);
7798 /* check if it is a sane block, elxe jump to next block */
7799 if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7801 sprintf(prntBuf, " Trampled \n");
7802 SDisplay(0, prntBuf);
7804 sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7805 SDisplay(0, prntBuf);
7808 * To go to next block in the heap we do not have any offset value
7809 * other than curHBlk->size. As the block is already trampled
7810 * we cannot rely on this size. So it is better to stop here unless there
7811 * exists any other mechanism(?) to know the offset to next block.
7816 /*mt009.301 Fixed 64BIT compilation warnings*/
7818 sprintf(prntBuf, " %8u", curHBlk->size);
7820 sprintf(prntBuf, " %8lu", curHBlk->size);
7822 SDisplay(0, prntBuf);
7824 if (CMM_IS_STATIC(curHBlk->memFlags))
7826 /*mt009.301 Fixed 64BIT compilation warnings*/
7828 sprintf(prntBuf, " Allocated Static %8u\n", curHBlk->requestedSize);
7830 sprintf(prntBuf, " Allocated Static %8lu\n", curHBlk->requestedSize);
7832 SDisplay(0, prntBuf);
7834 else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7836 /*mt009.301 Fixed 64BIT compilation warnings*/
7838 sprintf(prntBuf, " Allocated Dynamic %8u\n", curHBlk->requestedSize);
7840 sprintf(prntBuf, " Allocated Dynamic %8lu\n", curHBlk->requestedSize);
7842 SDisplay(0, prntBuf);
7844 else if (CMM_IS_FREE(curHBlk->memFlags))
7846 /*mt009.301 Fixed 64BIT compilation warnings*/
7848 sprintf(prntBuf, " Free %8u\n", curHBlk->requestedSize);
7850 sprintf(prntBuf, " Free %8lu\n", curHBlk->requestedSize);
7852 SDisplay(0, prntBuf);
7856 sprintf(prntBuf, " Trampled \n");
7857 SDisplay(0, prntBuf);
7859 /* goto next block in the heap */
7860 curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7866 #endif /* SSI_DEBUG_LEVEL1 */
7868 /*-- mt035.201 : Added new API for timestamp --*/
7871 * Fun: Get TimeStamp
7873 * Desc: This function is used to Get TimeStamp in micro seconds
7884 PUBLIC S16 SGetTimeStamp
7889 PUBLIC S16 SGetTimeStamp(ts)
7895 struct timespec ptime;
7897 struct timeval ptime;
7904 TRC1(SGetTimeStamp);
7907 clock_gettime(CLOCK_REALTIME, &ptime);
7909 gettimeofday(&ptime, NULL);
7912 /* Obtain the time of day, and convert it to a tm struct. --*/
7913 ptm = localtime (&ptime.tv_sec);
7914 /* Klock work fix ccpu00148484 */
7917 /* Format the date and time, down to a single second. --*/
7918 strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7921 /* Compute microseconds. --*/
7923 microseconds = ptime.tv_nsec / 1000;
7925 microseconds = ptime.tv_usec;
7928 /* Print the formatted time, in seconds, followed by a decimal point
7929 and the microseconds. --*/
7930 /*mt009.301 Fixed 64BIT compilation warnings*/
7932 sprintf(ts, "%s.%03d", time_string, microseconds);
7934 sprintf(ts, "%s.%03ld", time_string, microseconds);
7940 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7943 * Fun: Get SGetSystemTsk
7945 * Desc: This function is used to Get sytem task id
7955 PUBLIC U32 SGetSystemTsk
7960 PUBLIC U32 SGetSystemTsk()
7963 TRC1(SGetSystemTskS);
7965 RETVALUE(pthread_self());
7967 } /* end of SGetSystemTsk */
7969 #ifdef SS_MULTICORE_SUPPORT
7972 * Fun: Add Timer thread into system task table
7974 * Desc: This function is used to add the system task
7975 * associated with Timer thread.
7985 PRIVATE SsSTskEntry* ssdAddTmrSTsk(Void)
7987 PRIVATE SsSTskEntry* ssdAddTmrSTsk()
7993 TRC1(ssdAddTmrSTsk);
7995 /* lock the system task table */
7996 ret = SLock(&osCp.sTskTblLock);
8000 #if (ERRCLASS & ERRCLS_DEBUG)
8001 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8002 "Could not lock system task table");
8008 /* check count of system tasks */
8009 if (osCp.numSTsks == SS_MAX_STSKS)
8012 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8014 #if (ERRCLASS & ERRCLS_DEBUG)
8015 MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
8016 "Could not give the Semaphore");
8021 #if (ERRCLASS & ERRCLS_ADD_RES)
8022 MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
8029 /* initialize the system task entry with the information we have */
8030 sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
8032 /* store the system task priority */
8033 sTsk->tskPrior = SS_NORM_TSK_PRI;
8035 /* initialize the demand queue */
8036 if (ssInitDmndQ(&sTsk->dQ) != ROK)
8039 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8041 #if (ERRCLASS & ERRCLS_DEBUG)
8042 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8043 "Could not give the Semaphore");
8048 #if (ERRCLASS & ERRCLS_DEBUG)
8049 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8050 "Could not initialize demand queue");
8056 /* initialize the system task entry lock */
8057 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8059 ssDestroyDmndQ(&sTsk->dQ);
8061 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8063 #if (ERRCLASS & ERRCLS_DEBUG)
8064 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8065 "Could not give the Semaphore");
8070 #if (ERRCLASS & ERRCLS_DEBUG)
8071 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8072 "Could not initialize system task entry lock");
8079 /* success, update the table */
8080 sTsk->tskId = osCp.nxtSTskEntry;
8082 sTsk->termPend = FALSE;
8083 osCp.nxtSTskEntry = sTsk->nxt;
8086 /* unlock the system task table */
8088 if ( SUnlock(&osCp.sTskTblLock) != ROK)
8090 #if (ERRCLASS & ERRCLS_DEBUG)
8091 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8092 "Could not give the Semaphore");
8099 #endif /* SS_MULTICORE_SUPPORT */
8100 /* mt003.301 Readwrite lock and recursive mutex additions */
8101 #ifdef SS_LOCK_SUPPORT
8104 * Fun: ssdInitLockNew
8106 * Desc: This function is used to initialise lock/mutex
8116 PUBLIC S16 ssdInitLockNew
8122 PUBLIC S16 ssdInitLockNew(lockId, lockType)
8128 #ifdef SS_REC_LOCK_SUPPORT
8129 pthread_mutexattr_t attr;
8130 #endif /* SS_REC_LOCK_SUPPORT */
8131 Txt prntBuf[PRNTSZE];
8134 TRC1(ssdInitLockNew);
8138 #ifdef SS_RDWR_LOCK_SUPPORT
8141 if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
8143 sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
8144 SDisplay(0, prntBuf);
8149 #endif /* SS_RDWR_LOCK_SUPPORT */
8150 #ifdef SS_REC_LOCK_SUPPORT
8153 retVal = pthread_mutexattr_init(&attr);
8157 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
8162 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
8164 retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
8168 sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
8169 pthread_mutexattr_destroy(&attr);
8173 retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
8176 sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
8177 pthread_mutexattr_destroy(&attr);
8183 #endif /* SS_REC_LOCK_SUPPORT */
8186 sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
8187 SDisplay(0, prntBuf);
8197 * Desc: This function is used to aquire the read write lock
8207 PUBLIC S16 ssdLockNew
8213 PUBLIC S16 ssdLockNew(lockId, lockType)
8219 Txt prntBuf[PRNTSZE];
8226 #ifdef SS_RDWR_LOCK_SUPPORT
8229 if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
8231 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8232 SDisplay(0, prntBuf);
8239 if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
8241 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
8242 SDisplay(0, prntBuf);
8249 if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
8251 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8252 SDisplay(0, prntBuf);
8259 if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
8261 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
8262 SDisplay(0, prntBuf);
8267 #endif /* SS_RDWR_LOCK_SUPPORT */
8268 #ifdef SS_REC_LOCK_SUPPORT
8271 if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
8273 sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8274 SDisplay(0, prntBuf);
8279 #endif /* SS_REC_LOCK_SUPPORT */
8282 sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
8283 SDisplay(0, prntBuf);
8296 * Desc: This function is used to Unlock the read write lock
8306 PUBLIC S16 ssdUnlockNew
8312 PUBLIC S16 ssdUnlockNew(lockId, lockType)
8318 Txt prntBuf[PRNTSZE];
8325 #ifdef SS_RDWR_LOCK_SUPPORT
8328 if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
8330 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
8331 SDisplay(0, prntBuf);
8336 #endif /* SS_RDWR_LOCK_SUPPORT */
8337 #ifdef SS_REC_LOCK_SUPPORT
8340 if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
8342 sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
8343 SDisplay(0, prntBuf);
8348 #endif /* SS_REC_LOCK_SUPPORT */
8351 sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
8352 SDisplay(0, prntBuf);
8361 * Fun: ssdDestroyLockNew
8363 * Desc: This function is used to destroy the read write lock
8373 PUBLIC S16 ssdDestroyLockNew
8379 PUBLIC S16 ssdDestroyLockNew(lockId, lockType)
8384 Txt prntBuf[PRNTSZE];
8387 TRC1(ssdDestroyLockNew);
8391 #ifdef SS_RDWR_LOCK_SUPPORT
8394 if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
8396 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
8397 SDisplay(0, prntBuf);
8402 #endif /* SS_RDWR_LOCK_SUPPORT */
8403 #ifdef SS_REC_LOCK_SUPPORT
8406 if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
8408 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
8409 SDisplay(0, prntBuf);
8414 #endif /* SS_REC_LOCK_SUPPORT */
8417 sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
8418 SDisplay(0, prntBuf);
8424 #endif /* SS_LOCK_SUPPORT */
8426 /* mt005.301 : Cavium Changes */
8427 #ifdef SS_SEUM_CAVIUM
8431 * Fun: ssInitRcvWork
8433 * Desc: This is the initializtion function of receive
8437 * RFAILED - failed, general (optional)
8439 * Notes: Function to initialize the work queue packet
8440 * receiving thread. This creates the new thread to
8441 * receive the work and sets the affinity.
8447 PUBLIC S16 ssInitRcvWork
8452 PUBLIC S16 ssInitRcvWork()
8455 pthread_attr_t attr;
8458 TRC1(ssInitRcvWork);
8460 /* set the required attributes */
8461 pthread_attr_init(&attr);
8462 pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
8463 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8464 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8466 /* Create a new thread to receive the work queue messages */
8467 if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
8469 pthread_attr_destroy(&attr);
8474 pthread_attr_destroy(&attr);
8478 }/* ssInitRcvWork */
8485 * Desc: This is the handler function of receive
8489 * RFAILED - failed, general (optional)
8491 * Notes:The handler function of the work queue receiver task.
8492 * This will be waiting for the work and after receiving
8493 * it, work will converted and posted to that entityt
8500 PRIVATE void *workRcvTsk
8505 PRIVATE void *workRcvTsk (ptr)
8510 cvmx_wqe_t *workPtr;
8511 Buffer *mBuf, *rcvdBuf;
8512 SsMsgInfo *minfoPtr;
8522 /* get the work if its avilable */
8523 workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
8525 if ( workPtr == NULLP )
8527 /* If there is no work then sleep for 10 usec */
8529 ts.tv_nsec = 500000;
8531 nanosleep(&ts, NULLP);
8535 switch(workPtr->tag)
8537 /* Switch over according to the tag value */
8538 case SS_CVMX_MBUF_TAG:
8540 rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8542 /* Convert the physical address to Pointers */
8543 ret = SConvPhyPtr(&rcvdBuf);
8546 /* mt011.301: Cavium 32 bit changes */
8547 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8551 /* Copy the buffer to this region */
8552 ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8555 /* mt011.301: Cavium 32 bit changes */
8556 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8560 /* mt011.301: Cavium 32 bit changes */
8561 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8563 minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8565 /* Get the post strucutre and Post the message */
8566 if ( minfoPtr != NULLP)
8568 SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8570 (Void)SPstTsk(&pst, mBuf);
8572 /* Free the buffer allocated if it cannot be sent */
8581 /* Invalid tag value, drop the work */
8582 /* mt011.301: Cavium 32 bit changes */
8583 cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8592 #endif /* SS_SEUM_CAVIUM */
8594 #ifdef TENB_RTLIN_CHANGES
8595 PUBLIC S16 SInitLock(SLockId *l, U8 t)
8598 pthread_mutexattr_t prior;
8599 pthread_mutexattr_init(&prior);
8600 #ifndef RGL_SPECIFIC_CHANGES
8601 pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8603 r = pthread_mutex_init(l, &prior);
8604 pthread_mutexattr_destroy(&prior);
8608 #ifdef SS_THR_REG_MAP
8611 * Fun: ssRegMainThread
8613 * Desc: This function is used to add the memory region
8614 * mapping for the main thread.
8616 * Ret: VOID (Always successful)
8624 PUBLIC Void ssRegMainThread(Void)
8627 if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8629 printf("not able to get different Id for main thread\n");
8632 /* Here the default region is added as we dont have any region associated with
8633 * Main thread. The thread should not perform any allocation except
8634 * the initial configuratin
8636 #ifdef XEON_SPECIFIC_CHANGES
8637 SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8639 SS_GET_THREAD_MEM_REGION() =
8646 * Fun: ssCheckAndAddMemoryRegionMap
8648 * Desc: This function is used to add the memory region
8649 * mapping for the provided sTsk associated thread.
8650 * If the threadId can be placed in the thread memory
8651 * region mapping table and returns success if it is able
8652 * to place. If not, it keeps the thread ID in the static
8653 * local array and increments the count. Once thread Id
8654 * is successfully placed in the thread memory region mapping
8655 * table, pthread_cancel is sent for all the previous threads
8656 * which are failed to place in table.
8658 * Ret: TRUE - Thread ID successfully placed in thread memory region
8660 * FALSE - If thread Id is not placed in thread memory region
8663 * Notes:mapping tablemapping tablng tablee
8668 PUBLIC S32 ssCheckAndAddMemoryRegionMap
8670 pthread_t threadId, /* Thread Id of system task */
8671 Region region /* Region associated with thread */
8674 PRIVATE U32 createdThreads;
8675 PRIVATE pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8678 TRC1(ssCheckAndAddMemoryRegionMap);
8680 /* Here 0xFF is considered as invalid region and if the mapping table
8681 * contains 0xFF, that mapping entry is free
8683 if(SS_INVALID_THREAD_REG_MAP !=
8684 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8686 /* Klock work fix ccpu00148484 */
8687 if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8689 printf("failed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8690 printf("Not able to get the different thread ID, exiting\n");
8693 createdThreadIds[createdThreads++] = threadId;
8696 /* If we found free mapping table entry, place the region and send pthread_cancel
8697 * for all the thread Ids which are created before this
8699 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8700 #ifdef XEON_SPECIFIC_CHANGES
8701 printf("ThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8702 ((threadId >> SS_MEM_THREAD_ID_SHIFT) %
8703 SS_MAX_THREAD_REGION_MAP), region);
8705 for(indx = 0; indx < createdThreads; indx++)
8707 #ifdef XEON_SPECIFIC_CHANGES
8708 printf("Sending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8710 pthread_cancel(createdThreadIds[indx]);
8716 } /* ssCheckAndAddMemoryRegionMap */
8720 * Fun: ssCheckAndDelMemoryRegionMap
8722 * Desc: This function is used to add the memory region
8723 * mapping for the provided sTsk associated thread.
8724 * If the threadId can be placed in the thread memory
8725 * region mapping table and returns success if it is able
8726 * to place. If not, it keeps the thread ID in the static
8727 * local array and increments the count. Once thread Id
8728 * is successfully placed in the thread memory region mapping
8729 * table, pthread_cancel is sent for all the previous threads
8730 * which are failed to place in table.
8732 * Ret: TRUE - Thread ID successfully placed in thread memory region
8734 * FALSE - If thread Id is not placed in thread memory region
8737 * Notes:mapping tablemapping tablng tablee
8742 PUBLIC S32 ssCheckAndDelMemoryRegionMap
8744 pthread_t threadId /* Thread Id of system task */
8748 TRC1(ssCheckAndDelMemoryRegionMap);
8750 /* Raghu To-Do Check with team, is it necessary to acquire lock
8751 * as del and add may go parallel */
8752 /* Here 0xFF is considered as invalid region and if the mapping table
8753 * contains 0xFF, that mapping entry is free
8755 if(SS_INVALID_THREAD_REG_MAP ==
8756 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8759 printf("Invalid Thread ID (%ld)\n", (U32)threadId);
8761 printf("Invalid Thread ID (%d)\n", (U32)threadId);
8765 /* If we found free mapping table entry, place the region and send pthread_cancel
8766 * for all the thread Ids which are created before this
8768 osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8772 } /* ssCheckAndAddMemoryRegionMap */
8776 #ifdef SS_TSKLOG_ENABLE
8781 * Desc: This function will return current time through input parameter.
8784 * RFAILED - failed, general (optional)
8791 PUBLIC S16 SStartTask
8793 VOLATILE U32 *startTime,
8797 PUBLIC S16 SStartTask(startTime, taskId)
8798 VOLATILE U32 *startTime;
8802 #ifdef MSPD_MLOG_NEW
8803 *startTime = GetTIMETICK();
8812 * Desc: This function will return current time through input parameter.
8813 * and take the difference of start time provided as input parameter
8817 * RFAILED - failed, general (optional)
8824 PUBLIC S16 SStopTask
8826 VOLATILE U32 startTime,
8830 PUBLIC S16 SStopTask(startTime, taskId)
8831 VOLATILE U32 startTime;
8838 case PID_MAC_HARQ_IND:
8839 case PID_SCH_TTI_IND:
8841 case PID_MAC_DAT_IND:
8842 case PID_MAC_SF_ALLOC_REQ:
8843 case PID_MAC_STA_RSP:
8844 case PID_MAC_DL_SCHD:
8845 case PID_MAC_DL_CQI_IND:
8846 case PID_MAC_UL_CQI_IND:
8847 case PID_MAC_UL_SCHD:
8848 case PID_MAC_TTI_IND:
8849 case PID_CL_RCV_PHY_MSG:
8850 case PID_CL_HARQ_STA_IND:
8851 case PID_MAC_AM_HARQ_RLS:
8852 case PID_CL_DL_BATCH_PROC:
8853 case PID_CL_DLM_PRC_TTI_IND:
8854 case PID_CRC_IND_REAL:
8855 case PID_CRC_IND_DUMMY:
8856 case PID_TTI_LATENCY:
8857 case PID_RECPREQ_PROC:
8860 MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8862 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8865 MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8873 PUBLIC S16 SStartTask
8875 VOLATILE U32 * startTime,
8879 PUBLIC S16 SStartTask(startTime, taskId)
8880 VOLATILE U32 * startTime;
8889 PUBLIC S16 SStopTask
8891 VOLATILE U32 startTime,
8895 PUBLIC S16 SStopTask(startTime, taskId)
8896 VOLATILE U32 startTime;
8903 #endif /*#ifdef SS_TSKLOG_ENABLE */
8904 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8906 * This primitive is used to calculate the CPU Utilization per Core
8911 * @return Void - function is always success
8914 PUBLIC Void UpdateSocCpuInfo
8916 CmCpuStatsInfo *cpuInfo,
8920 PUBLIC Void UpdateSocCpuInfo(*cpuInfo, idx)
8921 CmCpuStatsInfo *cpuInfo;
8926 S8 mipsStr[MIPS_STRING_LEN];
8933 /* Open the file which holds the MIPS available value */
8934 mipsFd = fopen(MIPS_FILE, "r");
8941 /* Get the free mips available value from the file */
8942 if(NULLP == fgets(mipsStr, 24, mipsFd))
8944 printf("fgets to get the free mips available failed\n");
8949 strtok(mipsStr, " ");
8951 strPart = strtok(NULLP, " ");
8953 if(idx == CM_L2_CPU_UTIL)
8955 if(strPart != NULLP)
8957 l2FreeCpu = atoi(strPart);
8958 l2CpuUsed = 100 - l2FreeCpu;
8959 cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8960 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);;
8961 cpuInfo->cpuUtil[0].numSamples++;
8964 if(idx == CM_L3_CPU_UTIL)
8966 strPart = strtok(NULLP, " ");
8967 if(strPart != NULLP)
8969 l3FreeCpu = atoi(strPart);
8970 l3CpuUsed = 100 - l3FreeCpu;
8971 cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8972 cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);;
8973 cpuInfo->cpuUtil[0].numSamples++;
8976 if(idx == CM_L2_CPU_UTIL)
8978 cpuInfo->numCores = CM_NUM_L2_CORES ;
8980 else if(idx == CM_L3_CPU_UTIL)
8982 cpuInfo->numCores = CM_NUM_L3_CORES ;
8988 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8989 #ifdef SS_MULTICORE_SUPPORT
8992 * Fun: Add Timer thread into system task table
8994 * Desc: This function is used to add the system task
8995 * associated with Timer thread.
9005 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(
9009 PRIVATE SsSTskEntry* ssdReAddTmrSTsk(idx)
9016 TRC1(ssdReAddTmrSTsk);
9018 /* lock the system task table */
9019 ret = SLock(&osCp.sTskTblLock);
9023 #if (ERRCLASS & ERRCLS_DEBUG)
9024 MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
9025 "Could not lock system task table");
9031 /* initialize the system task entry with the information we have */
9032 sTsk = &osCp.sTskTbl[idx];
9037 SDestroyLock(&sTsk->lock);
9038 ssDestroyDmndQ(&sTsk->dQ);
9041 /* store the system task priority */
9042 sTsk->tskPrior = SS_NORM_TSK_PRI;
9044 /* initialize the demand queue */
9045 if (ssInitDmndQ(&sTsk->dQ) != ROK)
9048 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9050 #if (ERRCLASS & ERRCLS_DEBUG)
9051 MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
9052 "Could not give the Semaphore");
9057 #if (ERRCLASS & ERRCLS_DEBUG)
9058 MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
9059 "Could not initialize demand queue");
9065 /* initialize the system task entry lock */
9066 if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
9068 ssDestroyDmndQ(&sTsk->dQ);
9070 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9072 #if (ERRCLASS & ERRCLS_DEBUG)
9073 MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
9074 "Could not give the Semaphore");
9079 #if (ERRCLASS & ERRCLS_DEBUG)
9080 MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
9081 "Could not initialize system task entry lock");
9088 /* success, update the table */
9089 sTsk->tskId = idx + 1;
9091 sTsk->termPend = FALSE;
9093 /* unlock the system task table */
9095 if ( SUnlock(&osCp.sTskTblLock) != ROK)
9097 #if (ERRCLASS & ERRCLS_DEBUG)
9098 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9099 "Could not give the Semaphore");
9106 #endif /* SS_MULTICORE_SUPPORT */
9111 * Fun: Initialize timer table
9113 * Desc: This function initializes MTSS-specific information
9114 * in the timer table.
9124 PUBLIC S16 ssdReInitTmr
9129 PUBLIC S16 ssdReInitTmr()
9132 pthread_attr_t attr;
9133 struct sched_param param_sched;
9134 #ifndef XEON_SPECIFIC_CHANGES
9137 #ifdef SS_MULTICORE_SUPPORT
9139 #endif /* SS_MULTICORE_SUPPORT */
9140 #ifdef SS_THR_REG_MAP
9141 U32 threadCreated = FALSE;
9142 #endif /* SS_THR_REG_MAP */
9146 #ifndef XEON_SPECIFIC_CHANGES
9147 ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
9150 #if (ERRCLASS & ERRCLS_DEBUG)
9151 MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
9152 "Could not give the Semaphore");
9158 osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
9159 /* mt010.21: addition */
9161 #ifdef SS_MULTICORE_SUPPORT
9162 sTsk = ssdReAddTmrSTsk(0);
9167 #endif /* SS_MULTICORE_SUPPORT */
9168 /* create the timer handler thread */
9170 pthread_attr_init(&attr);
9171 /* mt021.201 - Addition to set stack size */
9172 pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
9173 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
9174 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9175 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
9176 param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
9177 pthread_attr_setschedparam(&attr, ¶m_sched);
9180 #ifdef SS_THR_REG_MAP
9181 /* When the thread is created, we check for the memory mapping table if
9182 * threadId can be placed in thread memory map table. If it is not able to place
9183 * threadId is stored in tmporary array. Once thread is created successful,
9184 * thread_cancel is sent for each thread which are created before. All the
9185 * threads are made to wait on sema which is cancel point for thread.
9187 while(threadCreated == FALSE)
9190 if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
9192 /* mt020.201 - Addition for destroying thread attribute object attr */
9193 pthread_attr_destroy(&attr);
9198 #ifdef SS_THR_REG_MAP
9199 threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID,
9202 #endif /* SS_THR_REG_MAP */
9203 #ifdef SS_MEM_WL_DEBUG
9204 tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
9207 /* mt020.201 - Addition for destroying thread attribute object attr */
9208 pthread_attr_destroy(&attr);
9209 sem_post(&osCp.dep.ssStarted);
9213 /**********************************************************************
9215 **********************************************************************/