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