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