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