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