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