** Warning: Cannot open xref database.
1 /* -*- mode: c; c-file-style: "linux"; -*- */
2 /*
3 Copyright (C) 2001-2003 Paul Davis
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 $Id: driver.c,v 1.13 2003/12/10 06:52:17 joq Exp $
20 */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <sys/mman.h>
28 #include <errno.h>
29
30 #include <config.h>
31
32 #include <jack/driver.h>
33 #include <jack/internal.h>
34 #include <jack/engine.h>
35
36 static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
37 static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
38 static int dummy_write (jack_driver_t *drv,
39 jack_nframes_t nframes) { return 0; }
40 static int dummy_read (jack_driver_t *drv, jack_nframes_t nframes) { return 0; }
41 static int dummy_null_cycle (jack_driver_t *drv,
42 jack_nframes_t nframes) { return 0; }
43 static int dummy_bufsize (jack_driver_t *drv,
44 jack_nframes_t nframes) {return 0;}
45 static int dummy_stop (jack_driver_t *drv) { return 0; }
46 static int dummy_start (jack_driver_t *drv) { return 0; }
47
48 void
49 jack_driver_init (jack_driver_t *driver)
50 {
51 memset (driver, 0, sizeof (*driver));
52
53 driver->attach = dummy_attach;
54 driver->detach = dummy_detach;
55 driver->write = dummy_write;
56 driver->read = dummy_read;
57 driver->null_cycle = dummy_null_cycle;
58 driver->bufsize = dummy_bufsize;
59 driver->start = dummy_start;
60 driver->stop = dummy_stop;
61 }
62
63
64
65 /****************************
66 *** Non-Threaded Drivers ***
67 ****************************/
68
69 static int dummy_nt_run_cycle (jack_driver_nt_t *drv) { return 0; }
70 static int dummy_nt_attach (jack_driver_nt_t *drv) { return 0; }
71 static int dummy_nt_detach (jack_driver_nt_t *drv) { return 0; }
72
73
74 /*
75 * These are used in driver->nt_run for controlling whether or not
76 * driver->engine->driver_exit() gets called (EXIT = call it, PAUSE = don't)
77 */
78 #define DRIVER_NT_RUN 0
79 #define DRIVER_NT_EXIT 1
80 #define DRIVER_NT_PAUSE 2
81
82 static int
83 jack_driver_nt_attach (jack_driver_nt_t * driver, jack_engine_t * engine)
84 {
85 driver->engine = engine;
86 return driver->nt_attach (driver);
87 }
88
89 static int
90 jack_driver_nt_detach (jack_driver_nt_t * driver, jack_engine_t * engine)
91 {
92 int ret;
93
94 ret = driver->nt_detach (driver);
95 driver->engine = NULL;
96
97 return ret;
98 }
99
100 static int
101 jack_driver_nt_become_real_time (jack_driver_nt_t* driver)
102 {
103 if (jack_acquire_real_time_scheduling (driver->nt_thread,
104 driver->engine->rtpriority)) {
105 return -1;
106 }
107
108 if (mlockall (MCL_CURRENT | MCL_FUTURE) != 0) {
109 jack_error ("cannot lock down memory for RT thread (%s)",
110 strerror (errno));
111 #ifdef ENSURE_MLOCK
112 return -1;
113 #endif /* ENSURE_MLOCK */
114 }
115
116 return 0;
117 }
118
119
120 static void *
121 jack_driver_nt_thread (void * arg)
122 {
123 jack_driver_nt_t * driver = (jack_driver_nt_t *) arg;
124 int rc = 0;
125 int run;
126
127 /* This thread may start running before pthread_create()
128 * actually stores the driver->nt_thread value. It's safer to
129 * store it here as well. */
130 driver->nt_thread = pthread_self();
131
132 if (driver->engine->control->real_time)
133 jack_driver_nt_become_real_time (driver);
134
135 pthread_mutex_lock (&driver->nt_run_lock);
136
137 while ( (run = driver->nt_run) == DRIVER_NT_RUN) {
138 pthread_mutex_unlock (&driver->nt_run_lock);
139
140 rc = driver->nt_run_cycle (driver);
141 if (rc) {
142 jack_error ("DRIVER NT: could not run driver cycle");
143 goto out;
144 }
145
146 pthread_mutex_lock (&driver->nt_run_lock);
147 }
148
149 pthread_mutex_unlock (&driver->nt_run_lock);
150
151 out:
152 if (rc) {
153 driver->engine->driver_exit (driver->engine);
154 }
155 pthread_exit (NULL);
156 }
157
158 static int
159 jack_driver_nt_start (jack_driver_nt_t * driver)
160 {
161 int err;
162
163 err = driver->nt_start (driver);
164 if (err) {
165 jack_error ("DRIVER NT: could not start driver");
166 return err;
167 }
168
169 driver->nt_run = DRIVER_NT_RUN;
170
171 err = pthread_create (&driver->nt_thread, NULL,
172 jack_driver_nt_thread, driver);
173 if (err) {
174 jack_error ("DRIVER NT: could not start driver thread!");
175 driver->nt_stop (driver);
176 return err;
177 }
178
179 return 0;
180 }
181
182 static int
183 jack_driver_nt_do_stop (jack_driver_nt_t * driver, int run)
184 {
185 int err;
186
187 pthread_mutex_lock (&driver->nt_run_lock);
188 driver->nt_run = run;
189 pthread_mutex_unlock (&driver->nt_run_lock);
190
191 err = pthread_join (driver->nt_thread, NULL);
192 if (err) {
193 jack_error ("DRIVER NT: error waiting for driver thread: %s",
194 strerror (err));
195 return err;
196 }
197
198 err = driver->nt_stop (driver);
199 if (err) {
200 jack_error ("DRIVER NT: error stopping driver");
201 return err;
202 }
203
204 return 0;
205 }
206
207 static int
208 jack_driver_nt_stop (jack_driver_nt_t * driver)
209 {
210 return jack_driver_nt_do_stop (driver, DRIVER_NT_EXIT);
211 }
212
213 static int
214 jack_driver_nt_bufsize (jack_driver_nt_t * driver, jack_nframes_t nframes)
215 {
216 int err;
217 int ret;
218
219 err = jack_driver_nt_do_stop (driver, DRIVER_NT_PAUSE);
220 if (err) {
221 jack_error ("DRIVER NT: could not stop driver to change buffer size");
222 driver->engine->driver_exit (driver->engine);
223 return err;
224 }
225
226 ret = driver->nt_bufsize (driver, nframes);
227
228 err = jack_driver_nt_start (driver);
229 if (err) {
230 jack_error ("DRIVER NT: could not restart driver during buffer size change");
231 driver->engine->driver_exit (driver->engine);
232 return err;
233 }
234
235 return ret;
236 }
237
238 void
239 jack_driver_nt_init (jack_driver_nt_t * driver)
240 {
241 memset (driver, 0, sizeof (*driver));
242
243 jack_driver_init ((jack_driver_t *) driver);
244
245 driver->attach = (JackDriverAttachFunction) jack_driver_nt_attach;
246 driver->detach = (JackDriverDetachFunction) jack_driver_nt_detach;
247 driver->bufsize = (JackDriverBufSizeFunction) jack_driver_nt_bufsize;
248 driver->stop = (JackDriverStartFunction) jack_driver_nt_stop;
249 driver->start = (JackDriverStopFunction) jack_driver_nt_start;
250
251 driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_bufsize;
252 driver->nt_start = (JackDriverNTStartFunction) dummy_start;
253 driver->nt_stop = (JackDriverNTStopFunction) dummy_stop;
254 driver->nt_attach = dummy_nt_attach;
255 driver->nt_detach = dummy_nt_detach;
256 driver->nt_run_cycle = dummy_nt_run_cycle;
257
258
259 pthread_mutex_init (&driver->nt_run_lock, NULL);
260 }
261
262 void
263 jack_driver_nt_finish (jack_driver_nt_t * driver)
264 {
265 pthread_mutex_destroy (&driver->nt_run_lock);
266 }
267
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.