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