From e0d0a314e505d32331744f422b0016ab00430f3f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 7 Jan 2016 16:35:32 +0100 Subject: [PATCH] Revert "vector_t to std::vector in discrete (nw)" This reverts commit ccf38aa73cc02a0e7e0f1fa44d281a44c502212c. --- src/devices/sound/discrete.cpp | 184 +++++++++++++++++---------------- src/devices/sound/discrete.h | 99 ++++++++++++++++-- 2 files changed, 187 insertions(+), 96 deletions(-) diff --git a/src/devices/sound/discrete.cpp b/src/devices/sound/discrete.cpp index 10e62a96075..ad7e8d1875a 100644 --- a/src/devices/sound/discrete.cpp +++ b/src/devices/sound/discrete.cpp @@ -39,6 +39,9 @@ #include "sound/wavwrite.h" #include "discrete.h" +/* for_each collides with c++ standard libraries - include it here */ +#define for_each(_T, _e, _l) for (_T _e = (_l)->begin_ptr() ; _e <= (_l)->end_ptr(); _e++) + // device type definition const device_type DISCRETE = &device_creator; @@ -117,7 +120,7 @@ public: node_step_list_t step_list; /* list of source nodes */ - std::vector source_list; /* discrete_source_node */ + vector_t source_list; /* discrete_source_node */ int task_group; @@ -137,7 +140,7 @@ protected: void check(discrete_task *dest_task); void prepare_for_queue(int samples); - std::vector m_buffers; + vector_t m_buffers; discrete_device & m_device; private: @@ -176,26 +179,26 @@ private: inline void discrete_task::step_nodes(void) { - for(input_buffer sn : source_list) + for_each(input_buffer *, sn, &source_list) { - sn.buffer = *sn.ptr++; + sn->buffer = *sn->ptr++; } if (EXPECTED(!m_device.profiling())) { - for(discrete_step_interface * entry : step_list) + for_each(discrete_step_interface **, entry, &step_list) { /* Now step the node */ - entry->step(); + (*entry)->step(); } } else { osd_ticks_t last = get_profile_ticks(); - for(discrete_step_interface * entry : step_list) + for_each(discrete_step_interface **, entry, &step_list) { - discrete_step_interface *node = entry; + discrete_step_interface *node = *entry; node->run_time -= last; node->step(); @@ -205,8 +208,8 @@ inline void discrete_task::step_nodes(void) } /* buffer the outputs */ - for(output_buffer outbuf : m_buffers) - *(outbuf.ptr++) = *outbuf.source; + for_each(output_buffer *, outbuf, &m_buffers) + *(outbuf->ptr++) = *outbuf->source; } void *discrete_task::task_callback(void *param, int threadid) @@ -214,14 +217,14 @@ void *discrete_task::task_callback(void *param, int threadid) task_list_t *list = (task_list_t *) param; do { - for(discrete_task * task : *list) + for_each(discrete_task **, task, list) { /* try to lock */ - if (task->lock_threadid(threadid)) + if ((*task)->lock_threadid(threadid)) { - if (!task->process()) + if (!(*task)->process()) return nullptr; - task->unlock(); + (*task)->unlock(); } } } while (1); @@ -234,11 +237,11 @@ bool discrete_task::process(void) int samples = MIN(m_samples, MAX_SAMPLES_PER_TASK_SLICE); /* check dependencies */ - for(input_buffer sn : source_list) + for_each(input_buffer *, sn, &source_list) { int avail; - avail = sn.linked_outbuf->ptr - sn.ptr; + avail = sn->linked_outbuf->ptr - sn->ptr; assert_always(avail >= 0, "task_callback: available samples are negative"); if (avail < samples) samples = avail; @@ -264,13 +267,13 @@ void discrete_task::prepare_for_queue(int samples) { m_samples = samples; /* set up task buffers */ - for(output_buffer ob : m_buffers) - ob.ptr = ob.node_buf; + for_each(output_buffer *, ob, &m_buffers) + ob->ptr = ob->node_buf; /* initialize sources */ - for(input_buffer sn : source_list) + for_each(input_buffer *, sn, &source_list) { - sn.ptr = sn.linked_outbuf->node_buf; + sn->ptr = sn->linked_outbuf->node_buf; } } @@ -281,13 +284,13 @@ void discrete_task::check(discrete_task *dest_task) /* Determine, which nodes in the task are referenced by nodes in dest_task * and add them to the list of nodes to be buffered for further processing */ - for(discrete_step_interface * node_entry : step_list) + for_each(discrete_step_interface **, node_entry, &step_list) { - discrete_base_node *task_node = node_entry->self; + discrete_base_node *task_node = (*node_entry)->self; - for(discrete_step_interface *step_entry : dest_task->step_list) + for_each(discrete_step_interface **, step_entry, &dest_task->step_list) { - discrete_base_node *dest_node = step_entry->self; + discrete_base_node *dest_node = (*step_entry)->self; /* loop over all active inputs */ for (inputnum = 0; inputnum < dest_node->active_inputs(); inputnum++) @@ -302,7 +305,7 @@ void discrete_task::check(discrete_task *dest_task) int i, found = -1; output_buffer *pbuf = nullptr; - for (i = 0; i < m_buffers.size(); i++) + for (i = 0; i < m_buffers.count(); i++) // if (m_buffers[i].node->block_node() == inputnode_num) if (m_buffers[i].node_num == inputnode_num) { @@ -321,9 +324,8 @@ void discrete_task::check(discrete_task *dest_task) buf.source = dest_node->m_input[inputnum]; buf.node_num = inputnode_num; //buf.node = device->discrete_find_node(inputnode); - m_buffers.size(); - m_buffers.push_back(buf); - pbuf = &m_buffers.back(); + m_buffers.count(); + pbuf = m_buffers.add(buf); } m_device.discrete_log("dso_task_start - buffering %d(%d) in task %p group %d referenced by %d group %d", NODE_INDEX(inputnode_num), NODE_CHILD_NODE_NUM(inputnode_num), this, task_group, dest_node->index(), dest_task->task_group); @@ -334,10 +336,10 @@ void discrete_task::check(discrete_task *dest_task) source.linked_outbuf = pbuf; source.buffer = 0.0; /* please compiler */ source.ptr = nullptr; - dest_task->source_list.push_back(source); + dest_task->source_list.add(source); /* point the input to a buffered location */ - dest_node->m_input[inputnum] = &dest_task->source_list[dest_task->source_list.size()-1].buffer; // was copied! &source.buffer; + dest_node->m_input[inputnum] = &dest_task->source_list[dest_task->source_list.count()-1].buffer; // was copied! &source.buffer; } } @@ -512,7 +514,7 @@ void discrete_device::discrete_build_list(const discrete_block *intf, sound_bloc if (intf[node_count].type == DSS_NULL) fatalerror("discrete_build_list: DISCRETE_REPLACE at end of node_list\n"); - for (int i=0; i < block_list.size(); i++) + for (int i=0; i < block_list.count(); i++) { const discrete_block *block = block_list[i]; @@ -532,9 +534,9 @@ void discrete_device::discrete_build_list(const discrete_block *intf, sound_bloc } else if (intf[node_count].type == DSO_DELETE) { - std::vector deletethem; + vector_t deletethem; - for (int i=0; inode <= intf[node_count].input_node[1])) { discrete_log("discrete_build_list() - DISCRETE_DELETE deleted NODE_%02d", NODE_INDEX(block->node) ); - deletethem.push_back(i); + deletethem.add(i); } } - for(int i : deletethem) - block_list.erase(block_list.begin() + i); + for_each (int *, i, &deletethem) + block_list.remove(*i); } else { discrete_log("discrete_build_list() - adding node %d\n", node_count); - block_list.push_back(&intf[node_count]); + block_list.add(&intf[node_count]); } node_count++; @@ -567,7 +569,7 @@ void discrete_device::discrete_sanity_check(const sound_block_list_t &block_list int node_count = 0; discrete_log("discrete_start() - Doing node list sanity check"); - for (int i=0; i < block_list.size(); i++) + for (int i=0; i < block_list.count(); i++) { const discrete_block *block = block_list[i]; @@ -614,10 +616,10 @@ static UINT64 list_run_time(const node_list_t &list) { UINT64 total = 0; - for(discrete_base_node * node : list) + for_each(discrete_base_node **, node, &list) { discrete_step_interface *step; - if (node->interface(step)) + if ((*node)->interface(step)) total += step->run_time; } return total; @@ -627,9 +629,9 @@ static UINT64 step_list_run_time(const node_step_list_t &list) { UINT64 total = 0; - for (discrete_step_interface * node : list) + for_each(discrete_step_interface **, node, &list) { - total += node->run_time; + total += (*node)->run_time; } return total; } @@ -643,25 +645,25 @@ void discrete_device::display_profiling(void) /* calculate total time */ total = list_run_time(m_node_list); - count = m_node_list.size(); + count = m_node_list.count(); /* print statistics */ printf("Total Samples : %16" I64FMT "d\n", m_total_samples); tresh = total / count; printf("Threshold (mean): %16" I64FMT "d\n", tresh / m_total_samples ); - for(discrete_base_node * node : m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { discrete_step_interface *step; - if (node->interface(step)) + if ((*node)->interface(step)) if (step->run_time > tresh) - printf("%3d: %20s %8.2f %10.2f\n", node->index(), node->module_name(), (double) step->run_time / (double) total * 100.0, ((double) step->run_time) / (double) m_total_samples); + printf("%3d: %20s %8.2f %10.2f\n", (*node)->index(), (*node)->module_name(), (double) step->run_time / (double) total * 100.0, ((double) step->run_time) / (double) m_total_samples); } /* Task information */ - for(discrete_task * task : task_list) + for_each(discrete_task **, task, &task_list) { - tt = step_list_run_time(task->step_list); + tt = step_list_run_time((*task)->step_list); - printf("Task(%d): %8.2f %15.2f\n", task->task_group, tt / (double) total * 100.0, tt / (double) m_total_samples); + printf("Task(%d): %8.2f %15.2f\n", (*task)->task_group, tt / (double) total * 100.0, tt / (double) m_total_samples); } printf("Average samples/double->update: %8.2f\n", (double) m_total_samples / (double) m_total_stream_updates); @@ -684,7 +686,7 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) /* check whether we have tasks ... */ if (USE_DISCRETE_TASKS) { - for (int i = 0; i < block_list.size(); i++) + for (int i = 0; i < block_list.count(); i++) { if (block_list[i]->type == DSO_TASK_START) has_tasks = 1; @@ -697,11 +699,11 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) * No need to create a node since there are no dependencies. */ task = auto_alloc_clear(machine(), discrete_task(*this)); - task_list.push_back(task); + task_list.add(task); } /* loop over all nodes */ - for (int i = 0; i < block_list.size(); i++) + for (int i = 0; i < block_list.count(); i++) { const discrete_block *block = block_list[i]; @@ -736,7 +738,7 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) if (task->task_group < 0 || task->task_group >= DISCRETE_MAX_TASK_GROUPS) fatalerror("discrete_dso_task: illegal task_group %d\n", task->task_group); //printf("task group %d\n", task->task_group); - task_list.push_back(task); + task_list.add(task); } break; @@ -762,7 +764,7 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) } /* add to node list */ - m_node_list.push_back(node); + m_node_list.add(node); /* our running order just follows the order specified */ /* does the node step ? */ @@ -773,7 +775,7 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) if (task == nullptr) fatalerror("init_nodes() - found node outside of task: %s\n", node->module_name() ); else - task->step_list.push_back(step); + task->step_list.add(step); } if (USE_DISCRETE_TASKS && block->type == DSO_TASK_END) @@ -802,11 +804,11 @@ int discrete_device::same_module_index(const discrete_base_node &node) { int index = 0; - for(discrete_base_node *n : m_node_list) + for_each(discrete_base_node **, n, &m_node_list) { - if (n == &node) + if (*n == &node) return index; - if (n->module_type() == node.module_type()) + if ((*n)->module_type() == node.module_type()) index++; } return -1; @@ -908,27 +910,27 @@ void discrete_device::device_start() init_nodes(block_list); /* now go back and find pointers to all input nodes */ - for(discrete_base_node *node :m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { - node->resolve_input_nodes(); + (*node)->resolve_input_nodes(); } /* allocate a queue */ m_queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ); /* Process nodes which have a start func */ - for(discrete_base_node * node :m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { - node->start(); + (*node)->start(); } /* Now set up tasks */ - for(discrete_task *task : task_list) + for_each(discrete_task **, task, &task_list) { - for(discrete_task *dest_task :task_list) + for_each(discrete_task **, dest_task, &task_list) { - if (task->task_group > dest_task->task_group) - dest_task->check(task); + if ((*task)->task_group > (*dest_task)->task_group) + (*dest_task)->check((*task)); } } } @@ -947,9 +949,9 @@ void discrete_device::device_stop() /* Process nodes which have a stop func */ - for(discrete_base_node *node : m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { - node->stop(); + (*node)->stop(); } if (DISCRETE_DEBUGLOG) @@ -974,31 +976,31 @@ void discrete_sound_device::device_start() discrete_device::device_start(); /* look for input stream nodes */ - for(discrete_base_node *node : m_node_list) + for_each(discrete_base_node **, node, &m_node_list) { /* if we are an stream input node, track that */ - discrete_dss_input_stream_node *input_stream = dynamic_cast(node); + discrete_dss_input_stream_node *input_stream = dynamic_cast(*node); if (input_stream != nullptr) { - m_input_stream_list.push_back(input_stream); + m_input_stream_list.add(input_stream); } /* if this is an output interface, add it the output list */ discrete_sound_output_interface *out; - if (node->interface(out)) - m_output_list.push_back(out); + if ((*node)->interface(out)) + m_output_list.add(out); } /* if no outputs, give an error */ - if (m_output_list.size() == 0) + if (m_output_list.count() == 0) fatalerror("init_nodes() - Couldn't find an output node\n"); /* initialize the stream(s) */ - m_stream = machine().sound().stream_alloc(*this,m_input_stream_list.size(), m_output_list.size(), m_sample_rate); + m_stream = machine().sound().stream_alloc(*this,m_input_stream_list.count(), m_output_list.count(), m_sample_rate); /* Finalize stream_input_nodes */ - for(discrete_dss_input_stream_node *node : m_input_stream_list) + for_each(discrete_dss_input_stream_node **, node, &m_input_stream_list) { - node->stream_start(); + (*node)->stream_start(); } @@ -1013,12 +1015,12 @@ void discrete_device::device_reset() update_to_current_time(); /* loop over all nodes */ - for(discrete_base_node *node : m_node_list) + for_each (discrete_base_node **, node, &m_node_list) { /* Fimxe : node_level */ - node->m_output[0] = 0; + (*node)->m_output[0] = 0; - node->reset(); + (*node)->reset(); } } @@ -1042,17 +1044,19 @@ void discrete_device::process(int samples) return; /* Setup tasks */ - for(discrete_task *task : task_list) + for_each(discrete_task **, task, &task_list) { /* unlock the thread */ - task->unlock(); + (*task)->unlock(); - task->prepare_for_queue(samples); + (*task)->prepare_for_queue(samples); } - /* Fire a work item for each task */ - osd_work_item_queue(m_queue, discrete_task::task_callback, (void *) &task_list, WORK_ITEM_FLAG_AUTO_RELEASE); - + for_each(discrete_task **, task, &task_list) + { + /* Fire a work item for each task */ + osd_work_item_queue(m_queue, discrete_task::task_callback, (void *) &task_list, WORK_ITEM_FLAG_AUTO_RELEASE); + } osd_work_queue_wait(m_queue, osd_ticks_per_second()*10); if (m_profiling) @@ -1075,16 +1079,16 @@ void discrete_sound_device::sound_stream_update(sound_stream &stream, stream_sam return; /* Setup any output streams */ - for(discrete_sound_output_interface *node : m_output_list) + for_each(discrete_sound_output_interface **, node, &m_output_list) { - node->set_output_ptr(outputs[outputnum]); + (*node)->set_output_ptr(outputs[outputnum]); outputnum++; } /* Setup any input streams */ - for(discrete_dss_input_stream_node * node : m_input_stream_list) + for_each(discrete_dss_input_stream_node **, node, &m_input_stream_list) { - node->m_ptr = (stream_sample_t *) inputs[node->m_stream_in_number]; + (*node)->m_ptr = (stream_sample_t *) inputs[(*node)->m_stream_in_number]; } /* just process it */ diff --git a/src/devices/sound/discrete.h b/src/devices/sound/discrete.h index 83883c9d81c..8a0ccfb8c6d 100644 --- a/src/devices/sound/discrete.h +++ b/src/devices/sound/discrete.h @@ -3740,6 +3740,93 @@ enum #define DISC_RC_INTEGRATE_TYPE2 0x01 #define DISC_RC_INTEGRATE_TYPE3 0x02 +/************************************* + * + * Classes and structs to handle + * linked lists. + * + *************************************/ + +/* + * add and delete may be slow - the focus is on access! + */ + + // TODO: replace with vector from utils +template struct vector_t +{ +public: + vector_t(int initial) { + m_count = 0; + m_allocated = initial; + m_arr = global_alloc_array_clear(_ElementType, m_allocated); + } + vector_t() { + m_count = 0; + m_allocated = 16; + m_arr = global_alloc_array_clear(_ElementType, m_allocated); + } + ~vector_t() { + global_free_array(m_arr); + } + _ElementType& operator [] (unsigned int index) const // get array item + { + return m_arr[index]; + } + + vector_t(const vector_t &a) // copy constructor + { + m_allocated = a.count(); + if (m_allocated < 16) + m_allocated = 16; + m_count = a.count(); + m_arr = global_alloc_array_clear(_ElementType, m_allocated); + for (int i=0; i < m_count; i++) + m_arr[i] = a[i]; + } + vector_t& operator = (const vector_t &a) // assignment operator + { + if (this == &a) return *this; + m_allocated = a.count(); + if (m_allocated < 16) + m_allocated = 16; + m_count = a.count(); + m_arr = global_alloc_array_clear(_ElementType, m_allocated); + for (int i=0; i < m_count; i++) + m_arr[i] = a[i]; + return *this; + } + + inline _ElementType* add(_ElementType object) + { + if (m_count >= m_allocated) + { + m_allocated *= 2; + auto newarr = global_alloc_array_clear(_ElementType, m_allocated); + for (int i=0; i < m_count; i++) + newarr[i] = m_arr[i]; + global_free_array(m_arr); + m_arr = newarr; + } + m_arr[m_count] = object; + m_count++; + return &m_arr[m_count-1]; + } + inline void remove(int index) + { + for (int i=index+1; i < m_count; i++) + m_arr[i-1] = m_arr[i]; + m_count--; + } + inline void clear(void) { m_count = 0; } + inline int count(void) const { return m_count; } + inline _ElementType *begin_ptr(void) const { return m_arr; } + inline _ElementType *end_ptr(void) const { return m_arr + (m_count - 1); } +private: + _ElementType *m_arr; + int m_count; + int m_allocated; +}; + /************************************* * * Node-specific struct types @@ -4098,9 +4185,9 @@ class discrete_task; class discrete_base_node; class discrete_dss_input_stream_node; class discrete_device; -using node_list_t = std::vector; -using istream_node_list_t = std::vector; -using task_list_t = std::vector; +typedef vector_t node_list_t; +typedef vector_t istream_node_list_t; +typedef vector_t task_list_t; /************************************* @@ -4129,7 +4216,7 @@ struct discrete_block const char * name; /* Node Name */ const char * mod_name; /* Module / class name */ }; -typedef std::vector sound_block_list_t; +typedef vector_t sound_block_list_t; /************************************* * @@ -4146,7 +4233,7 @@ public: osd_ticks_t run_time; discrete_base_node * self; }; -typedef std::vector node_step_list_t; +typedef vector_t node_step_list_t; class discrete_input_interface { @@ -4184,7 +4271,7 @@ public: //************************************************************************** class discrete_sound_output_interface; -typedef std::vector node_output_list_t; +typedef vector_t node_output_list_t; // ======================> discrete_device