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