[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;
127 }
130 /** print usage and exit */
131 static void printUsageExit (char * app)
132 {
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);
141 }
143 int main (int argc, char * argv [])
144 {
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;
219 }
222 #if defined (__cplusplus)
223 }
224 #endif /* defined (__cplusplus) */