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