Fixed 'use' help text to add new -t option in ipc_trace_daemon for QNX
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / build / Qnx / traceDaemon / IpcTraceDaemon.c
1 /*
2  *  @file  IpcTraceDaemon.c
3  *
4  *  @brief  Daemon for remote core IPC traces
5  *
6  *
7  *  ============================================================================
8  *
9  *  Copyright (c) 2010-2014, Texas Instruments Incorporated
10  *
11  *  Redistribution and use in source and binary forms, with or without
12  *  modification, are permitted provided that the following conditions
13  *  are met:
14  *
15  *  *  Redistributions of source code must retain the above copyright
16  *     notice, this list of conditions and the following disclaimer.
17  *
18  *  *  Redistributions in binary form must reproduce the above copyright
19  *     notice, this list of conditions and the following disclaimer in the
20  *     documentation and/or other materials provided with the distribution.
21  *
22  *  *  Neither the name of Texas Instruments Incorporated nor the names of
23  *     its contributors may be used to endorse or promote products derived
24  *     from this software without specific prior written permission.
25  *
26  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
28  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
33  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
35  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  *  Contact information for paper mail:
38  *  Texas Instruments
39  *  Post Office Box 655303
40  *  Dallas, Texas 75265
41  *  Contact information:
42  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
43  *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
44  *  ============================================================================
45  *
46  */
48 /* OS-specific headers */
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <unistd.h>
52 #include <string.h>
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 #include <pthread.h>
56 #include <semaphore.h>
58 #include <sys/procmgr.h>
59 #include <stdint.h>
60 #include <fcntl.h>
61 #include <stdbool.h>
62 #include <ti/syslink/Std.h>
63 #include <_MultiProc.h>
64 #include <limits.h>
65 #include <ti/ipc/MultiProc.h>
67 #if defined (__cplusplus)
68 extern "C" {
69 #endif /* defined (__cplusplus) */
71 #define TRACE_BUFFER_SIZE               0x8000
73 /* Default polling interval */
74 #define TIMEOUT_USECS                   500000
76 static char traceBuffer[TRACE_BUFFER_SIZE];
77 static useconds_t timeout = TIMEOUT_USECS;
79 static FILE *log;
80 sem_t        semPrint; /* Semaphore to allow only one thread to print at once */
82 /* pull char from queue */
83 void printTraces (void *arg)
84 {
85     int32_t           index = (int32_t)arg;
86     int32_t           numOfBytesInBuffer  = 0;
87     uint32_t          readPointer         = 0;
88     int               fd                  = -1;
89     char              path[_POSIX_PATH_MAX];
91     fprintf (log, "\nSpawning procId %d trace thread\n ", index);
93     /* Initialize read indexes to zero */
94     snprintf (path, _POSIX_PATH_MAX, "/dev/ipc-trace%d", index);
95     fd = open(path, O_RDONLY);
96     if (fd < 0) {
97         perror("Unable to open ipc-trace");
98         goto EXIT;
99     }
100     do {
101         sem_wait(&semPrint);    /* Acquire exclusive access to printing */
102         while ((numOfBytesInBuffer = read(fd, traceBuffer, TRACE_BUFFER_SIZE)) > 0) {
103             readPointer = 0;
104             fprintf (log, "\n[ProcId %d]: ", index);
105             while ( numOfBytesInBuffer-- ) {
106                 fprintf (log, "%c", traceBuffer[readPointer]);
107                 if (traceBuffer[readPointer] == '\n') {
108                     fprintf (log, "[ProcId %d]: ", index);
109                 }
111                 readPointer++;
112             }
113         }
114         fflush (log);
115         sem_post(&semPrint);    /* Release exclusive access to printing */
116         if (numOfBytesInBuffer < 0) {
117             perror ("\nError reading from ipc-trace");
118             break;
119         }
120         usleep(timeout);
121     } while(1);
123     close(fd);
124 EXIT:
125     fprintf (log, "Leaving printTraces thread function for ProcId %d\n", index);
126     return;
130 /** print usage and exit */
131 static void printUsageExit (char * app)
133     printf ("%s: [-h] [-l logfile] [-f] [-t interval]\n", app);
134     printf ("  -h   show this help message\n");
135     printf ("  -l   select file to log to (default stdout)\n");
136     printf ("  -f   run in foreground (do not fork daemon process)\n");
137     printf ("  -t   polling interval in microseconds (default %d)\n",
138         TIMEOUT_USECS);
140     exit (EXIT_SUCCESS);
143 int main (int argc, char * argv [])
145     pthread_t   threads[MultiProc_MAXPROCESSORS]; /* server thread object */
146     char      * log_file    = NULL;
147     bool        daemon      = true;
148     int         i;
149     struct stat sbuf;
150     char        names[MultiProc_MAXPROCESSORS][_POSIX_PATH_MAX];
151     int         c;
153     /* parse cmd-line args */
154     while (1) {
155         c = getopt(argc, argv, "l:fht:");
156         if (c == -1) {
157             break;
158         }
160         switch (c) {
161             case 'l':
162                 log_file = optarg;
163                 break;
165             case 'f':
166                 daemon = false;
167                 break;
169             case 'h':
170                 printUsageExit (argv[0]);
171                 break;
173             case 't':
174                 timeout = atoi(optarg);
175                 printf("Using polling interval of %d us\n", timeout);
176                 break;
178             default:
179                 fprintf (stderr, "Unrecognized argument\n");
180         }
181     }
183     if (!log_file) {
184         log = stdout;
185     }
186     else {
187         log = fopen (log_file, "a+");
188         if (log == NULL) {
189             printf("Bad filename specified for log file\n");
190             printUsageExit(argv[0]);
191         }
192     }
194     printf ("Spawning IPC Trace daemon...\n");
196     /* background the process, if requested */
197     if (daemon) {
198         procmgr_daemon(0, PROCMGR_DAEMON_NOCLOSE|PROCMGR_DAEMON_NODEVNULL);
199     }
201     sem_init(&semPrint, 0, 1);
202     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
203         snprintf (names[i], _POSIX_PATH_MAX, "/dev/ipc-trace%d", i);
204         if (-1 != stat(names[i], &sbuf)) {
205             pthread_create (&threads[i], NULL, (void *)&printTraces, (void *)i);
206         }
207         else
208             threads[i] = NULL;
209     }
211     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
212         if (threads[i])
213             pthread_join(threads[i], NULL);
214     }
216     sem_destroy(&semPrint);
218     return 0;
222 #if defined (__cplusplus)
224 #endif /* defined (__cplusplus) */