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