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