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