diff options
author | 2009-10-03 21:45:09 +0000 | |
---|---|---|
committer | 2009-10-03 21:45:09 +0000 | |
commit | de55177d940d8dec493b3889a509c5d6ff1afe44 (patch) | |
tree | e2a8c17bb3a460725ffb182e3b0bf862abeae52d /src/emu/sound/discrete.c | |
parent | fa947ec474dd89cb3a1010fdc3349c4375f500be (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.c | 166 |
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]); } } |