dc3c0b310a1c3160af4c7c0c054124bcf51c728d
[o-du/l2.git] / src / mt / mt_ss.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 /********************************************************************20**
20
21      Name:     Multi-threaded System Services - Solaris
22
23      Type:     C source file
24
25      Desc:     C source code for the MTSS-Solaris implementation of
26                System Services.
27
28      File:     mt_ss.c
29
30 *********************************************************************21*/
31
32
33 \f
34 /* POSIX includes */
35 #ifndef _POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE         199309L
37 #endif
38 /* mt003.301 moved env files to use the __USE_UNIX98 flag in sys includes */
39
40 #include <fcntl.h>
41 #include <pthread.h>
42 #include <signal.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <sys/types.h>
46 #include <termios.h>
47 #include <time.h>
48 #include <unistd.h>
49 #include <sys/mman.h>
50  /* mt003.301: included sys/time.h
51   * for both solaris and linux
52   * */
53 #include <sys/time.h>
54  /* mt008.21: addition */
55 #include <errno.h>
56
57
58 \f
59 /* header include files (.h) */
60
61
62 #include "common_def.h"
63 #include "mt_ss.h"         /* MTSS specific */
64 #include "mt_err.h"        /* MTSS error defines */
65
66 #include "ss_queue.h"      /* queues */
67 #include "ss_task.h"       /* tasking */
68 #include "ss_msg.h"        /* messaging */
69 #include "ss_mem.h"        /* memory management interface */
70 #include "ss_gen.h"        /* general */
71 /* mt003.301 Additions - Task deregistration */
72 #include "ss_err.h"        /* error */
73 #include "cm_mem.h"        /* common memory manager */
74 /* mt001.301 : Additions */
75 #ifdef SS_THREAD_PROFILE
76 #include "ss_err.h"
77 #endif
78 #ifdef SS_LOCKLESS_MEMORY
79 #include "cm_llist.h"
80 #include "cm_hash.h"
81 #endif
82
83 /* multi-core support enhancement */
84 /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
85 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
86 #ifdef SS_LINUX
87 #include <sched.h>
88 #include <execinfo.h>
89 #else
90 #ifdef SUNOS
91 #include <sys/types.h>
92 #include <sys/processor.h>
93 #include <sys/procset.h>
94 #endif /* SUNOS */
95 #endif /* SS_LINUX */
96 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
97 /* mt001.301 : Additions */
98 #ifdef SS_WATCHDOG
99 #include <sys/types.h>
100 #include <sys/socket.h>
101 #include <netinet/in.h>
102 #include <arpa/inet.h>
103 #endif /* SS_WATCHDOG */
104
105 #ifdef SS_USE_WLS_MEM
106 #include <rte_common.h>
107 #include <rte_debug.h>
108 #include <rte_eal.h>
109 #endif
110
111 /* header/extern include files (.x) */
112
113 #include "gen.x"           /* general layer */
114 #include "ssi.x"           /* system services */
115
116 #include "cm5.x"           /* common timers */
117
118 #include "mt_ss.x"         /* MTSS specific */
119 #ifdef SS_LOCKLESS_MEMORY
120 #include "mt_ss_wl.x"         /* MTSS specific */
121 #endif /* SS_LOCKLESS_MEMORY */
122
123 #include "ss_queue.x"      /* queues */
124 #include "ss_task.x"       /* tasking */
125 #include "ss_timer.x"      /* timers */
126 #include "ss_strm.x"       /* STREAMS */
127 #include "ss_msg.x"        /* messaging */
128 #include "ss_mem.x"        /* memory management interface */
129 #include "ss_drvr.x"       /* driver tasks */
130 #include "ss_gen.x"        /* general */
131 #ifdef SS_LOCKLESS_MEMORY
132 #include "cm_llist.x"
133 #include "cm_hash.x"
134 #include "cm_mem_wl.x"        /* common memory manager */
135 #else
136 #include "cm_mem.x"        /* common memory manager */
137 #endif /* SS_LOCKLESS_MEMORY */
138 #include "cm_lte.x"        /* common memory manager */
139 /* mt001.301 : Additions */
140 #ifdef SS_LOGGER_SUPPORT
141 #include "cm_lib.x"
142 #endif /*  SS_LOGGER_SUPPORT */
143
144 /*mt005.301: Cavium Changes */
145 #ifdef SS_SEUM_CAVIUM
146 /* cvmx includes files */
147 #include "cvmx-config.h"
148 #include "cvmx.h"
149 #include "cvmx-pow.h"
150 #include "cvmx-tim.h"
151 #include "cvmx-fpa.h"
152 #include "cvmx-helper-fpa.h"
153 #include "cvmx-malloc.h"
154 #endif /* SS_SEUM_CAVIUM */
155
156 #ifdef L2_L3_SPLIT
157 #include "mt_plat_t33.h"
158 #include "mt_plat_t33.x"
159 #include "sys/syscall.h"
160 #endif
161
162 #if defined(RGL_SPECIFIC_CHANGES) || defined(INTEL_WLS) || defined(SS_USE_WLS_MEM)
163 #include <wls_lib.h>
164 #include <hugetlbfs.h>
165 #endif
166
167 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
168 S16 rgBatchProc (Void);
169 #endif
170 #ifdef RLC_MAC_DAT_REQ_RBUF
171 S16 rgDlDatReqBatchProc ARGS(( 
172          Void));
173 #endif
174 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
175 S16 rgBatchProc ARGS((
176     Void));
177 #endif  
178
179 #ifdef  TENB_T2K3K_SPECIFIC_CHANGES
180 /* general purpose debug zone  */
181 char            my_buffer2[4096 * 4] = { 0 };
182 char            my_buffer[4096] = { 0 };
183 int             my_buffer_idx = 0;
184
185
186
187 #define sigsegv_print(x, ...)    my_buffer_idx += sprintf(&my_buffer[my_buffer_idx], x "\n", ##__VA_ARGS__)
188
189 struct sigcontext my_uc_mcontext = { 0 };
190
191
192 #include <unistd.h>
193 #include <signal.h>
194 #include <ucontext.h>
195 #include <dlfcn.h>
196
197
198 #define SIGSEGV_STACK_GENERIC
199 #define REGFORMAT "%x\n"
200
201 #ifdef XEON_SPECIFIC_CHANGES
202 Void cmPrcTmr ARGS((CmTqCp* tqCp, CmTqType* tq, PFV func));
203 #endif
204
205 void            dump_external(void);
206
207 static Void mtDelSigals(Void)
208 {
209    struct sigaction sa;
210
211    memset(&sa, 0, sizeof(struct sigaction));
212    sigemptyset(&sa.sa_mask);
213    sa.sa_handler = SIG_DFL;
214    sigaction(SIGSEGV, &sa, NULL);
215
216    memset(&sa, 0, sizeof(struct sigaction));
217    sigemptyset(&sa.sa_mask);
218    sa.sa_handler = SIG_DFL;
219    sigaction(SIGILL, &sa, NULL);
220
221    return;
222 }
223 static void signal_segv(int signum, siginfo_t * info, void *ptr)
224 {
225    static const char *si_codes[3] = { "", "SEGV_MAPERR", "SEGV_ACCERR" };
226    int             sz;
227    int             i;
228    ucontext_t     *ucontext = (ucontext_t *) ptr;
229 #ifdef XEON_SPECIFIC_CHANGES
230 #else
231    int            *p32 = (int *) 0x2fff0000;
232 #endif
233    void           *buffer[100];
234    char          **strings;
235
236    printf("\nsegv ooops @ %p\n", info->si_addr);
237    my_buffer2[0] = 1;
238
239    printf("\nSegmentation Fault!\n");
240    printf("\ninfo.si_signo = %d\n", signum);
241    printf("\ninfo.si_errno = %d\n", info->si_errno);
242    printf("\ninfo.si_code  = %d (%s)\n", info->si_code, si_codes[info->si_code]);
243    printf("\ninfo.si_addr  = %p\n", info->si_addr);
244
245    memcpy(&my_uc_mcontext, &ucontext->uc_mcontext, sizeof(struct sigcontext));
246
247    i = 0;
248 #ifndef RGL_SPECIFIC_CHANGES
249    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r0);
250    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r1);
251    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r2);
252    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r3);
253    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r4);
254    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r5);
255    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r6);
256    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r7);
257    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r8);
258    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r9);
259    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_r10);
260    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_fp);
261    printf("\nreg[%02d]       = 0x" REGFORMAT, i++, (unsigned int)ucontext->uc_mcontext.arm_ip);
262    printf("\nreg[sp]       = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_sp);
263    printf("\nreg[lr]       = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_lr);
264    printf("\nreg[pc]       = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_pc);
265    printf("\nreg[cpsr]     = 0x" REGFORMAT, (unsigned int)ucontext->uc_mcontext.arm_cpsr);
266 #endif
267
268    printf("\nStack trace (non-dedicated):\n");
269
270    sz = backtrace(buffer, 50);
271    strings = backtrace_symbols(buffer, sz);
272    for (i = 0; i < sz; ++i)
273       printf("%s\n", strings[i]);
274
275    printf("\nEnd of stack trace\n");
276
277 #ifdef XEON_SPECIFIC_CHANGES
278 #else
279    p32[0] = 1;
280 #endif
281
282    /* Lets first print our debug information */
283    printf("\nBefore dumping our Debug info\n");
284    mtStopHndlr();
285    printf("\nAfter dumping our Debug info\n");
286
287    /* Disable the signal and make the enodeb to dump. This will make
288     * eNB to generate the core with dumping the ccpu log
289     */
290    {
291       char           *abc = NULL;
292       mtDelSigals();
293       *abc = 100;
294    }
295    /* End printing debug information */
296    exit(1);
297    /*while (1);*/
298 }
299 #endif
300 /*** TBD: IMPORTANT ***
301  *** The following definition is temporary. This must be removed
302  *** when all products have been updated with latest ssi.h file OR
303  *** all ssi.h files have been updated to contain this definitions
304  ***/
305 /* New error class for FTHA added */
306 #ifndef ERRCLS_FTHA
307 #define ERRCLS_FTHA    0x8
308 #endif /* ERRCLS_FTHA */
309
310 typedef struct _SPThreadCreateArg
311 {
312    void *argument; /* argument that is to be passed to the actual pthread */
313    void *(*start_routine) (void *); /* function from which pthread starts */   
314 }SPThreadCreateArg;
315
316 void *pthreadCreateHdlr(void*  arg);
317
318 #ifdef SS_LOCKLESS_MEMORY
319 Buffer *mtTskBuffer1;
320 Buffer *mtTskBuffer2;
321
322 pthread_t tmpRegTidMap[20];
323 uint8_t stopBtInfo;
324 S16 SGlobMemInfoShow(void);
325 #endif /* SS_LOCKLESS_MEMORY */
326
327 #ifdef L2_L3_SPLIT
328 APP_CONTEXT AppContext;
329 S32 clusterMode;
330 #endif
331
332 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
333 unsigned int tlPost(void *handle);
334 #endif
335 \f
336 /* forward references */
337 /* mt003.301 Modifications - Moved to ss_gen.x */
338 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
339 Void *mtTskHdlrT2kL2 ARGS((Void*));
340 void mtSigSegvHndlr ARGS((void));
341 void mtSigUsr2Hndlr ARGS((void));
342 #endif
343
344 static S16 ssdSetPthreadAttr ARGS ((S32 tskPrior, pthread_attr_t *attr));
345 static Void *mtTskHdlr ARGS((void *));
346 static S16 mtTskHdlMsg ARGS((SsSTskEntry *sTsk));
347
348 static Void *mtTmrHdlr ARGS((void *));
349 static Void mtTimeout ARGS((PTR tCb, S16 evnt));
350
351 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
352 static Void mtIntSigHndlr ARGS((int));
353 static Void mtExitClnup ARGS((void));
354
355 #ifdef CONAVL
356 static Void *mtConHdlr ARGS((void *));
357 #endif
358
359 #ifndef L2_L3_SPLIT
360 #ifdef SS_DRVR_SUPPORT
361 static Void *mtIsTskHdlr ARGS((void *));
362 #endif
363 #endif
364
365 /* mt020.201 - Addition for no command line available */
366 #ifndef NOCMDLINE
367 static Void mtGetOpts ARGS((void));
368 /* mt003.301 Additions - File Based task registration made
369  * common for both MULTICORE and NON-MULTICORE
370  */
371 static Bool fileBasedMemCfg = FALSE;
372 #endif
373
374 /* mt033.201 - addition of local function to print the statistics such as
375  * (size vs. numAttempts) and (allocations vs. deallocations)
376  */
377 #ifdef SSI_DEBUG_LEVEL1
378 static S16 SPrintRegMemStats ARGS((Region region));
379 #endif /* SSI_DEBUG_LEVEL1 */
380 \f
381 #ifdef SS_MULTICORE_SUPPORT
382 static SsSTskEntry* ssdAddTmrSTsk(Void);
383 static SsSTskEntry* ssdReAddTmrSTsk ARGS((uint8_t idx));
384 #ifndef SS_LOCKLESS_MEMORY
385 #ifndef RGL_SPECIFIC_CHANGES
386 static S16 ssdInitMemInfo ARGS((void));
387 #endif
388 #endif
389 #endif
390
391 /* mt005.301: Cavium changes */
392 #ifdef SS_SEUM_CAVIUM
393 static Void *workRcvTsk ARGS((void *));
394 #endif /* SS_SEUM_CAVIUM */
395
396 #ifdef SS_THR_REG_MAP
397 S32 ssCheckAndAddMemoryRegionMap ARGS((pthread_t  threadId,
398          Region region));
399 S32 ssCheckAndDelMemoryRegionMap ARGS((pthread_t  threadId));
400 #endif /* SS_THR_REG_MAP */
401 \f
402 /* type declarations */
403
404 #ifdef SS_DRVR_SUPPORT
405 typedef struct mtIsFlag
406 {
407    uint16_t id;
408    uint8_t  action;
409
410 } MtIsFlag;
411 #endif
412
413
414 \f
415 /* public variable declarations */
416
417 Cntr cfgNumRegs = SS_MAX_REGS;
418 /* Set memory configuration as false.
419  * Set to true if memory configuration through file is successfull.
420  */
421 Bool memConfigured = FALSE;
422 /* mt022.201 - Modification for shared memory relay region and memcal tool */
423 SsRegCfg cfgRegInfo[SS_MAX_REGS] =
424 {
425    {
426       SS_DFLT_REGION, SS_MAX_POOLS_PER_REG - 1,
427       {
428          { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
429          { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
430          { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
431          { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
432          { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
433          { SS_POOL_STATIC, 0 }
434       }
435    }
436 #ifdef INTEL_WLS
437    ,
438       {
439          SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
440          {
441             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
442             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
443             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
444             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
445             { SS_POOL_STATIC, 0 }
446          }
447       }
448 #endif /* INTEL_WLS */
449
450 #ifdef SS_LOCKLESS_MEMORY
451    ,
452       {
453          SS_DFLT_REGION + 1, SS_MAX_POOLS_PER_REG - 1,
454          {
455             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
456             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
457             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
458             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
459             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
460             { SS_POOL_STATIC, 0 }
461          }
462       },
463       {
464          SS_DFLT_REGION + 2, SS_MAX_POOLS_PER_REG - 1,
465          {
466             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
467             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
468             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
469             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
470             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
471             { SS_POOL_STATIC, 0 }
472          }
473       },
474       {
475          SS_DFLT_REGION + 3, SS_MAX_POOLS_PER_REG - 1,
476          {
477             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
478             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
479             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
480             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
481             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
482             { SS_POOL_STATIC, 0 }
483          }
484       }, 
485       {
486          SS_DFLT_REGION + 4, SS_MAX_POOLS_PER_REG - 1,
487          {
488             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
489             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
490             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
491             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
492             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
493             { SS_POOL_STATIC, 0 }
494          }
495       },
496       {
497          SS_DFLT_REGION + 5, SS_MAX_POOLS_PER_REG - 1,
498          {
499             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
500             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
501             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
502             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
503             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
504             { SS_POOL_STATIC, 0 }
505          }
506       },
507       {
508          SS_DFLT_REGION + 6, SS_MAX_POOLS_PER_REG - 1,
509          {
510             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
511             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
512             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
513             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
514             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
515             { SS_POOL_STATIC, 0 }
516          }
517       }
518 #ifndef INTEL_WLS_MEM
519    ,
520       {
521          SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1,
522          {
523             { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE },
524             { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE },
525             { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE },
526             { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE },
527             { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE },
528             { SS_POOL_STATIC, 0 }
529          }
530       }
531 #endif
532
533 #endif /* SS_LOCKLESS_MEMORY */
534 };
535 /* mt003.301 Modifications - File Based task registration made
536  * common for both MULTICORE and NON-MULTICORE
537  */
538
539 #ifdef SS_LOCKLESS_MEMORY
540 MtDynMemCfg mtDynMemoCfg =
541 {
542    SS_MAX_REGS,                                /* number of regions */
543    {
544       {
545          SS_DFLT_REGION,                         /* region id */
546          MT_MAX_BKTS,                            /* number of buckets */
547          {
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}, 
553             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
554          }
555       },
556       {
557          SS_DFLT_REGION + 1,                         /* region id */
558          MT_MAX_BKTS,                            /* number of buckets */
559          {
560             /* block size, no. of blocks, Upper threshold, lower 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},
564             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
565             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD} 
566          }
567       },
568       {
569          SS_DFLT_REGION + 2,                         /* region id */
570          MT_MAX_BKTS,                            /* number of buckets */
571          {
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},
577             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
578          }
579       },
580       {
581          SS_DFLT_REGION + 3,                         /* region id */
582          MT_MAX_BKTS,                            /* number of buckets */
583          {
584             /* block size, no. of blocks, Upper threshold, lower threshold */
585             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
586             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
587             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
588             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
589             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD} 
590          }
591       },
592       {
593          SS_DFLT_REGION + 4,                         /* region id */
594          MT_MAX_BKTS,                            /* number of buckets */
595          {
596             /* block size, no. of blocks, Upper threshold, lower threshold */
597             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
598             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
599             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
600             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
601             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
602          }
603       },
604       {
605          SS_DFLT_REGION + 5,                         /* region id */
606          MT_MAX_BKTS,                            /* number of buckets */
607          {
608             /* block size, no. of blocks, Upper threshold, lower threshold */
609             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
610             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
611             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
612             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
613             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
614          }
615       },
616       {
617          SS_DFLT_REGION + 6,                         /* region id */
618          MT_MAX_BKTS,                            /* number of buckets */
619          {
620             /* block size, no. of blocks, Upper threshold, lower threshold */
621             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
622             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
623             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
624             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
625             {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
626          }
627       }
628 #ifndef INTEL_WLS_MEM
629       ,
630          {
631             SS_DFLT_REGION + 7,                         /* region id */
632             MT_MAX_BKTS,                            /* number of buckets */
633             {
634                /* block size, no. of blocks, Upper threshold, lower threshold */
635                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
636                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
637                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
638                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
639                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}
640             }
641          }
642 #endif
643 #if ((defined (SPLIT_RLC_DL_TASK)) && (!defined (L2_L3_SPLIT)))
644       ,
645          {
646             SS_DFLT_REGION + 7,                         /* region id */
647             MT_MAX_BKTS,                            /* number of buckets */
648             {
649                /* block size, no. of blocks, Upper threshold, lower threshold */
650                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
651                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
652                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD},
653                {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD} 
654             }
655          }
656 #endif
657    }
658
659 };
660
661 MtGlobMemCfg mtGlobMemoCfg =
662 {
663    MT_MAX_BKTS,                            /* number of buckets */
664    {
665 #if 1
666       /* block size, no. of blocks, Upper threshold, lower threshold */
667       {MT_BKT_0_DSIZE, (MT_BKT_0_NUMBLKS + MT_BKT_0_NUMBLKS), SS_DFLT_MEM_BLK_SET_SIZE},
668       {MT_BKT_1_DSIZE, MT_BKT_1_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
669       {MT_BKT_2_DSIZE, MT_BKT_2_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
670       {MT_BKT_3_DSIZE, MT_BKT_3_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE},
671       {MT_BKT_4_DSIZE, MT_BKT_4_NUMBLKS, SS_DFLT_MEM_BLK_SET_SIZE}
672 #else
673       {1024, 12800 /* MT_BKT_0_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
674          {1664, 12800 /* MT_BKT_1_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE},
675          {4096, 3840 /* MT_BKT_2_NUMBLKS*/, SS_DFLT_MEM_BLK_SET_SIZE},
676          {MT_BKT_3_DSIZE, 12800 /* MT_BKT_3_NUMBLKS */, SS_DFLT_MEM_BLK_SET_SIZE}
677 #endif
678    }
679 };
680 #endif /* SS_LOCKLESS_MEMORY */
681
682 /* mt022.201 - Modification for memory calculator tool */
683 /* mt018.201 - added memory configuration matrix */
684 MtMemCfg mtMemoCfg =
685 {
686 #ifdef  RY_ENBS5SHM
687    SS_MAX_REGS - 1,                            /* number of regions */
688 #else
689 #ifndef XEON_SPECIFIC_CHANGES  
690    SS_MAX_REGS,                                /* number of regions */
691 #else
692    2,
693 #endif  
694 #endif
695    {
696       {
697          SS_DFLT_REGION,                         /* region id */
698          MT_MAX_BKTS,                            /* number of buckets */
699          MT_HEAP_SIZE,                           /* heap size */
700          {
701 #ifndef XEON_SPECIFIC_CHANGES  
702             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
703             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
704             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
705             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
706             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}
707 #else
708             {256, 491520}, /* 60 pages of 2M*/
709                {512, 12288},  /* 3 pages of 2M */
710                {2048, 99328}, /* 97 Pages of 2M */
711                {8192, 75008}, /* 293 Pages of 2M */
712                {16384, 4096}  /* 32 pages of 2M */
713 #endif        
714          }
715       },
716 #ifdef INTEL_WLS
717 #ifndef SS_LOCKLESS_MEMORY    
718       {
719          SS_DFLT_REGION + 1,                         /* region id */
720          MT_MAX_BKTS,                            /* number of buckets */
721          /*MT_HEAP_SIZE 7194304 */ 10485760,                           /* heap size */
722          {
723             //{MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
724             //{MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
725             //{MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
726             //{MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}    /* block size, no. of blocks */
727             {128,   500000},
728             {256,   500000},
729             {2048,  200000},
730             {4096,  40960},
731             {18432, 10240}
732          }
733       },
734 #endif /* SS_LOCKLESS_MEMORY */
735 #endif /* INTEL_WLS */
736 #ifdef SS_LOCKLESS_MEMORY
737       {
738          SS_DFLT_REGION + 1,                         /* region id */
739          MT_MAX_BKTS,                            /* number of buckets */
740          MT_HEAP_SIZE,                           /* heap size */
741          {
742             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
743             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
744             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
745             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
746             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
747          }
748       },
749       {
750          SS_DFLT_REGION + 2,                         /* region id */
751          MT_MAX_BKTS,                            /* number of buckets */
752          MT_HEAP_SIZE,                           /* heap size */
753          {
754             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
755             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
756             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
757             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
758             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
759          }
760       },
761       {
762          SS_DFLT_REGION + 3,                         /* region id */
763          MT_MAX_BKTS,                            /* number of buckets */
764          MT_HEAP_SIZE,                           /* heap size */
765          {
766             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
767             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
768             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
769             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
770             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
771          }
772       },
773       {
774          SS_DFLT_REGION + 4,                         /* region id */
775          MT_MAX_BKTS,                            /* number of buckets */
776          MT_HEAP_SIZE,                           /* heap size */
777          {
778             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
779             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
780             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
781             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
782             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
783          }
784       },
785       {
786          SS_DFLT_REGION + 5,                         /* region id */
787          MT_MAX_BKTS,                            /* number of buckets */
788          MT_HEAP_SIZE,                           /* heap size */
789          {
790             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
791             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
792             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
793             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
794             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
795          }
796       },
797       {
798          SS_DFLT_REGION + 6,                         /* region id */
799          MT_MAX_BKTS,                            /* number of buckets */
800          MT_HEAP_SIZE,                           /* heap size */
801          {
802             {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
803             {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
804             {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
805             {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
806             {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
807          }
808       }
809 #ifndef INTEL_WLS_MEM
810       ,
811          {
812             SS_DFLT_REGION + 7,                         /* region id */
813             MT_MAX_BKTS,                            /* number of buckets */
814             MT_HEAP_SIZE,                           /* heap size */
815             {
816                {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS},   /* block size, no. of blocks */
817                {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS},    /* block size, no. of blocks */
818                {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS},   /* block size, no. of blocks */
819                {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS},    /* block size, no. of blocks */
820                {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS}    /* block size, no. of blocks */
821             }
822          }
823 #endif
824 #endif /* SS_LOCKLESS_MEMORY */
825       STATIC_MEM_CFG
826    }
827 };
828 /* mt003.301 Modifications - File Based task registration made
829  * common for both MULTICORE and NON-MULTICORE
830  * bucket info, as different regions may request for different no.
831  * of blocks
832  */
833 MtBktCfg mtBktInfo[MT_MAX_BKTS];
834 S16 msArgc;              /* argc */
835 Txt **msArgv;            /* argv */
836 S16 msOptInd;            /* SGetOpt vars */
837 S8 *msOptArg;            /* SGetOpt vars */
838
839
840 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
841 typedef struct _MtRegMemSz
842 {
843    uint32_t   reqdSz;
844    uint8_t    *startAddr;
845 }MtRegMemSz;
846
847 #ifdef SS_USE_WLS_MEM
848 static MtRegMemSz mtDynMemSz[MT_MAX_BKTS];
849 static S16 SPartitionWlsDynMem();
850 static S16 SAllocateWlsDynMem();
851 #endif
852 #ifdef INTEL_WLS
853 static MtRegMemSz mtRegMemSz[MT_MAX_BKTS+1];
854 #endif
855 #endif
856
857 \f
858 /* private variable declarations */
859 /* mt018.201 - change mtCMMRegCfg as array of pointers */
860 static CmMmRegCfg *mtCMMRegCfg[SS_MAX_REGS];
861 static CmMmRegCb *mtCMMRegCb[SS_MAX_REGS];
862 /* mt003.301 - Fixed compilation warnings */
863 /*mt004.301-addede new veriable for FAP*/
864 /*mt010.301 - removed veriable defined for FA*/
865
866
867 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
868
869 #ifdef NTL_LIB
870 void mtSetNtlHdl(unsigned int hdl)
871 {
872    osCp.ntl.hdl =  hdl;
873 }
874
875 unsigned int mtGetNtlHdl()
876 {
877    return(osCp.ntl.hdl);
878 }
879
880 #endif  /* NTL_LIB */
881 void mtGetWlsHdl(void **hdlr)
882 {
883    *hdlr = osCp.wls.intf;
884 }       
885
886 #ifdef XEON_MULTIPLE_CELL_CHANGES
887 S8 gWrWlsDeviceName[MAX_WLS_DEVICE_NAME_LEN];
888 S16 smWrReadWlsConfigParams (Void);
889 #endif
890
891 static int SOpenWlsIntf()
892 {
893    uint8_t i;
894    void *hdl;
895 #define WLS_DEVICE_NAME "wls0"
896
897    char *my_argv[] = {"gnodeb", "-c3", "--proc-type=auto", "--file-prefix", WLS_DEVICE_NAME, "--iova-mode=pa"};
898    printf("\nCalling rte_eal_init: ");
899    for (i = 0; i < RTE_DIM(my_argv); i++)
900    {
901       printf("%s ", my_argv[i]); 
902    }
903    printf("\n");
904
905    if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
906       rte_panic("\nCannot init EAL\n");
907
908
909 #ifdef XEON_SPECIFIC_CHANGES
910 #ifdef XEON_MULTIPLE_CELL_CHANGES
911    hdl = WLS_Open(gWrWlsDeviceName, 1);
912 #else
913    hdl = WLS_Open(WLS_DEVICE_NAME, 1);
914 #endif
915 #else
916    hdl = WLS_Open(WLS_DEVICE_NAME, WLS_MASTER_CLIENT, WLS_MEM_SIZE);
917 #endif
918
919    osCp.wls.intf = hdl;
920
921    if(!osCp.wls.intf)
922    {
923       printf("\nCould not open WLS Interface \n");
924       return (0);
925    }
926
927    return (1);
928 }
929 #endif
930
931 /* mt028.201 */
932 #ifndef API_MAIN
933 \f
934 /*
935  *
936  *       Fun:   main
937  *
938  *       Desc:  This function is the entry point for the final binary. It
939  *              calls SInit() in the common code. It can be replaced by a
940  *              user function if required (SInit() must still be called).
941  *
942  *       Ret:   none on success
943  *              exit on failure
944  *
945  *       Notes:
946  *
947  *       File:  mt_ss.c
948  *
949  */
950    int main
951 (
952  int argc,                       /* argument count */
953  char **argv                     /* argument vector */
954  )
955 {
956
957 #ifdef XEON_MULTIPLE_CELL_CHANGES
958    /* Read the WLS parameters from the file and copy into global control block */
959    if(smWrReadWlsConfigParams() != ROK)
960    {
961       fprintf(stderr, "Failed to read WLS params from file wr_cfg.txt");
962       return RFAILED;
963    } /* end of if statement */
964 #endif
965
966 #if defined (INTEL_WLS) || defined (SS_USE_WLS_MEM)
967    if(!SOpenWlsIntf())
968       return (0);
969 #endif /* INTEL_WLS */
970
971    msArgc = argc;
972    msArgv = argv;
973    /* mt003.301 Modifications */
974    if( ROK != SInit())
975    {
976       printf("\n SInit failed, SSI could not start \n");
977       /* pthread_exit(NULLP);*/ /* Commented to Come out of Main thread*/
978
979       return (0);
980    }
981    /*mt010.301  cleanup part exposed to user*/
982    SFini();
983    return (0);
984 }
985
986 #else
987 \f
988 /*
989  *
990  *       Fun:   ssMain
991  *
992  *       Desc:  This function is the entry point for the final binary. It
993  *              calls SInit() in the common code. It can be replaced by a
994  *              user function if required (SInit() must still be called).
995  *
996  *       Ret:   none on success
997  *              exit on failure
998  *
999  *       Notes:
1000  *
1001  *       File:  mt_ss.c
1002  *
1003  */
1004    int ssMain
1005 (
1006  int argc,                       /* argument count */
1007  char **argv                     /* argument vector */
1008  )
1009 {
1010
1011
1012    msArgc = argc;
1013    msArgv = argv;
1014
1015
1016    SInit();
1017
1018    return (0);
1019 }
1020
1021 #endif
1022 /*
1023  *  initialization functions
1024  */
1025
1026 /*
1027  *
1028  *       Fun:   Initialize OS control point
1029  *
1030  *       Desc:  This function initializes MTSS-specific information
1031  *              in the OS control point.
1032  *
1033  *       Ret:   ROK      - ok
1034  *
1035  *       Notes:
1036  *
1037  *       File:  mt_ss.c
1038  *
1039  */
1040 S16 ssdInitGen(void)
1041 {
1042    struct sigaction act;
1043    sigset_t set;
1044 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1045    struct sigaction sa;
1046 #endif
1047
1048
1049    /*mt014.301 : 4GMX release related changes*/
1050 #ifdef SS_4GMX_UCORE
1051    uarmInit();
1052 #endif
1053    /* mt005.301 : Cavium changes */
1054 #ifdef SS_SEUM_CAVIUM
1055    /* set group mask for the core */
1056    cvmx_pow_set_group_mask(cvmx_get_core_num(), SS_CVMX_GRP_MASK);
1057 #endif /* SS_SEUM_CAVIUM */
1058
1059    osCp.dep.sysTicks = 0;
1060
1061    /* mt020.201 - Addition for no command line available */
1062 #ifndef NOCMDLINE
1063    /* parse command line */
1064    mtGetOpts();
1065    /* mt003.301 Additions */
1066    if(fileBasedMemCfg == TRUE && memConfigured == FALSE)
1067    {
1068       printf("\n File Based Memory configuration failed \n");
1069       return RFAILED;
1070    }
1071 #endif
1072
1073 #ifndef RGL_SPECIFIC_CHANGES /* ANOOP :: This ssdInitMemInfo() was present in 2.1 */
1074 #ifndef SS_LOCKLESS_MEMORY
1075 #ifdef SS_MULTICORE_SUPPORT
1076    if(memConfigured == FALSE)
1077       ssdInitMemInfo();
1078 #endif
1079 #endif
1080 #endif
1081
1082    /* initialize the started semaphore */
1083    if (sem_init(&osCp.dep.ssStarted, 0, 0) != 0)
1084    {
1085       return RFAILED;
1086    }
1087
1088    /* mt028.201 added compile time flag to allow not to mask signals */
1089 #ifndef UNMASK_SIG
1090    /* mask all signals in the main thread */
1091    sigfillset(&set);
1092    sigdelset(&set, SIGINT);
1093 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1094    sigdelset(&set, SIGSEGV);
1095    sigdelset(&set, SIGUSR2);
1096    sigdelset(&set, SIGILL);
1097 #ifdef XEON_SPECIFIC_CHANGES
1098    sigdelset(&set, SIGABRT);
1099    sigdelset(&set, SIGTERM);
1100    sigdelset(&set, SIGHUP);
1101 #endif   
1102 #endif
1103    pthread_sigmask(SIG_SETMASK, &set, NULLP);
1104 #endif /* UNMASK_SIG */
1105
1106    /* install a SIGINT handler to shutdown */
1107    /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
1108
1109    /*Initialize SIGSEGV Signal */
1110 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
1111 #if 1
1112    memset(&sa, 0, sizeof(struct sigaction));
1113    sigemptyset(&sa.sa_mask);
1114    sa.sa_sigaction = signal_segv;
1115    sa.sa_flags = SA_SIGINFO;
1116 #ifndef XEON_SPECIFIC_CHANGES
1117    sigaction(SIGSEGV, &sa, NULL);
1118
1119    memset(&sa, 0, sizeof(struct sigaction));
1120    sigemptyset(&sa.sa_mask);
1121    sa.sa_sigaction = signal_segv;
1122    sa.sa_flags = SA_SIGINFO;
1123
1124    sigaction(SIGILL, &sa, NULL);
1125 #else
1126    if(sigaction(SIGILL, &sa, NULL) != 0)
1127    {
1128       printf("\nFailed to process sigaction for the SIGILL\n");
1129       return RFAILED;
1130    }
1131    if(sigaction(SIGSEGV, &sa, NULL) != 0)
1132    {
1133       printf("\nFailed to process sigaction for the SIGSEGV\n");
1134       return RFAILED;
1135    }
1136    if(sigaction(SIGABRT, &sa, NULL) != 0)
1137    {
1138       printf("\nFailed to process sigaction for the SIGABRT\n");
1139       return RFAILED;
1140    }
1141    if(sigaction(SIGTERM, &sa, NULL) != 0)
1142    {
1143       printf("\nFailed to process sigaction for the SIGTERM\n");
1144       return RFAILED;
1145    }
1146    if(sigaction(SIGHUP, &sa, NULL) != 0)
1147    {
1148       printf("\nFailed to process sigaction for the SIGHUP\n");
1149       return RFAILED;
1150    }
1151 #endif    
1152 #else
1153    signal (SIGSEGV, mtSigSegvHndlr);
1154    signal (SIGKILL, mtSigSegvHndlr);
1155    signal (SIGUSR2, mtSigUsr2Hndlr);
1156 #endif   
1157 #endif
1158
1159 #ifdef MLOG_XEON
1160    signal (SIGINT, mtStopHndlr);
1161 #else
1162
1163    act.sa_handler = mtIntSigHndlr;
1164    sigfillset(&act.sa_mask);
1165    act.sa_flags = 0;
1166    if (sigaction(SIGINT, &act, NULLP) != 0)
1167    {
1168       return RFAILED;
1169    }
1170 #endif
1171
1172    /* mt040.201 initialise random seed */
1173    osCp.dep.randSeed = time(NULLP);
1174
1175    return ROK;
1176 }
1177
1178 \f
1179 /*
1180  *
1181  *       Fun:   De-initialize OS control point
1182  *
1183  *       Desc:  This function reverses the initialization in ssdInitGen().
1184  *
1185  *       Ret:   ROK      - ok
1186  *
1187  *       Notes:
1188  *
1189  *       File:  mt_ss.c
1190  *
1191  */
1192 Void ssdDeinitGen(void)
1193 {
1194
1195
1196    sem_destroy(&osCp.dep.ssStarted);
1197
1198
1199    return;
1200 }
1201 #ifdef SS_LOCKLESS_MEMORY
1202 #ifdef USE_MALLOC
1203 /*
1204  *
1205  *       Fun:   ssPutDynMemBlkSet
1206  *
1207  *       Desc:  Returns the set of dynamic Blocks into the global region
1208  *
1209  *
1210  *       Ret:   ROK     - successful, 
1211  *              RFAILED - unsuccessful.
1212  *
1213  *       Notes: 
1214  *
1215  *       File:  cm_mem.c
1216  *
1217  */
1218 S16 ssPutDynMemBlkSet
1219 (
1220  uint8_t                    bktIdx,        /* Index to bucket list */
1221  CmMmBlkSetElement    *dynMemSetElem  /* Memory set element which is needs to be 
1222                                          added to global region */
1223  )
1224 {
1225    CmMmGlobRegCb        *globReg;
1226    CmMmGlobalBktCb      *bktCb;
1227    Data                 *blkPtr;
1228    uint8_t                    blkCnt;
1229
1230    globReg = osCp.globRegCb;
1231
1232 #if (ERRCLASS & ERRCLS_INT_PAR)
1233    if(bktIdx >= globReg->numBkts)
1234    {
1235       return RFAILED;
1236    }
1237 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1238
1239    bktCb = &(globReg->bktTbl[bktIdx]);
1240
1241    for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1242    {
1243       blkPtr = dynMemSetElem->nextBktPtr;
1244       dynMemSetElem->nextBktPtr = *((CmMmEntry **)blkPtr);
1245       free((Void *)blkPtr);
1246    }
1247
1248    dynMemSetElem->nextBktPtr = NULLP;
1249    dynMemSetElem->numFreeBlks = 0;
1250
1251    return ROK;
1252 }
1253
1254 /*
1255  *
1256  *       Fun:   ssGetDynMemBlkSet
1257  *
1258  *       Desc:  Gets the set of dynamic memory blocks from the global region
1259  *
1260  *
1261  *       Ret:   ROK     - successful, 
1262  *              RFAILED - unsuccessful.
1263  *
1264  *       Notes: 
1265  *
1266  *       File:  cm_mem.c
1267  *
1268  */
1269 S16 ssGetDynMemBlkSet
1270 (
1271  uint8_t               bktIdx,        /* Index to bucket list */
1272  CmMmBlkSetElement     *dynMemSetElem  /* Memory set element which is updated 
1273                                           with new set values */
1274  )
1275 {
1276
1277    CmMmGlobRegCb        *globReg;
1278    CmMmGlobalBktCb      *bktCb;
1279    Data                **basePtr;
1280    Data                 *blkPtr;
1281    uint8_t                    blkCnt;
1282
1283    globReg = osCp.globRegCb;
1284
1285 #if (ERRCLASS & ERRCLS_INT_PAR)
1286    if(bktIdx >= globReg->numBkts)
1287    {
1288       return RFAILED;
1289    }
1290 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1291
1292    bktCb   = &(globReg->bktTbl[bktIdx]);
1293    basePtr = &(dynMemSetElem->nextBktPtr);
1294
1295    for(blkCnt = 0; blkCnt < bktCb->bucketSetSize; blkCnt++)
1296    {
1297       blkPtr = (Data *)malloc(bktCb->size);
1298       *basePtr = blkPtr;
1299       basePtr = (CmMmEntry **)blkPtr;
1300    }
1301
1302    dynMemSetElem->numFreeBlks = bktCb->bucketSetSize;
1303
1304    return ROK;
1305
1306 } /* ssGetDynMemBlkSet */
1307
1308 #else
1309 /*
1310  *
1311  *       Fun:   ssPutDynMemBlkSet
1312  *
1313  *       Desc:  Returns the set of dynamic Blocks into the global region
1314  *
1315  *
1316  *       Ret:   ROK     - successful, 
1317  *              RFAILED - unsuccessful.
1318  *
1319  *       Notes: 
1320  *
1321  *       File:  cm_mem.c
1322  *
1323  */
1324 S16 ssPutDynMemBlkSet
1325 (
1326  uint8_t              bktIdx,               /* Index to bucket list */
1327  CmMmBlkSetElement    *dynMemSetElem,        /* Memory set element which is needs to be 
1328                                                 added to global region */
1329  uint32_t             doNotBlockForLock    /* Boolean whether to block for lock or not */
1330  )
1331 {
1332    CmMmGlobRegCb       *globReg;
1333    CmMmGlobalBktCb     *bktCb;
1334    CmLList             *lstNode;
1335    CmMmBlkSetElement   *globMemNode;
1336    S16                  lockRet = 0;
1337
1338
1339    globReg = osCp.globRegCb;
1340
1341 #if (ERRCLASS & ERRCLS_INT_PAR)
1342    if(bktIdx >= globReg->numBkts)
1343    {
1344       return RFAILED;
1345    }
1346 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1347
1348    bktCb = &(globReg->bktTbl[bktIdx]);
1349
1350    /* Lock the global region first. If the doNotBlockForLock is non-zero, the 
1351       try lock is used as it is not required to block as it will be taken
1352       in the next go else it will be blocked for lock as we have to get the
1353       blocks must */
1354    {
1355       SLock(&(bktCb->bucketLock));
1356    }
1357
1358    if(lockRet == 0)
1359    {
1360
1361       /* Get a free node from the free node linked list */
1362       lstNode = cmLListFirst(&(bktCb->listFreeBktSet));
1363       if(lstNode == NULLP)
1364       {
1365          SUnlock(&(bktCb->bucketLock));
1366          return RFAILED;
1367       }
1368
1369       cmLListDelFrm(&(bktCb->listFreeBktSet), lstNode);
1370
1371       /* Copy the content of the received element information on to free node 
1372        * and add it to valid linked list */
1373       globMemNode = (CmMmBlkSetElement *)lstNode->node;
1374       globMemNode->numFreeBlks = dynMemSetElem->numFreeBlks;
1375       globMemNode->nextBktPtr = dynMemSetElem->nextBktPtr;
1376       dynMemSetElem->numFreeBlks = 0;
1377       dynMemSetElem->nextBktPtr = NULLP;
1378
1379       cmLListAdd2Tail(&(bktCb->listValidBktSet), &(globMemNode->memSetNode));
1380
1381       SUnlock(&(bktCb->bucketLock));
1382    }
1383
1384    return ROK;
1385 }
1386
1387 /*
1388  *
1389  *       Fun:   ssGetDynMemBlkSet
1390  *
1391  *       Desc:  Gets the set of dynamic memory blocks from the global region
1392  *
1393  *
1394  *       Ret:   ROK     - successful, 
1395  *              RFAILED - unsuccessful.
1396  *
1397  *       Notes: The parameter doNotBlockForLock specifies whether to block for lock
1398  *              or not 
1399  *
1400  *       File:  cm_mem.c
1401  *
1402  */
1403 S16 ssGetDynMemBlkSet
1404 (
1405  uint8_t                     bktIdx,              /* Index to bucket list */
1406  CmMmBlkSetElement     *dynMemSetElem,       /* Memory set element which is updated 
1407                                                 with new set values */
1408  uint32_t                    doNotBlockForLock    /* Boolean whether to block for lock or not */
1409  )
1410 {
1411    CmMmGlobRegCb        *globReg;
1412    CmMmGlobalBktCb      *bktCb;
1413    CmLList              *lstNode;
1414    CmMmBlkSetElement    *globMemNode;
1415    S16                   lockRet = 0;
1416
1417
1418    globReg = osCp.globRegCb;
1419
1420 #if (ERRCLASS & ERRCLS_INT_PAR)
1421    if(bktIdx >= globReg->numBkts)
1422    {
1423       return RFAILED;
1424    }
1425 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1426
1427    bktCb = &(globReg->bktTbl[bktIdx]);
1428
1429    /* Lock the global region first. If the doNotBlockForLock is non-zero, the 
1430       try lock is used as it is not required to block as it will be taken
1431       in the next go else it will be blocked for lock as we have to get the
1432       blocks must */
1433    {
1434       SLock(&(bktCb->bucketLock));
1435    }
1436
1437    if(lockRet == 0)
1438    {
1439       lstNode = cmLListFirst(&(bktCb->listValidBktSet));
1440
1441       if(lstNode == NULLP)
1442       {
1443          SUnlock(&(bktCb->bucketLock));
1444          return RFAILED;
1445       }
1446
1447       /* Delete the node from the valid linked list and copy the values of the
1448        * elements of structrues into pointer */
1449       cmLListDelFrm(&(bktCb->listValidBktSet), lstNode);
1450       globMemNode = (CmMmBlkSetElement *)lstNode->node;
1451       dynMemSetElem->numFreeBlks = globMemNode->numFreeBlks;
1452       dynMemSetElem->nextBktPtr = globMemNode->nextBktPtr;
1453
1454       /* Add this node to the free node linked list */
1455       cmLListAdd2Tail(&(bktCb->listFreeBktSet), lstNode);
1456
1457       SUnlock(&(bktCb->bucketLock));
1458    }
1459
1460    return ROK;
1461 } /* ssGetDynMemBlkSet */
1462
1463
1464 #define NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN 100
1465 uint32_t gDynMemAlrm[4];
1466 static uint32_t memoryCheckCounter;
1467
1468 uint32_t isMemThreshReached(Region reg)
1469 {
1470    CmMmGlobRegCb        *globReg;
1471    CmMmGlobalBktCb      *bktCb;
1472    uint8_t bktIdx= reg;
1473
1474    globReg = osCp.globRegCb;
1475
1476 #if (ERRCLASS & ERRCLS_INT_PAR)
1477    if(bktIdx >= globReg->numBkts)
1478    {
1479       return RFAILED;
1480    }
1481 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1482
1483    bktCb   = &(globReg->bktTbl[bktIdx]);
1484
1485    if(gDynMemAlrm[bktIdx])
1486    {
1487       //        printf ("\nunder memory   bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1488       SLock(&(bktCb->bucketLock));
1489       if(bktCb->listValidBktSet.count > 25)
1490       {
1491          gDynMemAlrm[bktIdx] = FALSE;
1492          //      printf ("\nrecoverd bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1493       }
1494       SUnlock(&(bktCb->bucketLock));
1495       return RFAILED;
1496    }
1497    else
1498    {
1499
1500       if(memoryCheckCounter++ >= NUM_CALLS_TO_CHECK_MEM_DYN_AGAIN)
1501       {
1502          //    printf ("\nCHECK  bktCb->listValidBktSet.count %d bktIdx %d\n",bktCb->listValidBktSet.count ,bktIdx);
1503          SLock(&(bktCb->bucketLock));
1504          if(bktCb->listValidBktSet.count < 15 )
1505             gDynMemAlrm[bktIdx] = TRUE;
1506          memoryCheckCounter = 0;
1507          SUnlock(&(bktCb->bucketLock));
1508       }
1509    }
1510    return ROK;
1511 }
1512
1513 #endif /* USE_MALLOC */
1514 #endif /* SS_LOCKLESS_MEMORY */
1515
1516 #ifdef SS_USE_ICC_MEMORY
1517 /*
1518  *
1519  *       Fun:   Initialize region/pool tables
1520  *
1521  *       Desc:  This function initializes MTSS-specific information
1522  *              in the region/pool tables and configures the common
1523  *              memory manager for use.
1524  *
1525  *       Ret:   ROK      - ok
1526  *
1527  *       Notes:
1528  *
1529  *       File:  mt_ss.c
1530  *
1531  */
1532 Void * ssGetIccHdl(Region region)
1533 {
1534    CmMmDynRegCb *dynRegCb;
1535
1536    /* Klock work fix ccpu00148484 */
1537    if(!(region < SS_MAX_REGS))
1538    {
1539       return (NULLP);
1540    }
1541
1542    dynRegCb = (CmMmDynRegCb *)osCp.dynRegionTbl[region].regCb; 
1543
1544    return (dynRegCb->iccHdl);
1545 }
1546 #endif /* SS_USE_ICC_MEMORY */
1547
1548 #ifdef T2K_MEM_LEAK_DBG
1549 RegionMemLeakInfo regMemLeakInfo;
1550 #endif /* T2K_MEM_LEAK_DBG */
1551
1552 #ifdef SS_USE_WLS_MEM
1553 static S16 SPartitionWlsDynMem()
1554 {
1555    uint32_t i;
1556    uint8_t *bktMemStrtAddr = (uint8_t *)(((uint8_t*)osCp.wls.allocAddr) + (4 * 1024 * 1024));
1557
1558    for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1559    {
1560       mtDynMemSz[i].startAddr = bktMemStrtAddr;
1561       bktMemStrtAddr += mtDynMemSz[i].reqdSz;
1562    }
1563
1564    printf("\nGlobal Memory Info: \n");
1565    for (i = 0 ; i <  mtGlobMemoCfg.numBkts ; i++)
1566    {
1567       printf("mtDynMemSz[%d]: [0x%016lx]\n", i, (unsigned long int)mtDynMemSz[i].startAddr);
1568    }
1569    return ROK;
1570 }
1571
1572 static S16 SAllocateWlsDynMem()
1573 {
1574    uint32_t     reqdMemSz;
1575    uint32_t     i;
1576    reqdMemSz = 0;
1577    memset(&mtDynMemSz[0], 0, sizeof(mtDynMemSz));
1578
1579    for (i = 0 ; i < mtGlobMemoCfg.numBkts ; i++)
1580    {
1581       reqdMemSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1582       mtDynMemSz[i].reqdSz += (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1583    }
1584    osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf,
1585 #ifdef INTEL_L1_V19_10
1586          WLS_MEMORY_SIZE);
1587 #else
1588    (reqdMemSz + (4 * 1024 * 1024)));
1589 #endif
1590    printf("\n *************** \n WLS memory: %lx, %d\n", (PTR)osCp.wls.allocAddr, reqdMemSz);
1591    SPartitionWlsDynMem();
1592    return ROK;
1593 }
1594
1595 #endif
1596
1597 #ifdef INTEL_WLS
1598
1599 S16 SPartitionWlsMemory()
1600 {
1601    uint32_t    i;
1602 #ifndef ALIGN_64BIT
1603    uint64_t    reqdSz;
1604    uint64_t   pageSize[1], hugePageSize;
1605 #else
1606    long int reqdSz;
1607    long int pageSize[1], hugePageSize;
1608 #endif
1609    uint32_t numHugePg;
1610 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
1611
1612    uint8_t   *regMemStrtAddr = (uint8_t *)osCp.wls.allocAddr;
1613
1614    gethugepagesizes(pageSize,1);
1615    hugePageSize = pageSize[0];
1616    for (i = 0; i < 1; i++)
1617    {
1618       mtRegMemSz[i].startAddr = regMemStrtAddr;
1619       //CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Region-->Bkt[%d] Addr:%p\n", i, mtRegMemSz[i].startAddr);
1620
1621       numHugePg = DIV_ROUND_OFFSET(mtRegMemSz[i].reqdSz, hugePageSize);
1622       reqdSz    = numHugePg * hugePageSize;
1623       regMemStrtAddr += reqdSz;
1624 #ifdef T2K_MEM_LEAK_DBG
1625       /* Since wls is region 0 */
1626       regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1627       regMemLeakInfo.numActvRegions++;
1628 #endif /* T2K_MEM_LEAK_DBG */
1629    }
1630    //Store last region addr for validation
1631    mtRegMemSz[i].startAddr = regMemStrtAddr;
1632    return ROK;
1633 }
1634
1635 #ifdef SS_MEM_WL_DEBUG
1636 Void SChkAddrValid(int type, int region, PTR ptr)
1637 {
1638    char *tryPtr = NULL;
1639    if(type == 0) //Global
1640    {
1641       if(ptr < mtRegMemSz[0].startAddr || ptr >=
1642             (mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr + mtGlobMemoCfg.heapSize))
1643       {
1644          printf("\n****INVALID PTR in Global Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1645          *tryPtr = 0;
1646       }
1647    }
1648    else
1649    {
1650       if(ptr > mtRegMemSz[0].startAddr && ptr <= mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr )
1651       {
1652          printf("\n****INVALID PTR in Static Region: ptr:%p start:%p end:%p***\n", ptr, mtRegMemSz[0].startAddr, mtRegMemSz[mtGlobMemoCfg.numBkts].startAddr);
1653          *tryPtr = 0;
1654       }
1655
1656    }
1657 }
1658 #endif /* SS_MEM_WL_DEBUG */
1659
1660 S16 SPartitionStaticMemory(uint8_t  *startAddr)
1661 {
1662    int    i;
1663    uint32_t    reqdSz;
1664
1665    uint8_t   *regMemStrtAddr = (uint8_t *)startAddr;
1666
1667
1668    //for (i = 0; i < mtMemoCfg.numRegions; i++)
1669    for (i = 1; i < mtMemoCfg.numRegions; i++)
1670    {
1671       mtRegMemSz[i].startAddr = regMemStrtAddr;
1672       reqdSz    = /* regMemStrtAddr + */mtRegMemSz[i].reqdSz;
1673       regMemStrtAddr += reqdSz;
1674 #ifdef T2K_MEM_LEAK_DBG
1675       {  /* Since region 1 onwards are used for non wls */
1676          regMemLeakInfo.regStartAddr[i] = (uint64_t)mtRegMemSz[i].startAddr;
1677          regMemLeakInfo.numActvRegions++;
1678       }
1679 #endif /* T2K_MEM_LEAK_DBG */
1680    }
1681    return ROK;
1682 }
1683 S16 SAllocateWlsMem()
1684 {
1685
1686    uint32_t            reqdMemSz;
1687    uint32_t            i, j;
1688    MtRegCfg       *region;
1689
1690    reqdMemSz = 0;
1691    //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1692    memset(&mtRegMemSz[0], 0, sizeof(mtRegMemSz));
1693
1694    for (i = 0; i < 1; i++)
1695    {
1696       /* allocate space for the region */
1697       region = &mtMemoCfg.region[i];
1698       reqdMemSz += region->heapsize;
1699       mtRegMemSz[i].reqdSz  += region->heapsize;
1700
1701       for (j = 0; j < region->numBkts; j++)
1702       {
1703          reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1704          mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1705       }
1706    }
1707    osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (512 *1024 * 1024));
1708    //osCp.wls.allocAddr = WLS_Alloc(osCp.wls.intf, (reqdMemSz + (1024 * 1024 * 2 * 2)));
1709 #ifndef ALIGN_64BIT
1710    printf("\n ************* \n WLS memory: %llx, %ld\n ****** \n", osCp.wls.allocAddr, reqdMemSz); 
1711 #else
1712    printf("\n ************* \n WLS memory: %lx, %d\n ****** \n", (PTR)osCp.wls.allocAddr, reqdMemSz); 
1713 #endif
1714    SPartitionWlsMemory();
1715    return ROK;
1716 }
1717 S16 SAllocateStaticMem()
1718 {
1719
1720    uint32_t            reqdMemSz;
1721    int            i, j;
1722    MtRegCfg       *region;
1723    uint8_t             *startAddr;
1724
1725    reqdMemSz = 0;
1726    //memset(&mtRegMemSz[0], sizeof(mtRegMemSz), 0);
1727
1728    //for (i = 0; i < mtMemoCfg.numRegions; i++)
1729    for (i = 1; i <  mtMemoCfg.numRegions; i++)
1730    {
1731       /* allocate space for the region */
1732       region = &mtMemoCfg.region[i];
1733       reqdMemSz += region->heapsize;
1734       mtRegMemSz[i].reqdSz  += region->heapsize;
1735
1736       for (j = 0; j < region->numBkts; j++)
1737       {
1738          reqdMemSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1739          mtRegMemSz[i].reqdSz += region->bkt[j].blkSize * region->bkt[j].numBlks;
1740       }
1741    }
1742
1743    startAddr = malloc(reqdMemSz + (1024 * 10));
1744 #ifndef ALIGN_64BIT
1745    printf("\n ************* \n Static memory: %llx, %ld\n ****** \n", startAddr, reqdMemSz); 
1746 #else
1747    printf("\n ************* \n Static memory: %lx, %d\n ****** \n", (PTR)startAddr, reqdMemSz); 
1748 #endif
1749    SPartitionStaticMemory(startAddr);
1750    return ROK;
1751 }
1752 #endif /* INTEL_WLS */
1753
1754 \f
1755 \f
1756 /*
1757  *
1758  *       Fun:   Initialize region/pool tables
1759  *
1760  *       Desc:  This function initializes MTSS-specific information
1761  *              in the region/pool tables and configures the common
1762  *              memory manager for use.
1763  *
1764  *       Ret:   ROK      - ok
1765  *
1766  *       Notes:
1767  *
1768  *       File:  mt_ss.c
1769  *
1770  */
1771 S16 ssdInitMem(void)
1772 {
1773    /* mt018.201 - added local variable */
1774    uint8_t              i =0;
1775    uint16_t             j =0;
1776    uint8_t              k =0;
1777    MtRegCfg       *region = NULLP;
1778    Txt             errMsg[256] = {'\0'};
1779 #ifdef SS_LOCKLESS_MEMORY
1780    CmMmDynRegCb   *dynRegCb =0;
1781 #ifdef SS_USE_ICC_MEMORY
1782 #else
1783    CmMmGlobRegCb  *globReg = NULLP;
1784    Size            memSize =0;
1785 #endif
1786 #endif /* SS_LOCKLESS_MEMORY */
1787
1788
1789    /* Use the default SSI memory manager if the ICC memory manager is not 
1790     * avilable. If ICC memory manager is avilable, it will be used for
1791     * all sharable memory allocation and de-allocation */
1792 #ifdef SS_LOCKLESS_MEMORY
1793 #ifdef SS_USE_ICC_MEMORY
1794 #ifndef YS_PHY_3_8_2
1795 #endif
1796    for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1797    {
1798       dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1799       if(dynRegCb == NULLP)
1800       {
1801          return RFAILED;
1802       }
1803       for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1804       {
1805          dynRegCb->bktSize[k] = mtGlobMemoCfg.bkt[k].blkSize;
1806       }
1807       dynRegCb->region = i;
1808       cmMmDynRegInit(dynRegCb);
1809       printf("\niccHdl = %lx\n", (PTR)dynRegCb->iccHdl);
1810       sleep(1);
1811    }
1812    /*   ysIccHdl = dynRegCb->iccHdl; */
1813
1814 #else
1815    /* Initialize the global region first */
1816    osCp.globRegCb = calloc(1, sizeof(CmMmGlobRegCb));
1817
1818    if(osCp.globRegCb == NULLP)
1819    {
1820       return RFAILED;
1821    }
1822
1823    globReg = (CmMmGlobRegCb *)osCp.globRegCb;
1824
1825 #ifdef SS_USE_WLS_MEM
1826    SAllocateWlsDynMem();
1827 #endif
1828
1829    for(i = 0; i < mtGlobMemoCfg.numBkts; i++)
1830    {
1831       memSize = (mtGlobMemoCfg.bkt[i].blkSize * mtGlobMemoCfg.bkt[i].numBlks);
1832 #if !defined (INTEL_WLS) && defined (SS_USE_WLS_MEM)
1833       globReg->bktTbl[i].startAddr = (Data *)mtDynMemSz[i].startAddr;
1834       printf("\nStarting Address of Bkt Entry [%d]: [0x%016lx], memSize[%d]\n", i, (unsigned long int)globReg->bktTbl[i].startAddr, memSize);
1835 #else
1836 #ifndef INTEL_WLS      
1837       globReg->bktTbl[i].startAddr = (Data *)calloc(memSize, sizeof(Data));
1838 #else
1839       globReg->bktTbl[i].startAddr = (Data *)mtRegMemSz[i].startAddr;
1840 #endif
1841 #endif
1842       if(globReg->bktTbl[i].startAddr == NULLP)
1843       {
1844          return RFAILED;
1845       }
1846       globReg->bktTbl[i].poolId = i;
1847       globReg->bktTbl[i].size = mtGlobMemoCfg.bkt[i].blkSize;
1848       globReg->bktTbl[i].numBlks = mtGlobMemoCfg.bkt[i].numBlks;
1849       globReg->bktTbl[i].bucketSetSize = mtGlobMemoCfg.bkt[i].bucketSetSize;
1850    }
1851
1852    globReg->numBkts = mtGlobMemoCfg.numBkts;
1853    cmMmGlobRegInit(globReg);
1854
1855    /* Initialize the dynamic task regions and sanity check for the theshold 
1856     * values */
1857    for (i = 0; i < mtDynMemoCfg.numRegions; i++)
1858    {
1859       dynRegCb = (CmMmDynRegCb *)calloc(1, sizeof(CmMmDynRegCb));
1860       if(dynRegCb == NULLP)
1861       {
1862          return RFAILED;
1863       }
1864       for(k = 0; k < mtDynMemoCfg.region[i].numBkts; k++)
1865       {
1866          if((mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold < 
1867                   mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold) ||
1868                (mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold == 0) ||
1869                (mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold == 0))
1870          {
1871 #ifdef XEON_SPECIFIC_CHANGES
1872             free(dynRegCb);
1873 #endif            
1874             return RFAILED;
1875          }
1876          dynRegCb->bktTbl[k].poolId = k;
1877          dynRegCb->bktTbl[k].size = mtGlobMemoCfg.bkt[k].blkSize;
1878          dynRegCb->bktTbl[k].blkSetRelThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetRelThreshold;
1879          dynRegCb->bktTbl[k].blkSetAcquireThreshold = mtDynMemoCfg.region[i].bkt[k].blkSetAcquireThreshold;
1880          dynRegCb->bktTbl[k].bucketSetSize = mtGlobMemoCfg.bkt[k].bucketSetSize;
1881          if(dynRegCb->bktMaxBlkSize < dynRegCb->bktTbl[k].size)
1882          {
1883             dynRegCb->bktMaxBlkSize = dynRegCb->bktTbl[k].size;
1884          }
1885       }
1886       dynRegCb->region = i;
1887       dynRegCb->numBkts = mtDynMemoCfg.region[i].numBkts;
1888       cmMmDynRegInit(dynRegCb);
1889    }
1890 #endif /* SS_USE_ICC_MEMORY */
1891 #endif /* SS_LOCKLESS_MEMORY */
1892
1893 #ifdef T2K_MEM_LEAK_DBG
1894    uint8_t reg =0; 
1895    /* Initailize mem leak tool memorys for debguing */
1896    regMemLeakInfo.numActvRegions=0;
1897    for(reg=0; reg <SS_MAX_REGS; reg++)
1898    {   
1899       regMemLeakInfo.gMemLeakInfo[reg] =  malloc(sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1900       memset(regMemLeakInfo.gMemLeakInfo[reg],0x0,
1901             sizeof(T2kMeamLeakInfo)*T2K_MEM_LEAK_INFO_TABLE_SIZE);
1902       regMemLeakInfo.regStartAddr[reg] = 0;
1903
1904
1905       regMemLeakInfo.regStartAddr[reg] = 0;
1906       if (pthread_mutex_init(&(regMemLeakInfo.memLock[reg]), NULL) != 0)
1907       {
1908          printf("\n mutex init failed\n");
1909          return RFAILED;
1910       }
1911    }
1912 #endif
1913 #ifdef INTEL_WLS
1914    /* Now allocate WLS memory */
1915    SAllocateWlsMem();
1916    SAllocateStaticMem();
1917 #endif
1918    /* mt018.201 - CMM Initialization */
1919    for (i = 0; i < mtMemoCfg.numRegions; i++)
1920    {
1921       /* allocate space for the region control block */
1922       mtCMMRegCb[i] = (CmMmRegCb *)calloc(1, sizeof(CmMmRegCb));
1923 #ifdef TENB_RTLIN_CHANGES
1924       mlock(mtCMMRegCb[i], sizeof(CmMmRegCb));
1925 #endif
1926       if (mtCMMRegCb[i] == NULLP)
1927       {
1928          sprintf(errMsg,"\n ssdInitMem(): Could not allocated memory \
1929                for the Region:%d control block\n",i);
1930          SPrint(errMsg);
1931          for (k = 0; k < i; k++)
1932          {
1933             cmMmRegDeInit(mtCMMRegCb[k]);
1934             free(mtCMMRegCfg[k]->vAddr);
1935             free(mtCMMRegCb[k]);
1936             free(mtCMMRegCfg[k]);
1937          }
1938          return RFAILED;
1939       }
1940
1941       mtCMMRegCfg[i] = (CmMmRegCfg *)calloc(1, sizeof(CmMmRegCfg));
1942 #ifdef TENB_RTLIN_CHANGES
1943       mlock(mtCMMRegCfg[i], sizeof(CmMmRegCfg));
1944 #endif
1945       if (mtCMMRegCfg[i] == NULLP)
1946       {
1947          for (k = 0; k < i; k++)
1948          {
1949             cmMmRegDeInit(mtCMMRegCb[k]);
1950             free(mtCMMRegCfg[k]->vAddr);
1951             free(mtCMMRegCb[k]);
1952             free(mtCMMRegCfg[k]);
1953          }
1954          free(mtCMMRegCb[i]);
1955          return RFAILED;
1956       }
1957
1958
1959       /* allocate space for the region */
1960       region = &mtMemoCfg.region[i];
1961       mtCMMRegCfg[i]->size = region->heapsize;
1962       for (j = 0; j < region->numBkts; j++)
1963       {
1964          /* mt033.201 - addition for including the header size while computing the total size */
1965 #ifdef SSI_DEBUG_LEVEL1
1966          mtCMMRegCfg[i]->size += (region->bkt[j].blkSize + sizeof(CmMmBlkHdr)) *\
1967                                  (region->bkt[j].numBlks);
1968 #else
1969          mtCMMRegCfg[i]->size += region->bkt[j].blkSize * region->bkt[j].numBlks;
1970 #endif /* SSI_DEBUG_LEVEL1 */
1971       }
1972 #ifdef INTEL_WLS
1973       mtCMMRegCfg[i]->vAddr = (Data *)mtRegMemSz[i].startAddr;
1974 #else
1975       mtCMMRegCfg[i]->vAddr = (Data *)calloc(mtCMMRegCfg[i]->size,
1976             sizeof(Data));
1977 #endif
1978 #ifdef XEON_SPECIFIC_CHANGES
1979       CM_LOG_DEBUG(CM_LOG_ID_MT, "Static Region-->Bkt[%d] Addr:[%p] RegionId=[%d] Size=[%d] \n", 
1980             i, mtCMMRegCfg[i]->vAddr, region->regionId, mtCMMRegCfg[i]->size);
1981 #endif      
1982 #ifdef TENB_RTLIN_CHANGES
1983       mlock(mtCMMRegCfg[i]->vAddr, mtCMMRegCfg[i]->size*sizeof(Data));
1984 #endif
1985
1986       if (mtCMMRegCfg[i]->vAddr == NULLP)
1987       {
1988          sprintf(errMsg,"\n ssdInitMem(): Could not allocate memory \
1989                for the Region:%d \n",i);
1990          SPrint(errMsg);
1991          for (k = 0; k < i; k++)
1992          {
1993             cmMmRegDeInit(mtCMMRegCb[k]);
1994             free(mtCMMRegCfg[k]->vAddr);
1995             free(mtCMMRegCb[k]);
1996             free(mtCMMRegCfg[k]);
1997          }
1998          free(mtCMMRegCb[i]);
1999          free(mtCMMRegCfg[i]);
2000          return RFAILED;
2001       }
2002
2003
2004       /* set up the CMM configuration structure */
2005       mtCMMRegCfg[i]->lType = SS_LOCK_MUTEX;
2006       mtCMMRegCfg[i]->chFlag = 0;
2007       mtCMMRegCfg[i]->bktQnSize = MT_BKTQNSIZE;
2008       mtCMMRegCfg[i]->numBkts = region->numBkts;
2009
2010       for (j = 0; j < region->numBkts; j++)
2011       {
2012          mtCMMRegCfg[i]->bktCfg[j].size    = region->bkt[j].blkSize;
2013          mtCMMRegCfg[i]->bktCfg[j].numBlks = region->bkt[j].numBlks;
2014       }
2015
2016       /* initialize the CMM */
2017 #ifdef SS_LOCKLESS_MEMORY
2018       if (cmMmStatRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2019 #else
2020          if (cmMmRegInit(region->regionId, mtCMMRegCb[i], mtCMMRegCfg[i]) != ROK)
2021 #endif /* SS_LOCKLESS_MEMORY */
2022          {
2023             for (k = 0; k < i; k++)
2024             {
2025                cmMmRegDeInit(mtCMMRegCb[k]);
2026                free(mtCMMRegCfg[k]->vAddr);
2027                free(mtCMMRegCb[k]);
2028                free(mtCMMRegCfg[k]);
2029             }
2030             free(mtCMMRegCfg[i]->vAddr);
2031             free(mtCMMRegCb[i]);
2032             free(mtCMMRegCfg[i]);
2033             return RFAILED;
2034          }
2035
2036
2037       /* initialize the STREAMS module */
2038       /* mt019.201: STREAMS module will only apply to DFLT_REGION */
2039       if (region->regionId == 0)
2040       {
2041          if (ssStrmCfg(region->regionId, region->regionId) != ROK)
2042          {
2043             for (k = 0; k < i; k++)
2044             {
2045                cmMmRegDeInit(mtCMMRegCb[k]);
2046                free(mtCMMRegCfg[k]->vAddr);
2047                free(mtCMMRegCb[k]);
2048                free(mtCMMRegCfg[k]);
2049             }
2050             cmMmRegDeInit(mtCMMRegCb[i]);
2051             free(mtCMMRegCfg[i]->vAddr);
2052             free(mtCMMRegCb[i]);
2053             free(mtCMMRegCfg[i]);
2054             return RFAILED;
2055          }
2056       }
2057    }
2058    /* mt001.301 : Additions */
2059 #ifdef SS_MEM_LEAK_STS
2060    cmInitMemLeakMdl();
2061 #endif /* SS_MEM_LEAK_STS */
2062
2063    return ROK;
2064 }
2065
2066 \f
2067 /*
2068  *
2069  *       Fun:   De-initialize region/pool tables
2070  *
2071  *       Desc:  This function reverses the initialization in ssdInitMem().
2072  *
2073  *       Ret:   ROK      - ok
2074  *
2075  *       Notes:
2076  *
2077  *       File:  mt_ss.c
2078  *
2079  */
2080 Void ssdDeinitMem(void)
2081 {
2082    /* mt018.201 - added local variables */
2083    uint8_t     i;
2084
2085    /* mt008.301 Additions */
2086 #ifdef SS_MEM_LEAK_STS
2087    cmDeinitMemLeakMdl();
2088 #endif /* SS_MEM_LEAK_STS */
2089
2090    for (i = 0; i < mtMemoCfg.numRegions; i++)
2091    {
2092       cmMmRegDeInit(mtCMMRegCb[i]);
2093       free(mtCMMRegCfg[i]->vAddr);
2094       free(mtCMMRegCb[i]);
2095       free(mtCMMRegCfg[i]);
2096    }
2097
2098    return;
2099 }
2100
2101 \f
2102 /*
2103  *
2104  *       Fun:   Initialize task table
2105  *
2106  *       Desc:  This function initializes MTSS-specific information
2107  *              in the task table.
2108  *
2109  *       Ret:   ROK      - ok
2110  *
2111  *       Notes:
2112  *
2113  *       File:  mt_ss.c
2114  *
2115  */
2116 S16 ssdInitTsk(void)
2117 {
2118    /* mt001.301 : Additions */
2119    /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
2120 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
2121    uint32_t tskInd = 0;
2122 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2123
2124
2125
2126    /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
2127 #if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT)
2128    /* initialize system task information */
2129    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
2130    {
2131       osCp.sTskTbl[tskInd].dep.lwpId = 0;
2132    }
2133 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
2134    return ROK;
2135 }
2136
2137 \f
2138 /*
2139  *
2140  *       Fun:   Deinitialize task table
2141  *
2142  *       Desc:  This function reverses the initialization perfomed in
2143  *              ssdInitTsk().
2144  *
2145  *       Ret:   ROK      - ok
2146  *
2147  *       Notes:
2148  *
2149  *       File:  mt_ss.c
2150  *
2151  */
2152 Void ssdDeinitTsk(void)
2153 {
2154
2155    return;
2156 }
2157
2158 \f
2159 #ifdef SS_DRVR_SUPPORT
2160 /*
2161  *
2162  *       Fun:   Initialize driver task table
2163  *
2164  *       Desc:  This function initializes MTSS-specific information
2165  *              in the driver task table.
2166  *
2167  *       Ret:   ROK      - ok
2168  *
2169  *       Notes:
2170  *
2171  *       File:  mt_ss.c
2172  *
2173  */
2174 S16 ssdInitDrvr(void)
2175 {
2176    S16 i;
2177 #ifndef L2_L3_SPLIT
2178    pthread_attr_t attr;
2179 #endif
2180
2181
2182
2183    /* initialize the dependent portion of the driver task entries */
2184    for (i = 0;  i < SS_MAX_DRVRTSKS;  i++)
2185    {
2186       osCp.drvrTskTbl[i].dep.flag = FALSE;
2187    }
2188
2189
2190    /* create pipe for communication between SSetIntPend() and
2191     *  the isTskHdlr thread.
2192     */
2193    if (pipe(osCp.dep.isFildes) != 0)
2194    {
2195       return RFAILED;
2196    }
2197
2198 #ifndef L2_L3_SPLIT
2199    /* create the isTskHdlr thread */
2200    pthread_attr_init(&attr);
2201    /* mt021.201 - Addition to set stack size */
2202    pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
2203    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2204    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2205    if ((pthread_create(&osCp.dep.isTskHdlrTID, &attr, mtIsTskHdlr, NULLP)) != 0)
2206    {
2207       /* mt020.201 - Addition for destroying thread attribute object attr */
2208       pthread_attr_destroy(&attr);
2209
2210       return RFAILED;
2211    }
2212 #endif   
2213
2214    /*mt014.301 : 4GMX release related changes*/
2215 #ifdef SS_4GMX_UCORE
2216    uarmDrvrInit();
2217 #endif
2218
2219 #ifdef L2_L3_SPLIT
2220    drvrTskInit();
2221 #endif
2222 #ifndef L2_L3_SPLIT
2223    /* mt020.201 - Addition for destroying thread attribute object attr */
2224    pthread_attr_destroy(&attr);
2225 #endif
2226
2227    return ROK;
2228 }
2229
2230 \f
2231 /*
2232  *
2233  *       Fun:   Deinitialize driver information
2234  *
2235  *       Desc:  This function reverses the initialization performed in
2236  *              ssdInitDrvr().
2237  *
2238  *       Ret:   ROK      - ok
2239  *
2240  *       Notes:
2241  *
2242  *       File:  mt_ss.c
2243  *
2244  */
2245 Void ssdDeinitDrvr(void)
2246 {
2247    /* mt008.301: Terminate the Driver Task on exit */
2248    while(pthread_cancel(osCp.dep.isTskHdlrTID));
2249
2250 #ifdef L2_L3_SPLIT
2251    TL_Close(AppContext.hUAII);
2252    if (clusterMode == RADIO_CLUSTER_MODE)
2253    {
2254       TL_Close(AppContext.hUAII_second);
2255    }
2256 #endif
2257
2258    return;
2259 }
2260 #endif /* SS_DRVR_SUPPORT */
2261
2262 \f
2263 /*
2264  *
2265  *       Fun:   Initialize timer table
2266  *
2267  *       Desc:  This function initializes MTSS-specific information
2268  *              in the timer table.
2269  *
2270  *       Ret:   ROK      - ok
2271  *
2272  *       Notes:
2273  *
2274  *       File:  mt_ss.c
2275  *
2276  */
2277 S16 ssdInitTmr(void)
2278 {
2279    pthread_attr_t attr;
2280    struct sched_param param_sched;
2281    /* mt010.21: addition */
2282    S32 i;
2283 #ifdef SS_MULTICORE_SUPPORT
2284    SsSTskEntry     *sTsk;
2285 #endif /* SS_MULTICORE_SUPPORT */
2286 #ifdef SS_THR_REG_MAP
2287    uint32_t threadCreated = FALSE;
2288 #endif /* SS_THR_REG_MAP */
2289
2290
2291
2292    osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
2293    /* mt010.21: addition */
2294    osCp.dep.tmrTqCp.nxtEnt = 0;
2295    for (i=0; i< SS_MAX_TMRS; i++)
2296    {
2297       osCp.dep.tmrTq[i].first = (CmTimer *)NULLP;
2298    }
2299
2300 #ifdef SS_MULTICORE_SUPPORT
2301    sTsk = ssdAddTmrSTsk();
2302    if(!sTsk)
2303    {
2304       return RFAILED;
2305    }
2306 #endif /* SS_MULTICORE_SUPPORT */
2307    /* create the timer handler thread */
2308    pthread_attr_init(&attr);
2309    /* mt021.201 - Addition to set stack size */
2310    pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
2311    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2312    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2313    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2314    param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
2315    pthread_attr_setschedparam(&attr, &param_sched);
2316
2317
2318 #ifdef SS_THR_REG_MAP
2319    /* When the thread is created, we check for the memory mapping table if
2320     * threadId can be placed in thread memory map table. If it is not able to place
2321     * threadId is stored in tmporary array. Once thread is created successful,
2322     * thread_cancel is sent for each thread which are created before. All the 
2323     * threads are made to wait on sema which is cancel point for thread.
2324     */
2325    while(threadCreated == FALSE)
2326    {
2327 #endif
2328       if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
2329       {
2330          /* mt020.201 - Addition for destroying thread attribute object attr */
2331          pthread_attr_destroy(&attr);
2332
2333          return RFAILED;
2334       }
2335
2336 #ifdef SS_THR_REG_MAP
2337       threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID, 
2338             sTsk->region);
2339    }
2340 #endif /* SS_THR_REG_MAP */
2341 #ifdef SS_MEM_WL_DEBUG
2342    tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
2343 #endif
2344
2345    /* mt020.201 - Addition for destroying thread attribute object attr */
2346    pthread_attr_destroy(&attr);
2347
2348
2349    return ROK;
2350 }
2351
2352 \f
2353 /*
2354  *
2355  *       Fun:   Deinitialize timer table
2356  *
2357  *       Desc:  This function reverses the initialization performed in
2358  *              ssdInitTmr().
2359  *
2360  *       Ret:   ROK      - ok
2361  *
2362  *       Notes:
2363  *
2364  *       File:  mt_ss.c
2365  *
2366  */
2367 Void ssdDeinitTmr(void)
2368 {
2369 #ifdef SS_MULTICORE_SUPPORT
2370    SsSTskEntry *sTsk;
2371    S16         ret;
2372 #endif /* SS_MULTICORE_SUPPORT */
2373
2374
2375 #ifdef SS_MULTICORE_SUPPORT
2376    ret = SLock(&osCp.sTskTblLock);
2377    if (ret != ROK)
2378    {
2379
2380 #if (ERRCLASS & ERRCLS_DEBUG)
2381       MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
2382             "Could not lock system task table");
2383 #endif
2384       return;
2385    }
2386    sTsk = &osCp.sTskTbl[0]; /* first entry is timer entry always */
2387    /* clean up the system task entry */
2388    sTsk->used = FALSE;
2389    sTsk->tskPrior = 0;
2390    sTsk->numTTsks = 0;
2391    SDestroyLock(&sTsk->lock);
2392    ssDestroyDmndQ(&sTsk->dQ);
2393
2394
2395    /* make this entry available in the system task table */
2396    sTsk->nxt = osCp.nxtSTskEntry;
2397    osCp.nxtSTskEntry = 0;
2398
2399    osCp.numSTsks--;
2400
2401    /* unlock the system task table */
2402    SUnlock(&osCp.sTskTblLock);
2403
2404 #endif /* SS_MULTICORE_SUPPORT */
2405    /* mt008.301: Terminate the timer thread on exit */
2406    while(pthread_cancel(osCp.dep.tmrHdlrTID));
2407    return;
2408 }
2409
2410
2411 \f
2412 /*
2413  *
2414  *       Fun:   ssdInitLog
2415  *
2416  *       Desc:  Pre-tst() initialization.
2417  *
2418  *       Ret:   ROK      - ok
2419  *
2420  *       Notes:
2421  *
2422  *       File:  mt_ss.c
2423  *
2424  */
2425 S16 ssdInitLog(void)
2426 {
2427    /* mt027.201 - Modification to fix warnings with no STDIN and STDOUT */
2428 #ifdef CONAVL
2429 #ifndef CONRD
2430    S32 flags;
2431    pthread_attr_t attr;
2432 #ifndef CONSTDIO
2433    struct termios tio;
2434 #endif /* CONSTDIO */
2435    S16 fd;
2436 #endif /* CONRD */
2437 #endif /* CONAVL */
2438
2439    /* mt008.301: ssdInitFinal changed to ssdInitLog */
2440
2441
2442 #ifdef CONAVL
2443
2444    osCp.dep.conInFp = (FILE *) stdin;
2445    osCp.dep.conOutFp = (FILE *) stdout;
2446    /* added compile time flag CONRD: mt017.21 */
2447 #ifndef CONRD
2448 #ifndef CONSTDIO
2449
2450    /* disable canonical input processing */
2451    fd = fileno(osCp.dep.conInFp);
2452    if ((tcgetattr(fd, &tio)) != 0)
2453    {
2454       printf("\nError: disable canonical input processing\n");
2455       return RFAILED;
2456    }
2457
2458    tio.c_lflag &= ~ICANON;
2459    tio.c_cc[VMIN] = 1;   /* wait for a minimum of 1 character input */
2460    tio.c_cc[VTIME] = 0;
2461    if ((tcsetattr(fd, TCSANOW, &tio)) != 0)
2462    {
2463       printf("\nError: while tcsetattr() processing\n");
2464       return RFAILED;
2465    }
2466
2467 #endif /* CONSTDIO */
2468
2469
2470    /* set up the input fd to block when no data is available */
2471    fd = fileno(osCp.dep.conInFp);
2472    flags = fcntl(fd, F_GETFL, &flags);
2473    flags &= ~O_NONBLOCK;
2474    if (fcntl(fd, F_SETFL, flags) == -1)
2475    {
2476       printf("\nError: while fcntl processing\n");
2477       return RFAILED;
2478    }
2479
2480
2481    /* create the console handler thread */
2482    pthread_attr_init(&attr);
2483    /* mt021.201 - Addition to set stack size */
2484    pthread_attr_setstacksize(&attr, (size_t)MT_CONSOLE_STACK);
2485    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
2486    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2487
2488
2489    if((SCreatePThread(&osCp.dep.conHdlrTID, &attr, mtConHdlr, NULLP)) != 0)
2490    {
2491       /* mt020.201 - Addition for destroying thread attribute object attr */
2492       pthread_attr_destroy(&attr);
2493
2494       printf("\nError: Logging Thread creation failed \n");
2495       return RFAILED;
2496    }
2497
2498    /* mt020.201 - Addition for destroying thread attribute object attr */
2499    pthread_attr_destroy(&attr);
2500
2501 #endif /* CONRD */
2502 #endif /* CONAVL */
2503
2504
2505    return ROK;
2506 }
2507
2508 \f
2509 /*
2510  *
2511  *       Fun:   ssdDeinitLog
2512  *
2513  *       Desc:  This function reverses the initialization performed in
2514  *              ssdInitLog().
2515  *
2516  *       Ret:   ROK      - ok
2517  *
2518  *       Notes:
2519  *
2520  *       File:  mt_ss.c
2521  *
2522  */
2523 /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2524 Void ssdDeinitLog(void)
2525 {
2526    /* mt008.301: ssdDeinitFinal changed to ssdDeinitLog */
2527 #ifdef CONAVL
2528 #ifndef CONRD
2529    /* mt008.301: Terminate the console reader on exit */
2530    while(pthread_cancel(osCp.dep.conHdlrTID));
2531 #endif /* CONRD */
2532 #endif /* CONVAL */
2533
2534    return;
2535 }
2536 /* mt001.301 : Additions */
2537 #ifdef SS_WATCHDOG
2538
2539
2540 S16 ssdInitWatchDog(uint16_t port)
2541 {
2542    uint8_t idx;
2543    Txt prntBuf[PRNTSZE];
2544    Pst     pst;
2545    Buffer *mBuf;
2546 #ifdef SS_WATCHDOG_IPV6
2547    struct sockaddr_in6 tmpaddr;
2548 #else
2549    struct sockaddr_in tmpaddr;
2550 #endif /* SS_WATCHDOG_IPV6 */
2551 #ifdef SS_MULTIPLE_PROCS
2552    ProcId procId = SS_WD_WDPROC;
2553    if (SAddProcIdLst(1, &procId) != ROK)
2554    {
2555       return RFAILED;
2556    }
2557 #endif /* SS_MULTIPLE_PROCS */
2558
2559
2560    SInitLock(&osCp.wdCp.wdLock, SS_LOCK_MUTEX);
2561
2562    /* Create a watch dog system task */
2563    SCreateSTsk(0, &(osCp.wdCp.watchDgTskId));
2564
2565    /* Create a watch dog reveiver system task */
2566    SCreateSTsk(0, &(osCp.wdCp.watchDgRcvrTskId));
2567
2568    /* Register and attach watch dog TAPA task */
2569 #ifdef SS_MULTIPLE_PROCS
2570    SRegTTsk (procId, ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2571    SAttachTTsk (procId, ENTDW, INST0, osCp.wdCp.watchDgTskId);
2572 #else
2573    SRegTTsk ( ENTDW, INST0, TTNORM, PRIOR0, NULLP, watchDgActvTsk);
2574    SAttachTTsk ( ENTDW, INST0, osCp.wdCp.watchDgTskId);
2575 #endif /* SS_MULTIPLE_PROCS */
2576    /* Register and attach watch dog receiver TAPA task */
2577 #ifdef SS_MULTIPLE_PROCS
2578    SRegTTsk (procId, ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2579    SAttachTTsk (procId, ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2580 #else
2581    SRegTTsk ( ENTHB, INST0, TTNORM, PRIOR0, NULLP, watchDgRcvrActvTsk);
2582    SAttachTTsk ( ENTHB, INST0, osCp.wdCp.watchDgRcvrTskId);
2583 #endif /* SS_MULTIPLE_PROCS */
2584
2585 #ifndef SS_MULTIPLE_PROCS
2586    osCp.wdCp.watchDgPst.srcProcId = SFndProcId();
2587    osCp.wdCp.watchDgPst.dstProcId = SFndProcId();
2588 #else
2589    osCp.wdCp.watchDgPst.srcProcId = procId;
2590    osCp.wdCp.watchDgPst.dstProcId = procId;
2591 #endif /* SS_MULTIPLE_PROCS */
2592
2593    /* Initialise the pst structure */
2594    ssdInitWatchDgPst(&(osCp.wdCp.watchDgPst));
2595    /* Initialize the watch dog timer resolution default is 1 sec */
2596
2597    cmInitTimers(osCp.wdCp.watchDgTmr, (uint8_t)1);
2598    osCp.wdCp.watchDgTqCp.nxtEnt = 0;
2599    osCp.wdCp.watchDgTqCp.tmrLen = 1;
2600    for(idx = 0; idx < 1; idx++)
2601    {
2602       osCp.wdCp.watchDgTs[idx].first = NULLP;
2603       osCp.wdCp.watchDgTs[idx].tail = NULLP;
2604    }
2605 #ifdef SS_MULTIPLE_PROCS
2606    SRegCfgTmr(procId,ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2607 #else
2608    SRegCfgTmr(ENTDW, INST0, 10, SS_100MS, ssdWatchDgActvTmr);
2609 #endif /* SS_MULTIPLE_PROCS */
2610
2611    /* Create the watch dog receiver socket */
2612    osCp.wdCp.globWd.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2613    if(osCp.wdCp.globWd.sock == -1)
2614    {
2615       sprintf(prntBuf,"ssdInitWatchDog: socket failed errno [%d]\n", errno);
2616       SPrint(prntBuf);
2617    }
2618
2619 #ifdef SS_WATCHDOG_IPV6
2620    tmpaddr.sin6_len = sizeof(tmpadDr);
2621    tmpaddr.sin6_family = AF_INET6;
2622    tmpaddr.sin6_addr = in6addr_any;
2623    tmpaddr.sin6_port = htons(port);
2624 #else
2625    tmpaddr.sin_family = AF_INET;
2626    tmpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
2627    tmpaddr.sin_port = htons(port);
2628 #endif /* SS_WATCHDOG_IPV6 */
2629
2630    if(bind(osCp.wdCp.globWd.sock, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr)) != 0
2631      )
2632    {
2633       sprintf(prntBuf,"ssdInitWatchDog: bind failed errno [%d]\n", errno);
2634       SPrint(prntBuf);
2635    }
2636
2637    if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
2638    {
2639       return RFAILED;
2640    }
2641 #ifndef SS_MULTIPLE_PROCS
2642    pst.srcProcId = SFndProcId();
2643    pst.dstProcId = SFndProcId();
2644 #else
2645    pst.srcProcId = procId;
2646    pst.dstProcId = procId;
2647 #endif /* SS_MULTIPLE_PROCS */
2648    pst.event     = EVTSSHRTBTREQ;
2649    ssdInitWatchDgPst(&pst);
2650    SPstTsk(&pst, mBuf);
2651
2652    return ROK;
2653 }
2654
2655 S16 ssdInitWatchDgPst(Pst *pst)
2656 {
2657
2658    pst->selector  = SS_LOOSE_COUPLING;
2659
2660    pst->region    = DFLT_REGION;             /* region */
2661    pst->pool      = DFLT_POOL;                 /* pool */
2662
2663    pst->prior     = PRIOR0;                   /* priority */
2664    pst->route     = RTESPEC;                  /* route */
2665
2666    pst->dstEnt    = ENTHB;                   /* destination entity */
2667    pst->dstInst   = 0;
2668    pst->srcEnt    = ENTDW;                   /* source entity */
2669    pst->srcInst   = 0;
2670
2671    return ROK;
2672 }
2673
2674 #ifdef SS_MULTIPLE_PROCS
2675    S16 ssdWatchDgActvTmr
2676 (
2677  ProcId proc,
2678  Ent ent,
2679  Inst inst
2680  )
2681 #else
2682 S16 ssdWatchDgActvTmr(Void)
2683 #endif /* SS_MULTIPLE_PROCS */
2684 {
2685
2686    cmPrcTmr(&osCp.wdCp.watchDgTqCp, osCp.wdCp.watchDgTs, (PFV)ssdWatchDgTmrEvt);
2687
2688    return ROK;
2689 }
2690
2691    Void ssdWatchDgTmrEvt
2692 (
2693  PTR       cb,        /* control block */
2694  S16       event      /* timer number */
2695  )
2696 {
2697    /* mt003.301 Fixed warings */
2698 #ifdef DEBUGP
2699    DateTime dt;
2700 #endif /* DEBUGP */
2701    Txt prntBuf[PRNTSZE];
2702    Bool restartTmr;
2703    int i;
2704
2705
2706    switch(event)
2707    {
2708       case SS_TMR_HRTBT:
2709 #ifdef DEBUGP
2710          SPrint("Timer Heartbeat Request Expired");
2711          SGetDateTime(&dt);
2712          sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2713          SPrint(prntBuf);
2714 #endif
2715          restartTmr=TRUE;
2716
2717          SLock(&osCp.wdCp.wdLock);
2718          for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2719          {
2720             if(osCp.wdCp.globWd.wdsta[i].status == 0)
2721             {
2722                sprintf(prntBuf, "Node [ %s ] Down. Calling user callback\n", inet_ntoa(osCp.wdCp.globWd.wdsta[i].addr));
2723                SPrint(prntBuf);
2724                if(osCp.wdCp.globWd.callback != 0)
2725                {
2726                   osCp.wdCp.globWd.callback(osCp.wdCp.globWd.data);
2727                }
2728             }
2729          }
2730          SUnlock(&osCp.wdCp.wdLock);
2731
2732          if(!osCp.wdCp.globWd.watchdogStop)
2733          {
2734             ssdStartWatchDgTmr(NULLP, SS_TMR_HRTBT, osCp.wdCp.globWd.timeout);
2735             ssdSndHrtBtMsg(restartTmr, SS_WD_HB_REQ);
2736          }
2737          break;
2738
2739       default:
2740          break;
2741    }
2742
2743 }
2744
2745    Void ssdStartWatchDgTmr
2746 (
2747  void     *cb,
2748  S16      event,
2749  uint16_t wait
2750  )
2751 {
2752    CmTmrArg    arg;
2753    int i;
2754 #ifdef DEBUGP
2755    DateTime dt;
2756    Txt prntBuf[PRNTSZE];
2757 #endif
2758
2759
2760    /* mt003.301 Modifications */
2761 #ifdef DEBUGP
2762    SGetDateTime(&dt);
2763    sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2764    if(event == SS_TMR_HRTBT)
2765    {
2766       SPrint("\nSTART SS_TMR_HRTBT");
2767       SPrint(prntBuf);
2768    }
2769 #endif
2770
2771    /* Re-init ACKs */
2772
2773    SLock(&osCp.wdCp.wdLock);
2774    for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2775    {
2776       osCp.wdCp.globWd.wdsta[i].status = 0;
2777    }
2778    SUnlock(&osCp.wdCp.wdLock);
2779
2780    arg.tq     = osCp.wdCp.watchDgTs;
2781    arg.tqCp   = &osCp.wdCp.watchDgTqCp;
2782    arg.timers = osCp.wdCp.watchDgTmr;
2783    arg.cb     = (PTR)NULLP;
2784    arg.evnt   = event;
2785    arg.wait   = osCp.wdCp.globWd.timeout = wait;
2786    arg.tNum   = NOTUSED;
2787    arg.max    = 1;
2788    cmPlcCbTq(&arg);
2789
2790    return;
2791 }
2792
2793    Void ssdStopWatchDgTmr
2794 (
2795  void *cb,
2796  S16  event
2797  )
2798 {
2799    CmTmrArg    arg;
2800 #ifdef DEBUGP
2801    DateTime dt;
2802    Txt prntBuf[PRNTSZE];
2803    int i;
2804 #endif
2805
2806    /* mt003.301 Modifications */
2807 #ifdef DEBUGP
2808    SGetDateTime(&dt);
2809    sprintf(prntBuf," Time: %02d:%02d:%02d\n",dt.hour,dt.min, dt.sec);
2810    if(event == SS_TMR_HRTBT)
2811    {
2812       SPrint("STOP SS_TMR_HRTBT");
2813       SPrint(prntBuf);
2814    }
2815    /* Re-init ACKs */
2816    SLock(&osCp.wdCp.wdLock);
2817    for(i=0; i < osCp.wdCp.globWd.numNodes; i++)
2818    {
2819       osCp.wdCp.globWd.wdsta[i].status = 0;
2820    }
2821    SUnlock(&osCp.wdCp.wdLock);
2822
2823 #endif
2824    arg.tq     = osCp.wdCp.watchDgTs;
2825    arg.tqCp   = &osCp.wdCp.watchDgTqCp;
2826    arg.timers = osCp.wdCp.watchDgTmr;
2827    arg.cb     = (PTR)NULLP;
2828    arg.evnt   = event;
2829    arg.wait   = NOTUSED;
2830    arg.tNum   = NOTUSED;
2831    arg.max    = 1;
2832    cmRmvCbTq(&arg);
2833
2834    return;
2835 }
2836
2837    S16 ssdSndHrtBtMsg
2838 (
2839  Bool      restart,
2840  uint32_t  type
2841  )
2842 {
2843    S16     ret = ROK;
2844 #ifdef DEBUGP
2845    DateTime dt;
2846    Txt prntBuf[PRNTSZE];
2847 #endif
2848    struct sockaddr_in tmpaddr;
2849    char hbMsg[SS_WD_HB_MSG_SIZE];
2850    int             n;
2851    int             err;
2852
2853
2854 #ifdef DEBUGP
2855    SGetDateTime(&dt);
2856    sprintf(prntBuf,"TX HEARTBEAT REQ Time: %02d:%02d:%02d\n", dt.hour, dt.min, dt.sec);
2857    SPrint(prntBuf);
2858 #endif
2859
2860    /* Pack the message */
2861    strcpy(hbMsg, "<HB>REQ</HB>");
2862
2863    /* Send the heartbeat messages to all the configured nodes */
2864    SLock(&osCp.wdCp.wdLock);
2865    for (n=0; n < osCp.wdCp.globWd.numNodes; n++)
2866    {
2867       if(osCp.wdCp.globWd.wdsta[n].addr.s_addr == 0)
2868       {
2869          continue;
2870       }
2871
2872       /* Identify the destination node */
2873 #ifdef SS_WATCHDOG_IPV6
2874       tmpaddr.sin6_len = sizeof(tmpaddr);
2875       tmpaddr.sin6_family = AF_INET6;
2876       tmpaddr.sin6_addr = osCp.wdCp.globWd.wdsta[n].addr;
2877       tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2878 #else
2879       tmpaddr.sin_family = AF_INET;
2880       tmpaddr.sin_addr.s_addr = osCp.wdCp.globWd.wdsta[n].addr.s_addr;
2881       tmpaddr.sin_port = osCp.wdCp.globWd.wdsta[n].port;
2882 #endif /* SS_WATCHDOG_IPV6 */
2883
2884       err = sendto(osCp.wdCp.globWd.sock, hbMsg, strlen(hbMsg), 0, (struct sockaddr *)&tmpaddr, sizeof(struct sockaddr));
2885       if(err == -1)
2886       {
2887 #ifdef DEBUGP
2888          sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] failed status[%d]\n",
2889                inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, errno);
2890          SPrint(prntBuf);
2891 #endif /* DEBUGP */
2892       }
2893       else
2894       {
2895 #ifdef DEBUGP
2896          sprintf(prntBuf,"ssdSndHrtBtMsg: HB to node [%s:%d] sent[%d]\n", inet_ntoa(tmpaddr.sin_addr), tmpaddr.sin_port, err);
2897          SPrint(prntBuf);
2898 #endif /* DEBUGP */
2899       }
2900    }
2901    SUnlock(&osCp.wdCp.wdLock);
2902
2903    return (ret);
2904 }
2905
2906 #endif /* SS_WATCHDOG */
2907
2908
2909 \f
2910 /* mt022.201 - Modification to fix problem when NOCMDLINE is defined */
2911 #ifndef NOCMDLINE
2912 /*
2913  *
2914  *       Fun:   mtGetOpts
2915  *
2916  *       Desc:  This function gets command line options.
2917  *
2918  *       Ret:
2919  *
2920  *       Notes:
2921  *
2922  *       File:  mt_ss.c
2923  *
2924  */
2925 static Void mtGetOpts(void)
2926 {
2927    S32 argc;
2928    S8 **argv;
2929    S16 ret;
2930    /* mt028.201 */
2931 #ifndef NOFILESYS
2932    FILE         *memOpt;             /* memory options file pointer */
2933    Txt pBuf[128];
2934    uint8_t i;
2935    /* mt007.301 : Fix related to file based mem config on 64 bit machine */
2936    PTR numReg;
2937    PTR numBkts;
2938    PTR bktSz = NULLP;
2939    PTR heapSz=0;
2940    PTR bktNum;
2941    /*KWORK_FIX: Initializing the variable for avoidning corruption */
2942    PTR bktIdx = 0;
2943    /*mt010.301 Fix for reading the variables on 64 bit/32bit platforms correctly */
2944    PTR bktUpdtCnt = 0;
2945    PTR regUpdtCnt = 0;
2946    PTR regId;
2947    PTR numPools;
2948    PTR poolIdx;
2949 #ifdef SS_LOCKLESS_MEMORY
2950    PTR bktSetSize;
2951    PTR bktRelThr;
2952    PTR bktAqurThr;
2953 #endif
2954    Txt line[256];
2955    Bool error = FALSE;
2956    Cntr   idx=0;
2957 #endif
2958
2959
2960
2961    msOptInd = 1;
2962
2963 #ifndef NOFILESYS
2964    osCp.dep.fileOutFp = (FILE *)NULLP;
2965
2966    /* initialize memOpt */
2967    memOpt = (FILE *) NULLP;
2968 #endif
2969
2970    argc = msArgc;
2971    argv = msArgv;
2972
2973    /* mt028.201 */
2974    while ((ret = SGetOpt(argc, argv, "o:f:s:m:c:")) != EOF)
2975    {
2976       switch (ret)
2977       {
2978 #ifndef NOFILESYS
2979          /* mt001.301 : Additions */
2980 #ifdef SS_MEM_LEAK_STS
2981          case 'm':
2982             cmMemOpenMemLkFile(msOptArg);
2983             break;
2984 #endif
2985          case 'o':
2986             osCp.dep.fileOutFp = fopen(msOptArg, "w");
2987             break;
2988          case 'f':
2989             fileBasedMemCfg = TRUE;
2990             memOpt = fopen(msOptArg, "r");
2991
2992             /* if file does not exist or could not be opened then use the
2993              * default memory configuration as defined in mt_ss.h
2994              */
2995             if (memOpt == (FILE *) NULLP)
2996             {
2997                sprintf(pBuf, "\nMTSS: Memory configuration file: %s could not\
2998                      be opened, using default mem configuration\n", msOptArg);
2999                SPrint(pBuf);
3000                break;
3001             }
3002             i = 0;
3003             while (fgets((Txt *)line, 256, memOpt) != NULLP)
3004             {
3005                if(line[0] == '#' || line[0] < '0' || line[0] > '9') /* Comment line or non numeric character, so skip it and read next line */
3006                   continue;
3007                if(error == TRUE)
3008                   break;
3009                switch  (i)
3010                {
3011                   case 0:  /*** INPUT: Number of regions ***/
3012                      sscanf(line, "%ld", (long *) &numReg);
3013                      mtMemoCfg.numRegions = numReg;
3014                      if(mtMemoCfg.numRegions > SS_MAX_REGS)
3015                      {
3016                         printf("\n No. of regions are > SS_MAX_REGS:%d \n",SS_MAX_REGS);
3017                         error = TRUE;
3018                         break;
3019                      }
3020                      i++;
3021                      break;
3022                   case 1: /*** INPUT: Number of buckets and number of Pools ***/
3023                      sscanf(line, "%ld %ld", (long *) &numBkts, (long *) &numPools);
3024                      if(numBkts > MT_MAX_BKTS)
3025                      {
3026                         printf("\n No. of buckets are > MT_MAX_BKTS :%d \n",MT_MAX_BKTS);
3027                         error = TRUE;
3028                         break;
3029                      }
3030                      if(numPools > SS_MAX_POOLS_PER_REG)
3031                      {
3032                         printf("\n No. of pools are > SS_MAX_POOLS_PER_REG:%d \n",SS_MAX_POOLS_PER_REG);
3033                         error = TRUE;
3034                         break;
3035                      }
3036                      /*
3037                       * Delay updation from local variable to global
3038                       * structure of number of regions and heap data to
3039                       * counter error conditions present above.
3040                       */
3041                      for(idx = 0; idx < cfgNumRegs; idx++)
3042                      {
3043                         mtMemoCfg.region[idx].numBkts = numBkts;
3044                         cfgRegInfo[idx].region = idx;
3045                         cfgRegInfo[idx].numPools = numPools;
3046                         /*
3047                          * Initialize the pool info as static type with size zero
3048                          */
3049                         for(poolIdx = 0; poolIdx < numPools; poolIdx++)
3050                         {
3051                            cfgRegInfo[idx].pools[poolIdx].type = SS_POOL_STATIC;
3052                            cfgRegInfo[idx].pools[poolIdx].size = 0;
3053                         }
3054                      }
3055                      i++;
3056                      break;
3057                   case 2: /*** INPUT: Bucket Id and size of the bucket ***/
3058                      if(bktUpdtCnt < numBkts) /* more set of bucket can be added */
3059                      {
3060                         sscanf(line, "%ld %ld",(long *)&bktIdx, (long *) &bktSz);
3061                      }
3062                      if(bktIdx >= numBkts)
3063                      {
3064                         printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3065                         error = TRUE;
3066                         break;
3067
3068                      }
3069                      mtBktInfo[bktIdx].blkSize  = bktSz;
3070                      bktUpdtCnt++;
3071                      if(bktUpdtCnt == numBkts)
3072                      {
3073                         i++; /*done reading bkt info, start reading individual region info*/
3074                         bktUpdtCnt = 0;
3075                      }
3076                      break;
3077                   case 3: /*** INPUT: Region Id (ranges from 0 to numRegions-1) **/
3078                      sscanf(line,"%ld",(long *) &regId);
3079                      if(regId >= mtMemoCfg.numRegions)
3080                      {
3081                         printf("\n Invalid Region Id, may be >= the No. of regions:%d\n",mtMemoCfg.numRegions);
3082 #ifndef XEON_SPECIFIC_CHANGES                       
3083                         error = TRUE;
3084 #endif                       
3085                         break;
3086                      }
3087                      mtMemoCfg.region[regId].regionId = regId;
3088                      i++;
3089                      break;
3090                   case 4: /*** INPUT: BktId (ranges from 0 to numBkts-1), No. of blks ***/
3091                      if(bktUpdtCnt < numBkts)
3092                      {
3093                         sscanf(line, "%ld %ld",(long *)&bktIdx, (long *)&bktNum);
3094                         if(bktIdx >= numBkts)
3095                         {
3096                            printf("\n Invalid Bucket Id, may be >= the No. of buckets:%ld\n",numBkts);
3097                            error = TRUE;
3098                            break;
3099
3100                         }
3101                         if(bktIdx < MT_MAX_BKTS)
3102                         {
3103                            mtMemoCfg.region[regId].bkt[bktIdx].blkSize = mtBktInfo[bktIdx].blkSize;
3104                            mtMemoCfg.region[regId].bkt[bktIdx].numBlks = bktNum;
3105                            cfgRegInfo[regId].pools[bktIdx].type = SS_POOL_DYNAMIC;
3106                            cfgRegInfo[regId].pools[bktIdx].size = mtBktInfo[bktIdx].blkSize - (sizeof(SsMblk)+sizeof(SsDblk));
3107                         }
3108                         bktUpdtCnt++;
3109                         if(bktUpdtCnt == numBkts)
3110                         {
3111                            i++;
3112                            bktUpdtCnt = 0;
3113                         }
3114                      }
3115                      break;
3116                   case 5: /* INPUT: Heapsize ***/
3117                      sscanf(line, "%ld", (long *) &heapSz);
3118                      mtMemoCfg.region[regId].heapsize = heapSz;
3119                      regUpdtCnt++;
3120                      if(regUpdtCnt != mtMemoCfg.numRegions)
3121                      {
3122                         i = 3;   
3123                      }
3124                      else
3125                      {
3126                         i++;
3127                      }
3128                      break;
3129 #ifdef SS_LOCKLESS_MEMORY
3130                   case 6:
3131                      sscanf(line, "%ld", (long *) &numBkts);
3132                      mtGlobMemoCfg.numBkts = numBkts;
3133 #ifndef XEON_SPECIFIC_CHANGES                     
3134                      mtDynMemoCfg.numRegions = mtMemoCfg.numRegions;
3135 #endif                     
3136
3137 #ifdef XEON_SPECIFIC_CHANGES
3138                      CM_LOG_DEBUG(CM_LOG_ID_MT, "numRegions = %d numBkts = %d\n",
3139                            mtDynMemoCfg.numRegions, mtGlobMemoCfg.numBkts);
3140                      for(idx = 0; idx < mtDynMemoCfg.numRegions; idx++)
3141 #else                     
3142                         for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3143 #endif                        
3144                         {
3145                            mtDynMemoCfg.region[idx].regionId = idx;
3146                            mtDynMemoCfg.region[idx].numBkts = numBkts;
3147                         }
3148
3149                      bktUpdtCnt = 0;
3150                      i++;
3151                      break;
3152
3153                   case 7:
3154                      if(bktUpdtCnt < numBkts)
3155                      {
3156                         sscanf(line, "%ld %ld %ld %ld %ld %ld", (long *) &bktIdx,
3157                               (long *) &bktSz, (long *) &bktNum,
3158                               (long *) &bktSetSize, (long *) &bktRelThr, 
3159                               (long *) &bktAqurThr);
3160                         /* Klock work fix ccpu00148484 */
3161                         if(bktIdx < SS_MAX_POOLS_PER_REG)
3162                         {
3163                            mtGlobMemoCfg.bkt[bktIdx].blkSize = bktSz;
3164                            mtGlobMemoCfg.bkt[bktIdx].numBlks = bktNum;
3165                            mtGlobMemoCfg.bkt[bktIdx].bucketSetSize = bktSetSize;
3166 #ifdef XEON_SPECIFIC_CHANGES
3167                            CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSize %d numBlks %d bucketSetSize %d\n",
3168                                  bktUpdtCnt, mtGlobMemoCfg.bkt[bktIdx].blkSize,
3169                                  mtGlobMemoCfg.bkt[bktIdx].numBlks, mtGlobMemoCfg.bkt[bktIdx].bucketSetSize); 
3170
3171                            if(bktIdx >= SS_MAX_POOLS_PER_REG)
3172                            {
3173                               printf("\nNo. of Buckets/pools are > SS_MAX_POOLS_PER_REG:%d\n",SS_MAX_POOLS_PER_REG);
3174                               error = TRUE;
3175                               break;
3176                            }
3177
3178 #endif                           
3179                            for(idx = 0; idx < mtMemoCfg.numRegions; idx++)
3180                            {
3181                               mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold = bktRelThr;
3182                               mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold = bktAqurThr;
3183 #ifdef XEON_SPECIFIC_CHANGES
3184                               CM_LOG_DEBUG(CM_LOG_ID_MT, "Pool [%d] blkSetRelThreshold %d blkSetAcquireThreshold %d\n",
3185                                     bktUpdtCnt, mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetRelThreshold,
3186                                     mtDynMemoCfg.region[idx].bkt[bktIdx].blkSetAcquireThreshold);
3187 #endif                           
3188                            } 
3189                         }
3190                         bktUpdtCnt++;
3191                      }
3192 #ifdef XEON_SPECIFIC_CHANGES
3193                      if(bktUpdtCnt == numBkts)
3194                      {   
3195                         i=8;
3196                      }
3197                      break;
3198
3199                   case 8: /* INPUT: Global Heapsize ***/
3200                      sscanf(line, "%ld", (long *) &heapSz);
3201                      mtGlobMemoCfg.heapSize = heapSz;
3202                      CM_LOG_DEBUG(CM_LOG_ID_MT, "Global Heap size = %d\n", mtGlobMemoCfg.heapSize);
3203 #endif                           
3204                      break;
3205 #endif
3206                }
3207             }
3208             if(error == TRUE)
3209             {
3210                memConfigured = FALSE;
3211             }
3212             else
3213             {
3214                memConfigured = TRUE;
3215             }
3216             fclose (memOpt);
3217             break;
3218 #endif
3219
3220
3221          case 's':
3222             /* mt028.201: modification: multiple procs support related changes */
3223 #ifndef SS_MULTIPLE_PROCS
3224
3225 #ifdef ENB_RELAY
3226             osCp.procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3227 #else
3228             osCp.procId = (ProcId) strtol(msOptArg, NULLP, 0);
3229 #endif
3230
3231 #else /* SS_MULTIPLE_PROCS */
3232             {
3233                ProcId procId;
3234 #ifdef ENB_RELAY
3235                procId = PID_STK((ProcId) strtol(msOptArg, NULLP, 0));
3236 #else
3237                procId = (ProcId) strtol(msOptArg, NULLP, 0);
3238 #endif
3239                SAddProcIdLst(1, &procId);
3240             }
3241
3242 #endif /* SS_MULTIPLE_PROCS */
3243             break;
3244
3245          case 'c':
3246             osCp.configFilePath = msOptArg;
3247             break;
3248
3249          case '?':
3250             /* fall through */
3251
3252
3253          default:
3254             break;
3255       }
3256    }
3257
3258    msOptInd = 1;
3259
3260
3261    return;
3262 }
3263 #endif
3264
3265 \f
3266 /*
3267  *
3268  *       Fun:   SGetOpt
3269  *
3270  *       Desc:  Get options from command line
3271  *
3272  *       Ret:   option  - success
3273  *              '?'     - fail
3274  *              EOF     - end of options
3275  *
3276  *       Notes: Handles command lines like the following
3277  *
3278  *              if opts = "abc:d"
3279  *                 then command line should look like this...
3280  *                    -a foo -b foo1 -c -d foo
3281  *
3282  *              code usage:
3283  *
3284  *              while ((ret = SGetOpt(msArgc, msArgv, "ls")) != EOF )
3285  *              {
3286  *                 switch(ret)
3287  *                 {
3288  *                    case 'l':
3289  *                       nloops = atoi(msArgv[msOptInd]);
3290  *                       break;
3291  *                    case 's':
3292  *                       state1 = atoi(msArgv[msOptInd]);
3293  *                    case '?':
3294  *                    default:
3295  *                       break;
3296  *                 }
3297  *              }
3298  *
3299  *       File:  mt_ss.c
3300  *
3301  */
3302    S16 SGetOpt
3303 (
3304  int argc,                   /* argument count */
3305  char **argv,                /* argument value */
3306  char *opts                  /* options */
3307  )
3308 {
3309    /* mt020.201 - Removed for no command line */
3310 #ifndef NOCMDLINE
3311    S16 sp;
3312    S16 c;
3313    S8 *cp;
3314 #endif
3315
3316
3317    /* mt020.201 - Addition for no command line */
3318 #ifdef NOCMDLINE
3319    UNUSED(argc);
3320    UNUSED(argv);
3321    UNUSED(opts);
3322
3323    return (EOF);
3324 #else
3325
3326    sp = 1;
3327    if (sp == 1)
3328    {
3329       /*mt013.301 : Changes as per coding standards*/
3330       if (msOptInd >= (S16) argc  ||  argv[msOptInd][0] == '\0')
3331       {
3332          return (EOF);
3333       }
3334       else
3335       {
3336          if (!strcmp(argv[msOptInd], "--"))
3337          {
3338             msOptInd++;
3339             return (EOF);
3340          }
3341          else if (argv[msOptInd][0] != '-')
3342          {
3343             msOptInd++;
3344             return ('?');
3345          }
3346       }
3347    }
3348
3349    c = argv[msOptInd][sp];
3350    if (c == ':'  ||  (cp = (S8 *) strchr(opts, c)) == (S8 *) NULLP)
3351    {
3352       if (argv[msOptInd][++sp] == '\0')
3353       {
3354          msOptInd++;
3355          sp = 1;
3356       }
3357
3358       return ('?');
3359    }
3360
3361    if (*++cp == ':')
3362    {
3363       if (argv[msOptInd][sp+1] != '\0') msOptArg = &argv[msOptInd++][sp+1];
3364       else
3365       {
3366          if (++msOptInd >= (S16) argc)
3367          {
3368             sp = 1;
3369             return ('?');
3370          }
3371          else msOptArg = argv[msOptInd++];
3372
3373          sp = 1;
3374       }
3375    }
3376    else
3377    {
3378       if (argv[msOptInd][++sp] == '\0')
3379       {
3380          sp = 1;
3381          msOptInd++;
3382       }
3383
3384       msOptArg = NULLP;
3385    }
3386
3387
3388    return (c);
3389
3390 #endif /* NOCMDLINE */
3391 }
3392
3393 \f
3394 /*
3395  *
3396  *       Fun:   ssdStart
3397  *
3398  *       Desc:  This function starts system services execution; the
3399  *              permanent tasks are started and the system enters a
3400  *              ready state.
3401  *
3402  *       Ret:   Void
3403  *
3404  *       Notes:
3405  *
3406  *       File:  mt_ss.c
3407  *
3408  */
3409 Void ssdStart(void)
3410 {
3411    S16 i;
3412
3413
3414
3415
3416    /* mt025.201 - Modification for adding lock to timer handler */
3417    for (i = 0;  i <= SS_MAX_STSKS + 5;  i++)
3418    {
3419       sem_post(&osCp.dep.ssStarted);
3420    }
3421
3422
3423    return;
3424 }
3425
3426 \f
3427 /*
3428  *     indirect interface functions to system services service user
3429  */
3430
3431 \f
3432 /*
3433  *
3434  *       Fun:   ssdAttachTTsk
3435  *
3436  *       Desc:  This function sends the initial tick message to a TAPA
3437  *              task if the task is a permanent task.
3438  *
3439  *       Ret:   ROK      - ok
3440  *
3441  *       Notes:
3442  *
3443  *       File:  mt_ss.c
3444  *
3445  */
3446    S16 ssdAttachTTsk
3447 (
3448  SsTTskEntry *tTsk           /* pointer to TAPA task entry */
3449  )
3450 {
3451    Buffer *mBuf;
3452    SsMsgInfo *mInfo;
3453    S16 ret;
3454
3455    if (tTsk->tskType == SS_TSK_PERMANENT)
3456    {
3457       /* Send a permanent tick message to this task, to start
3458        * execution.
3459        */
3460       ret = SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
3461       if (ret != ROK)
3462       {
3463 #if (ERRCLASS & ERRCLS_DEBUG)
3464          MTLOGERROR(ERRCLS_DEBUG, EMT001, ret, "SGetMsg() failed");
3465 #endif
3466          return RFAILED;
3467       }
3468
3469       mInfo = (SsMsgInfo *)mBuf->b_rptr;
3470       mInfo->eventInfo.event = SS_EVNT_PERMTICK;
3471
3472       /* set up post structure */
3473       /* mt028.201: modification: multiple procs support related changes */
3474 #ifndef SS_MULTIPLE_PROCS
3475       mInfo->pst.dstProcId = SFndProcId();
3476       mInfo->pst.srcProcId = SFndProcId();
3477 #else /* SS_MULTIPLE_PROCS */
3478       mInfo->pst.dstProcId = tTsk->proc;
3479       mInfo->pst.srcProcId = tTsk->proc;
3480 #endif /* SS_MULTIPLE_PROCS */
3481       mInfo->pst.selector  = SEL_LC_NEW;
3482       mInfo->pst.region    = DFLT_REGION;
3483       mInfo->pst.pool      = DFLT_POOL;
3484       mInfo->pst.prior     = PRIOR3;
3485       mInfo->pst.route     = RTESPEC;
3486       mInfo->pst.event     = 0;
3487       mInfo->pst.dstEnt    = tTsk->ent;
3488       mInfo->pst.dstInst   = tTsk->inst;
3489       mInfo->pst.srcEnt    = tTsk->ent;
3490       mInfo->pst.srcInst   = tTsk->inst;
3491
3492       ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
3493             (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR3);
3494
3495       if (ret != ROK)
3496       {
3497          SPutMsg(mBuf);
3498
3499 #if (ERRCLASS & ERRCLS_DEBUG)
3500          MTLOGERROR(ERRCLS_DEBUG, EMT002, ret,
3501                "Could not write to demand queue");
3502 #endif
3503          return RFAILED;
3504       }
3505    }
3506
3507
3508    return ROK;
3509 }
3510
3511 \f
3512 /*
3513  *
3514  *       Fun:   ssdDetachTTsk
3515  *
3516  *       Desc:  Does nothing.
3517  *
3518  *       Ret:   ROK      - ok
3519  *
3520  *       Notes:
3521  *
3522  *       File:  mt_ss.c
3523  *
3524  */
3525    S16 ssdDetachTTsk
3526 (
3527  SsTTskEntry *tTsk           /* pointer to TAPA task entry */
3528  )
3529 {
3530
3531    return ROK;
3532 }
3533
3534 \f
3535 /*
3536  *
3537  *       Fun:   ssdCreateSTsk
3538  *
3539  *       Desc:  This function creates a system task. A thread is started
3540  *              on the system task handler function defined later.
3541  *
3542  *       Ret:   ROK      - ok
3543  *
3544  *       Notes:
3545  *
3546  *       File:  mt_ss.c
3547  *
3548  */
3549    S16 ssdCreateSTsk
3550 (
3551  SsSTskEntry *sTsk           /* pointer to system task entry */
3552  )
3553 {
3554    S16  ret;
3555    pthread_attr_t attr;
3556    /* struct sched_param param_sched;*/
3557
3558 #ifdef SS_THR_REG_MAP
3559    uint32_t threadCreated = FALSE;
3560 #endif
3561
3562
3563
3564 #ifdef SS_SINGLE_THREADED
3565    /* mt001.301 : Additions */
3566 #ifndef SS_WATCHDOG
3567 #ifdef SS_MULTICORE_SUPPORT
3568    if (osCp.numSTsks > 1)
3569 #else
3570       if (osCp.numSTsks > 0)
3571 #endif /* SS_MULTICORE_SUPPORT */
3572 #else
3573 #ifdef SS_MULTICORE_SUPPORT
3574          if (osCp.numSTsks > 3)
3575 #else
3576             if (osCp.numSTsks > 2)
3577 #endif /* SS_MULTICORE_SUPPORT */
3578 #endif /* SS_WATCHDOG */
3579             {
3580                return ROK;
3581             }
3582 #endif
3583
3584
3585    /* set the current executing entity and instance IDs to
3586     * 'not configured'. create the lock to access them.
3587     */
3588    sTsk->dep.ent = ENTNC;
3589    sTsk->dep.inst = INSTNC;
3590
3591
3592    /* create the thread */
3593    pthread_attr_init(&attr);
3594    ssdSetPthreadAttr(sTsk->tskPrior, &attr);
3595
3596    printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3597 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
3598    if (sTsk->tskPrior == 0)
3599    {
3600       printf("\nCreating RT thread #######################\n");
3601 #ifdef SS_THR_REG_MAP
3602       /* When the thread is created, we check for the memory mapping table if
3603        * threadId can be placed in thread memory map table. If it is not able to place
3604        * threadId is stored in tmporary array. Once thread is created successful,
3605        * thread_cancel is sent for each thread which are created before. All the 
3606        * threads are made to wait on sema which is cancel point for thread.
3607        */
3608       while(threadCreated == FALSE)
3609       {
3610 #endif
3611          ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3612          if (ret != 0)
3613          {
3614             DU_LOG("\nDU APP : Failed to create thread. Cause[%d]",ret);
3615             pthread_attr_destroy(&attr);
3616
3617 #if (ERRCLASS & ERRCLS_DEBUG)
3618             MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3619 #endif
3620
3621             return RFAILED;
3622          }
3623 #ifdef SS_THR_REG_MAP
3624          threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId, 
3625                sTsk->region);
3626       }
3627 #endif
3628    }
3629    else
3630 #endif
3631    {
3632 #ifdef SS_THR_REG_MAP
3633       /* When the thread is created, we check for the memory mapping table if
3634        * threadId can be placed in thread memory map table. If it is not able to place
3635        * threadId is stored in tmporary array. Once thread is created successful,
3636        * thread_cancel is sent for each thread which are created before. All the 
3637        * threads are made to wait on sema which is cancel point for thread.
3638        */
3639       while(threadCreated == FALSE)
3640       {
3641 #endif
3642          ret = pthread_create(&sTsk->dep.tId, &attr, mtTskHdlr, (Ptr)sTsk);
3643          if (ret != 0)
3644          {
3645
3646             /* mt020.201 - Addition for destroying thread attribute object attr */
3647             pthread_attr_destroy(&attr);
3648
3649 #if (ERRCLASS & ERRCLS_DEBUG)
3650             MTLOGERROR(ERRCLS_DEBUG, EMT004, ERRZERO, "Could not create thread");
3651 #endif
3652
3653             return RFAILED;
3654          }
3655 #ifdef SS_THR_REG_MAP
3656          threadCreated = ssCheckAndAddMemoryRegionMap(sTsk->dep.tId, 
3657                sTsk->region);
3658       }
3659 #endif
3660    }
3661
3662
3663    /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
3664 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3665    {
3666       static uint32_t stLwpId = 3;
3667       sTsk->dep.lwpId = ++stLwpId;
3668    }
3669 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
3670
3671    /* mt020.201 - Addition for destroying thread attribute object attr */
3672    pthread_attr_destroy(&attr);
3673
3674    return ROK;
3675 }
3676
3677
3678    int SCreatePThread
3679 (
3680  pthread_t* tid,
3681  pthread_attr_t* attr,
3682  void *(*start_routine) (void *),
3683  void* arg
3684  )
3685 {
3686    int retVal = 0;
3687 #ifdef SS_THR_REG_MAP
3688    uint32_t threadCreated = FALSE;
3689 #endif
3690
3691    SPThreadCreateArg* threadArg = (SPThreadCreateArg*)malloc(sizeof(SPThreadCreateArg));
3692    /* Klock work fix ccpu00148484 */
3693    if(threadArg == NULLP)
3694    {
3695       return RFAILED;
3696    }
3697    threadArg->argument = arg;
3698    threadArg->start_routine = start_routine;
3699
3700
3701    printf("\nCreating thread here %s %d\n", __FILE__, __LINE__);
3702    {
3703 #ifdef SS_THR_REG_MAP
3704       /* When the thread is created, we check for the memory mapping table if
3705        * threadId can be placed in thread memory map table. If it is not able to place
3706        * threadId is stored in tmporary array. Once thread is created successful,
3707        * thread_cancel is sent for each thread which are created before. All the 
3708        * threads are made to wait on sema which is cancel point for thread.
3709        */
3710       while(threadCreated == FALSE)
3711       {
3712 #endif
3713          /*pthreadCreateHdlr */
3714          if (((retVal = pthread_create(tid, attr, pthreadCreateHdlr, threadArg))) != 0)
3715          {
3716
3717             return (retVal);
3718          }
3719 #ifdef SS_THR_REG_MAP
3720          threadCreated = ssCheckAndAddMemoryRegionMap(*tid, SS_MAX_REGS - 1);
3721       }
3722 #endif
3723    }
3724
3725    return (retVal);
3726 }
3727
3728
3729 /*
3730  *
3731  *       Fun:   Set Pthread Attributes
3732  *
3733  *       Desc:  This function is used to set various explicit
3734  *              pthread attributes like, priority scheduling,etc
3735  *
3736  *       Ret:   ROK      - ok
3737  *
3738  *       Notes:
3739  *
3740  *       File:  mt_ss.c
3741  *
3742  */
3743
3744    static S16 ssdSetPthreadAttr
3745 (
3746  S32              tskPrior,
3747  pthread_attr_t  *attr
3748  )
3749 {
3750    struct sched_param    param;
3751
3752
3753    SMemSet(&param, 0, sizeof(param));
3754
3755 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
3756    param.sched_priority = 100 - 1 - tskPrior;
3757 #else
3758    param.sched_priority = 100 - 10 - tskPrior;
3759 #endif
3760
3761 #if 1/* Nawas:: Overriding DL RLC prority to one higher than iccserv */
3762    /* TODO:: This can be avoided by reducing the priority
3763     * of iccserv thread in l1_master.sh*/
3764 #ifdef L2_L3_SPLIT
3765    if (clusterMode == RADIO_CLUSTER_MODE)
3766    {
3767       if(tskPrior == PRIOR1)
3768       {/* DL RLC */
3769          param.sched_priority = 91;
3770       }
3771    }
3772
3773 #endif
3774 #endif
3775
3776    printf("\nSet priority %u\n", param.sched_priority);
3777
3778    /* Set Scheduler to explicit, without this non of the below
3779       pthread attr works */
3780 #ifdef  TENB_RTLIN_CHANGES
3781    pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
3782 #endif
3783
3784    pthread_attr_setstacksize(attr, (size_t)MT_TASK_STACK);
3785    pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
3786    pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
3787 #ifdef TENB_RTLIN_CHANGES
3788    pthread_attr_setschedpolicy(attr, SCHED_FIFO);
3789 #endif
3790    pthread_attr_setschedparam(attr, &param);
3791
3792    return  (ROK);
3793
3794 } /* ssdSetPthreadAttr */
3795
3796 /************* multi-core support **************/
3797 /*mt013.301 :Added SS_AFFINITY_SUPPORT  */
3798 #if defined(SS_MULTICORE_SUPPORT) ||defined(SS_AFFINITY_SUPPORT)
3799
3800 /*
3801  *
3802  *       Fun:   Get the current core/cpu affinity for a thread/lwp
3803  *
3804  *       Desc:  This function is used to get the current processor/core
3805  *              affinity for a a system task (thread/lwp). It sets the
3806  *              affinity based on the mode supplied by the caller.
3807  *
3808  *       Ret:   ROK      - ok
3809  *              RFAILED  - failed, general (optional)
3810  *
3811  *       Notes:
3812  *
3813  *       File:  ss_task.c
3814  *
3815  */
3816    S16 ssdGetAffinity
3817 (
3818  SSTskId *tskId,                  /* filled in with system task ID */
3819  uint32_t *coreId                      /* the core/processor id to which the affinity is set */
3820  )
3821 {
3822
3823    uint32_t tskInd;
3824
3825 #ifdef SS_LINUX
3826
3827    pthread_t tId =0;
3828    cpu_set_t cpuSet;
3829    uint32_t cpuInd = 0;
3830    /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3831 #else
3832 #ifdef SUNOS
3833    uint32_t lwpId = *tskId;
3834 #endif /*SUNOS*/
3835 #endif /*SS_LINUX*/
3836 #ifdef SS_LINUX
3837    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
3838    {
3839       if (osCp.sTskTbl[tskInd].tskId == *tskId)
3840       {
3841          tId = osCp.sTskTbl[tskInd].dep.tId;
3842          break;
3843       } /* end if */
3844    } /* end for */
3845
3846    /* if tskId is not found in the tskTbl */
3847    if (tskInd == SS_MAX_STSKS)
3848    {
3849       MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3850       return RFAILED;
3851    }
3852
3853
3854    /* initialize the cpu mask */
3855    CPU_ZERO( &cpuSet);
3856
3857    /* set thread affinity for linux */
3858    if (pthread_getaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3859    {
3860 #if (ERRCLASS & ERRCLS_DEBUG)
3861       MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3862 #endif
3863       return RFAILED;
3864    } /* end if pthread_setaffinity fails */
3865
3866    for (cpuInd = 0; cpuInd <CPU_SETSIZE; cpuInd++)
3867    {
3868       if (CPU_ISSET (cpuInd, & cpuSet))
3869       {
3870          *coreId = cpuInd;
3871          break;
3872       } /* end if */
3873    } /* end for */
3874
3875 #else
3876 #ifdef SUNOS
3877    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
3878    {
3879       if (osCp.sTskTbl[tskInd].tskId == *tskId)
3880       {
3881          lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3882          break;
3883       } /* end if */
3884    } /* end for */
3885
3886    /* if tskId is not found in the tskTbl */
3887    if (tskInd == SS_MAX_STSKS)
3888    {
3889       MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3890       return RFAILED;
3891    }
3892
3893    /* set thread affinity for Solaris */
3894    if (processor_bind(P_LWPID, lwpId, PBIND_QUERY, (processorid_t*)coreId) < 0)
3895    {
3896 #if (ERRCLASS & ERRCLS_DEBUG)
3897       MTLOGERROR(ERRCLS_DEBUG, EMT037, ERRZERO, "Could not get thread affinity\n");
3898 #endif
3899       return RFAILED;
3900    } /* end if processor_bind fails */
3901
3902 #endif /* SUNOS */
3903 #endif /* SS_LINUX */
3904
3905    return ROK;
3906
3907 } /* ssdGetAffinity */
3908
3909
3910 /*
3911  *
3912  *       Fun:   Set the core/cpu affinity for a thread/lwp
3913  *
3914  *       Desc:  This function is used to set processor/core affinity for a
3915  *              a system task (thread/lwp). It sets the affinity based on the
3916  *              mode supplied by the caller.
3917  *
3918  *       Ret:   ROK      - ok
3919  *              RFAILED  - failed, general (optional)
3920  *
3921  *       Notes:
3922  *
3923  *       File:  ss_task.c
3924  *
3925  */
3926    S16 ssdSetAffinity
3927 (
3928  SSTskId *tskId,                  /* filled in with system task ID */
3929  uint32_t coreId                       /* the core/processor id to which the affinity has to be set */
3930  )
3931 {
3932
3933    uint32_t tskInd = 0;
3934 #ifdef SS_LINUX
3935
3936    pthread_t tId = 0;
3937    cpu_set_t cpuSet;
3938    /*mt013.301 :Fix for TRACE5 feature crash due to missing TRC MACRO*/
3939 #else
3940 #ifdef SUNOS
3941    uint32_t lwpId = *tskId;
3942 #endif /*SUNOS*/
3943 #endif /*SS_LINUX*/
3944
3945
3946 #ifdef SS_LINUX
3947    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
3948    {
3949       /* Here tskId can not be used as index as the task may be terminated if
3950          there is a TERM even for that tsk, thus breaking the task Id numbering
3951          sequence  */
3952       if (osCp.sTskTbl[tskInd].tskId == *tskId)
3953       {
3954          tId = osCp.sTskTbl[tskInd].dep.tId;
3955          break;
3956       } /* end if */
3957    } /* end for */
3958
3959    /* if tskId is not found in the tskTbl */
3960    if (tskInd == SS_MAX_STSKS)
3961    {
3962       MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3963       return RFAILED;
3964    }
3965
3966    /* initialize the cpu mask */
3967    CPU_ZERO( &cpuSet);
3968
3969    /* set the cpu mask */
3970    CPU_SET(coreId, &cpuSet);
3971
3972    /* set thread affinity for linux */
3973    if (pthread_setaffinity_np(tId, sizeof(cpuSet), &cpuSet) < 0)
3974    {
3975 #if (ERRCLASS & ERRCLS_DEBUG)
3976       MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
3977 #endif
3978       return RFAILED;
3979    } /* end if pthread_setaffinity fails */
3980
3981 #else
3982 #ifdef SUNOS
3983    for (tskInd = 0;  tskInd < SS_MAX_STSKS;  tskInd++)
3984    {
3985       /* comment: modify to use tskId as lwpId to avoid the loop and the new lwpId variable  in dep */
3986       if (osCp.sTskTbl[tskInd].tskId == *tskId)
3987       {
3988          lwpId = osCp.sTskTbl[tskInd].dep.lwpId;
3989          break;
3990       } /* end if */
3991    } /* end for */
3992
3993    /* if tskId is not found in the tskTbl */
3994    if (tskInd == SS_MAX_STSKS)
3995    {
3996       MTLOGERROR(ERRCLS_DEBUG, EMT036, ERRZERO, "Invalid system task Id\n");
3997       return RFAILED;
3998    }
3999
4000    /* set thread affinity for Solaris */
4001    if (processor_bind(P_LWPID, lwpId, coreId, NULL) < 0)
4002    {
4003 #if (ERRCLASS & ERRCLS_DEBUG)
4004       MTLOGERROR(ERRCLS_DEBUG, EMT038, ERRZERO, "Could not set thread affinity\n");
4005 #endif
4006       return RFAILED;
4007    } /* end if processor_bind fails */
4008
4009 #endif /* SUNOS */
4010 #endif /* SS_LINUX */
4011    return ROK;
4012 } /* ssdSetAffinity */
4013
4014 #endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */
4015 /************ end multi-core support *************/
4016
4017 \f
4018 /*
4019  *
4020  *       Fun:   ssdDestroySTsk
4021  *
4022  *       Desc:  This function destroys a system task. A terminate
4023  *              event message is sent to the thread function.
4024  *
4025  *       Ret:   ROK      - ok
4026  *
4027  *       Notes:
4028  *
4029  *       File:  mt_ss.c
4030  *
4031  */
4032    S16 ssdDestroySTsk
4033 (
4034  SsSTskEntry *sTsk           /* pointer to system task entry */
4035  )
4036 {
4037    Buffer *mBuf;
4038    SsMsgInfo *mInfo;
4039
4040
4041
4042
4043    /* we send a message to this system task to tell it to die */
4044    if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
4045    {
4046
4047 #if (ERRCLASS & ERRCLASS_DEBUG)
4048       MTLOGERROR(ERRCLS_DEBUG, EMT005, ERRZERO, "Could not get a message");
4049 #endif
4050
4051       return RFAILED;
4052    }
4053
4054    mInfo = (SsMsgInfo *)mBuf->b_rptr;
4055    mInfo->eventInfo.event = SS_EVNT_TERM;
4056
4057    if (ssDmndQPutLast(&sTsk->dQ, mBuf, 0) != ROK)
4058    {
4059       SPutMsg(mBuf);
4060
4061 #if (ERRCLASS & ERRCLASS_DEBUG)
4062       MTLOGERROR(ERRCLS_DEBUG, EMT006, ERRZERO,
4063             "Could not write to demand queue");
4064 #endif
4065
4066       return RFAILED;
4067    }
4068
4069
4070    return ROK;
4071 }
4072
4073 /* mt023.201 - Added SThreadYield function to yield CPU
4074  *
4075  *       Fun:   SThreadYield
4076  *
4077  *       Desc:  This function defers thread execution to any other ready
4078  *              thread.
4079  *
4080  *       Ret:   ROK      - ok
4081  *              RFAILED  - failure
4082  *
4083  *       Notes:
4084  *
4085  *       File:  mt_ss.c
4086  *
4087  */
4088 S16 SThreadYield(void)
4089 {
4090
4091
4092    /* mt024.201 - seperated Linux and other UNIX implementations
4093     */
4094 #ifdef SS_LINUX
4095    {
4096       struct timeval tw;
4097
4098       /* Set sleep value to 0 to yield CPU */
4099       tw.tv_sec=0;
4100       tw.tv_usec=0;
4101
4102       return (select(0,0,0,0,&tw) == 0 ? ROK : RFAILED);
4103    }
4104 #else /* other UNICes */
4105
4106    return (sleep(0) == 0 ? ROK : RFAILED);
4107
4108 #endif /* SS_LINUX */
4109
4110 }
4111
4112 \f
4113 /*
4114  *
4115  *       Fun:   Register timer
4116  *
4117  *       Desc:  This function is used to register a timer
4118  *              function for the service user. System services
4119  *              will invoke the timer activation function
4120  *              passed to it at the specified intervals.
4121  *
4122  *       Ret:   ROK      - ok
4123  *
4124  *       Notes: Timing is handled by the common timers. The
4125  *              ticks are handled by a thread that uses
4126  *              nanosleep() and thus timing precision will not
4127  *              be very accurate.
4128  *
4129  *       File:  mt_ss.c
4130  *
4131  */
4132    S16 ssdRegTmr
4133 (
4134  SsTmrEntry *tmr             /* pointer to timer entry */
4135  )
4136 {
4137    CmTmrArg arg;
4138
4139
4140
4141
4142    /* initialize common timers */
4143    cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
4144
4145
4146    /* start the timer */
4147    arg.tq = osCp.dep.tmrTq;
4148    arg.tqCp = &osCp.dep.tmrTqCp;
4149    arg.timers = tmr->dep.timers;
4150    arg.cb = (PTR) tmr;
4151    arg.evnt = TMR_DEF;
4152    arg.wait = 0;
4153    arg.tNum = NOTUSED;
4154    arg.max = TMR_DEF_MAX;
4155    arg.wait = tmr->interval;
4156    cmPlcCbTq(&arg);
4157
4158
4159    return ROK;
4160 }
4161
4162 \f
4163 /*
4164  *
4165  *       Fun:   Deregister timer
4166  *
4167  *       Desc:  This function is used to deregister a timer function.
4168  *
4169  *       Ret:   ROK      - ok
4170  *
4171  *       Notes:
4172  *
4173  *       File:  mt_ss.c
4174  *
4175  */
4176    S16 ssdDeregTmr
4177 (
4178  SsTmrEntry *tmr             /* pointer to timer entry */
4179  )
4180 {
4181    CmTmrArg arg;
4182
4183
4184
4185
4186    /* stop the timer */
4187    arg.tq = osCp.dep.tmrTq;
4188    arg.tqCp = &osCp.dep.tmrTqCp;
4189    arg.timers = tmr->dep.timers;
4190    arg.cb = (PTR) tmr;
4191    arg.evnt = TMR_DEF;
4192    arg.wait = 0;
4193    arg.tNum = NOTUSED;
4194    arg.max = TMR_DEF_MAX;
4195    arg.wait = tmr->interval;
4196    cmRmvCbTq(&arg);
4197
4198
4199    return ROK;
4200 }
4201
4202 \f
4203 /*
4204  *
4205  *       Fun:   Critical error
4206  *
4207  *       Desc:  This function is called when a critical error occurs.
4208  *
4209  *       Ret:   ROK      - ok
4210  *
4211  *       Notes:
4212  *
4213  *       File:  mt_ss.c
4214  *
4215  */
4216    S16 ssdError
4217 (
4218  Seq seq,                    /* sequence number */
4219  Reason reason               /* reset reason */
4220  )
4221 {
4222    S16 i;
4223    pthread_t tId;
4224    Txt errBuf[256];
4225
4226
4227
4228
4229    /* get calling task ID */
4230    tId = pthread_self();
4231
4232
4233    /* set up the message to display */
4234    sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
4235          "reason = %d\n\n", (uint8_t)tId, seq, reason);
4236    SPrint(errBuf);
4237
4238
4239    /* delete all system tasks */
4240    for (i = 0;  i < SS_MAX_STSKS;  i++)
4241    {
4242       if (osCp.sTskTbl[i].used
4243             &&  !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4244       {
4245          pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4246       }
4247    }
4248
4249
4250    /* delete self */
4251    pthread_exit(NULLP);
4252
4253
4254    /* won't reach here */
4255    return ROK;
4256 }
4257
4258 \f
4259 /*
4260  *
4261  *       Fun:   Log error
4262  *
4263  *       Desc:  This function is called to log an error.
4264  *
4265  *       Ret:   ROK      - ok
4266  *
4267  *       Notes:
4268  *
4269  *       File:  mt_ss.c
4270  *
4271  */
4272    Void ssdLogError
4273 (
4274  Ent ent,                    /* Calling layer's entity id */
4275  Inst inst,                  /* Calling layer's instance id */
4276  ProcId procId,              /* Calling layer's processor id */
4277  Txt *file,                  /* file name where error occured */
4278  S32 line,                   /* line in file where error occured */
4279  ErrCls errCls,              /* error class */
4280  ErrCode errCode,            /* layer unique error code */
4281  ErrVal errVal,              /* error value */
4282  Txt *errDesc                /* description of error */
4283  )
4284 {
4285 #ifndef DEBUGNOEXIT
4286    S16 i;
4287    pthread_t tId;
4288 #endif
4289    Txt *errClsMsg;
4290    Txt errBuf[512];
4291
4292
4293
4294
4295    /* get calling task ID */
4296 #ifndef DEBUGNOEXIT
4297    tId = pthread_self();
4298 #endif
4299
4300
4301    switch(errCls)
4302    {
4303       case ERRCLS_ADD_RES:
4304          errClsMsg = "ERRCLS_ADD_RES";
4305          break;
4306
4307       case ERRCLS_INT_PAR:
4308          errClsMsg = "ERRCLS_INT_PAR";
4309          break;
4310
4311       case ERRCLS_DEBUG:
4312          errClsMsg = "ERRCLS_DEBUG";
4313          break;
4314
4315          /* mt028.201 : Addition - ERRCLS_FTHA changes */
4316       case ERRCLS_FTHA:
4317          errClsMsg = "ERRCLS_FTHA";
4318          break;
4319
4320       default:
4321          errClsMsg = "INVALID ERROR CLASS!";
4322          break;
4323    }
4324
4325
4326    /*mt009.301 Fixed 64BIT compilation warnings*/
4327 #ifdef ALIGN_64BIT
4328    sprintf(errBuf,
4329          "\nmtss(posix): sw error:  ent: %03d  inst: %03d  proc id: %03d \n"
4330          "file: %s line: %03d errcode: %05d errcls: %s\n"
4331          "errval: %05d  errdesc: %s\n",
4332          ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4333 #else
4334    sprintf(errBuf,
4335          "\nmtss(posix): sw error:  ent: %03d  inst: %03d  proc id: %03d \n"
4336          "file: %s line: %03ld errcode: %05ld errcls: %s\n"
4337          "errval: %05ld  errdesc: %s\n",
4338          ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
4339 #endif
4340    SDisplay(0, errBuf);
4341    /* mt001.301 : Additions */
4342 #ifdef SS_LOGGER_SUPPORT
4343    SWrtLogBuf(errBuf);
4344 #endif /* SS_LOGGER_SUPPORT  */
4345
4346
4347 #ifndef DEBUGNOEXIT
4348    /* debug errors halt the system */
4349    if (errCls == ERRCLS_DEBUG)
4350    {
4351       /* mt001.301 : Additions */
4352 #ifdef SS_LOGGER_SUPPORT
4353       SCleanUp();
4354 #endif /* SS_LOGGER_SUPPORT  */
4355       /* delete all system tasks */
4356       for (i = 0;  i < SS_MAX_STSKS;  i++)
4357       {
4358          if (osCp.sTskTbl[i].used
4359                &&  !pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
4360          {
4361             pthread_kill(osCp.sTskTbl[i].dep.tId, SIGKILL);
4362          }
4363       }
4364
4365
4366       /* delete self */
4367       pthread_exit(NULLP);
4368    }
4369 #endif
4370
4371
4372    return;
4373 }
4374
4375 #ifdef ENB_RELAY
4376 \f
4377 /*
4378  *
4379  *       Fun:   Register driver task
4380  *
4381  *       Desc:  This function is called to register the handlers for a
4382  *              driver task.
4383  *
4384  *       Ret:   ROK      - ok
4385  *
4386  *       Notes:
4387  *
4388  *       File:  mt_ss.c
4389  *
4390  */
4391    S16 ssdRegDrvrTsk
4392 (
4393  SsDrvrTskEntry *drvrTsk         /* driver task entry */
4394  )
4395 {
4396
4397
4398    return ROK;
4399 }
4400 /* mt001.30 : Additions */
4401 /*
4402  *
4403  *       Fun:   Deregister driver task
4404  *
4405  *       Desc:  This function is called to deregister the handlers for a
4406  *              driver task.
4407  *
4408  *       Ret:   ROK      - ok
4409  *
4410  *       Notes:
4411  *
4412  *       File:  mt_ss.c
4413  *
4414  */
4415    S16 ssdDeregDrvrTsk
4416 (
4417  SsDrvrTskEntry *drvrTsk         /* driver task entry */
4418  )
4419 {
4420
4421
4422    return ROK;
4423 }
4424 #endif
4425
4426
4427
4428 \f
4429 /*
4430  * mt003.301 Additions - SDeRegTTsk fix
4431  */
4432 #ifdef SS_MULTIPLE_PROCS
4433    S16 ssdProcTTskTerm
4434 (
4435  ProcId procIdx,
4436  SsTTskEntry *tTsk,
4437  SsIdx idx
4438  )
4439 #else /*SS_MULTIPLE_PROCS*/
4440    S16 ssdProcTTskTerm
4441 (
4442  SsTTskEntry *tTsk,
4443  SsIdx idx
4444  )
4445 #endif /*SS_MULTIPLE_PROCS*/
4446 {
4447 #ifdef SS_MULTIPLE_PROCS
4448    ProcId proc;
4449 #endif
4450    Ent ent;
4451    Inst inst;
4452    SsSTskEntry *sTsk;
4453    S16 n;
4454    S16  ret;
4455
4456
4457
4458    ent = tTsk->ent;
4459    inst = tTsk->inst;
4460    /* We check the sTsk element; if it is not NULLP, the
4461     *  task is attached. So we have to detach it before
4462     *  deregistering the task.
4463     */
4464    ret = SLock(&osCp.sTskTblLock);
4465    if (ret != ROK)
4466    {
4467       MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock system task table");
4468       return RFAILED;
4469    }
4470    SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
4471    if (ret != ROK)
4472    {
4473 #if (ERRCLASS & ERRCLS_DEBUG)
4474       MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not lock TAPA task table");
4475 #endif
4476       if ( SUnlock(&osCp.sTskTblLock) != ROK)
4477       {
4478 #if (ERRCLASS & ERRCLS_DEBUG)
4479          MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4480          return RFAILED;
4481 #endif
4482       }
4483
4484       return RFAILED;
4485    }
4486
4487 #ifdef SS_MULTIPLE_PROCS
4488    proc = tTsk->proc;
4489    if (tTsk->initTsk != NULLP)
4490    {
4491 #ifndef USE_MEMCAL
4492       (Void)(*(tTsk->initTsk))(proc, ent, inst,
4493             DFLT_REGION,
4494             NRM_TERM,
4495             &(osCp.tTskTbl[idx].xxCb));
4496 #else
4497       (Void)(*(tTsk->initTsk))(proc, ent, inst,
4498             SS_STATIC_REGION,
4499             NRM_TERM,
4500             &(osCp.tTskTbl[idx].xxCb));
4501 #endif /* USE_MEMCAL */
4502    }
4503 #endif /* SS_MULTIPLE_PROCS */
4504
4505    if (tTsk->sTsk != NULLP)
4506    {
4507       sTsk = tTsk->sTsk;
4508
4509       sTsk->dep.ent = ent;
4510       sTsk->dep.inst = inst;
4511
4512       for (n = 0;  n < SS_MAX_TTSKS;  n++)
4513       {
4514          if (sTsk->tTsks[n] == idx)
4515          {
4516             sTsk->tTsks[n] = SS_INVALID_IDX;
4517             sTsk->numTTsks--;
4518             break;
4519          }
4520       }
4521
4522       /* call the implementation to detach the task */
4523       ssdDetachTTsk(tTsk);
4524       /* 100178 */
4525       sTsk->dep.ent = ENTNC;
4526       sTsk->dep.inst = INSTNC;
4527    }
4528
4529    /* Now we empty the entry for this task and update the table
4530     *  information
4531     */
4532 #ifdef SS_MULTIPLE_PROCS
4533    osCp.tTskIds[procIdx][ent][inst] = SS_TSKNC;
4534 #else /* SS_MULTIPLE_PROCS */
4535    osCp.tTskIds[ent][inst] = SS_TSKNC;
4536 #endif /* SS_MULTIPLE_PROCS */
4537
4538    tTsk->used    = FALSE;
4539 #ifdef SS_MULTIPLE_PROCS
4540    tTsk->proc    = PROCNC;
4541 #endif /* SS_MULTIPLE_PROCS */
4542    tTsk->ent     = ENTNC;
4543    tTsk->inst    = INSTNC;
4544    tTsk->tskType = TTUND;
4545    tTsk->initTsk = NULLP;
4546    tTsk->actvTsk = NULLP;
4547    tTsk->sTsk    = NULLP;
4548
4549    tTsk->nxt = osCp.nxtTTskEntry;
4550    osCp.nxtTTskEntry = idx;
4551    osCp.numTTsks--;
4552
4553 #ifdef SS_MULTIPLE_PROCS
4554    /* mark the control block for this task as invalid */
4555    osCp.tTskTbl[idx].xxCb = NULLP;
4556 #endif
4557
4558    SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
4559    if ( SUnlock(&osCp.sTskTblLock) != ROK)
4560    {
4561 #if (ERRCLASS & ERRCLS_DEBUG)
4562       MTLOGERROR(ERRCLS_DEBUG, EMTXXX, ERRZERO, "Could not Unlock system task table");
4563 #endif
4564       return RFAILED;
4565    }
4566    return ROK;
4567 }
4568
4569 //#ifndef SPLIT_RLC_DL_TASK
4570 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
4571 #if defined (L2_L3_SPLIT) && defined(SPLIT_RLC_DL_TASK) 
4572 Void ysMtTskHdlr(Void);
4573 Void ysMtPollPhyMsg(uint8_t region);
4574 Void ysMtRcvPhyMsg(Void);
4575    Void *mtTskHdlrT2kL2
4576 (
4577  Ptr tskPtr                      /* pointer to task entry */
4578  )
4579 {
4580    S16 ret;
4581
4582
4583    /* wait for SS to come up */
4584    /* It is required to block on this semaphore before starting actual processing of 
4585       the thread becasue the creator of this thread might want to cance it without
4586       doing any processing. When this semaphore is released, means the creator gives
4587       the go ahead for actual processing and we should never come back to this point */
4588    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4589       continue;
4590
4591 #ifdef YS_PHY_3_8_2
4592    tlSetReady(NULL);
4593 #endif
4594
4595    while(1)
4596    {
4597       ysMtPollPhyMsg(0); /* blocks, waiting for messages for L2
4598                           * (processes L1 msgs) */
4599    }
4600
4601    return (NULLP);
4602 }
4603 #else
4604 Void ysMtTskHdlr(Void);
4605 Void YsPhyRecvMsg();
4606    Void *mtTskHdlrT2kL2
4607 (
4608  Ptr tskPtr                      /* pointer to task entry */
4609  )
4610 {
4611    S16 ret;
4612    SsSTskEntry *sTsk;
4613
4614    /* get out the system task entry from the parameter */
4615    sTsk = (SsSTskEntry *) tskPtr;
4616
4617    /* wait for SS to come up */
4618    /* It is required to block on this semaphore before starting actual processing of 
4619       the thread becasue the creator of this thread might want to cance it without
4620       doing any processing. When this semaphore is released, means the creator gives
4621       the go ahead for actual processing and we should never come back to this point */
4622    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4623       continue;
4624
4625 #ifndef RGL_SPECIFIC_CHANGES
4626 #ifdef YS_PHY_3_8_2
4627    tlSetReady(NULL);
4628 #endif
4629 #endif
4630
4631    while(1)
4632    {
4633 #ifdef V5GTF_SPECIFIC_CHANGES
4634       YsPhyRecvMsg();      
4635 #else      
4636       ysMtTskHdlr(); /* blocks, waiting for messages for L2
4637                       * (processes L1 msgs) */
4638 #endif
4639       /* get a message from the demand queue */
4640       /* RT Processing */
4641 #ifdef RLC_MAC_DAT_REQ_RBUF
4642       rgDlDatReqBatchProc();
4643 #endif
4644
4645       ret = mtTskHdlMsg(sTsk); 
4646       if (ret != ROK)
4647       {
4648          /* exit the for loop here */
4649          break;
4650       }
4651 #if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF)
4652       rgBatchProc();
4653 #endif  
4654    }
4655
4656    return (NULLP);
4657 }
4658 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
4659 #endif
4660
4661 void *pthreadCreateHdlr(void * arg)
4662 {
4663    S16 ret;
4664    SPThreadCreateArg*  pthreadCreateArg = (SPThreadCreateArg*)arg;
4665    /* mt038.201 changed how sem_wait is called  */
4666    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4667       continue;
4668
4669    pthreadCreateArg->start_routine(pthreadCreateArg->argument);
4670    return ROK;
4671 }
4672 \f
4673 /*
4674  *
4675  *       Fun:   Task handler
4676  *
4677  *       Desc:  This is the system task handler function. It blocks on
4678  *              the system task's demand queue. On receiving a message,
4679  *              it identifies the target TAPA task, verifies that the
4680  *              TAPA task belongs to this system task and if so, calls
4681  *              the activation function of that TAPA task with the
4682  *              received message. The task activation function or the
4683  *              timer activation function may be called.
4684  *
4685  *       Ret:   (thread function)
4686  *
4687  *       Notes:
4688  *
4689  *       File:  mt_ss.c
4690  *
4691  */
4692    Void *mtTskHdlr
4693 (
4694  Ptr tskPtr                      /* pointer to task entry */
4695  )
4696 {
4697    S16 ret = ROK;
4698    SsSTskEntry *sTsk;
4699
4700    /* get out the system task entry from the parameter */
4701    sTsk = (SsSTskEntry *) tskPtr;
4702
4703
4704    /* wait for SS to come up */
4705
4706    /* mt038.201 changed how sem_wait is called  */
4707    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
4708       continue;
4709 #ifdef XEON_SPECIFIC_CHANGES
4710    printf("\n**********MT Task Handler********\n");
4711 #endif   
4712    while (1)
4713    {
4714       /* Wait for a message from the demand queue */
4715 #ifdef SS_CDMNDQ_SUPPORT
4716       ret = ssCDmndQWait(&sTsk->dQ);
4717 #else
4718       ret = ssDmndQWait(&sTsk->dQ);
4719 #endif
4720       if (ret != ROK)
4721          continue;
4722
4723       ret = mtTskHdlMsg(sTsk); 
4724       if (ret != ROK)
4725       {
4726          break;
4727       }
4728    }
4729
4730    return (NULLP);
4731 }
4732
4733 \f
4734 /*
4735  *
4736  *       Fun:   Task handler
4737  *
4738  *       Desc:  This is the system task handler function. It blocks on
4739  *              the system task's demand queue. On receiving a message,
4740  *              it identifies the target TAPA task, verifies that the
4741  *              TAPA task belongs to this system task and if so, calls
4742  *              the activation function of that TAPA task with the
4743  *              received message. The task activation function or the
4744  *              timer activation function may be called.
4745  *
4746  *       Ret:   (thread function)
4747  *
4748  *       Notes:
4749  *
4750  *       File:  mt_ss.c
4751  *
4752  */
4753    S16 mtTskHdlMsg
4754 (
4755  SsSTskEntry *sTsk
4756  )
4757 {
4758    S16 i =0;
4759    S16 ret =0;
4760    SsIdx idx =0;
4761    SsTTskEntry *tTsk=NULLP;
4762    Buffer *mBuf=NULLP;
4763 #ifdef SS_PERF
4764    Buffer *mBuf2=NULLP;
4765 #endif
4766    SsMsgInfo *mInfo=NULLP;
4767    Pst nPst;
4768    /* mt028.201: modification: multiple procs support related changes */
4769 #ifndef SS_MULTIPLE_PROCS
4770 #ifdef SS_MT_TMR
4771    PAIFTMRS16 tmrActvFnMt = NULLP;
4772 #endif
4773    /* mt015.301 Initialized the timer activation functions with NULLP */
4774    PFS16 tmrActvFn = NULLP;
4775 #else
4776    PAIFTMRS16 tmrActvFn =NULLP;
4777    uint16_t procIdIdx =0;
4778 #endif /* SS_MULTIPLE_PROCS */
4779    /* mt003.301 Modifications */
4780 #ifdef SS_THREAD_PROFILE
4781    EpcTime et1,et2;
4782 #endif /* SS_THREAD_PROFILE */
4783
4784
4785    ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
4786    if (ret != ROK)
4787    {
4788       /* nothing to receive */
4789       return ROK;
4790    }
4791
4792    /* if we can't lock this system task entry, return the message */
4793    ret = SLock(&sTsk->lock);
4794    if (ret != ROK)
4795    {
4796
4797 #if (ERRCLASS & ERRCLS_DEBUG)
4798       MTLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
4799             "Could not lock system task entry");
4800 #endif
4801       SPutMsg(mBuf);
4802       return ROK;
4803    }
4804
4805    /* mt034.201 */
4806 #ifdef SS_PERF
4807    do 
4808    {
4809       mBuf2 = mBuf->b_next;
4810 #endif
4811       /* find out what kind of message this is */
4812       mInfo = (SsMsgInfo *)mBuf->b_rptr;
4813 #ifdef SS_MEM_WL_DEBUG
4814       mtTskBuffer1 = mBuf2;
4815       if(mBuf2)
4816          mtTskBuffer2 = mBuf2->b_next;
4817
4818       if(mInfo == 0x5050505)
4819       {
4820          stopBtInfo = TRUE;
4821          SGlobMemInfoShow();
4822          cmAnalyseBtInfo((PTR) mBuf,4);
4823          SGlobMemInfoShow();
4824          printf("\n In trouble .... \n");
4825       }
4826       else if (mInfo == 0x2020202)
4827       {
4828          stopBtInfo = TRUE;
4829          cmAnalyseBtInfo((PTR) mBuf,1);
4830          printf("\n In trouble .... \n");
4831       }
4832 #endif /* SS_MEM_WL_DEBUG */
4833       switch (mInfo->eventInfo.event)
4834       {
4835          /* this is a termination event, we die */
4836          case SS_EVNT_TERM:
4837             /* release the message */
4838             SPutMsg(mBuf);
4839
4840             /* Unlock the system task entry and lock the system
4841              *  task table to clean our entry up.
4842              */
4843             SUnlock(&sTsk->lock);
4844
4845             ret = SLock(&osCp.sTskTblLock);
4846             if (ret != ROK)
4847             {
4848
4849 #if (ERRCLASS & ERRCLS_DEBUG)
4850                MTLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
4851                      "Could not lock system task table");
4852 #endif
4853                /* what to do here? */
4854                return ROK;
4855             }
4856
4857             /* clean up the system task entry */
4858             sTsk->used = FALSE;
4859             sTsk->tskPrior = 0;
4860             /* mt003.301 Modifications - SDeRegTTsk */
4861             /* sTsk->numTTsks = 0; */
4862             SDestroyLock(&sTsk->lock);
4863             ssDestroyDmndQ(&sTsk->dQ);
4864
4865             /* lock for current executing TAPA task ID */
4866
4867             /* make this entry available in the system task table */
4868             sTsk->nxt = osCp.nxtSTskEntry;
4869             for (i = 0;  i < SS_MAX_STSKS;  i++)
4870             {
4871                if (sTsk == &osCp.sTskTbl[i])
4872                {
4873                   osCp.nxtSTskEntry = i;
4874                   break;
4875                }
4876             }
4877
4878             osCp.numSTsks--;
4879
4880             /* unlock the system task table */
4881             SUnlock(&osCp.sTskTblLock);
4882
4883             return RFAILED;
4884
4885
4886             /* this is a data message or a permanent task keep-alive message */
4887          case SS_EVNT_DATA:
4888          case SS_EVNT_PERMTICK:
4889             /* message to a task. find the destination task */
4890             /* mt028.201: modification: multiple procs support related changes */
4891 #ifdef SS_MULTIPLE_PROCS
4892             procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
4893
4894             if (procIdIdx == SS_INV_PROCID_IDX)
4895             {
4896                SPutMsg(mBuf);
4897                break;
4898             }
4899
4900             idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
4901 #else /* SS_MULTIPLE_PROCS */
4902             idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
4903 #endif /* SS_MULTIPLE_PROCS */
4904
4905             /* verify that it hasn't been deregistered */
4906             if (idx == SS_TSKNC)
4907             {
4908                SPutMsg(mBuf);
4909                break;
4910             }
4911
4912             /* verify that this system task is still running it */
4913             tTsk = &osCp.tTskTbl[idx];
4914             if (tTsk->sTsk != sTsk)
4915             {
4916                SPutMsg(mBuf);
4917                break;
4918             }
4919
4920             /* set the current executing TAPA task ID */
4921             sTsk->dep.ent = mInfo->pst.dstEnt;
4922             sTsk->dep.inst = mInfo->pst.dstInst;
4923
4924             /* copy the Pst structure into a local duplicate */
4925             for (i = 0;  i < (S16) sizeof(Pst);  i++)
4926                *(((uint8_t *)(&nPst)) + i) = *(((uint8_t *)&mInfo->pst) + i);
4927
4928             /* Give the message to the task activation function. If
4929              *  its a normal data message, we pass it, if this is a
4930              *  keep-alive message for a permanent task then we pass
4931              *  NULLP in place of the message to the task activation
4932              *  function.
4933              */
4934             if (mInfo->eventInfo.event == SS_EVNT_DATA)
4935             {
4936 #ifndef RGL_SPECIFIC_CHANGES
4937 #ifdef SS_TSKLOG_ENABLE
4938                uint32_t t = MacGetTick();
4939 #endif
4940 #endif
4941                /* mt003.301 Modifications */
4942 #if SS_THREAD_PROFILE
4943                tTsk->curEvent = nPst.event;
4944                SGetEpcTime(&et1);
4945 #endif /* SS_THREAD_PROFILE */
4946                tTsk->actvTsk(&nPst, mBuf);
4947 #ifndef RGL_SPECIFIC_CHANGES
4948 #ifdef SS_TSKLOG_ENABLE
4949                SStopTask(t,PID_SSI_TSK);
4950 #endif
4951 #endif
4952 #if SS_THREAD_PROFILE
4953                SGetEpcTime(&et2);
4954                tTsk->curEvtTime = (uint32_t)(et2 - et1);
4955                tTsk->totTime += (uint64_t)tTsk->curEvtTime;
4956 #endif /* SS_THREAD_PROFILE */
4957             }
4958             else
4959             {
4960 #if (ERRCLASS & ERRCLS_DEBUG)
4961                /* this message should only come to a permanent task */
4962                if (tTsk->tskType != SS_TSK_PERMANENT)
4963                {
4964                   MTLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
4965                   break;
4966                }
4967 #endif
4968                tTsk->actvTsk(&nPst, NULLP);
4969
4970                /* We need to re-send this message back to ourselves so
4971                 *  the permanent task continues to run.
4972                 */
4973                /* Check if this task got deregistered or detached
4974                 *  by the activation function; if so, there's nothing
4975                 *  more to do here, otherwise go ahead.
4976                 */
4977                ret = ROK;
4978                if (tTsk->used == TRUE  &&  tTsk->sTsk != NULLP)
4979                {
4980                   ret = ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
4981                         ((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
4982                         mInfo->pst.prior);
4983                }
4984
4985                /* failure here is a real problem */
4986                if (ret != ROK)
4987                {
4988 #if (ERRCLASS & ERRCLS_DEBUG)
4989                   MTLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
4990                         "Could not write to demand queue");
4991 #endif
4992                   SPutMsg(mBuf);
4993                }
4994             }
4995
4996             /* unset the current executing TAPA task ID */
4997             sTsk->dep.ent = ENTNC;
4998             sTsk->dep.inst = INSTNC;
4999             break;
5000
5001
5002          case SS_EVNT_TIMER:
5003             /* timer event. find the timer entry */
5004             idx = mInfo->eventInfo.u.tmr.tmrIdx;
5005
5006             /* lock the timer table, coz we're going to peek in it */
5007             ret = SLock(&osCp.tmrTblLock);
5008             if (ret != ROK)
5009             {
5010
5011 #if (ERRCLASS & ERRCLS_DEBUG)
5012                MTLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
5013                      "Could not lock timer table");
5014 #endif
5015                SPutMsg(mBuf);
5016                break;
5017             }
5018
5019             /* Verify that this timer entry is still around and that it
5020              *  belongs to our task.
5021              */
5022             if (osCp.tmrTbl[idx].used == FALSE
5023                   /* mt028.201: modification: multiple procs support related changes */
5024 #ifdef SS_MULTIPLE_PROCS
5025                   ||  osCp.tmrTbl[idx].ownerProc != mInfo->pst.dstProcId
5026 #endif /* SS_MULTIPLE_PROCS */
5027                   ||  osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
5028                   ||  osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst)
5029             {
5030                SUnlock(&osCp.tmrTblLock);
5031                SPutMsg(mBuf);
5032                break;
5033             }
5034
5035             /* mt005.21: addition */
5036             /* set the current executing TAPA task ID */
5037             sTsk->dep.ent = mInfo->pst.dstEnt;
5038             sTsk->dep.inst = mInfo->pst.dstInst;
5039
5040 #ifndef SS_MULTIPLE_PROCS
5041 #ifdef SS_MT_TMR
5042             /*mt006.301 Adding Initializing the tmrActvFnMt*/
5043             tmrActvFnMt = NULLP;
5044             if (osCp.tmrTbl[idx].ssTmrActvFn.mtFlag == TRUE)
5045             {
5046                tmrActvFnMt = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFnMt;
5047             }
5048             else
5049 #endif
5050 #endif
5051             {
5052                tmrActvFn = osCp.tmrTbl[idx].ssTmrActvFn.actvFnc.tmrActvFn;
5053             }
5054
5055             /* unlock the timer table */
5056             SUnlock(&osCp.tmrTblLock);
5057
5058             /* activate the timer function */
5059             /* mt028.201: modification: multiple procs support related changes */
5060 #ifndef SS_MULTIPLE_PROCS
5061 #ifdef SS_MT_TMR
5062             if (tmrActvFnMt)
5063             {
5064                tmrActvFnMt(osCp.tmrTbl[idx].ownerEnt,
5065                      osCp.tmrTbl[idx].ownerInst);
5066             }
5067             else
5068 #endif
5069             {
5070                tmrActvFn();
5071             }
5072 #else
5073             tmrActvFn(osCp.tmrTbl[idx].ownerProc, osCp.tmrTbl[idx].ownerEnt,
5074                   osCp.tmrTbl[idx].ownerInst);
5075 #endif /* SS_MULTIPLE_PROCS */
5076
5077             /*mt005.21: addition */
5078             /* unset the current executing TAPA task ID */
5079             sTsk->dep.ent = ENTNC;
5080             sTsk->dep.inst = INSTNC;
5081
5082
5083             /* return the message buffer */
5084             SPutMsg(mBuf);
5085             break;
5086             /*
5087              * mt003.301 - SDeRegTTsk fix
5088              */
5089          case SS_EVNT_TTSK_TERM:
5090 #ifdef SS_MULTIPLE_PROCS
5091             procIdIdx = SGetProcIdIdx(mInfo->pst.dstProcId);
5092
5093             if (procIdIdx == SS_INV_PROCID_IDX)
5094             {
5095                SPutMsg(mBuf);
5096                break;
5097             }
5098
5099             idx = osCp.tTskIds[procIdIdx][mInfo->pst.dstEnt][mInfo->pst.dstInst];
5100 #else /* SS_MULTIPLE_PROCS */
5101             idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
5102 #endif /* SS_MULTIPLE_PROCS */
5103
5104             /* verify that it hasn't been deregistered */
5105             if (idx == SS_TSKNC)
5106             {
5107                SPutMsg(mBuf);
5108                break;
5109             }
5110
5111             /* verify that this system task is still running it */
5112             tTsk = &osCp.tTskTbl[idx];
5113             if (tTsk->sTsk != sTsk)
5114             {
5115                SPutMsg(mBuf);
5116                break;
5117             }
5118 #ifdef SS_MULTIPLE_PROCS
5119             ssdProcTTskTerm(procIdIdx, tTsk, idx);
5120 #else
5121             ssdProcTTskTerm(tTsk, idx);
5122 #endif
5123             SPutMsg(mBuf);
5124             break;
5125
5126          default:
5127 #if (ERRCLASS & ERRCLS_DEBUG)
5128             MTLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
5129                   "Illegal event");
5130 #endif
5131             break;
5132       }
5133 #ifdef SS_PERF
5134       mBuf = mBuf2;
5135    } while (mBuf != NULLP);
5136 #endif
5137
5138    /* unlock the system task entry */
5139    SUnlock(&sTsk->lock);
5140
5141 #ifndef SS_PERF
5142    /* yield for other threads */
5143    /* mt024.201 - changed to use SSI SThreadYield instead of sleep */
5144    SThreadYield();
5145 #endif
5146
5147    return ROK;
5148 }
5149
5150 Bool g_usettitmr;
5151 /*
5152  *       Fun:   mtTmrHdlrPublic
5153  */
5154 Void mtTmrHdlrPublic()
5155 {
5156    if (SLock(&osCp.tmrTblLock) != ROK)
5157    {
5158 #if (ERRCLASS & ERRCLS_DEBUG)
5159       MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5160 #endif
5161       return;
5162    }
5163    cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5164    /* unlock the timer table */
5165    SUnlock(&osCp.tmrTblLock);
5166 }
5167
5168 \f
5169 /*
5170  *
5171  *       Fun:   mtTmrHdlr
5172  *
5173  *       Desc:  The timer handler thread function. Counts time
5174  *              and invokes the common timer function on each
5175  *              tick.
5176  *
5177  *       Ret:   (thread function)
5178  *
5179  *       Notes:
5180  *
5181  *       File:  mt_ss.c
5182  *
5183  */
5184 /*mt041.201 Modified SSI tick handling in mtTmrHdlr() */
5185    static Void *mtTmrHdlr
5186 (
5187  void *parm                        /* unused */
5188  )
5189 {
5190    /*mt004.301-addede new region*/
5191    /* mt010.301 Removed SS_FAP portion and
5192     * enabled oroginal code in function mtTmrHdlr */
5193
5194    struct timespec ts;
5195    uint32_t time_int;
5196    uint32_t i, cnt, oldTicks, newTicks;
5197    struct timeval tv1,tv2;
5198    /* mt038.201 added return */
5199    S16 ret;
5200    /* mt039.201 changes for nanosleep */
5201    struct timespec tsN;
5202    static uint32_t err_in_usec;
5203
5204    /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5205
5206
5207    UNUSED(parm);
5208
5209    /* mt027.201 - Modification for SRegCfgTmr support */
5210    /* check SS_TICKS_SEC */
5211    if (SS_1MS < SS_TICKS_SEC)
5212    {
5213       MTLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Minimum SSI ticks is 1ms");
5214    }
5215
5216    /* mt025.201 - Addition to stop timer handler till task registration is done */
5217    /* wait for SS to come up */
5218    /* mt038.201 changed how sem_wait is called  */
5219    while ((ret = sem_wait(&osCp.dep.ssStarted) != ROK) && (errno == EINTR))
5220       continue;
5221
5222    /* mt027.201 - Modification for SRegCfgTmr support */
5223    /* set up parameter to nanosleep() for SS_TICKS_SEC */
5224    ts.tv_sec = 0;
5225    ts.tv_nsec = (MT_TICK_CNT * 1000);
5226    /* mt039.201 changes for nanosleep */
5227    tsN.tv_sec = 0;
5228    tsN.tv_nsec = 0;
5229
5230    err_in_usec =  0;
5231
5232    if (gettimeofday(&tv1, NULL) == -1)
5233    {
5234 #if (ERRCLASS & ERRCLS_DEBUG)
5235       MTLOGERROR(ERRCLS_DEBUG, EMT014, (ErrVal) errno,
5236             "Error in clock_gettime");
5237 #endif
5238    }
5239
5240    /* infinite loop */
5241    for (; ;)
5242    {
5243 #if 1
5244       if (g_usettitmr)
5245       {
5246 #ifndef STUB_TTI_HANDLING_5GTF        
5247          printf("\nReturning from mtTmrHdlr()\n");
5248          return NULL;
5249 #endif        
5250       }
5251 #endif
5252       /* mt039.201 changes for nanosleep */
5253       /* sleep for MT_TICK_CNT milli seconds */
5254       ts.tv_nsec = (MT_TICK_CNT - err_in_usec) * 1000;
5255       while ((ret = nanosleep (&ts, &tsN) != ROK) && (errno == EINTR))
5256       {
5257          ts.tv_nsec = tsN.tv_nsec;
5258          tsN.tv_nsec = 0;
5259          continue;
5260       }
5261
5262       if (gettimeofday(&tv2,NULL) == -1)
5263       {
5264 #if (ERRCLASS & ERRCLS_DEBUG)
5265          MTLOGERROR(ERRCLS_DEBUG, EMT015, (ErrVal) errno,
5266                "Error in clock_gettime");
5267 #endif
5268       }
5269
5270       /*mt013.301 : changed check while calculating timer to fix
5271        * diffrence between MTSS time and real unix time
5272        */
5273       if ((tv2.tv_sec == tv1.tv_sec)&&(tv2.tv_usec > tv1.tv_usec))
5274       {
5275          time_int = (tv2.tv_usec - tv1.tv_usec);
5276       }
5277       else if (tv2.tv_sec > tv1.tv_sec)
5278       {
5279          time_int = ((tv2.tv_sec - tv1.tv_sec)*1000000) + (tv2.tv_usec - tv1.tv_usec);
5280       }
5281       else /*  ts2 < ts1, this will not happen in normal scenario */
5282       {
5283          /* to make sure cnt = 1  */
5284          err_in_usec = 0;
5285          time_int = MT_TICK_CNT;
5286       }
5287
5288       oldTicks = osCp.dep.sysTicks;
5289       osCp.dep.sysTicks += (time_int/(MT_TICK_CNT - err_in_usec));
5290       err_in_usec = (time_int % (MT_TICK_CNT - err_in_usec));
5291       newTicks = osCp.dep.sysTicks;
5292       tv1.tv_usec = tv2.tv_usec;
5293       tv1.tv_sec = tv2.tv_sec;
5294
5295       cnt = newTicks - oldTicks;
5296
5297       while(err_in_usec >= MT_TICK_CNT)
5298       {
5299          cnt++;
5300          err_in_usec -= MT_TICK_CNT;
5301       }
5302       if( cnt >= MT_MAX_TICK_CNT_VAL)
5303          cnt = MT_MIN_TICK_CNT_VAL;
5304       /* call the common timer tick handler */
5305       for (i = 0; i < cnt; i++)
5306       {
5307          /* mt008.301: cmPrcTmr is guarded with a lock */
5308          /* lock the timer table */
5309          if (SLock(&osCp.tmrTblLock) != ROK)
5310          {
5311 #if (ERRCLASS & ERRCLS_DEBUG)
5312             MTLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO, "Could not lock timer table");
5313 #endif
5314             continue;
5315          }
5316          cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, mtTimeout);
5317          /* unlock the timer table */
5318          SUnlock(&osCp.tmrTblLock);
5319       }
5320    }
5321
5322    /* mt009.21: addition */
5323    return ( (Void *) NULLP);
5324    /* will not reach here */
5325 }
5326
5327 \f
5328 /*
5329  *
5330  *       Fun:   mtTimeout
5331  *
5332  *       Desc:  Process timer event. Called from the common timer
5333  *              code when a timeout occurs.
5334  *
5335  *       Ret:   Void
5336  *
5337  *       Notes:
5338  *
5339  *       File:  mt_ss.c
5340  *
5341  */
5342    Void mtTimeout
5343 (
5344  PTR tCb,                        /* control block */
5345  S16 evnt                        /* event */
5346  )
5347 {
5348    Buffer *mBuf;
5349    SsMsgInfo *mInfo;
5350    CmTmrArg arg;
5351    SsTmrEntry *tEnt;
5352    SsTTskEntry *tTsk;
5353    SsIdx idx;
5354 #ifndef TENB_RTLIN_CHANGES
5355    S16 ret;
5356 #endif
5357    /* mt028.201: modification: multiple procs support related changes */
5358 #ifdef SS_MULTIPLE_PROCS
5359    uint16_t procIdIdx;
5360 #endif /* SS_MULTIPLE_PROCS */
5361 #ifdef RGL_SPECIFIC_CHANGES
5362 #ifdef MSPD_MLOG_NEW
5363    uint32_t t = GetTIMETICK();
5364 #endif
5365 #endif
5366
5367
5368
5369    /* get the timer entry */
5370    tEnt = (SsTmrEntry *) tCb;
5371
5372
5373    /* if the timer was deleted, this will be NULL, so drop it */
5374    if (tEnt == NULL)
5375    {
5376       return;
5377    }
5378
5379    /* mt008.301 Deletion: tmrTbl Lock is moved to mtTmrHdlr */
5380
5381
5382    /* Hmmmm, the timer might have been deleted while we've been
5383     *  working at getting here, so we just skip this.
5384     */
5385    if (tEnt->used == FALSE)
5386    {
5387       return;
5388    }
5389
5390
5391    /* Set up and send a timer message to the destination tasks'
5392     * demand queue.
5393     */
5394 #ifndef SS_MULTICORE_SUPPORT
5395    if (SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK)
5396 #else
5397 #ifdef RGL_SPECIFIC_CHANGES
5398       if (SGetMsg((SS_DFLT_REGION), SS_DFLT_POOL, &mBuf) != ROK)
5399 #else
5400          if (SGetMsg((osCp.sTskTbl[0].region), SS_DFLT_POOL, &mBuf) != ROK)
5401 #endif
5402 #endif
5403          {
5404
5405 #if (ERRCLASS & ERRCLS_DEBUG)
5406             MTLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO, "Could not get message");
5407 #endif
5408
5409             return;
5410          }
5411
5412    mInfo = (SsMsgInfo *)mBuf->b_rptr;
5413    mInfo->eventInfo.event = SS_EVNT_TIMER;
5414    mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
5415
5416    mInfo->pst.dstEnt = tEnt->ownerEnt;
5417    mInfo->pst.dstInst = tEnt->ownerInst;
5418    mInfo->pst.srcEnt = tEnt->ownerEnt;
5419    mInfo->pst.srcInst = tEnt->ownerInst;
5420    /* mt028.201: modification: multiple procs support related changes */
5421 #ifndef SS_MULTIPLE_PROCS
5422    mInfo->pst.dstProcId = SFndProcId();
5423    mInfo->pst.srcProcId = SFndProcId();
5424 #else /* SS_MULTIPLE_PROCS */
5425    mInfo->pst.dstProcId = tEnt->ownerProc;
5426    mInfo->pst.srcProcId = tEnt->ownerProc;
5427 #endif /* SS_MULTIPLE_PROCS */
5428    mInfo->pst.selector = SEL_LC_NEW;
5429 #ifndef SS_MULTICORE_SUPPORT
5430    mInfo->pst.region = DFLT_REGION;
5431 #else
5432 #endif
5433    mInfo->pst.pool = DFLT_POOL;
5434    mInfo->pst.prior = PRIOR0;
5435    mInfo->pst.route = RTESPEC;
5436    mInfo->pst.event = 0;
5437
5438
5439 #ifndef TENB_RTLIN_CHANGES
5440    /* get a semaphore for the TAPA task table */
5441    SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
5442    if (ret != ROK)
5443    {
5444       SPutMsg(mBuf);
5445
5446 #if (ERRCLASS & ERRCLS_DEBUG)
5447       MTLOGERROR(ERRCLS_DEBUG, EMT018, ret, "Could not lock TAPA task table");
5448 #endif
5449
5450       return;
5451    }
5452 #endif
5453
5454
5455    /* find the owner TAPA task */
5456    /* mt028.201: modification: multiple procs support related changes */
5457 #ifdef SS_MULTIPLE_PROCS
5458    procIdIdx = SGetProcIdIdx(tEnt->ownerProc);
5459    idx = osCp.tTskIds[procIdIdx][tEnt->ownerEnt][tEnt->ownerInst];
5460 #else /* SS_MULTIPLE_PROCS */
5461    idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
5462 #endif /* SS_MULTIPLE_PROCS */
5463    if (idx == SS_TSKNC)
5464    {
5465 #ifndef TENB_RTLIN_CHANGES
5466       SS_RELEASE_SEMA(&osCp.tTskTblSem);
5467 #endif
5468       SPutMsg(mBuf);
5469       return;
5470    }
5471
5472
5473    /* ensure that the TAPA task is hale and hearty */
5474    tTsk = &osCp.tTskTbl[idx];
5475    if (!tTsk->used)
5476    {
5477 #ifndef TENB_RTLIN_CHANGES
5478       SS_RELEASE_SEMA(&osCp.tTskTblSem);
5479 #endif
5480       SPutMsg(mBuf);
5481       return;
5482    }
5483    /* Klock work fix ccpu00148484 */
5484    /* write the timer message to the queue of the destination task */
5485    /* mt008.301 : check sTsk before putting into it's DQ */
5486    if (tTsk->sTsk == NULLP)
5487    {
5488 #ifndef TENB_RTLIN_CHANGES
5489       SS_RELEASE_SEMA(&osCp.tTskTblSem);
5490 #endif
5491       SPutMsg(mBuf);
5492
5493 #if (ERRCLASS & ERRCLS_DEBUG)
5494       MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5495             "Could not write to demand queue");
5496 #endif
5497
5498       return;
5499    }
5500 #ifdef SS_LOCKLESS_MEMORY
5501    mInfo->pst.region = tTsk->sTsk->region;
5502    mInfo->region = tTsk->sTsk->region;
5503 #endif /* SS_LOCKLESS_MEMORY */
5504    if (ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
5505             (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK)
5506    {
5507 #ifndef TENB_RTLIN_CHANGES
5508       SS_RELEASE_SEMA(&osCp.tTskTblSem);
5509 #endif
5510       SPutMsg(mBuf);
5511
5512 #if (ERRCLASS & ERRCLS_DEBUG)
5513       MTLOGERROR(ERRCLS_DEBUG, EMT019, ERRZERO,
5514             "Could not write to demand queue");
5515 #endif
5516
5517       return;
5518    }
5519    /* Fix for ccpu00130657 */
5520 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5521    if (tTsk->sTsk->tskPrior == PRIOR0)
5522    {
5523 #ifdef INTEL_WLS
5524       WLS_WakeUp(mtGetWlsHdl());
5525 #else
5526       tlPost(NULLP);
5527 #endif
5528    }
5529 #endif
5530
5531    /* release the semaphore for the TAPA task table */
5532 #ifndef TENB_RTLIN_CHANGES
5533    SS_RELEASE_SEMA(&osCp.tTskTblSem);
5534 #endif
5535
5536
5537    /* restart the timer */
5538    arg.tq = osCp.dep.tmrTq;
5539    arg.tqCp = &osCp.dep.tmrTqCp;
5540    arg.timers = tEnt->dep.timers;
5541    arg.cb = (PTR) tEnt;
5542    arg.evnt = TMR_DEF;
5543    arg.wait = 0;
5544    arg.tNum = NOTUSED;
5545    arg.max = TMR_DEF_MAX;
5546    arg.wait = tEnt->interval;
5547    cmPlcCbTq(&arg);
5548 #ifdef RGL_SPECIFIC_CHANGES
5549 #ifdef MSPD_MLOG_NEW
5550    MLogTask(131313, RESOURCE_LARM, t, GetTIMETICK());
5551 #endif
5552 #endif
5553    return;
5554 }
5555
5556 \f
5557 #ifdef CONAVL
5558 /*
5559  *
5560  *       Fun:   mtConHdlr
5561  *
5562  *       Desc:  This thread reads the console and hands over any
5563  *              data read to a user function.
5564  *
5565  *       Ret:   (thread function)
5566  *
5567  *       Notes:
5568  *
5569  *       File:  mt_ss.c
5570  *
5571  */
5572    static Void *mtConHdlr
5573 (
5574  Ptr parm                        /* unused */
5575  )
5576 {
5577    int fd;
5578    Data data;
5579
5580
5581    /*mt013.301 : doesn't need TRC macro ,as this will never return*/
5582
5583
5584    UNUSED(parm);
5585
5586
5587    /* check if we have a console input file handle */
5588    if (osCp.dep.conInFp == NULLP)
5589    {
5590       /* die */
5591       return (NULLP);
5592    }
5593
5594    fd = fileno(osCp.dep.conInFp);
5595
5596    /* infinite loop */
5597    for (; ;)
5598    {
5599       if ((read(fd, &data, 1)) != 1)
5600       {
5601          continue;
5602       }
5603
5604
5605       /* call rdConQ, defined by the system service user */
5606       //rdConQ(data);
5607    }
5608
5609
5610    /* not reached */
5611 }
5612 #endif /* CONAVL */
5613
5614 #ifndef L2_L3_SPLIT
5615 #ifdef SS_DRVR_SUPPORT
5616 /*
5617  *
5618  *       Fun:   Interrupt service task handler
5619  *
5620  *       Desc:  This is the interrupt service task handler. It blocks
5621  *              on a pipe from which it reads an isFlag structure. The
5622  *              structure indicates which interrupt service task is to
5623  *              be executed. The thread identifies the task, calls the
5624  *              isTsk function and sends itself a message to repeat
5625  *              this operation until it receives a message to cease.
5626  *
5627  *       Ret:   ROK      - ok
5628  *
5629  *       Notes:
5630  *
5631  *       File:  mt_ss.c
5632  *
5633  */
5634 /* mt009.21: addition */
5635    static Void *mtIsTskHdlr
5636 (
5637  Ptr tskPtr                      /* pointer to task entry */
5638  )
5639 {
5640 #if (ERRCLASS & ERRCLS_DEBUG)
5641    int ret;
5642 #endif
5643    MtIsFlag isFlag;
5644
5645    for (; ;)
5646    {
5647       if (read(osCp.dep.isFildes[0], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
5648       {
5649          continue;
5650       }
5651
5652       switch (isFlag.action)
5653       {
5654          case MT_IS_SET:
5655             osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
5656
5657             /* call the interrupt service task activation function */
5658             osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5659
5660             /* send self a message to keep doing this */
5661             isFlag.action = MT_IS_RESET;
5662
5663 #if (ERRCLASS & ERRCLS_DEBUG)
5664             ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5665             if (ret != sizeof(isFlag))
5666             {
5667                MTLOGERROR(ERRCLS_DEBUG, EMT020, ERRZERO,
5668                      "write() to pipe failed");
5669             }
5670 #else
5671             write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5672 #endif
5673
5674             break;
5675
5676
5677          case MT_IS_UNSET:
5678             osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
5679             break;
5680
5681
5682          case MT_IS_RESET:
5683             if (osCp.drvrTskTbl[isFlag.id].dep.flag)
5684             {
5685                /* call the interrupt service task activation function */
5686                osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
5687
5688 #if (ERRCLASS & ERRCLS_DEBUG)
5689                /* send self a message to do this again */
5690                ret = write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5691
5692                if (ret != sizeof(isFlag))
5693                {
5694                   MTLOGERROR(ERRCLS_DEBUG, EMT021, ERRZERO,
5695                         "write() to pipe failed");
5696                }
5697 #else
5698                write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag));
5699 #endif
5700
5701             }
5702             break;
5703
5704
5705          default:
5706             /* where did THIS come from?? */
5707             break;
5708       }
5709    }
5710    /* mt009.21: addition */
5711    return ( (Void *) NULLP);
5712
5713    /* not reached */
5714 }
5715 #endif /* SS_DRVR_SUPPORT */
5716 #endif /* L2_L3_SPLIT */
5717
5718 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5719 \f
5720 /*
5721  *
5722  *       Fun:   mtIntSigHndlr
5723  *
5724  *       Desc:  Exit function, shuts down.
5725  *
5726  *       Ret:   Void
5727  *
5728  *       Notes:
5729  *
5730  *       File:  mt_ss.c
5731  *
5732  */
5733 Void mtIntSigHndlr(int arg)
5734 {
5735
5736    osCp.dep.sigEvnt=TRUE;
5737
5738 #ifdef MSPD
5739 #ifdef TENB_RTLIN_CHANGES
5740    mtStopHndlr();
5741 #endif
5742 #endif
5743
5744    return;
5745 }
5746
5747 /*mt010.301 Fix for core when run with -o option and when killed with SIGINT*/
5748 /*
5749  *
5750  *       Fun:   mtExitClnup
5751  *
5752  *       Desc:   function, shuts down.
5753  *
5754  *       Ret:   Void
5755  *
5756  *       Notes:
5757  *
5758  *       File:  mt_ss.c
5759  *
5760  */
5761 Void mtExitClnup(void)
5762 {
5763    Ticks ticks;
5764    S8 buf[128];
5765
5766
5767    SGetSysTime(&ticks);
5768 #ifdef ALIGN_64BIT
5769    sprintf(buf, "\n\nmtss(posix) ends\nticks: %u\n", ticks);
5770 #else
5771    sprintf(buf, "\n\nmtss(posix) ends\nticks: %lu\n", ticks);
5772 #endif
5773 #ifdef SS_HISTOGRAM_SUPPORT
5774    SDisplay(0, buf);
5775 #endif
5776
5777    osCp.dep.sigEvnt=FALSE;
5778 #ifndef NOFILESYS
5779    if (osCp.dep.fileOutFp)
5780    {
5781       fclose(osCp.dep.fileOutFp);
5782    }
5783 #endif
5784
5785    exit(0);
5786 }
5787
5788 Ticks TtiCount = 0;
5789 Void SIncrementTtiCount(Void)
5790 {
5791    TtiCount++;
5792 }
5793
5794 Ticks SGetTtiCount(Void)
5795 {
5796    return TtiCount;
5797 }
5798
5799 /*
5800  *
5801  *       Fun:   SDisplay
5802  *
5803  *       Desc:  This function displays a string to a given output
5804  *              channel.
5805  *
5806  *       Ret:   ROK      - ok
5807  *
5808  *       Notes: Buffer should be null terminated.
5809  *
5810  *              channel 0 is reserved for backwards compatibility
5811  *              with SPrint
5812  *
5813  *       File:  mt_ss.c
5814  *
5815  */
5816    S16 SDisplay
5817 (
5818  S16 chan,                   /* channel */
5819  Txt *buf                    /* buffer */
5820  )
5821 {
5822
5823    /* mt020.201 - Fixed typo */
5824 #if (ERRCLASS & ERRCLS_INT_PAR)
5825    if (buf == NULLP)
5826    {
5827       MTLOGERROR(ERRCLS_INT_PAR, EMT022, ERRZERO, "Null pointer");
5828       return RFAILED;
5829    }
5830 #endif
5831
5832 #ifndef XEON_SPECIFIC_CHANGES
5833 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
5834    ssMemlog(buf, strlen(buf));
5835    return ROK;
5836 #endif
5837 #endif
5838
5839    /* mt012.301 :FIX for LOG RELATED ISSUE  */
5840 #ifdef CONAVL
5841    if(chan==1)
5842    {
5843       printf("%s",buf);
5844    }
5845    else
5846    {
5847       if (osCp.dep.conOutFp) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
5848    }
5849 #endif
5850
5851
5852 #ifndef NOFILESYS
5853    if (osCp.dep.fileOutFp)
5854       fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
5855    /*mt031.201 added under compile time flag FLUSHBUFF a call to fflush() */
5856 #ifdef FLUSHBUFF
5857
5858    fflush(osCp.dep.fileOutFp);
5859
5860 #endif
5861 #endif
5862
5863    return ROK;
5864 }
5865
5866 /*mt010.301 */
5867 /*
5868  *
5869  *       Fun:   SFini
5870  *
5871  *       Desc:  function, shuts down.
5872  *
5873  *       Ret:   Void
5874  *
5875  *       Notes:
5876  *
5877  *       File:  mt_ss.c
5878  *
5879  */
5880 S16 SFini(void)
5881 {
5882
5883    /* mt030.201 added under compilet time flag SS_LINUX and SLES9_PLUS
5884       a loop to overcome the child processes being killed upon exiting the
5885       thread */
5886 #ifdef SS_LINUX  /* this should have already been defined */
5887    /* mt010.301 removed flag SLES9_PLUS */
5888    /* wait forever for children */
5889    for (;;)
5890    {
5891       pause();
5892       if(osCp.dep.sigEvnt==TRUE)
5893       {
5894          mtExitClnup();
5895       }
5896    }
5897
5898 #endif
5899    pthread_exit(NULLP);
5900    return (0);
5901 }
5902 \f
5903 /*
5904  *
5905  *       Fun:   Set date and time
5906  *
5907  *       Desc:  This function is used to set the calendar
5908  *              date and time.
5909  *
5910  *       Ret:   ROK      - ok
5911  *
5912  *       Notes: Unimplemented
5913  *
5914  *       File:  mt_ss.c
5915  *
5916  */
5917    S16 SSetDateTime
5918 (
5919  REG1 DateTime *dt           /* date and time */
5920  )
5921 {
5922
5923    UNUSED(dt);
5924
5925
5926    return ROK;
5927 }
5928
5929 \f
5930 /*
5931  *
5932  *       Fun:   Get date and time
5933  *
5934  *       Desc:  This function is used to determine the calendar
5935  *              date and time. This information may be used for
5936  *              some management functions.
5937  *
5938  *       Ret:   ROK      - ok
5939  *              RFAILED  - error
5940  *
5941  *       Notes:
5942  *
5943  *       File:  mt_ss.c
5944  *
5945  */
5946    S16 SGetDateTime
5947 (
5948  REG1 DateTime *dt           /* date and time */
5949  )
5950 {
5951    /*-- mt035.201 : SSI enhancements for micro second in datetime struct --*/
5952    /* time_t tt; --*/
5953 #ifndef SS_LINUX
5954    struct timespec ptime;
5955 #else
5956    struct timeval ptime;
5957 #endif
5958
5959    struct tm tme;
5960
5961
5962
5963 #if (ERRCLASS & ERRCLS_INT_PAR)
5964    if (dt == NULLP)
5965    {
5966       MTLOGERROR(ERRCLS_INT_PAR, EMT023, ERRZERO, "Null pointer");
5967       return RFAILED;
5968    }
5969 #endif
5970
5971
5972    /*-- mt035.201 --*/
5973    /*--
5974      time(&tt);
5975      localtime_r(&tt, &tme);
5976      --*/
5977 #ifndef SS_LINUX
5978    clock_gettime(CLOCK_REALTIME, &ptime);
5979 #else
5980    gettimeofday(&ptime, NULL);
5981 #endif
5982    localtime_r(&ptime.tv_sec, &tme);
5983
5984    dt->month = (uint8_t) tme.tm_mon + 1;
5985    dt->day = (uint8_t) tme.tm_mday;
5986    dt->year = (uint8_t) tme.tm_year;
5987    dt->hour = (uint8_t) tme.tm_hour;
5988    dt->min = (uint8_t) tme.tm_min;
5989    dt->sec = (uint8_t) tme.tm_sec;
5990    dt->tenths = 0;
5991
5992 #ifdef SS_DATETIME_USEC
5993 #ifndef SS_LINUX
5994    dt->usec = ptime.tv_nsec / 1000;
5995 #else
5996    dt->usec = ptime.tv_usec;
5997 #endif
5998 #endif /*-- SS_DATETIME_USEC --*/
5999
6000    return ROK;
6001 }
6002
6003 /*
6004  * Get time from epoch in milliseconds
6005  *
6006  *       Fun:   Get time from epoch in milliseconds
6007  *
6008  *       Desc:  This function is used to get the time from epoch in milli seconds.
6009  *              This information may be used for calculating a layer's activation function
6010  *              execution time used for thread profiling.
6011  *
6012  *       Ret:   ROK      - ok
6013  *              RFAILED  - error
6014  *
6015  *       Notes:
6016  *
6017  *       File:  mt_ss.c
6018  */
6019 /* mt003.301 Modifications */
6020    S16 SGetEpcTime
6021 (
6022  EpcTime *et           /* date and time */
6023  )
6024 {
6025    /* mt003.301 Modifications */
6026    static uint64_t now;
6027    uint64_t  to_sec  = 1000000;
6028    uint64_t  to_nsec = 1000;
6029 #ifndef SS_LINUX
6030    struct timespec ptime;
6031 #else
6032    struct timeval ptime;
6033 #endif
6034
6035
6036
6037 #if (ERRCLASS & ERRCLS_INT_PAR)
6038    if (et == NULLP)
6039    {
6040       return RFAILED;
6041    }
6042 #endif
6043
6044
6045 #ifndef SS_LINUX
6046    clock_gettime(CLOCK_REALTIME, &ptime);
6047 #else
6048    gettimeofday(&ptime, NULL);
6049 #endif /* SS_LINUX */
6050
6051    now = (ptime.tv_sec * to_sec);
6052
6053 #ifndef SS_LINUX
6054    now += (ptime.tv_nsec / to_nsec);
6055 #else /* SS_LINUX */
6056    now += (ptime.tv_usec);
6057
6058 #endif /* SS_LINUX */
6059    now = (now / to_nsec);
6060
6061    *et = now;
6062
6063    return ROK;
6064 }
6065
6066
6067 \f
6068 /*
6069  *
6070  *       Fun:   Get system time
6071  *
6072  *       Desc:  This function is used to determine the system time.
6073  *
6074  *       Ret:   ROK      - ok
6075  *
6076  *       Notes: osCp.dep.sysTicks is updated by the timer thread.
6077  *
6078  *       File:  mt_ss.c
6079  *
6080  */
6081    S16 SGetSysTime
6082 (
6083  Ticks *sysTime              /* system time */
6084  )
6085 {
6086
6087
6088 #if (ERRCLASS & ERRCLS_INT_PAR)
6089    if (sysTime == NULLP)
6090    {
6091       MTLOGERROR(ERRCLS_INT_PAR, EMT024, ERRZERO, "Null pointer");
6092       return RFAILED;
6093    }
6094 #endif
6095
6096
6097    *sysTime = osCp.dep.sysTicks;
6098
6099
6100    return ROK;
6101 }
6102
6103 /* mt021.201 - Addition of SGetRefTime function */
6104 /*
6105  *
6106  *       Fun:   Get referenced time
6107  *
6108  *       Desc:  This function is used to determine the time in seconds
6109  *              and microseconds from a reference time.  The reference
6110  *              time is expressed in seconds from UTC EPOC, January 1,
6111  *              1970.
6112  *
6113  *       Ret:   ROK      - ok
6114  *              RFAILED  - fail
6115  *
6116  *       Notes: Macros are defined for reference times:
6117  *                 SS_REFTIME_01_01_1970
6118  *                 SS_REFTIME_01_01_2002
6119  *
6120  *       File:  mt_ss.c
6121  *
6122  */
6123    S16 SGetRefTime
6124 (
6125  uint32_t refTime,             /* reference time */
6126  uint32_t *sec,
6127  uint32_t *usec
6128  )
6129 {
6130
6131 #ifndef SS_LINUX
6132    struct timespec ptime;
6133 #else
6134    struct timeval ptime;
6135 #endif
6136
6137
6138 #ifndef SS_LINUX
6139    clock_gettime(CLOCK_REALTIME, &ptime);
6140 #else
6141    gettimeofday(&ptime, NULL);
6142 #endif
6143
6144 #if (ERRCLASS & ERRCLS_INT_PAR)
6145    if (sec == NULLP || usec == NULLP)
6146    {
6147       MTLOGERROR(ERRCLS_INT_PAR, EMT025, ERRZERO, "Null pointer");
6148       return RFAILED;
6149    }
6150    /* mt022.201 - Modification to fix compile warning */
6151    if (refTime > (uint32_t)(ptime.tv_sec))
6152    {
6153       MTLOGERROR(ERRCLS_INT_PAR, EMT026, ERRZERO, "Reference time exceeds present time");
6154       return RFAILED;
6155    }
6156 #endif
6157
6158    *sec = ptime.tv_sec - refTime;
6159 #ifndef SS_LINUX
6160    *usec = ptime.tv_nsec / 1000;
6161 #else
6162    *usec = ptime.tv_usec;
6163 #endif
6164
6165    return ROK;
6166
6167 }
6168
6169 \f
6170 /*
6171  *
6172  *       Fun:   Get Random Number
6173  *
6174  *       Desc:  Invoked by layer when a pseudorandom number is required.
6175  *
6176  *       Ret:   ROK      - ok
6177  *
6178  *       Notes: Suggested approach uses shuffled Linear Congruential
6179  *              Operators as described in Byte magazine October
6180  *              1984; "Generating and Testing Pseudorandom Numbers"
6181  *
6182  *       File:  mt_ss.c
6183  *
6184  */
6185    S16 SRandom
6186 (
6187  Random *value               /* random number */
6188  )
6189 {
6190
6191
6192 #if (ERRCLASS & ERRCLS_INT_PAR)
6193    if (value == NULLP)
6194    {
6195       /* mt011.21: addition */
6196       MTLOGERROR(ERRCLS_INT_PAR, EMT028, (ErrVal)0 , "Null pointer");
6197       return RFAILED;
6198    }
6199 #endif
6200
6201
6202    *value = (Random) rand_r(&osCp.dep.randSeed);
6203
6204
6205    return ROK;
6206 }
6207
6208 \f
6209 /*
6210  *
6211  *       Fun:   Exit Task
6212  *
6213  *       Desc:  This function exits from a task.
6214  *
6215  *       Ret:   ROK      - ok
6216  *
6217  *       Notes: Currently does nothing.
6218  *
6219  *       File:  mt_ss.c
6220  *
6221  */
6222 S16 SExitTsk(void)
6223 {
6224
6225
6226    return ROK;
6227 }
6228
6229 \f
6230 /*
6231  *
6232  *       Fun:   Exit Interrupt
6233  *
6234  *       Desc:  This function exits from an interrupt.
6235  *
6236  *       Ret:   ROK      - ok
6237  *
6238  *       Notes: Currently does nothing.
6239  *
6240  *       File:  mt_ss.c
6241  *
6242  */
6243 S16 SExitInt(void)
6244 {
6245
6246
6247    return ROK;
6248 }
6249
6250 \f
6251 /*
6252  *
6253  *       Fun:   Hold Interrupt
6254  *
6255  *       Desc:  This function prohibits interrupts from being enabled until
6256  *              release interrupt. This function should be called when
6257  *              interrupts are disabled and prior to any call to system
6258  *              services either by entry to an interrupt service routine or
6259  *              by explicit call to disable interrupt.
6260  *
6261  *       Ret:   ROK      - ok
6262  *
6263  *       Notes: Currently does nothing
6264  *
6265  *       File:  mt_ss.c
6266  *
6267  */
6268 S16 SHoldInt(void)
6269 {
6270
6271
6272    return ROK;
6273 }
6274
6275 \f
6276 /*
6277  *
6278  *       Fun:   Release Interrupt
6279  *
6280  *       Desc:  This function allows interrupts to be enabled.
6281  *
6282  *       Ret:   ROK      - ok
6283  *
6284  *       Notes: Currently does nothing.
6285  *
6286  *       File:  mt_ss.c
6287  *
6288  */
6289 S16 SRelInt(void)
6290 {
6291
6292
6293    return ROK;
6294 }
6295
6296 \f
6297 /*
6298  *
6299  *       Fun:   SEnbInt
6300  *
6301  *       Desc:  Enable interrupts
6302  *
6303  *       Ret:   ROK on success
6304  *              RFAILED on error
6305  *
6306  *       Notes: Currently does nothing.
6307  *
6308  *       File:  mt_ss.c
6309  *
6310  */
6311 inline S16 SEnbInt(void)
6312 {
6313
6314
6315    return ROK;
6316 }
6317
6318 \f
6319 /*
6320  *
6321  *       Fun:   SDisInt
6322  *
6323  *       Desc:  Disable interrupts
6324  *
6325  *       Ret:   ROK on success
6326  *              RFAILED on error
6327  *
6328  *       Notes: Currently does nothing.
6329  *
6330  *       File:  mt_ss.c
6331  *
6332  */
6333 inline S16 SDisInt(void)
6334 {
6335
6336
6337    return ROK;
6338 }
6339
6340 \f
6341 /*
6342  *
6343  *       Fun:   Get Vector
6344  *
6345  *       Desc:  This function gets the function address stored at the
6346  *              specified interrupt vector.
6347  *
6348  *       Ret:   ROK      - ok
6349  *
6350  *       Notes: Currently does nothing.
6351  *
6352  *       File:  mt_ss.c
6353  *
6354  */
6355    S16 SGetVect
6356 (
6357  VectNmb vectNmb,                /* vector number */
6358  PIF *vectFnct                   /* vector function */
6359  )
6360 {
6361
6362
6363    UNUSED(vectNmb);
6364    UNUSED(vectFnct);
6365
6366
6367    return ROK;
6368 }
6369
6370 \f
6371 /*
6372  *
6373  *       Fun:   Put Vector
6374  *
6375  *       Desc:  This function installs the specified function at the
6376  *              specified interrupt vector.
6377  *
6378  *       Ret:   ROK      - ok
6379  *
6380  *       Notes: Currently does nothing.
6381  *
6382  *       File:  mt_ss.c
6383  *
6384  */
6385    S16 SPutVect
6386 (
6387  VectNmb vectNmb,                /* vector number */
6388  PIF vectFnct                    /* vector function */
6389  )
6390 {
6391
6392
6393    UNUSED(vectNmb);
6394    UNUSED(vectFnct);
6395
6396
6397    return ROK;
6398 }
6399
6400 /* mt028.201: modification: multiple procs support related changes */
6401 #ifndef SS_MULTIPLE_PROCS
6402 \f
6403 /*
6404  *
6405  *       Fun:   SGetEntInst
6406  *
6407  *       Desc:  This function gets the current entity and instance.
6408  *
6409  *       Ret:   ROK      - ok
6410  *              RFAILED  - failed, general (optional)
6411  *
6412  *       Notes: This function may be called by the OS or Layer 1
6413  *              hardware drivers.
6414  *
6415  *       File:  mt_ss.c
6416  *
6417  */
6418    S16 SGetEntInst
6419 (
6420  Ent *ent,                       /* entity */
6421  Inst *inst                      /* instance */
6422  )
6423 {
6424    S16 i;
6425    S16 ret;
6426    pthread_t tId;
6427    SsSTskEntry *sTsk;
6428
6429
6430
6431
6432 #if (ERRCLASS & ERRCLS_INT_PAR)
6433    /* check pointers */
6434    if (ent == NULLP  ||  inst == NULLP)
6435    {
6436       MTLOGERROR(ERRCLS_INT_PAR, EMT029, ERRZERO, "Null pointer");
6437       return RFAILED;
6438    }
6439 #endif
6440
6441
6442    /* get the thread id */
6443    tId = pthread_self();
6444
6445
6446    /* find the system task in whose context we're running */
6447    sTsk = NULLP;
6448    ret = SLock(&osCp.sTskTblLock);
6449    if (ret != ROK)
6450    {
6451       return RFAILED;
6452    }
6453    for (i = 0;  i < SS_MAX_STSKS;  i++)
6454    {
6455       if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6456       {
6457          sTsk = &osCp.sTskTbl[i];
6458          break;
6459       }
6460    }
6461    if (sTsk != NULLP)
6462    {
6463       *ent = sTsk->dep.ent;
6464       *inst = sTsk->dep.inst;
6465    }
6466    SUnlock(&osCp.sTskTblLock);
6467
6468
6469    return (ret == ROK ? ROK : RFAILED);
6470 }
6471
6472 \f
6473 /*
6474  *
6475  *       Fun:   SSetEntInst
6476  *
6477  *       Desc:  This function sets the current entity and instance.
6478  *
6479  *       Ret:   ROK      - ok
6480  *
6481  *       Notes:
6482  *
6483  *       File:  mt_ss.c
6484  *
6485  */
6486    S16 SSetEntInst
6487 (
6488  Ent ent,                    /* entity */
6489  Inst inst                   /* instance */
6490  )
6491 {
6492    S16 i;
6493    S16 ret;
6494    pthread_t tId;
6495    SsSTskEntry *sTsk;
6496
6497
6498
6499
6500 #if (ERRCLASS & ERRCLS_INT_PAR)
6501    /* check entity and instance IDs */
6502    if (ent >= ENTNC  ||  inst >= INSTNC)
6503    {
6504       MTLOGERROR(ERRCLS_INT_PAR, EMT030, ERRZERO, "Invalid entity/instance");
6505       return RFAILED;
6506    }
6507 #endif
6508
6509
6510    /* get the thread id */
6511    tId = pthread_self();
6512
6513
6514    /* find the system task in whose context we're running */
6515    sTsk = NULLP;
6516    ret = SLock(&osCp.sTskTblLock);
6517    if (ret != ROK)
6518    {
6519       return RFAILED;
6520    }
6521    for (i = 0;  i < SS_MAX_STSKS;  i++)
6522    {
6523       if (pthread_equal(osCp.sTskTbl[i].dep.tId, tId))
6524       {
6525          sTsk = &osCp.sTskTbl[i];
6526          break;
6527       }
6528    }
6529    if (sTsk != NULLP)
6530    {
6531       sTsk->dep.ent = ent;
6532       sTsk->dep.inst = inst;
6533    }
6534    SUnlock(&osCp.sTskTblLock);
6535
6536
6537    return (ret == ROK ? ROK : RFAILED);
6538 }
6539
6540 #endif /* SS_MULTIPLE_PROCS */
6541
6542 #ifdef SS_DRVR_SUPPORT
6543 \f
6544 /*
6545  *
6546  *       Fun:   SSetIntPend
6547  *
6548  *       Desc:  Set interrupt pending flag
6549  *
6550  *       Ret:   ROK on success
6551  *              RFAILED on error
6552  *
6553  *       Notes:
6554  *
6555  *       File:  mt_ss.c
6556  *
6557  */
6558    inline S16 SSetIntPend
6559 (
6560  uint16_t id,                         /* driver task identifier */
6561  Bool flag                       /* flag */
6562  )
6563 {
6564    MtIsFlag isFlag;
6565
6566
6567
6568
6569 #if (ERRCLASS & ERRCLS_INT_PAR)
6570    if (id >= SS_MAX_DRVRTSKS  ||  osCp.drvrTskTbl[id].used == FALSE)
6571    {
6572       MTLOGERROR(ERRCLS_INT_PAR, EMT031, id, "Invalid instance");
6573       return RFAILED;
6574    }
6575 #endif
6576
6577
6578    isFlag.id = id;
6579    isFlag.action = (flag ? MT_IS_SET : MT_IS_UNSET);
6580
6581    if (write(osCp.dep.isFildes[1], &isFlag, sizeof(isFlag)) != sizeof(isFlag))
6582    {
6583       return RFAILED;
6584    }
6585
6586
6587    return ROK;
6588 }
6589 #endif  /* SS_DRVR_SUPPORT */
6590
6591
6592 #ifdef SS_LOCKLESS_MEMORY
6593 /*
6594  *
6595  *       Fun:   SGlobMemInfoShow
6596  *
6597  *       Desc:  This function displays the memory usage information
6598  *              for the destined region. It will show the usage of
6599  *              each configured bucket and the heap for the specified region.
6600  *
6601  *       Ret:   ROK             OK
6602  *              RFAILED         Region not registered
6603  *
6604  *       File:  mt_ss.c
6605  *
6606  */
6607 S16 SGlobMemInfoShow(Void)
6608 {
6609    uint16_t   idx;
6610    Txt   prntBuf[100];
6611    CmMmGlobRegCb   *globReg;
6612
6613
6614    globReg = osCp.globRegCb;
6615
6616    sprintf(prntBuf, "--------------------------------------------------------------\n");
6617    SDisplay(0, prntBuf);
6618    sprintf(prntBuf, "Global Region Bucket Information\n");
6619    SDisplay(0, prntBuf);
6620    sprintf(prntBuf, "====================================================\n");
6621    SDisplay(0, prntBuf);
6622    sprintf(prntBuf, "Bucket Id  Set Size  Free Sets  Allocated\n");
6623    SDisplay(0, prntBuf);
6624    sprintf(prntBuf, "====================================================\n");
6625    SDisplay(0, prntBuf);
6626
6627
6628    for (idx = 0; idx < globReg->numBkts; idx++)
6629    {
6630 #ifdef XEON_SPECIFIC_CHANGES
6631       sprintf(prntBuf, "%2u  %12lu  %12lu  %8lu %9lu\n",
6632             idx, globReg->bktTbl[idx].size, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6633 #else      
6634 #ifndef ALIGN_64BIT
6635       sprintf(prntBuf, "%2u  %12lu  %8lu %9lu\n", 
6636             idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6637 #else
6638       sprintf(prntBuf, "%2u  %12u  %8u %9u\n", 
6639             idx, globReg->bktTbl[idx].bucketSetSize, globReg->bktTbl[idx].listValidBktSet.count, globReg->bktTbl[idx].listFreeBktSet.count);
6640 #endif
6641 #endif      
6642       SDisplay(0, prntBuf);
6643    }
6644    sprintf(prntBuf, "--------------------------------------------------------------\n");
6645    SDisplay(0, prntBuf);
6646
6647    return ROK;
6648 }   
6649
6650 #endif /* SS_LOCKLESS_MEMORY */
6651
6652 /*
6653    Bool IsMemoryThresholdHit(Region reg, Pool pool)
6654    {
6655    if((mtCMMRegCb[reg]->bktTbl[pool].numAlloc * 100 )/mtCMMRegCb[reg]->bktTbl[pool].numBlks > 70)
6656    {
6657    MSPD_DBG("Threshold reached reg(%d) pool(%d) numAllc(%d) numBlks(%d)\n",
6658    reg,
6659    pool,
6660    mtCMMRegCb[reg]->bktTbl[pool].numAlloc,
6661    mtCMMRegCb[reg]->bktTbl[pool].numBlks);
6662    return (TRUE);
6663    }
6664    return (FALSE);
6665    }
6666  */
6667
6668 /* mt022.201 - Addition of SRegInfoShow function */
6669 /*
6670  *
6671  *       Fun:   SRegInfoShow
6672  *
6673  *       Desc:  This function displays the memory usage information
6674  *              for the destined region. It will show the usage of
6675  *              each configured bucket and the heap for the specified region.
6676  *
6677  *       Ret:   ROK             OK
6678  *              RFAILED         Region not registered
6679  *
6680  *       Notes: A Sample Output from the function
6681  *       Bucket Memory: region 1
6682  *       ====================================================
6683  *       Bucket  Number of Blks configured  Size  Allocated
6684  *       ====================================================
6685  *       0                     1             16         1
6686  *       1                     1             32         0
6687  *       2                     1             80         0
6688  *       3                     1            256         0
6689  *       4                     1            320         0
6690  *
6691  *       ---------------
6692  *       Heap Memory: region 1
6693  *       Heap Size: 0
6694  *       Heap Allocated: 0
6695  *       Heap Segmented blocks: 0
6696  *
6697  *
6698  *       File:  mt_ss.c
6699  *
6700  */
6701    S16 SRegInfoShow
6702 (
6703  Region region,
6704  uint32_t *availmem
6705  )
6706 {
6707    uint16_t   idx;
6708    Txt   prntBuf[100];
6709
6710
6711 #if (ERRCLASS & ERRCLS_INT_PAR)
6712    if (region > (SS_MAX_REGS-1) )
6713    {
6714       MTLOGERROR(ERRCLS_INT_PAR, EMT032, ERRZERO, "Invalid Region");
6715       return RFAILED;
6716    }
6717 #endif
6718
6719    *availmem = 0;
6720
6721 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
6722    sprintf(prntBuf, "\n\nBucket Memory: region %d\n", region);
6723    SDisplay(0, prntBuf);
6724    sprintf(prntBuf, "====================================================\n");
6725    SDisplay(0, prntBuf);
6726    sprintf(prntBuf, "Bucket  Number of Blks configured  Size  Allocated\n");
6727    SDisplay(0, prntBuf);
6728    sprintf(prntBuf, "====================================================\n");
6729    SDisplay(0, prntBuf);
6730 #endif
6731
6732
6733    for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6734    {
6735 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
6736 #ifdef ALIGN_64BIT
6737       sprintf((char *)prntBuf, "%2u              %8u          %5u  %8u  %8u\n",
6738             idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6739             mtCMMRegCb[region]->bktTbl[idx].size,
6740             mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6741             mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6742 #else
6743       sprintf((char *)prntBuf, "%2u              %8lu          %5lu  %8lu  %8lu\n",
6744             idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6745             mtCMMRegCb[region]->bktTbl[idx].size,
6746             mtCMMRegCb[region]->bktTbl[idx].numAlloc,
6747             mtCMMRegCb[region]->bktTbl[idx].maxAlloc);
6748 #endif
6749 #else
6750       /*mt009.301 Fixed 64BIT compilation warnings*/
6751 #ifdef ALIGN_64BIT
6752       sprintf(prntBuf, "%2u              %8u          %5u  %8u\n",
6753             idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6754             mtCMMRegCb[region]->bktTbl[idx].size,
6755             mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6756 #else
6757       sprintf(prntBuf, "%2u              %8lu          %5lu  %8lu\n",
6758             idx, mtCMMRegCb[region]->bktTbl[idx].numBlks,
6759             mtCMMRegCb[region]->bktTbl[idx].size,
6760             mtCMMRegCb[region]->bktTbl[idx].numAlloc);
6761 #endif
6762 #endif /* not TENB_RTLIN_CHANGES */
6763       SDisplay(0, prntBuf);
6764       *availmem = *availmem + (mtCMMRegCb[region]->bktTbl[idx].size * \
6765             (mtCMMRegCb[region]->bktTbl[idx].numBlks -  \
6766              mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6767    }
6768    sprintf(prntBuf, "\n---------------\n");
6769    SDisplay(0, prntBuf);
6770    sprintf(prntBuf, "Heap Memory: region %d\n", region);
6771    SDisplay(0, prntBuf);
6772    /*mt009.301 Fixed 64BIT compilation warnings*/
6773 #ifdef ALIGN_64BIT
6774    sprintf(prntBuf, "Heap Size: %u\n", mtCMMRegCb[region]->heapSize);
6775 #else
6776    sprintf(prntBuf, "Heap Size: %lu\n", mtCMMRegCb[region]->heapSize);
6777 #endif
6778    SDisplay(0, prntBuf);
6779    /*mt009.301 Fixed 64BIT compilation warnings*/
6780 #ifdef ALIGN_64BIT
6781    sprintf(prntBuf, "Heap Allocated: %u\n",
6782          (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6783 #else
6784    sprintf(prntBuf, "Heap Allocated: %lu\n",
6785          (mtCMMRegCb[region]->heapSize - mtCMMRegCb[region]->heapCb.avlSize));
6786 #endif
6787    SDisplay(0, prntBuf);
6788    *availmem = *availmem + mtCMMRegCb[region]->heapCb.avlSize;
6789 #if (ERRCLASS & ERRCLS_DEBUG)
6790    sprintf(prntBuf, "Heap Segmented blocks: %d\n",
6791          mtCMMRegCb[region]->heapCb.numFragBlk);
6792    SDisplay(0, prntBuf);
6793 #endif
6794
6795    return ROK;
6796 }
6797 #ifdef XEON_SPECIFIC_CHANGES
6798 #define  SSI_MAX_BKT_THRESHOLD 6
6799 #define  SSI_MAX_REG_THRESHOLD 2
6800 uint32_t SMemMaxThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6801 uint32_t SMemMidThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6802 uint32_t SMemLowThreshold[SSI_MAX_REG_THRESHOLD][SSI_MAX_BKT_THRESHOLD] = {{0}};
6803
6804    static Void SInitMemThreshold
6805 (
6806  Region region,
6807  uint8_t     maxBkt
6808  )
6809 {
6810    uint8_t   idx = 0;
6811    for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6812    {
6813       SMemMaxThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*95)/100;
6814       SMemMidThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*85)/100;
6815       SMemLowThreshold[region][idx] = (mtCMMRegCb[region]->bktTbl[idx].numBlks*80)/100;
6816       printf("\nREGION:%d, BKT:%d max:%d mid:%d low:%d\n", region, idx, SMemMaxThreshold[region][idx], SMemMidThreshold[region][idx], SMemLowThreshold[region][idx]);
6817    }
6818 }
6819
6820    S16 SRegReachedMemThreshold
6821 (
6822  Region region,
6823  uint8_t     maxBkt
6824  )
6825 {
6826    uint8_t           idx       = 0;
6827    uint8_t           memStatus = 3;
6828    static uint8_t   initFlag  = 1;
6829    if(initFlag)
6830    {
6831       initFlag = 0;
6832       SInitMemThreshold(region, maxBkt);
6833    }
6834
6835    for (idx = 0; (idx < maxBkt && idx < mtCMMRegCb[region]->numBkts); idx++)
6836    {
6837       if(mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMaxThreshold[region][idx])
6838       {
6839          memStatus = 0;
6840          break;
6841       }
6842       else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemMidThreshold[region][idx]) && (memStatus >1))
6843       {
6844          memStatus = 1;
6845       }
6846       else if((mtCMMRegCb[region]->bktTbl[idx].numAlloc >= SMemLowThreshold[region][idx]) && (memStatus >2))
6847       {
6848          memStatus = 2;
6849       }
6850    }
6851    return (memStatus);
6852 }
6853 #endif
6854 /* mt033.201 - addition of API to return the memory statistical data */
6855 /*
6856  *
6857  *       Fun:   SGetRegInfo
6858  *
6859  *       Desc:  This function returns the memory usage information
6860  *              for the destined region. It will return the usage of
6861  *              each configured bucket and the heap for the specified region.
6862  *
6863  *       Ret:   ROK   OK
6864  *              RFAILED   Region not registered
6865  *
6866  *       Notes:
6867  *
6868  *       File:  mt_ss.c
6869  *
6870  */
6871    S16 SGetRegInfo
6872 (
6873  Region region,
6874  SsMemDbgInfo *dbgInfo
6875  )
6876 {
6877    uint32_t idx;
6878
6879
6880 #if (ERRCLASS & ERRCLS_INT_PAR)
6881    if (region >= mtMemoCfg.numRegions )
6882    {
6883       MTLOGERROR(ERRCLS_INT_PAR, EMT033, ERRZERO, "Invalid Region");
6884       return RFAILED;
6885    }
6886 #endif
6887
6888    dbgInfo->availmem = 0;
6889
6890    if (mtCMMRegCb[region]->numBkts > SS_MAX_BKT_PER_DBGTBL)
6891       dbgInfo->numBkts = SS_MAX_BKT_PER_DBGTBL;
6892    else
6893       dbgInfo->numBkts = mtCMMRegCb[region]->numBkts;
6894
6895    for (idx = 0; (idx < mtCMMRegCb[region]->numBkts) && (idx < SS_MAX_BKT_PER_DBGTBL); idx++)
6896    {
6897       dbgInfo->bktDbgTbl[idx].numBlks = mtCMMRegCb[region]->bktTbl[idx].numBlks;
6898       dbgInfo->bktDbgTbl[idx].size = mtCMMRegCb[region]->bktTbl[idx].size;
6899       dbgInfo->bktDbgTbl[idx].numAlloc = mtCMMRegCb[region]->bktTbl[idx].numAlloc;
6900
6901       dbgInfo->availmem += (mtCMMRegCb[region]->bktTbl[idx].size * \
6902             (mtCMMRegCb[region]->bktTbl[idx].numBlks -  \
6903              mtCMMRegCb[region]->bktTbl[idx].numAlloc));
6904    }
6905
6906    dbgInfo->region = region;
6907
6908    dbgInfo->heapSize = mtCMMRegCb[region]->heapSize;
6909
6910    dbgInfo->heapAlloc = (mtCMMRegCb[region]->heapSize - \
6911          mtCMMRegCb[region]->heapCb.avlSize);
6912
6913    dbgInfo->availmem += mtCMMRegCb[region]->heapCb.avlSize;
6914
6915 #if (ERRCLASS & ERRCLS_DEBUG)
6916    dbgInfo->numFragBlk = mtCMMRegCb[region]->heapCb.numFragBlk;
6917 #endif
6918
6919    return ROK;
6920 }
6921
6922    S16 SGetRegPoolInfo
6923 (
6924  uint8_t *numRegion,
6925  uint8_t *numPool
6926  )
6927 {
6928    /* Send number of Region available */
6929    *numRegion = mtMemoCfg.numRegions;
6930    /* Send number of Pools available */
6931    *numPool = cfgRegInfo[0].numPools;
6932
6933    return ROK;
6934 }
6935
6936 /* mt033.201 - addition of APIs to print the memory statistical data
6937  * as defined by SSI enhancements
6938  */
6939 #ifdef SSI_DEBUG_LEVEL1
6940 /*
6941  *
6942  *       Fun:   SPrintRegMemStatusInfo
6943  *
6944  *       Desc:  This function displays the memory usage information
6945  *              for the destined region. It will show the total memory
6946  *              used for static and dynamic memory if typeFlag is
6947  *              SS_MEM_BKT_ALLOC_PROFILE. It will show the number of
6948  *              memory block allocated for a particular size if typeFlag
6949  *              is SS_MEM_BLK_SIZE_PROFILE from the hash list by
6950  *              calling SRegPrintMemStats.
6951  *
6952  *       Ret:   ROK
6953  *
6954  *       Notes:
6955  *
6956  *       File:  mt_ss.c
6957  *
6958  */
6959    S16 SPrintRegMemStatusInfo
6960 (
6961  Region region,
6962  uint8_t typeFlag
6963  )
6964 {
6965    Txt prntBuf[150];
6966    uint32_t idx;
6967    uint32_t statMemSize;
6968    uint32_t dynMemSize;
6969
6970
6971 #if (ERRCLASS & ERRCLS_INT_PAR)
6972    if (region >= mtMemoCfg.numRegions )
6973    {
6974       MTLOGERROR(ERRCLS_INT_PAR, EMT034, ERRZERO, "Invalid Region");
6975       return RFAILED;
6976    }
6977 #endif
6978
6979    /* initialize the counters*/
6980    statMemSize = 0;
6981    dynMemSize = 0;
6982
6983    if (typeFlag == SS_MEM_BKT_ALLOC_PROFILE)
6984    {
6985       /* total static and dynamic memory allocated from all the buckets in region requested */
6986       sprintf(prntBuf, "\nAllocated Memory profile of Buckets from region: %d \n", region);
6987       SDisplay(0, prntBuf);
6988       sprintf(prntBuf, "===========================================\n");
6989       SDisplay(0, prntBuf);
6990       sprintf(prntBuf, "Bucket        Static Memory      Dynamic Memory\n");
6991       SDisplay(0, prntBuf);
6992       sprintf(prntBuf, "===========================================\n");
6993       SDisplay(0, prntBuf);
6994       for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
6995       {
6996          /*mt009.301 Fixed 64BIT compilation warnings*/
6997 #ifdef ALIGN_64BIT
6998          sprintf(prntBuf, "%2u           %8u           %8u\n", idx,
6999                mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7000                mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7001 #else
7002          sprintf(prntBuf, "%2lu           %8lu           %8lu\n", idx,
7003                mtCMMRegCb[region]->bktTbl[idx].staticMemUsed,
7004                mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed);
7005 #endif
7006          SDisplay(0, prntBuf);
7007          /* update the total count */
7008          statMemSize += mtCMMRegCb[region]->bktTbl[idx].staticMemUsed;
7009          dynMemSize += mtCMMRegCb[region]->bktTbl[idx].dynamicMemUsed;
7010       }
7011       /* from buckets */
7012       /*mt009.301 Fixed 64BIT compilation warnings*/
7013 #ifdef ALIGN_64BIT
7014       sprintf(prntBuf, "Total Static Memory allocated from buckets: %u\n", statMemSize);
7015       SDisplay(0, prntBuf);
7016       sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %u\n", dynMemSize);
7017 #else
7018       sprintf(prntBuf, "Total Static Memory allocated from buckets: %lu\n", statMemSize);
7019       SDisplay(0, prntBuf);
7020       /*mt010.301 fix for compilation error*/
7021       sprintf(prntBuf, "Total Dynamic Memory allocated from buckets: %lu\n", dynMemSize);
7022 #endif
7023       SDisplay(0, prntBuf);
7024       /* from heap */
7025       sprintf(prntBuf, "\n\nAllocated Memory profile from Heap of region: %d \n", region);
7026       SDisplay(0, prntBuf);
7027       /*mt009.301 Fixed 64BIT compilation warnings*/
7028 #ifdef ALIGN_64BIT
7029       sprintf(prntBuf, "STATIC MEMORY: %u       DYNAMIC MEMORY:%u \n",
7030             mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7031 #else
7032       sprintf(prntBuf, "STATIC MEMORY: %lu      DYNAMIC MEMORY:%lu \n",
7033             mtCMMRegCb[region]->heapCb.staticHeapMemUsed, mtCMMRegCb[region]->heapCb.dynamicHeapMemUsed);
7034 #endif
7035       SDisplay(0, prntBuf);
7036    }
7037    else if (typeFlag == SS_MEM_BLK_SIZE_PROFILE)
7038    {
7039       /* Bucket Memory allocation Statistics */
7040       return (SPrintRegMemStats(region));
7041    }
7042    else
7043    {
7044       /* error case */
7045       sprintf(prntBuf, "\n Invalid choice \n");
7046       SDisplay(0, prntBuf);
7047    }
7048
7049    return ROK;
7050 }
7051
7052 /*
7053  *
7054  *       Fun:   SPrintRegMemStats
7055  *
7056  *       Desc:  This function displays the memory usage information for
7057  *              the destined region. It will show the number of memory
7058  *              block allocated for a particular size from the hash list.
7059  *
7060  *       Ret:   ROK
7061  *
7062  *       Notes:
7063  *
7064  *       File:  mt_ss.c
7065  *
7066  */
7067 static S16 SPrintRegMemStats(Region region)
7068 {
7069    CmMmHashListCp *hashListCp;
7070    Txt prntBuf[150];
7071    uint32_t idx;
7072    uint32_t cntEnt;
7073
7074
7075    hashListCp = &mtCMMRegCb[region]->hashListCp;
7076
7077    sprintf(prntBuf, "\n\nSize Vs. NumAttempts and Alloc/Dealloc profile of region %d\n", region);
7078    SDisplay(0, prntBuf);
7079    sprintf(prntBuf, "Maximum Entries: %u    Current Entries: %u\n",
7080          hashListCp->numOfbins, hashListCp->numOfEntries);
7081    SDisplay(0, prntBuf);
7082    sprintf(prntBuf, "===================================\n");
7083    SDisplay(0, prntBuf);
7084    sprintf(prntBuf, "Block Size      Total number of requests\n");
7085    SDisplay(0, prntBuf);
7086    sprintf(prntBuf, "===================================\n");
7087    SDisplay(0, prntBuf);
7088
7089    for (idx = 0, cntEnt=0; (cntEnt < hashListCp->numOfEntries) &&
7090          (idx < CMM_STAT_HASH_TBL_LEN); idx++)
7091    {
7092       if (hashListCp->hashList[idx].numAttempts)
7093       {
7094          cntEnt++;
7095          /*mt009.301 Fixed 64BIT compilation warnings*/
7096 #ifdef ALIGN_64BIT
7097          sprintf(prntBuf, "%8u           %8u\n", hashListCp->hashList[idx].size,
7098                hashListCp->hashList[idx].numAttempts);
7099 #else
7100          sprintf(prntBuf, "%8lu           %8lu\n", hashListCp->hashList[idx].size,
7101                hashListCp->hashList[idx].numAttempts);
7102 #endif
7103          SDisplay(0, prntBuf);
7104       }
7105    }
7106
7107    sprintf(prntBuf, "\nAllocation/De-allocation profile in Buckets\n");
7108    SDisplay(0, prntBuf);
7109    sprintf(prntBuf, "=================================================\n");
7110    SDisplay(0, prntBuf);
7111    sprintf(prntBuf, "Bucket    Num of Alloc Attempts    Num of De-alloc Attempts\n");
7112    SDisplay(0, prntBuf);
7113    sprintf(prntBuf, "=================================================\n");
7114    SDisplay(0, prntBuf);
7115
7116    /* Print the statistics of total number of alloc/de-alloc attempts in each bucket of this region */
7117    for (idx = 0; idx < mtCMMRegCb[region]->numBkts; idx++)
7118    {
7119       /*mt009.301 Fixed 64BIT compilation warnings*/
7120 #ifdef ALIGN_64BIT
7121       sprintf(prntBuf, "%4u        %8u             %8u\n", idx,
7122             mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7123             mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7124 #else
7125       sprintf(prntBuf, "%4lu        %8lu             %8lu\n", idx,
7126             mtCMMRegCb[region]->bktTbl[idx].numAllocAttempts,
7127             mtCMMRegCb[region]->bktTbl[idx].numDeallocAttempts);
7128 #endif
7129       SDisplay(0, prntBuf);
7130    }
7131    sprintf(prntBuf, "\nAllocation/De-allocation profile in Heap\n");
7132    SDisplay(0, prntBuf);
7133    /*mt009.301 Fixed 64BIT compilation warnings*/
7134 #ifdef ALIGN_64BIT
7135    sprintf(prntBuf, "Num of Alloc Attempts: %u      Num of De-alloc Attempts: %u\n",
7136          mtCMMRegCb[region]->heapCb.numAllocAttempts,
7137          mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7138 #else
7139    sprintf(prntBuf, "Num of Alloc Attempts: %lu      Num of De-alloc Attempts: %lu\n",
7140          mtCMMRegCb[region]->heapCb.numAllocAttempts,
7141          mtCMMRegCb[region]->heapCb.numDeallocAttempts);
7142 #endif
7143    SDisplay(0, prntBuf);
7144    sprintf(prntBuf, "\n");
7145    SDisplay(0, prntBuf);
7146
7147    return ROK;
7148 }
7149
7150 /*
7151  *
7152  *       Fun:   SRegMemErrHdlr
7153  *
7154  *       Desc:  This function handles the errors returned from the memory
7155  *              related functions. Customers are suggested to modify this
7156  *              API according to their specific requirement.
7157  *
7158  *       Ret:   ROK   OK
7159  *
7160  *       Notes:
7161  *
7162  *       File:  mt_ss.c
7163  *
7164  */
7165    Void SRegMemErrHdlr
7166 (
7167  Region region,
7168  Data *ptr,
7169  S16 errCode
7170  )
7171 {
7172    Txt prntBuf[150];
7173
7174
7175    if (errCode == RDBLFREE)
7176    {
7177       sprintf(prntBuf, "\nDouble free attempted at location:%8p  in region:%d\n", ptr, region);
7178       SDisplay(0, prntBuf);
7179    }
7180    else if (errCode == RTRAMPLINGNOK)
7181    {
7182       sprintf(prntBuf, "\nMemory Trampling crossed Threshold in region:%d\n", region);
7183       SDisplay(0, prntBuf);
7184    }
7185
7186    return;
7187 }
7188
7189 /*
7190  *
7191  *       Fun:   SPrintRegMemProfile
7192  *
7193  *       Desc:  This function displays the memory profile information
7194  *              for the destined region. This function prints for:
7195  *              1) each memory bucket-Block address, size, size for which it is allocated, free/allocated, static/dynamic
7196  *              2) heap - memory block address, size, requested size, free/allocated, static/dynamic
7197  *
7198  *       Ret:   ROK   OK
7199  *
7200  *       Notes:
7201  *
7202  *       File:  mt_ss.c
7203  *
7204  */
7205    S16 SPrintRegMemProfile
7206 (
7207  Region region
7208  )
7209 {
7210    CmMmHeapCb *heapCb;
7211    CmMmRegCb *regCb;
7212    CmMmBlkHdr *curBktBlk;
7213    CmHEntry *curHBlk;
7214    Size offsetToNxtBlk;
7215    Size hdrSize;
7216    Txt prntBuf[250];
7217    uint32_t idx;
7218    uint32_t blkCnt;
7219
7220
7221
7222 #if (ERRCLASS & ERRCLS_INT_PAR)
7223    if (region >= mtMemoCfg.numRegions )
7224    {
7225       MTLOGERROR(ERRCLS_INT_PAR, EMT035, ERRZERO, "Invalid Region");
7226       return RFAILED;
7227    }
7228 #endif
7229
7230    regCb = mtCMMRegCb[region];
7231
7232    /* memory profile */
7233    sprintf(prntBuf, "\n\nFull Memory Profile of region %d\n", region);
7234    SDisplay(0, prntBuf);
7235
7236    /* bucket profile */
7237    sprintf(prntBuf, "\nBucket Profile\n");
7238    SDisplay(0, prntBuf);
7239
7240    for (idx = 0; idx < regCb->numBkts; idx++)
7241    {
7242
7243       /*mt009.301 Fixed 64BIT compilation warnings*/
7244 #ifdef ALIGN_64BIT
7245       sprintf(prntBuf, "\nBucket number:%4u  of Size:%u  Num of Blocks: %u\n",
7246             idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7247 #else
7248       sprintf(prntBuf, "\nBucket number:%4lu  of Size:%lu  Num of Blocks: %lu\n",
7249             idx, regCb->bktTbl[idx].size, regCb->bktTbl[idx].numBlks);
7250 #endif
7251       SDisplay(0, prntBuf);
7252
7253       sprintf(prntBuf, "==========================================================================\n");
7254       SDisplay(0, prntBuf);
7255       sprintf(prntBuf, " Block    Location    Free/Allocated  Static/dynamic  Size requested\n");
7256       SDisplay(0, prntBuf);
7257       sprintf(prntBuf, "==========================================================================\n");
7258       SDisplay(0, prntBuf);
7259
7260       offsetToNxtBlk = regCb->bktTbl[idx].size + sizeof(CmMmBlkHdr);
7261
7262       for (blkCnt=0, curBktBlk = (CmMmBlkHdr *)(regCb->bktTbl[idx].bktStartPtr);
7263             ((curBktBlk) && (blkCnt < regCb->bktTbl[idx].numBlks));
7264             curBktBlk = (CmMmBlkHdr *)((Data *)curBktBlk + offsetToNxtBlk), blkCnt++)
7265       {
7266          /*mt009.301 Fixed 64BIT compilation warnings*/
7267 #ifdef ALIGN_64BIT
7268          sprintf(prntBuf, "%6u   %8p", blkCnt, (void *)curBktBlk);
7269 #else
7270          sprintf(prntBuf, "%6lu   %8p", blkCnt, (void *)curBktBlk);
7271 #endif
7272          SDisplay(0, prntBuf);
7273          /* check if it is a sane block, elxe jump to next block */
7274          if (cmMmRegIsBlkSane(curBktBlk) != ROK)
7275          {
7276             sprintf(prntBuf, "     Trampled                         \n");
7277             SDisplay(0, prntBuf);
7278
7279             continue;
7280          }
7281
7282          if (CMM_IS_STATIC(curBktBlk->memFlags))
7283          {
7284             /*mt009.301 Fixed 64BIT compilation warnings*/
7285 #ifdef ALIGN_64BIT
7286             sprintf(prntBuf, "     Allocated     Static      %8u\n", curBktBlk->requestedSize);
7287 #else
7288             sprintf(prntBuf, "     Allocated     Static      %8lu\n", curBktBlk->requestedSize);
7289 #endif
7290             SDisplay(0, prntBuf);
7291          }
7292          else if (CMM_IS_DYNAMIC(curBktBlk->memFlags))
7293          {
7294             /*mt009.301 Fixed 64BIT compilation warnings*/
7295 #ifdef ALIGN_64BIT
7296             sprintf(prntBuf, "     Allocated       Dynamic      %8u\n", curBktBlk->requestedSize);
7297 #else
7298             sprintf(prntBuf, "     Allocated       Dynamic      %8lu\n", curBktBlk->requestedSize);
7299 #endif
7300             SDisplay(0, prntBuf);
7301          }
7302          else if (CMM_IS_FREE(curBktBlk->memFlags))
7303          {
7304             /*mt009.301 Fixed 64BIT compilation warnings*/
7305 #ifdef ALIGN_64BIT
7306             sprintf(prntBuf, "     Free                        %8u\n", curBktBlk->requestedSize);
7307 #else
7308             sprintf(prntBuf, "     Free                        %8lu\n", curBktBlk->requestedSize);
7309 #endif
7310             SDisplay(0, prntBuf);
7311          }
7312          else
7313          {
7314             sprintf(prntBuf, "     Trampled                         \n");
7315             SDisplay(0, prntBuf);
7316          }
7317       }
7318    }
7319
7320    /* heap profile */
7321    sprintf(prntBuf, "\nHeap Profile\n");
7322    SDisplay(0, prntBuf);
7323
7324    /* point to heapCb */
7325    heapCb = &(regCb->heapCb);
7326
7327    sprintf(prntBuf, "\nHeap Start: %8p          Heap End: %8p\n", heapCb->vStart, heapCb->vEnd);
7328    SDisplay(0, prntBuf);
7329    sprintf(prntBuf, "==========================================================================\n");
7330    SDisplay(0, prntBuf);
7331    sprintf(prntBuf, " Block     Location      Size    Free/Allocated   Static/dynamic  Size requested\n");
7332    SDisplay(0, prntBuf);
7333    sprintf(prntBuf, "==========================================================================\n");
7334    SDisplay(0, prntBuf);
7335
7336    /* traverse the entire heap to output the heap profile */
7337    hdrSize = sizeof(CmHEntry);
7338    for (blkCnt=0, curHBlk = (CmHEntry *)heapCb->vStart;
7339          ((curHBlk) && (curHBlk < (CmHEntry *)heapCb->vEnd)); blkCnt++)
7340    {
7341       /*mt009.301 Fixed 64BIT compilation warnings*/
7342 #ifdef ALIGN_64BIT
7343       sprintf(prntBuf, "%6u   %8p", blkCnt, (void *)curHBlk);
7344 #else
7345       sprintf(prntBuf, "%6lu   %8p", blkCnt, (void *)curHBlk);
7346 #endif
7347       SDisplay(0, prntBuf);
7348
7349       /* check if it is a sane block, elxe jump to next block */
7350       if (cmMmRegIsBlkSane((CmMmBlkHdr *)curHBlk) != ROK)
7351       {
7352          sprintf(prntBuf, "                Trampled                         \n");
7353          SDisplay(0, prntBuf);
7354
7355          sprintf(prntBuf, "Trampled block encountered: Stopping heap profile\n");
7356          SDisplay(0, prntBuf);
7357
7358          /*
7359           * To go to next block in the heap we do not have any offset value
7360           * other than curHBlk->size. As the block is already trampled
7361           * we cannot rely on this size. So it is better to stop here unless there
7362           * exists any other mechanism(?) to know the offset to next block.
7363           */
7364          return ROK;
7365       }
7366
7367       /*mt009.301 Fixed 64BIT compilation warnings*/
7368 #ifdef ALIGN_64BIT
7369       sprintf(prntBuf, "   %8u", curHBlk->size);
7370 #else
7371       sprintf(prntBuf, "   %8lu", curHBlk->size);
7372 #endif
7373       SDisplay(0, prntBuf);
7374
7375       if (CMM_IS_STATIC(curHBlk->memFlags))
7376       {
7377          /*mt009.301 Fixed 64BIT compilation warnings*/
7378 #ifdef ALIGN_64BIT
7379          sprintf(prntBuf, "     Allocated       Static       %8u\n", curHBlk->requestedSize);
7380 #else
7381          sprintf(prntBuf, "     Allocated       Static       %8lu\n", curHBlk->requestedSize);
7382 #endif
7383          SDisplay(0, prntBuf);
7384       }
7385       else if (CMM_IS_DYNAMIC(curHBlk->memFlags))
7386       {
7387          /*mt009.301 Fixed 64BIT compilation warnings*/
7388 #ifdef ALIGN_64BIT
7389          sprintf(prntBuf, "     Allocated       Dynamic      %8u\n", curHBlk->requestedSize);
7390 #else
7391          sprintf(prntBuf, "     Allocated       Dynamic      %8lu\n", curHBlk->requestedSize);
7392 #endif
7393          SDisplay(0, prntBuf);
7394       }
7395       else if (CMM_IS_FREE(curHBlk->memFlags))
7396       {
7397          /*mt009.301 Fixed 64BIT compilation warnings*/
7398 #ifdef ALIGN_64BIT
7399          sprintf(prntBuf, "     Free                      %8u\n", curHBlk->requestedSize);
7400 #else
7401          sprintf(prntBuf, "     Free                      %8lu\n", curHBlk->requestedSize);
7402 #endif
7403          SDisplay(0, prntBuf);
7404       }
7405       else
7406       {
7407          sprintf(prntBuf, "     Trampled                         \n");
7408          SDisplay(0, prntBuf);
7409       }
7410       /* goto next block in the heap */
7411       curHBlk = (CmHEntry *)((Data *)curHBlk + hdrSize + curHBlk->size);
7412
7413    }
7414
7415    return ROK;
7416 }
7417 #endif /* SSI_DEBUG_LEVEL1 */
7418
7419 /*-- mt035.201 : Added new API for timestamp --*/
7420 /*--
7421  *
7422  *       Fun:   Get TimeStamp
7423  *
7424  *       Desc:  This function is used to Get TimeStamp in micro seconds
7425  *
7426  *       Ret:   ROK      - ok
7427  *              RFAILED  - error
7428  *
7429  *       Notes:
7430  *
7431  *       File:  mt_ss.c
7432  *
7433  --*/
7434    S16 SGetTimeStamp
7435 (
7436  S8    *ts
7437  )
7438 {
7439
7440 #ifndef SS_LINUX
7441    struct timespec ptime;
7442 #else
7443    struct timeval ptime;
7444 #endif
7445
7446    struct tm* ptm;
7447    S8 time_string[40];
7448    S32 microseconds;
7449
7450
7451 #ifndef SS_LINUX
7452    clock_gettime(CLOCK_REALTIME, &ptime);
7453 #else
7454    gettimeofday(&ptime, NULL);
7455 #endif
7456
7457    /* Obtain the time of day, and convert it to a tm struct. --*/
7458    ptm = localtime (&ptime.tv_sec);
7459    /* Klock work fix ccpu00148484 */
7460    if(ptm != NULLP)
7461    {
7462       /* Format the date and time, down to a single second. --*/
7463       strftime (time_string, sizeof (time_string), "%a %b %d %Y %H:%M:%S", ptm);
7464    }
7465
7466    /* Compute microseconds. --*/
7467 #ifndef SS_LINUX
7468    microseconds = ptime.tv_nsec / 1000;
7469 #else
7470    microseconds = ptime.tv_usec;
7471 #endif
7472
7473    /* Print the formatted time, in seconds, followed by a decimal point
7474       and the microseconds. --*/
7475    /*mt009.301 Fixed 64BIT compilation warnings*/
7476 #ifdef ALIGN_64BIT
7477    sprintf(ts, "%s.%03d", time_string, microseconds);
7478 #else
7479    sprintf(ts, "%s.%03ld", time_string, microseconds);
7480 #endif
7481
7482    return ROK;
7483
7484 }
7485 /*-- mt037.201 : Added new API for SGetSystemTsk --*/
7486 /*
7487  *
7488  *       Fun:   Get SGetSystemTsk
7489  *
7490  *       Desc:  This function is used to Get sytem task id
7491  *
7492  *       Ret:   task id
7493  *
7494  *       Notes:
7495  *
7496  *       File:  mt_ss.c
7497  *
7498  --*/
7499 uint32_t SGetSystemTsk(Void)
7500 {
7501
7502    return (pthread_self());
7503
7504 } /* end of SGetSystemTsk */
7505
7506 #ifdef SS_MULTICORE_SUPPORT
7507 /*
7508  *
7509  *       Fun:   Add Timer thread into system task table
7510  *
7511  *       Desc:  This function is used to add the system task
7512  *              associated with Timer thread.
7513  *
7514  *       Ret:   None
7515  *
7516  *       Notes:
7517  *
7518  *       File:  mt_ss.c
7519  *
7520  --*/
7521 static SsSTskEntry* ssdAddTmrSTsk(Void)
7522 {
7523    SsSTskEntry *sTsk;
7524    S16 ret;
7525
7526    sTsk = NULLP;
7527    /* lock the system task table */
7528    ret = SLock(&osCp.sTskTblLock);
7529    if (ret != ROK)
7530    {
7531
7532 #if (ERRCLASS & ERRCLS_DEBUG)
7533       MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
7534             "Could not lock system task table");
7535 #endif
7536
7537       return (sTsk);
7538    }
7539
7540    /* check count of system tasks */
7541    if (osCp.numSTsks == SS_MAX_STSKS)
7542    {
7543
7544       if ( SUnlock(&osCp.sTskTblLock) != ROK)
7545       {
7546 #if (ERRCLASS & ERRCLS_DEBUG)
7547          MTLOGERROR(ERRCLS_DEBUG, EMT040, ERRZERO,
7548                "Could not give the Semaphore");
7549          return (sTsk);
7550 #endif
7551       }
7552
7553 #if (ERRCLASS & ERRCLS_ADD_RES)
7554       MTLOGERROR(ERRCLS_ADD_RES, EMT041, ERRZERO, "Too many system tasks");
7555 #endif
7556
7557       return (sTsk);
7558    }
7559
7560
7561    /* initialize the system task entry with the information we have */
7562    sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];
7563
7564    /* store the system task priority */
7565    sTsk->tskPrior = SS_NORM_TSK_PRI;
7566
7567    /* initialize the demand queue */
7568    if (ssInitDmndQ(&sTsk->dQ) != ROK)
7569    {
7570
7571       if ( SUnlock(&osCp.sTskTblLock) != ROK)
7572       {
7573 #if (ERRCLASS & ERRCLS_DEBUG)
7574          MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
7575                "Could not give the Semaphore");
7576          return (NULLP);
7577 #endif
7578       }
7579
7580 #if (ERRCLASS & ERRCLS_DEBUG)
7581       MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
7582             "Could not initialize demand queue");
7583 #endif
7584
7585       return (NULLP);
7586    }
7587
7588    /* initialize the system task entry lock */
7589    if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
7590    {
7591       ssDestroyDmndQ(&sTsk->dQ);
7592
7593       if ( SUnlock(&osCp.sTskTblLock) != ROK)
7594       {
7595 #if (ERRCLASS & ERRCLS_DEBUG)
7596          MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
7597                "Could not give the Semaphore");
7598          return (NULLP);
7599 #endif
7600       }
7601
7602 #if (ERRCLASS & ERRCLS_DEBUG)
7603       MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
7604             "Could not initialize system task entry lock");
7605 #endif
7606
7607       return (NULLP);
7608    }
7609
7610
7611    /* success, update the table */
7612    sTsk->tskId       = osCp.nxtSTskEntry;
7613    sTsk->used        = TRUE;
7614    sTsk->termPend    = FALSE;
7615    osCp.nxtSTskEntry = sTsk->nxt;
7616    osCp.numSTsks++;
7617
7618    /* unlock the system task table */
7619
7620    if ( SUnlock(&osCp.sTskTblLock) != ROK)
7621    {
7622 #if (ERRCLASS & ERRCLS_DEBUG)
7623       MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
7624             "Could not give the Semaphore");
7625       return (NULLP);
7626 #endif
7627    }
7628
7629    return (sTsk);
7630 }
7631 #endif /* SS_MULTICORE_SUPPORT */
7632 /* mt003.301 Readwrite lock and recursive mutex additions */
7633 #ifdef SS_LOCK_SUPPORT
7634 /*
7635  *
7636  *       Fun:   ssdInitLockNew
7637  *
7638  *       Desc:  This function is used to initialise lock/mutex
7639  *
7640  *       Ret:   ROK   OK
7641  *
7642  *       Notes:
7643  *
7644  *       File:  mt_ss.c
7645  *
7646  */
7647 S16 ssdInitLockNew(SLockInfo *lockId,uint8_t lockType)
7648 {
7649
7650 #ifdef SS_REC_LOCK_SUPPORT
7651    pthread_mutexattr_t attr;
7652 #endif /* SS_REC_LOCK_SUPPORT */
7653    Txt prntBuf[PRNTSZE];
7654    S16    retVal = ROK;
7655
7656
7657    switch(lockType)
7658    {
7659 #ifdef SS_RDWR_LOCK_SUPPORT
7660       case SRDWRLOCK :
7661          {
7662             if((retVal = pthread_rwlock_init((&(lockId->l.rdWrLockId)), NULLP)) != ROK)
7663             {
7664                sprintf(prntBuf, "\n\n ssdInitLockNew(): Initialization of read write lock failed,Error# retVal %d\n", retVal);
7665                SDisplay(0, prntBuf);
7666                return RFAILED;
7667             }
7668             break;
7669          }
7670 #endif /* SS_RDWR_LOCK_SUPPORT */
7671 #ifdef SS_REC_LOCK_SUPPORT
7672       case SMUTEXRECUR:
7673          {
7674             retVal = pthread_mutexattr_init(&attr);
7675
7676             if(retVal != 0)
7677             {
7678                sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr init failed,Error# %d \n",retVal);
7679                SPrint(prntBuf);
7680                return RFAILED;
7681             }
7682 #ifdef SS_LINUX
7683             retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
7684 #else
7685             retVal = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
7686 #endif
7687             if(retVal != 0)
7688             {
7689                sprintf(prntBuf,"\n ssdInitLockNew(): mutexattr settype failed,Error# %d \n",retVal);
7690                pthread_mutexattr_destroy(&attr);
7691                SPrint(prntBuf);
7692                return RFAILED;
7693             }
7694             retVal = pthread_mutex_init((pthread_mutex_t *)&(lockId->l.recurLock), &attr);
7695             if(retVal != 0)
7696             {
7697                sprintf(prntBuf,"\n ssdInitLockNew(): mutex init failed,Error# %d \n",retVal);
7698                pthread_mutexattr_destroy(&attr);
7699                SPrint(prntBuf);
7700                return RFAILED;
7701             }
7702             break;
7703          }
7704 #endif /* SS_REC_LOCK_SUPPORT */
7705       default :
7706          {
7707             sprintf(prntBuf, "\n\n ssdInitLockNew(): Invalid lock type %d\n", lockType);
7708             SDisplay(0, prntBuf);
7709             return RFAILED;
7710          }
7711    }
7712    return ROK;
7713 }
7714 /*
7715  *
7716  *       Fun:   ssdLockNew
7717  *
7718  *       Desc:  This function is used to aquire the read write lock
7719  *
7720  *       Ret:   ROK   OK
7721  *
7722  *       Notes:
7723  *
7724  *       File:  mt_ss.c
7725  *
7726  */
7727 S16 ssdLockNew(SLockInfo *lockId,uint8_t lockType)
7728 {
7729
7730    Txt prntBuf[PRNTSZE];
7731    S16    retVal = ROK;
7732
7733
7734    switch(lockType)
7735    {
7736 #ifdef SS_RDWR_LOCK_SUPPORT
7737       case SRDLOCK :
7738          {
7739             if((retVal = pthread_rwlock_rdlock(&(lockId->l.rdWrLockId))) != ROK)
7740             {
7741                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7742                SDisplay(0, prntBuf);
7743                return RFAILED;
7744             }
7745             break;
7746          }
7747       case SWRLOCK :
7748          {
7749             if((retVal = pthread_rwlock_wrlock(&(lockId->l.rdWrLockId))) != ROK)
7750             {
7751                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the write lock,Error# %d\n", retVal);
7752                SDisplay(0, prntBuf);
7753                return RFAILED;
7754             }
7755             break;
7756          }
7757       case STRYRDLOCK :
7758          {
7759             if((retVal = pthread_rwlock_tryrdlock(&(lockId->l.rdWrLockId))) != ROK)
7760             {
7761                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7762                SDisplay(0, prntBuf);
7763                return RFAILED;
7764             }
7765             break;
7766          }
7767       case STRYWRLOCK:
7768          {
7769             if((retVal = pthread_rwlock_trywrlock(&(lockId->l.rdWrLockId))) != ROK)
7770             {
7771                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the read lock,Error# %d\n", retVal);
7772                SDisplay(0, prntBuf);
7773                return RFAILED;
7774             }
7775             break;
7776          }
7777 #endif /* SS_RDWR_LOCK_SUPPORT */
7778 #ifdef SS_REC_LOCK_SUPPORT
7779       case SMUTEXRECUR:
7780          {
7781             if((retVal = pthread_mutex_lock(&(lockId->l.recurLock)) != ROK))
7782             {
7783                sprintf(prntBuf, "\n\n ssdLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7784                SDisplay(0, prntBuf);
7785                return RFAILED;
7786             }
7787             break;
7788          }
7789 #endif /* SS_REC_LOCK_SUPPORT */
7790       default :
7791          {
7792             sprintf(prntBuf, "\n\n ssdLockNew(): Invalid lock type %d\n", lockType);
7793             SDisplay(0, prntBuf);
7794             return RFAILED;
7795          }
7796    }
7797
7798    return ROK;
7799 }
7800
7801
7802 /*
7803  *
7804  *       Fun:   ssdUnlockNew
7805  *
7806  *       Desc:  This function is used to Unlock the read write lock
7807  *
7808  *       Ret:   ROK   OK
7809  *
7810  *       Notes:
7811  *
7812  *       File:  mt_ss.c
7813  *
7814  */
7815 S16 ssdUnlockNew(SLockInfo *lockId,uint8_t lockType)
7816 {
7817
7818    Txt prntBuf[PRNTSZE];
7819    S16    retVal = ROK;
7820
7821
7822    switch(lockType)
7823    {
7824 #ifdef SS_RDWR_LOCK_SUPPORT
7825       case SRDWRLOCK :
7826          {
7827             if((retVal = pthread_rwlock_unlock(&(lockId->l.rdWrLockId))) != ROK)
7828             {
7829                sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to unlock the lock,Error# %d\n", retVal);
7830                SDisplay(0, prntBuf);
7831                return RFAILED;
7832             }
7833             break;
7834          }
7835 #endif /* SS_RDWR_LOCK_SUPPORT */
7836 #ifdef SS_REC_LOCK_SUPPORT
7837       case SMUTEXRECUR:
7838          {
7839             if((retVal = pthread_mutex_unlock(&(lockId->l.recurLock)) != ROK))
7840             {
7841                sprintf(prntBuf, "\n\n ssdUnLockNew(): Failed to aquire the recursive mutex,Error# %d\n", retVal);
7842                SDisplay(0, prntBuf);
7843                return RFAILED;
7844             }
7845             break;
7846          }
7847 #endif /* SS_REC_LOCK_SUPPORT */
7848       default :
7849          {
7850             sprintf(prntBuf, "\n\n ssdUnlockNew(): Invalid lock type %d\n", lockType);
7851             SDisplay(0, prntBuf);
7852             return RFAILED;
7853          }
7854    }
7855    return ROK;
7856 }
7857
7858 /*
7859  *
7860  *       Fun:   ssdDestroyLockNew
7861  *
7862  *       Desc:  This function is used to destroy the read write lock
7863  *
7864  *       Ret:   ROK   OK
7865  *
7866  *       Notes:
7867  *
7868  *       File:  mt_ss.c
7869  *
7870  */
7871 S16 ssdDestroyLockNew(SLockInfo *lockId,uint8_t lockType)
7872 {
7873    Txt prntBuf[PRNTSZE];
7874    S16    retVal = ROK;
7875
7876
7877    switch(lockType)
7878    {
7879 #ifdef SS_RDWR_LOCK_SUPPORT
7880       case SRDWRLOCK :
7881          {
7882             if((retVal = pthread_rwlock_destroy(&(lockId->l.rdWrLockId))) != ROK)
7883             {
7884                sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the lock,Error# %d\n", retVal);
7885                SDisplay(0, prntBuf);
7886                return RFAILED;
7887             }
7888             break;
7889          }
7890 #endif /* SS_RDWR_LOCK_SUPPORT */
7891 #ifdef SS_REC_LOCK_SUPPORT
7892       case SMUTEXRECUR:
7893          {
7894             if((retVal = pthread_mutex_destroy(&(lockId->l.recurLock)) != ROK))
7895             {
7896                sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Failed to destroy the mutex,Error# %d\n", retVal);
7897                SDisplay(0, prntBuf);
7898                return RFAILED;
7899             }
7900             break;
7901          }
7902 #endif /* SS_REC_LOCK_SUPPORT */
7903       default :
7904          {
7905             sprintf(prntBuf, "\n\n ssdDestroyLockNew(): Invalid lock type %d\n", lockType);
7906             SDisplay(0, prntBuf);
7907             return RFAILED;
7908          }
7909    }
7910    return ROK;
7911 }
7912 #endif /* SS_LOCK_SUPPORT */
7913
7914 /* mt005.301 : Cavium Changes */
7915 #ifdef SS_SEUM_CAVIUM
7916
7917 /*
7918  *
7919  *        Fun:   ssInitRcvWork
7920  *
7921  *       Desc:  This is the initializtion function of receive
7922  *              work thread.
7923  *
7924  *       Ret:   ROK      - ok
7925  *              RFAILED  - failed, general (optional)
7926  *
7927  *       Notes: Function to initialize the work queue packet
7928  *              receiving thread. This creates the new thread to
7929  *              receive the work and sets the affinity.
7930  *
7931  *       File:
7932  *
7933  **/
7934 S16 ssInitRcvWork(void)
7935 {
7936    pthread_attr_t attr;
7937    pthread_t      thread;
7938
7939
7940    /* set the required attributes */
7941    pthread_attr_init(&attr);
7942    pthread_attr_setstacksize(&attr, (size_t)MT_ISTASK_STACK);
7943    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
7944    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
7945
7946    /* Create a new thread to receive the work queue messages */
7947    if ((pthread_create(&thread, &attr, workRcvTsk, NULLP)) != 0)
7948    {
7949       pthread_attr_destroy(&attr);
7950
7951       return RFAILED;
7952    }
7953
7954    pthread_attr_destroy(&attr);
7955
7956    return ROK;
7957
7958 }/* ssInitRcvWork */
7959
7960
7961 /*
7962  *
7963  *       Fun:   workRcvTsk
7964  *
7965  *       Desc:  This is the handler function of receive
7966  *              work thread.
7967  *
7968  *       Ret:   ROK      - ok
7969  *              RFAILED  - failed, general (optional)
7970  *
7971  *       Notes:The handler function of the work queue receiver task.
7972  *             This will be waiting for the work and after receiving
7973  *             it, work will converted and posted to that entityt
7974  *
7975  *       File:
7976  *
7977  **/
7978
7979 static void *workRcvTsk(Ptr ptr)
7980 {
7981
7982    cvmx_wqe_t *workPtr;
7983    Buffer     *mBuf, *rcvdBuf;
7984    SsMsgInfo  *minfoPtr;
7985    S16         ret;
7986    struct timespec ts;
7987    Pst         pst;
7988
7989
7990
7991    for (;;)
7992    {
7993       /* get the work if its avilable */
7994       workPtr = cvmx_pow_work_request_sync(CVMX_POW_NO_WAIT);
7995
7996       if ( workPtr == NULLP )
7997       {
7998          /* If there is no work then sleep for 10 usec */
7999          ts.tv_sec = 0;
8000          ts.tv_nsec = 500000;
8001
8002          nanosleep(&ts, NULLP);
8003          continue;
8004       }
8005
8006       switch(workPtr->tag)
8007       {
8008          /* Switch over according to the tag value */
8009          case SS_CVMX_MBUF_TAG:
8010
8011             rcvdBuf = (Buffer*)workPtr->packet_ptr.ptr;
8012
8013             /* Convert the physical address to Pointers */
8014             ret = SConvPhyPtr(&rcvdBuf);
8015             if (ret != ROK)
8016             {
8017                /* mt011.301: Cavium 32 bit changes */
8018                cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8019                continue;
8020             }
8021
8022             /* Copy the buffer to this region */
8023             ret = SCpyFpaMsg(rcvdBuf, SS_DFLT_REGION, SS_DFLT_POOL, &mBuf);
8024             if( ret != ROK )
8025             {
8026                /* mt011.301: Cavium 32 bit changes */
8027                cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8028                continue;
8029             }
8030
8031             /* mt011.301: Cavium 32 bit changes */
8032             cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8033
8034             minfoPtr = (SsMsgInfo*)mBuf->b_rptr;
8035
8036             /* Get the post strucutre and Post the message */
8037             if ( minfoPtr != NULLP)
8038             {
8039                SMemCpy( &pst, &minfoPtr->pst, sizeof(Pst));
8040
8041                (Void)SPstTsk(&pst, mBuf);
8042             }
8043             /* Free the buffer allocated if it cannot be sent */
8044             else
8045             {
8046                SPutMsg(mBuf);
8047             }
8048             break;
8049
8050          default:
8051             {
8052                /* Invalid tag value, drop the work */
8053                /* mt011.301: Cavium 32 bit changes */
8054                cvmx_fpa_free(workPtr, SS_CVMX_WQE_POOL, 0);
8055                continue;
8056             }
8057             break;
8058       }
8059
8060    }
8061 } /* workRcvTsk */
8062
8063 #endif /* SS_SEUM_CAVIUM */
8064
8065 #ifdef TENB_RTLIN_CHANGES
8066 S16 SInitLock(SLockId *l, uint8_t t)
8067 {
8068    S16 r = 0;
8069    pthread_mutexattr_t prior;
8070    pthread_mutexattr_init(&prior);
8071 #ifndef RGL_SPECIFIC_CHANGES
8072    pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
8073 #endif
8074    r = pthread_mutex_init(l, &prior);
8075    pthread_mutexattr_destroy(&prior);
8076    return r;
8077 }
8078 #endif
8079 #ifdef SS_THR_REG_MAP
8080 /*
8081  *
8082  *       Fun:   ssRegMainThread
8083  *
8084  *       Desc:  This function is used to add the memory region
8085  *              mapping for the main thread.
8086  *
8087  *       Ret:   VOID (Always successful)
8088  *
8089  *       Notes:
8090  *
8091  *       File: mt_ss.c
8092  *
8093  */
8094
8095 Void ssRegMainThread(Void)
8096 {
8097
8098    if(SS_INVALID_THREAD_REG_MAP != SS_GET_THREAD_MEM_REGION())
8099    {
8100       printf("\nnot able to get different Id for main thread\n");
8101       exit(1);
8102    }
8103    /* Here the default region is added as we dont have any region associated with
8104     * Main thread. The thread should not perform any allocation except 
8105     * the initial configuratin 
8106     */
8107 #ifdef XEON_SPECIFIC_CHANGES
8108    SS_GET_THREAD_MEM_REGION() = mtMemoCfg.numRegions;
8109 #else   
8110    SS_GET_THREAD_MEM_REGION() = 
8111 #endif      
8112       DFLT_REGION;
8113 }
8114
8115 /*
8116  *
8117  *       Fun:   ssCheckAndAddMemoryRegionMap
8118  *
8119  *       Desc:  This function is used to add the memory region
8120  *              mapping for the provided sTsk associated thread.
8121  *              If the threadId can be placed in the thread memory 
8122  *              region mapping table and returns success if it is able
8123  *              to place. If not, it keeps the thread ID in the static
8124  *              local array and increments the count. Once thread Id 
8125  *              is successfully placed in the thread memory region mapping 
8126  *              table, pthread_cancel is sent for all the previous threads
8127  *              which are failed to place in table.
8128  *
8129  *       Ret:   TRUE - Thread ID successfully placed in thread memory region
8130  *                     mapping table
8131  *              FALSE - If thread Id is not placed in thread memory region
8132  *                     mapping table
8133  *
8134  *       Notes:mapping tablemapping tablng tablee
8135  *
8136  *       File: mt_ss.c
8137  *
8138  */
8139    S32 ssCheckAndAddMemoryRegionMap
8140 (
8141  pthread_t    threadId,    /* Thread Id of system task */
8142  Region       region       /* Region associated with thread */
8143  )
8144 {
8145    static uint32_t       createdThreads;
8146    static pthread_t createdThreadIds[SS_MAX_THREAD_CREATE_RETRY];
8147    uint32_t               indx;
8148
8149
8150    /* Here  0xFF is considered as invalid region and if the mapping table
8151     * contains 0xFF, that mapping entry is free
8152     */
8153    if(SS_INVALID_THREAD_REG_MAP != 
8154          osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8155    {
8156       /* Klock work fix ccpu00148484 */
8157       if(!(createdThreads < SS_MAX_THREAD_CREATE_RETRY))
8158       {
8159          printf("\nfailed in index = %ld\n", ((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP));
8160          printf("\nNot able to get the different thread ID, exiting\n");
8161          exit(1);
8162       }
8163       createdThreadIds[createdThreads++] = threadId;
8164       return (FALSE);
8165    }
8166    /* If we found free mapping table entry, place the region and send pthread_cancel
8167     * for all the thread Ids which are created before this 
8168     */
8169    osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = region;
8170 #ifdef XEON_SPECIFIC_CHANGES
8171    printf("\nThreadId %ld, Thread Idx %d, Region %d\n", threadId,
8172          ((threadId >> SS_MEM_THREAD_ID_SHIFT) % 
8173           SS_MAX_THREAD_REGION_MAP), region);
8174 #endif   
8175    for(indx = 0; indx < createdThreads; indx++)
8176    {
8177 #ifdef XEON_SPECIFIC_CHANGES
8178       printf("\nSending pthred Cancel to thread Id %d \n",createdThreadIds[indx]);
8179 #endif      
8180       pthread_cancel(createdThreadIds[indx]);
8181    }
8182    createdThreads = 0;
8183
8184    return (TRUE);
8185
8186 } /* ssCheckAndAddMemoryRegionMap */
8187
8188 /*
8189  *
8190  *       Fun:   ssCheckAndDelMemoryRegionMap
8191  *
8192  *       Desc:  This function is used to add the memory region
8193  *              mapping for the provided sTsk associated thread.
8194  *              If the threadId can be placed in the thread memory 
8195  *              region mapping table and returns success if it is able
8196  *              to place. If not, it keeps the thread ID in the static
8197  *              local array and increments the count. Once thread Id 
8198  *              is successfully placed in the thread memory region mapping 
8199  *              table, pthread_cancel is sent for all the previous threads
8200  *              which are failed to place in table.
8201  *
8202  *       Ret:   TRUE - Thread ID successfully placed in thread memory region
8203  *                     mapping table
8204  *              FALSE - If thread Id is not placed in thread memory region
8205  *                     mapping table
8206  *
8207  *       Notes:mapping tablemapping tablng tablee
8208  *
8209  *       File: mt_ss.c
8210  *
8211  */
8212    S32 ssCheckAndDelMemoryRegionMap
8213 (
8214  pthread_t    threadId    /* Thread Id of system task */
8215  )
8216 {
8217
8218
8219    /* Raghu To-Do Check with team, is it necessary to acquire lock
8220     * as del and add may go parallel */
8221    /* Here  0xFF is considered as invalid region and if the mapping table
8222     * contains 0xFF, that mapping entry is free
8223     */
8224    if(SS_INVALID_THREAD_REG_MAP ==
8225          osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)])
8226    {
8227 #ifndef ALIGN_64BIT
8228       printf("\nInvalid Thread ID (%ld)\n", (uint32_t)threadId);
8229 #else
8230       printf("\nInvalid Thread ID (%d)\n", (uint32_t)threadId);
8231 #endif
8232       return RFAILED;
8233    }
8234    /* If we found free mapping table entry, place the region and send pthread_cancel
8235     * for all the thread Ids which are created before this 
8236     */
8237    osCp.threadMemoryRegionMap[((threadId >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] = SS_INVALID_THREAD_REG_MAP;
8238
8239    return ROK;
8240
8241 } /* ssCheckAndAddMemoryRegionMap */
8242
8243
8244 #endif
8245 #ifdef SS_TSKLOG_ENABLE
8246 /*
8247  *
8248  *       Fun:   SStartTask
8249  *
8250  *       Desc:  This function will return current time through input parameter.
8251  *
8252  *       Ret:   ROK      - ok
8253  *              RFAILED  - failed, general (optional)
8254  *
8255  *
8256  *       File:  pt_ss.c
8257  *
8258  */
8259    S16 SStartTask
8260 (
8261  volatile uint32_t      *startTime,
8262  uint32_t       taskId
8263  )
8264 {
8265 #ifdef MSPD_MLOG_NEW
8266    *startTime = GetTIMETICK();
8267 #endif
8268    return ROK;
8269 }
8270 \f
8271 /*
8272  *
8273  *       Fun:   SStopTask
8274  *
8275  *       Desc:  This function will return current time through input parameter.
8276  *              and take the difference of start time provided as input parameter
8277  *              and current time.
8278  *
8279  *       Ret:   ROK      - ok
8280  *              RFAILED  - failed, general (optional)
8281  *
8282  *
8283  *       File:  pt_ss.c
8284  *
8285  */
8286    S16 SStopTask
8287 (
8288  volatile uint32_t       startTime,
8289  uint32_t       taskId
8290  )
8291 {
8292    /*uint32_t      stopTime;*/
8293    switch(taskId)
8294    {
8295       case PID_MAC_HARQ_IND:
8296       case PID_SCH_TTI_IND:               
8297       case PID_SSI_TSK:               
8298       case PID_MAC_DAT_IND:
8299       case PID_MAC_SF_ALLOC_REQ:
8300       case PID_MAC_STA_RSP:
8301       case PID_MAC_DL_SCHD:
8302       case PID_MAC_DL_CQI_IND:
8303       case PID_MAC_UL_CQI_IND:
8304       case PID_MAC_UL_SCHD:
8305       case PID_MAC_TTI_IND:
8306       case PID_CL_RCV_PHY_MSG:
8307       case PID_CL_HARQ_STA_IND:
8308       case PID_MAC_AM_HARQ_RLS:
8309       case PID_CL_DL_BATCH_PROC:
8310       case PID_CL_DLM_PRC_TTI_IND:
8311       case PID_CRC_IND_REAL:
8312       case PID_CRC_IND_DUMMY:
8313       case PID_TTI_LATENCY:
8314       case PID_RECPREQ_PROC:
8315 #ifdef CA_PHY
8316 #ifndef LTE_TDD               
8317          MLogTask(0, taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8318 #else
8319          MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8320 #endif
8321 #else
8322          MLogTask(taskId, RESOURCE_LARM, startTime, GetTIMETICK());
8323 #endif
8324          break;
8325    }
8326    return ROK;
8327 }
8328 #else
8329    S16 SStartTask
8330 (
8331  volatile uint32_t * startTime,
8332  uint32_t taskId
8333  )
8334 {
8335    *startTime = 0;
8336    return ROK;
8337 }
8338
8339    S16 SStopTask
8340 (
8341  volatile uint32_t startTime,
8342  uint32_t taskId
8343  )
8344 {
8345    return ROK;
8346 }
8347
8348 #endif /*#ifdef SS_TSKLOG_ENABLE */
8349 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
8350 /** @details
8351  * This primitive is used to calculate the CPU Utilization per Core
8352  * for Intel T2200
8353  *
8354  * @param [in]   Void
8355  *
8356  * @return  Void - function is always success
8357  */
8358    Void UpdateSocCpuInfo
8359 (
8360  CmCpuStatsInfo *cpuInfo, 
8361  uint8_t    idx
8362  )
8363 {
8364    FILE       *mipsFd;
8365    S8         mipsStr[MIPS_STRING_LEN];
8366    S8         *strPart;
8367    uint32_t   l2FreeCpu;
8368    uint32_t   l2CpuUsed;
8369    uint32_t   l3FreeCpu;
8370    uint32_t   l3CpuUsed;
8371
8372    /* Open the file which holds the MIPS available value */
8373    mipsFd = fopen(MIPS_FILE, "r");
8374
8375    if(mipsFd == NULLP)
8376    {
8377       return;
8378    }
8379
8380    /* Get the free mips available value from the file */
8381    if(NULLP  == fgets(mipsStr, 24, mipsFd))
8382    {
8383       printf("\nfgets to get the free mips available failed\n");
8384       fclose(mipsFd);
8385       return;
8386    }
8387
8388    strtok(mipsStr, " ");
8389
8390    strPart = strtok(NULLP, " ");
8391
8392    if(idx == CM_L2_CPU_UTIL)
8393    {  
8394       if(strPart != NULLP)
8395       {
8396          l2FreeCpu = atoi(strPart);   
8397          l2CpuUsed = 100 - l2FreeCpu;
8398          cpuInfo->cpuUtil[0].totCpuUtil += l2CpuUsed;
8399          cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l2CpuUsed);
8400          cpuInfo->cpuUtil[0].numSamples++;
8401       }
8402    }
8403    if(idx == CM_L3_CPU_UTIL)
8404    {  
8405       strPart = strtok(NULLP, " ");
8406       if(strPart != NULLP)
8407       {
8408          l3FreeCpu = atoi(strPart);   
8409          l3CpuUsed = 100 - l3FreeCpu;
8410          cpuInfo->cpuUtil[0].totCpuUtil += l3CpuUsed;
8411          cpuInfo->cpuUtil[0].maxCpuUtil = GET_CPU_MAX((cpuInfo->cpuUtil[0].maxCpuUtil), l3CpuUsed);
8412          cpuInfo->cpuUtil[0].numSamples++;
8413       }
8414    }
8415    if(idx == CM_L2_CPU_UTIL)
8416    {   
8417       cpuInfo->numCores = CM_NUM_L2_CORES ; 
8418    }
8419    else if(idx == CM_L3_CPU_UTIL)
8420    {   
8421       cpuInfo->numCores = CM_NUM_L3_CORES ; 
8422    }
8423    fclose(mipsFd);
8424
8425    return;
8426 }
8427 #endif /* TENB_T2K3K_SPECIFIC_CHANGES */
8428 #ifdef SS_MULTICORE_SUPPORT
8429 /*
8430  *
8431  *       Fun:   Add Timer thread into system task table
8432  *
8433  *       Desc:  This function is used to add the system task
8434  *              associated with Timer thread.
8435  *
8436  *       Ret:   None
8437  *
8438  *       Notes:
8439  *
8440  *       File:  mt_ss.c
8441  *
8442  --*/
8443 static SsSTskEntry* ssdReAddTmrSTsk(
8444       uint8_t idx
8445       )
8446 {
8447    SsSTskEntry *sTsk;
8448    S16 ret;
8449
8450    sTsk = NULLP;
8451    /* lock the system task table */
8452    ret = SLock(&osCp.sTskTblLock);
8453    if (ret != ROK)
8454    {
8455
8456 #if (ERRCLASS & ERRCLS_DEBUG)
8457       MTLOGERROR(ERRCLS_DEBUG, EMT039, (ErrVal) ret,
8458             "Could not lock system task table");
8459 #endif
8460
8461       return (sTsk);
8462    }
8463
8464    /* initialize the system task entry with the information we have */
8465    sTsk = &osCp.sTskTbl[idx];
8466
8467    sTsk->used = FALSE;
8468    sTsk->tskPrior = 0;
8469    sTsk->numTTsks = 0;
8470    SDestroyLock(&sTsk->lock);
8471    ssDestroyDmndQ(&sTsk->dQ);
8472
8473
8474    /* store the system task priority */
8475    sTsk->tskPrior = SS_NORM_TSK_PRI;
8476
8477    /* initialize the demand queue */
8478    if (ssInitDmndQ(&sTsk->dQ) != ROK)
8479    {
8480
8481       if ( SUnlock(&osCp.sTskTblLock) != ROK)
8482       {
8483 #if (ERRCLASS & ERRCLS_DEBUG)
8484          MTLOGERROR(ERRCLS_DEBUG, EMT042, ERRZERO,
8485                "Could not give the Semaphore");
8486          return (NULLP);
8487 #endif
8488       }
8489
8490 #if (ERRCLASS & ERRCLS_DEBUG)
8491       MTLOGERROR(ERRCLS_DEBUG, EMT043, (ErrVal) ret,
8492             "Could not initialize demand queue");
8493 #endif
8494
8495       return (NULLP);
8496    }
8497
8498    /* initialize the system task entry lock */
8499    if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
8500    {
8501       ssDestroyDmndQ(&sTsk->dQ);
8502
8503       if ( SUnlock(&osCp.sTskTblLock) != ROK)
8504       {
8505 #if (ERRCLASS & ERRCLS_DEBUG)
8506          MTLOGERROR(ERRCLS_DEBUG, EMT044, ERRZERO,
8507                "Could not give the Semaphore");
8508          return (NULLP);
8509 #endif
8510       }
8511
8512 #if (ERRCLASS & ERRCLS_DEBUG)
8513       MTLOGERROR(ERRCLS_DEBUG, EMT045, (ErrVal) ret,
8514             "Could not initialize system task entry lock");
8515 #endif
8516
8517       return (NULLP);
8518    }
8519
8520
8521    /* success, update the table */
8522    sTsk->tskId       = idx + 1;
8523    sTsk->used        = TRUE;
8524    sTsk->termPend    = FALSE;
8525
8526    /* unlock the system task table */
8527
8528    if ( SUnlock(&osCp.sTskTblLock) != ROK)
8529    {
8530 #if (ERRCLASS & ERRCLS_DEBUG)
8531       MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8532             "Could not give the Semaphore");
8533       return (NULLP);
8534 #endif
8535    }
8536
8537    return (sTsk);
8538 }
8539 #endif /* SS_MULTICORE_SUPPORT */
8540
8541 \f
8542 /*
8543  *
8544  *       Fun:   Initialize timer table
8545  *
8546  *       Desc:  This function initializes MTSS-specific information
8547  *              in the timer table.
8548  *
8549  *       Ret:   ROK      - ok
8550  *
8551  *       Notes:
8552  *
8553  *       File:  mt_ss.c
8554  *
8555  */
8556 S16 ssdReInitTmr(void)
8557 {
8558    pthread_attr_t attr;
8559    struct sched_param param_sched;
8560 #ifndef XEON_SPECIFIC_CHANGES
8561    uint8_t ret = ROK;
8562 #endif
8563 #ifdef SS_MULTICORE_SUPPORT
8564    SsSTskEntry     *sTsk;
8565 #endif /* SS_MULTICORE_SUPPORT */
8566 #ifdef SS_THR_REG_MAP
8567    uint32_t threadCreated = FALSE;
8568 #endif /* SS_THR_REG_MAP */
8569
8570
8571 #ifndef XEON_SPECIFIC_CHANGES
8572    ret = ssCheckAndDelMemoryRegionMap(osCp.dep.tmrHdlrTID);
8573    if(ret != ROK)
8574    {
8575 #if (ERRCLASS & ERRCLS_DEBUG)
8576       MTLOGERROR(ERRCLS_DEBUG, EMT046, ERRZERO,
8577             "Could not give the Semaphore");
8578 #endif
8579       return RFAILED;
8580    }
8581 #endif   
8582
8583    osCp.dep.tmrTqCp.tmrLen = SS_MAX_TMRS;
8584    /* mt010.21: addition */
8585
8586 #ifdef SS_MULTICORE_SUPPORT
8587    sTsk = ssdReAddTmrSTsk(0);
8588    if(!sTsk)
8589    {
8590       return RFAILED;
8591    }
8592 #endif /* SS_MULTICORE_SUPPORT */
8593    /* create the timer handler thread */
8594
8595    pthread_attr_init(&attr);
8596    /* mt021.201 - Addition to set stack size */
8597    pthread_attr_setstacksize(&attr, (size_t)MT_TMRTASK_STACK);
8598    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
8599    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8600    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
8601    param_sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
8602    pthread_attr_setschedparam(&attr, &param_sched);
8603
8604
8605 #ifdef SS_THR_REG_MAP
8606    /* When the thread is created, we check for the memory mapping table if
8607     * threadId can be placed in thread memory map table. If it is not able to place
8608     * threadId is stored in tmporary array. Once thread is created successful,
8609     * thread_cancel is sent for each thread which are created before. All the 
8610     * threads are made to wait on sema which is cancel point for thread.
8611     */
8612    while(threadCreated == FALSE)
8613    {
8614 #endif
8615       if ((pthread_create(&osCp.dep.tmrHdlrTID, &attr, mtTmrHdlr, NULLP)) != 0)
8616       {
8617          /* mt020.201 - Addition for destroying thread attribute object attr */
8618          pthread_attr_destroy(&attr);
8619
8620          return RFAILED;
8621       }
8622
8623 #ifdef SS_THR_REG_MAP
8624       threadCreated = ssCheckAndAddMemoryRegionMap(osCp.dep.tmrHdlrTID, 
8625             sTsk->region);
8626    }
8627 #endif /* SS_THR_REG_MAP */
8628 #ifdef SS_MEM_WL_DEBUG
8629    tmpRegTidMap[sTsk->region] = osCp.dep.tmrHdlrTID;
8630 #endif
8631
8632    /* mt020.201 - Addition for destroying thread attribute object attr */
8633    pthread_attr_destroy(&attr);
8634    sem_post(&osCp.dep.ssStarted);
8635    return ROK;
8636 }
8637
8638 /**********************************************************************
8639   End of file
8640  **********************************************************************/