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