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