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