Exemplo n.º 1
0
/*!
 \brief signal_read_rtvars_thread() is thread which fires off the read msg
 to get a new set of realtiem variables.  It does so by queing messages to
 a thread which handles I/O.  This function will check the queue depth and 
 if the queue is backed up it will skip sending a request for data, as that 
 will only aggravate the queue roadblock.
 \returns 0 on signal to exit
 */
G_MODULE_EXPORT void * signal_read_rtvars_thread(gpointer data)
{
	static void (*signal_read_rtvars)(void);
	static gboolean (*setup_rtv)(void);
	static gboolean (*teardown_rtv)(void);
	Serial_Params *serial_params;
	GMutex * mutex = g_mutex_new();
	GTimeVal time;
	GAsyncQueue *io_data_queue = NULL;
	GAsyncQueue *pf_dispatch_queue = NULL;
	GCond *rtv_thread_cond = NULL;
	GMutex *rtv_thread_mutex = NULL;

	serial_params = DATA_GET(global_data,"serial_params");
	io_data_queue = DATA_GET(global_data,"io_data_queue");
	pf_dispatch_queue = DATA_GET(global_data,"pf_dispatch_queue");
	rtv_thread_cond = DATA_GET(global_data,"rtv_thread_cond");
	rtv_thread_mutex = DATA_GET(global_data,"rtv_thread_mutex");
	get_symbol("signal_read_rtvars",(void *)&signal_read_rtvars);
	get_symbol("setup_rtv",(void *)&setup_rtv);
	get_symbol("teardown_rtv",(void *)&teardown_rtv);

	g_return_val_if_fail(serial_params,NULL);
	g_return_val_if_fail(signal_read_rtvars,NULL);
	g_return_val_if_fail(io_data_queue,NULL);
	g_return_val_if_fail(pf_dispatch_queue,NULL);
	g_return_val_if_fail(rtv_thread_cond,NULL);
	g_return_val_if_fail(rtv_thread_mutex,NULL);

	if (setup_rtv)
		if (!setup_rtv())
			g_thread_exit(NULL);
	g_mutex_lock(mutex);
	g_async_queue_ref(io_data_queue);
	g_async_queue_ref(pf_dispatch_queue);
	g_mutex_lock(rtv_thread_mutex);
	while (TRUE)
	{
		dbg_func(IO_MSG|THREADS,g_strdup(__FILE__": signal_read_rtvars_thread()\n\tsending message to thread to read RT vars\n"));

		signal_read_rtvars();

		/* Auto-throttling if gui gets sluggish */
		while (( g_async_queue_length(io_data_queue) > 2) || 
				(g_async_queue_length(pf_dispatch_queue) > 3))
		{
			g_get_current_time(&time);
			g_time_val_add(&time,1000*g_async_queue_length(pf_dispatch_queue));
			if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time))
				goto breakout;
		}
		g_get_current_time(&time);
		g_time_val_add(&time,serial_params->read_wait*1000);
		if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time))
			goto breakout;
	}
breakout:
	g_mutex_unlock(rtv_thread_mutex);
	g_async_queue_unref(io_data_queue);
	g_async_queue_unref(pf_dispatch_queue);
	g_mutex_unlock(mutex);
	g_mutex_free(mutex);
	if (teardown_rtv)
		teardown_rtv();
	g_thread_exit(0);
	return NULL;
}
Exemplo n.º 2
0
/*!
  \brief signal_read_rtvars_thread() is thread which fires off the read msg
  to get a new set of realtime variables.  It does so by queing messages to
  a thread which handles I/O.  This function will check the queue depth and 
  if the queue is backed up it will skip sending a request for data, as that 
  will only aggravate the queue roadblock.
  \param data is unused
  \returns 0 on signal to exit
  */
G_MODULE_EXPORT void * signal_read_rtvars_thread(gpointer data)
{
	static void (*signal_read_rtvars)(void);
	static gboolean (*setup_rtv)(void);
	Serial_Params *serial_params;
	GMutex * mutex = g_mutex_new();
	GTimeVal time;
	GAsyncQueue *io_data_queue = NULL;
	GAsyncQueue *pf_dispatch_queue = NULL;
	GCond *rtv_thread_cond = NULL;
	GMutex *rtv_thread_mutex = NULL;
	gint count = 0;
	gint io_queue_len = 0;
	gint pf_queue_len = 0;
	gint delay = 0;

	g_mutex_lock(mutex);
	serial_params = (Serial_Params *)DATA_GET(global_data,"serial_params");
	io_data_queue = (GAsyncQueue *)DATA_GET(global_data,"io_data_queue");
	pf_dispatch_queue = (GAsyncQueue *)DATA_GET(global_data,"pf_dispatch_queue");
	rtv_thread_cond = (GCond *)DATA_GET(global_data,"rtv_thread_cond");
	rtv_thread_mutex = (GMutex *)DATA_GET(global_data,"rtv_thread_mutex");
	get_symbol("signal_read_rtvars",(void **)&signal_read_rtvars);
	get_symbol("setup_rtv",(void **)&setup_rtv);

	g_return_val_if_fail(serial_params,NULL);
	g_return_val_if_fail(signal_read_rtvars,NULL);
	g_return_val_if_fail(io_data_queue,NULL);
	g_return_val_if_fail(pf_dispatch_queue,NULL);
	g_return_val_if_fail(rtv_thread_cond,NULL);
	g_return_val_if_fail(rtv_thread_mutex,NULL);
	g_return_val_if_fail(setup_rtv,NULL);

	if (!setup_rtv())
	{
		g_mutex_unlock(mutex);
		g_mutex_free(mutex);
		g_thread_exit(NULL);
	}
	g_async_queue_ref(io_data_queue);
	g_async_queue_ref(pf_dispatch_queue);
	g_mutex_lock(rtv_thread_mutex);
	while (TRUE)
	{
		MTXDBG(IO_MSG|THREADS,_("Sending message to thread to read RT vars\n"));

		signal_read_rtvars();
		count = 0;

		/* Auto-throttling if gui gets sluggish */
		while ((g_async_queue_length(io_data_queue) > 2) || (g_async_queue_length(pf_dispatch_queue) > 3))
		{
			count++;
			pf_queue_len = g_async_queue_length(pf_dispatch_queue);
			io_queue_len = g_async_queue_length(io_data_queue);
			//printf("Auto-throttling, io queue length %i, pf queue length %i, loop iterations %i\n",io_queue_len,pf_queue_len,count);
			g_get_current_time(&time);
			delay = MAX(io_queue_len,pf_queue_len);

			g_time_val_add(&time,10000*(delay));
			//printf("io_queue_len is %i pf queue length is %i, delay is %i\n",io_queue_len,pf_queue_len,delay );
			if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time))
				goto breakout;
		}
		g_get_current_time(&time);
		//printf("serial_params->read_wait is %i\n",serial_params->read_wait);
		g_time_val_add(&time,serial_params->read_wait*1000);
		if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time))
			goto breakout;
	}
breakout:
	g_async_queue_unref(io_data_queue);
	g_async_queue_unref(pf_dispatch_queue);
	g_mutex_unlock(mutex);
	g_mutex_free(mutex);
	g_mutex_unlock(rtv_thread_mutex);
	g_thread_exit(0);
	return NULL;
}