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