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