summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound/discrete.c
diff options
context:
space:
mode:
author Couriersud <couriersud@users.noreply.github.com>2009-10-03 21:45:09 +0000
committer Couriersud <couriersud@users.noreply.github.com>2009-10-03 21:45:09 +0000
commitde55177d940d8dec493b3889a509c5d6ff1afe44 (patch)
treee2a8c17bb3a460725ffb182e3b0bf862abeae52d /src/emu/sound/discrete.c
parentfa947ec474dd89cb3a1010fdc3349c4375f500be (diff)
Discrete task groups
- DISCRETE_TASK_START now requires a parameter TASK_GROUP (>=0, <=9) - Tasks are scheduled in the order of their task group - Nodes are automatically buffered between task groups - Discrete core determines nodes which need buffering to minimize overhead (information in DISCRETE_LOG) - A discrete block list now must put each stepped node into a task if it uses tasks - Drivers not using tasks will get one task allocated automatically - Updated drivers accordingly - Some more constification
Diffstat (limited to 'src/emu/sound/discrete.c')
-rw-r--r--src/emu/sound/discrete.c166
1 files changed, 82 insertions, 84 deletions
diff --git a/src/emu/sound/discrete.c b/src/emu/sound/discrete.c
index 0edbe39b47e..93f6475dc7b 100644
--- a/src/emu/sound/discrete.c
+++ b/src/emu/sound/discrete.c
@@ -78,9 +78,9 @@ struct _task_info
*
*************************************/
-static void init_nodes(discrete_info *info, linked_list_entry *block_list, const device_config *device);
-static void find_input_nodes(discrete_info *info);
-static node_description *discrete_find_node(const discrete_info *info, int node);
+static void init_nodes(discrete_info *info, const linked_list_entry *block_list, const device_config *device);
+static void find_input_nodes(const discrete_info *info);
+static node_description *discrete_find_node(const discrete_info *info, const int node);
static DEVICE_RESET( discrete );
static STREAM_UPDATE( discrete_stream_update );
static STREAM_UPDATE( buffer_stream_update );
@@ -103,6 +103,7 @@ static void CLIB_DECL ATTR_PRINTF(2,3) discrete_log(const discrete_info *disc_in
{
vfprintf(disc_info->disclogfile, text, arg);
fprintf(disc_info->disclogfile, "\n");
+ fflush(disc_info->disclogfile);
}
va_end(arg);
@@ -200,8 +201,8 @@ static const discrete_module module_list[] =
{ DSO_IMPORT ,"DSO_IMPORT" , 0 ,0 ,NULL ,NULL ,NULL ,NULL },
/* parallel modules */
- { DSO_TASK_START ,"DSO_TASK_START" , 0 ,0 ,NULL ,NULL ,NULL ,NULL },
- { DSO_TASK_END ,"DSO_TASK_END" , 0 ,0 ,dso_task_reset ,dso_task_step ,dso_task_start ,NULL },
+ { DSO_TASK_START ,"DSO_TASK_START" , 0 ,0 ,dso_task_reset ,dso_task_start_step ,dso_task_start_start ,NULL },
+ { DSO_TASK_END ,"DSO_TASK_END" , 0 ,0 ,dso_task_reset ,dso_task_end_step ,NULL ,NULL },
{ DSO_TASK_SYNC ,"DSO_TASK_SYNC" , 0 ,0 ,NULL ,NULL ,NULL ,NULL },
/* nop */
@@ -431,7 +432,7 @@ static void discrete_build_list(discrete_info *info, const discrete_sound_block
static void discrete_sanity_check(const discrete_info *info)
{
- linked_list_entry *entry;
+ const linked_list_entry *entry;
int node_count = 0;
discrete_log(info, "discrete_start() - Doing node list sanity check");
@@ -470,8 +471,8 @@ static void discrete_sanity_check(const discrete_info *info)
static DEVICE_START( discrete )
{
linked_list_entry **intf;
- linked_list_entry *entry;
- discrete_sound_block *intf_start = (discrete_sound_block *)device->static_config;
+ const linked_list_entry *entry;
+ const discrete_sound_block *intf_start = (discrete_sound_block *)device->static_config;
discrete_info *info = get_safe_token(device);
char name[32];
@@ -503,10 +504,8 @@ static DEVICE_START( discrete )
/* Start with empty lists */
info->node_list = NULL;
- info->main_list = NULL;
info->output_list = NULL;
info->input_list = NULL;
- info->main_source_list = NULL;
/* allocate memory to hold pointers to nodes by index */
info->indexed_node = auto_alloc_array_clear(device->machine, node_description *, DISCRETE_MAX_NODES);
@@ -587,11 +586,8 @@ static void display_profiling(const discrete_info *info)
discrete_task *task = (discrete_task *) entry->ptr;
tt = list_run_time(task->list);
- printf("Task: %8.2f %15.2f\n", tt / (double) total * 100.0, tt / (double) info->total_samples);
+ printf("Task(%d): %8.2f %15.2f\n", task->task_group, tt / (double) total * 100.0, tt / (double) info->total_samples);
}
- tt = list_run_time(info->main_list);
-
- printf("Main: %8.2f %15.2f\n", tt / (double) total * 100.0, tt / (double) info->total_samples);
printf("Average samples/stream_update: %8.2f\n", (double) info->total_samples / (double) info->total_stream_updates);
}
@@ -599,7 +595,7 @@ static void display_profiling(const discrete_info *info)
static DEVICE_STOP( discrete )
{
discrete_info *info = get_safe_token(device);
- linked_list_entry *entry;
+ const linked_list_entry *entry;
osd_work_queue_free(info->queue);
@@ -637,8 +633,8 @@ static DEVICE_STOP( discrete )
static DEVICE_RESET( discrete )
{
- discrete_info *info = get_safe_token(device);
- linked_list_entry *entry;
+ const discrete_info *info = get_safe_token(device);
+ const linked_list_entry *entry;
/* loop over all nodes */
for (entry = info->node_list; entry != 0; entry = entry->next)
@@ -665,16 +661,17 @@ static DEVICE_RESET( discrete )
static void *task_callback(void *param, int threadid)
{
- task_info *ti = (task_info *) param;
- linked_list_entry *entry;
+ const task_info *ti = (task_info *) param;
+ const linked_list_entry *entry;
+ discrete_task *task = ti->task;
int samples, i;
/* set up task buffers */
- for (i = 0; i < ti->task->numbuffered; i++)
- ti->task->ptr[i] = ti->task->node_buf[i];
+ for (i = 0; i < task->numbuffered; i++)
+ task->ptr[i] = task->node_buf[i];
/* initialize sources */
- for (entry = ti->task->source_list; entry != 0; entry = entry->next)
+ for (entry = task->source_list; entry != 0; entry = entry->next)
{
discrete_source_node *sn = (discrete_source_node *) entry->ptr;
sn->ptr = sn->task->node_buf[sn->output_node];
@@ -683,50 +680,19 @@ static void *task_callback(void *param, int threadid)
samples = ti->samples;
while (samples-- > 0)
{
- /* update source node buffer */
- for (entry = ti->task->source_list; entry != 0; entry = entry->next)
- {
- discrete_source_node *sn = (discrete_source_node *) entry->ptr;
- sn->buffer = *sn->ptr++;
- }
-
/* step */
- step_nodes_in_list(ti->task->list);
+ step_nodes_in_list(task->list);
}
free(param);
return NULL;
}
-INLINE void update_main_nodes(discrete_info *info, int samples)
-{
- linked_list_entry *entry;
-
- /* initialize sources */
- for (entry = info->main_source_list; entry != 0; entry = entry->next)
- {
- discrete_source_node *sn = (discrete_source_node *) entry->ptr;
- sn->ptr = sn->task->node_buf[sn->output_node];
- }
-
- while (samples-- > 0)
- {
- /* update source node buffer */
- for (entry = info->main_source_list; entry != 0; entry = entry->next)
- {
- discrete_source_node *sn = (discrete_source_node *) entry->ptr;
- sn->buffer = *sn->ptr++;
- }
-
- /* loop over all nodes */
- step_nodes_in_list(info->main_list);
- }
-}
static STREAM_UPDATE( buffer_stream_update )
{
- node_description *node = (node_description *) param;
- struct dss_input_context *context = (struct dss_input_context *)node->context;
+ const node_description *node = (node_description *) param;
+ const struct dss_input_context *context = (struct dss_input_context *)node->context;
stream_sample_t *ptr = outputs[0];
int data = context->data;
int samplenum = samples;
@@ -739,8 +705,8 @@ static STREAM_UPDATE( buffer_stream_update )
static STREAM_UPDATE( discrete_stream_update )
{
discrete_info *info = (discrete_info *)param;
- linked_list_entry *entry;
- int outputnum;
+ const linked_list_entry *entry;
+ int outputnum, task_group;
if (samples == 0)
return;
@@ -758,23 +724,26 @@ static STREAM_UPDATE( discrete_stream_update )
context->ptr = (stream_sample_t *) inputs[context->stream_in_number];
}
- /* Queue tasks */
- for (entry = info->task_list; entry != 0; entry = entry->next)
+ for (task_group = 0; task_group < DISCRETE_MAX_TASK_GROUPS; task_group++)
{
- task_info *ti = (task_info *)malloc(sizeof(task_info));
- discrete_task *task = (discrete_task *) entry->ptr;
-
- /* Fire task */
- ti->task = task;
- ti->samples = samples;
- osd_work_item_queue(info->queue, task_callback, (void *) ti, WORK_ITEM_FLAG_AUTO_RELEASE);
- }
+ /* Queue tasks */
+ for (entry = info->task_list; entry != 0; entry = entry->next)
+ {
+ discrete_task *task = (discrete_task *) entry->ptr;
- /* and wait for them */
- osd_work_queue_wait(info->queue, osd_ticks_per_second()*10);
+ if (task->task_group == task_group)
+ {
+ task_info *ti = (task_info *)malloc(sizeof(task_info));
- /* Now we must do samples iterations of the node list, one output for each step */
- update_main_nodes(info, samples);
+ /* Fire task */
+ ti->task = task;
+ ti->samples = samples;
+ osd_work_item_queue(info->queue, task_callback, (void *) ti, WORK_ITEM_FLAG_AUTO_RELEASE);
+ }
+ }
+ /* and wait for them */
+ osd_work_queue_wait(info->queue, osd_ticks_per_second()*10);
+ }
if (DISCRETE_PROFILING)
{
@@ -793,23 +762,38 @@ static STREAM_UPDATE( discrete_stream_update )
*************************************/
-static void init_nodes(discrete_info *info, linked_list_entry *block_list, const device_config *device)
+static void init_nodes(discrete_info *info, const linked_list_entry *block_list, const device_config *device)
{
- linked_list_entry **task_node_list_ptr = NULL;
- linked_list_entry *entry;
+ const linked_list_entry *entry;
linked_list_entry *task_node_list = NULL;
discrete_task *task = NULL;
/* list tail pointers */
- linked_list_entry **main_list_ptr = &info->main_list;
+ linked_list_entry **task_node_list_ptr = NULL;
linked_list_entry **node_list_ptr = &info->node_list;
linked_list_entry **task_list_ptr = &info->task_list;
linked_list_entry **output_list_ptr = &info->output_list;
linked_list_entry **input_list_ptr = &info->input_list;
+ int has_tasks = 0;
+ /* check whether we have tasks ... */
+ for (entry = block_list; entry != NULL; entry = entry->next)
+ {
+ const discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
+ if (block->type == DSO_TASK_START)
+ has_tasks = 1;
+ }
+
+ if (!has_tasks)
+ {
+ /* set up a main task */
+ task_node_list = NULL;
+ task_node_list_ptr = &task_node_list;
+ }
+
/* loop over all nodes */
for (entry = block_list; entry != NULL; entry = entry->next)
{
- discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
+ const discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
node_description *node = auto_alloc_clear(info->device->machine, node_description);
int modulenum;
@@ -864,6 +848,8 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
case DSO_TASK_START:
if (task_node_list_ptr != NULL)
fatalerror("init_nodes() - Nested DISCRETE_START_TASK.");
+ task = auto_alloc_clear(info->device->machine, discrete_task);
+ node->context = task;
task_node_list = NULL;
task_node_list_ptr = &task_node_list;
break;
@@ -871,10 +857,9 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
case DSO_TASK_END:
if (task_node_list_ptr == NULL)
fatalerror("init_nodes() - NO DISCRETE_START_TASK.");
- task = auto_alloc_clear(info->device->machine, discrete_task);
task->numbuffered = 0;
task->list = task_node_list;
- task->task_group = 99; /* will be set later */
+ task->task_group = -1; /* will be set later */
task->source_list = NULL;
linked_list_tail_add(info, &task_list_ptr, task);
node->context = task;
@@ -914,7 +899,7 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
{
/* do we belong to a task? */
if (task_node_list_ptr == NULL)
- linked_list_tail_add(info, &main_list_ptr, node);
+ fatalerror("init_nodes() - found node outside of task.");
else
linked_list_tail_add(info, &task_node_list_ptr, node);
}
@@ -929,6 +914,19 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
state_save_register_device_item_array(device, node->block->node, node->output);
}
+ if (!has_tasks)
+ {
+ /* make sure we have one simple task
+ * No need to create a node since there are no dependencies.
+ */
+ task = auto_alloc_clear(info->device->machine, discrete_task);
+ task->numbuffered = 0;
+ task->list = task_node_list;
+ task->task_group = 0;
+ task->source_list = NULL;
+ linked_list_tail_add(info, &task_list_ptr, task);
+ }
+
/* if no outputs, give an error */
if (linked_list_count(info->output_list) == 0)
fatalerror("init_nodes() - Couldn't find an output node");
@@ -941,10 +939,10 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
*
*************************************/
-static void find_input_nodes(discrete_info *info)
+static void find_input_nodes(const discrete_info *info)
{
+ const linked_list_entry *entry;
int inputnum;
- linked_list_entry *entry;
/* loop over all nodes */
for (entry = info->node_list; entry != NULL; entry = entry->next)
@@ -960,7 +958,7 @@ static void find_input_nodes(discrete_info *info)
/* if this input is node-based, find the node in the indexed list */
if IS_VALUE_A_NODE(inputnode)
{
- node_description *node_ref = info->indexed_node[NODE_INDEX(inputnode)];
+ const node_description *node_ref = info->indexed_node[NODE_INDEX(inputnode)];
if (!node_ref)
fatalerror("discrete_start - NODE_%02d referenced a non existent node NODE_%02d", NODE_BLOCKINDEX(node), NODE_INDEX(inputnode));
@@ -987,7 +985,7 @@ static void find_input_nodes(discrete_info *info)
}
for (inputnum = node->active_inputs; inputnum < DISCRETE_MAX_INPUTS; inputnum++)
{
- //FIXME: Check that no nodes follow !
+ /* FIXME: Check that no nodes follow ! */
node->input[inputnum] = &(block->initial[inputnum]);
}
}