diff --git a/alsa_driver.c b/alsa_driver.c index 45bfffc..e948620 100644 --- a/alsa_driver.c +++ b/alsa_driver.c @@ -849,6 +849,7 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delay } driver->poll_last = poll_ret; driver->poll_next = poll_ret + (unsigned long long) floor ((driver->period_usecs * driver->cpu_mhz)); + driver->engine->control->time.cycles = get_cycles(); } /* check to see if it was the extra FD that caused us to return from poll @@ -875,12 +876,6 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delay return (driver->pfd[nfds-1].revents == POLLIN) ? 0 : -1; } - if (driver->engine) { - struct timeval tv; - gettimeofday (&tv, NULL); - driver->engine->control->time.microseconds = tv.tv_sec * 1000000 + tv.tv_usec; - } - p_timed_out = 0; if (need_playback) { diff --git a/client.c b/client.c index 6738ca1..b7a4b8f 100644 --- a/client.c +++ b/client.c @@ -77,6 +77,7 @@ struct _jack_client { void *on_shutdown_arg; char thread_ok : 1; char first_active : 1; + float cpu_mhz; }; #define event_fd pollfd[0].fd @@ -123,6 +124,7 @@ jack_client_alloc () client->thread_ok = FALSE; client->first_active = TRUE; client->on_shutdown = NULL; + client->cpu_mhz = (float) jack_get_mhz (); return client; } @@ -1560,18 +1562,52 @@ jack_get_ports (jack_client_t *client, return matching_ports; } +static inline void +jack_read_frame_time (const jack_client_t *client, jack_frame_timer_t *copy) +{ + int tries = 0; + + do { + /* throttle the busy wait if we don't get + the answer very quickly. + */ + + if (tries > 10) { + usleep (20); + tries = 0; + } + + *copy = client->engine->frame_timer; + + tries++; + + } while (copy->guard1 != copy->guard2); +} + nframes_t -jack_frames_since_cycle_start (jack_client_t *client) +jack_frames_since_cycle_start (const jack_client_t *client) { - struct timeval now; float usecs; - gettimeofday (&now, NULL); - usecs = ((now.tv_sec * 1000000) + now.tv_usec) - client->engine->time.microseconds; - + usecs = (float) (get_cycles() - client->engine->time.cycles) / client->cpu_mhz; return (nframes_t) floor ((((float) client->engine->time.frame_rate) / 1000000.0f) * usecs); } +nframes_t +jack_frame_time (const jack_client_t *client) +{ + jack_frame_timer_t current; + float usecs; + nframes_t elapsed; + + jack_read_frame_time (client, ¤t); + + usecs = (float) (get_cycles() - current.stamp) / client->cpu_mhz; + elapsed = (nframes_t) floor ((((float) client->engine->time.frame_rate) / 1000000.0f) * usecs); + + return current.frames + elapsed; +} + int jack_port_lock (jack_client_t *client, jack_port_t *port) { @@ -1796,3 +1832,6 @@ jack_cpu_load (jack_client_t *client) { return client->engine->cpu_load; } + + + diff --git a/configure.in b/configure.in index 2c405c6..9b5bc9b 100644 --- a/configure.in +++ b/configure.in @@ -4,8 +4,8 @@ AC_INIT(client.c) AC_CONFIG_AUX_DIR(.) JACK_MAJOR_VERSION=0 -JACK_MINOR_VERSION=26 -JACK_MICRO_VERSION=3 +JACK_MINOR_VERSION=27 +JACK_MICRO_VERSION=0 BETA= diff --git a/engine.c b/engine.c index 6466890..7c88c4f 100644 --- a/engine.c +++ b/engine.c @@ -1244,6 +1244,7 @@ jack_engine_new (int realtime, int rtpriority, int verbose) engine->control->buffer_size = 0; engine->control->time.frame_rate = 0; engine->control->time.frame = 0; + engine->control->in_process = 0; snprintf (engine->fifo_prefix, sizeof (engine->fifo_prefix), "%s/jack-ack-fifo-%d", jack_temp_dir, getpid()); @@ -1337,6 +1338,23 @@ jack_engine_notify_clients_about_delay (jack_engine_t *engine) jack_unlock_graph (engine); } +static inline void +jack_inc_frame_time (jack_engine_t *engine, nframes_t amount) +{ + jack_frame_timer_t *time = &engine->control->frame_timer; + + // atomic_inc (&time->guard1, 1); + // really need a memory barrier here + + time->guard1++; + time->frames += amount; + time->stamp = get_cycles (); + + // atomic_inc (&time->guard2, 1); + // might need a memory barrier here + time->guard2++; +} + static void * jack_main_thread (void *arg) @@ -1344,7 +1362,8 @@ jack_main_thread (void *arg) jack_engine_t *engine = (jack_engine_t *) arg; jack_driver_t *driver = engine->driver; int consecutive_excessive_delays; - unsigned long long cycle_start, cycle_end; + unsigned long long cycle_end; + nframes_t nframes; if (engine->control->real_time) { @@ -1368,15 +1387,15 @@ jack_main_thread (void *arg) consecutive_excessive_delays = 0; engine->watchdog_check = 1; + nframes = 0; while (1) { int status; - nframes_t nframes; float delayed_usecs; nframes = driver->wait (driver, -1, &status, &delayed_usecs); - - cycle_start = get_cycles(); + + jack_inc_frame_time (engine, nframes); engine->watchdog_check = 1; @@ -1434,9 +1453,10 @@ jack_main_thread (void *arg) cycle_end = get_cycles (); - /* store the execution time for this this part of the graph */ + /* store the execution time for later averaging */ - engine->rolling_client_usecs[engine->rolling_client_usecs_index++] = (float) (cycle_end - cycle_start) / engine->cpu_mhz; + engine->rolling_client_usecs[engine->rolling_client_usecs_index++] = + (float) (cycle_end - engine->control->time.cycles) / engine->cpu_mhz; if (engine->rolling_client_usecs_index >= JACK_ENGINE_ROLLING_COUNT) { engine->rolling_client_usecs_index = 0; @@ -2815,3 +2835,4 @@ jack_set_asio_mode (jack_engine_t *engine, int yn) { engine->asio_mode = yn; } + diff --git a/hammerfall.c b/hammerfall.c index 65e1a7c..149e553 100644 --- a/hammerfall.c +++ b/hammerfall.c @@ -205,7 +205,6 @@ hammerfall_release (jack_hardware_t *hw) static void * hammerfall_monitor_controls (void *arg) - { jack_hardware_t *hw = (jack_hardware_t *) arg; hammerfall_t *h = (hammerfall_t *) hw->private; diff --git a/jack/internal.h b/jack/internal.h index 933aa15..0a81250 100644 --- a/jack/internal.h +++ b/jack/internal.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,7 @@ typedef struct _time_info { nframes_t frame; nframes_t frame_rate; - unsigned long microseconds; + cycles_t cycles; jack_transport_state_t transport_state; nframes_t loop_start; nframes_t loop_end; @@ -73,9 +74,19 @@ typedef struct _time_info } jack_time_info_t; +typedef struct { + volatile unsigned long long guard1; + volatile nframes_t frames; + volatile cycles_t stamp; + volatile unsigned long long guard2; +} jack_frame_timer_t; + typedef struct { jack_time_info_t time; + jack_frame_timer_t frame_timer; + int in_process; + nframes_t frames_at_cycle_start; pid_t engine_pid; unsigned long buffer_size; char real_time; diff --git a/jack/jack.h b/jack/jack.h index d44e228..e5c0e2f 100644 --- a/jack/jack.h +++ b/jack/jack.h @@ -515,7 +515,16 @@ void jack_update_time (jack_client_t *, nframes_t); * callbacks of all its clients. */ -nframes_t jack_frames_since_cycle_start (jack_client_t *); +nframes_t jack_frames_since_cycle_start (const jack_client_t *); + +/** + * Return an estimate of the current time in frames. It is a running + * counter - no significance should be attached to the return + * value. it should be used to compute the difference between + * a previously returned value. + */ + +nframes_t jack_frame_time (const jack_client_t *); /** * This returns the current CPU load estimated by JACK diff --git a/jackd.c b/jackd.c index cd717af..c8e8b4f 100644 --- a/jackd.c +++ b/jackd.c @@ -232,7 +232,6 @@ static void jack_main (int argc, char **argv) { int sig; - int err; pthread_t waiter_thread; waiter_arg_t warg; @@ -273,8 +272,12 @@ jack_main (int argc, char **argv) sigdelset (&signals, SIGINT); } + if (verbose) { + fprintf (stderr, "%d waiting for signals\n", getpid()); + } + while(1) { - err = sigwait (&signals, &sig); + sigwait (&signals, &sig); printf ("jack main caught signal %d\n", sig);