Previous 199869 Revisions Next

r34208 Tuesday 6th January, 2015 at 01:56:24 UTC by Oliver Stöneberg
some small work_osd.c refactoring and lots of TODOs (nw)
[src/osd/modules/sync]work_osd.c

trunk/src/osd/modules/sync/work_osd.c
r242719r242720
5353
5454#define ENV_PROCESSORS               "OSDPROCESSORS"
5555
56// TODO: tests have shown, that 50000 appears to be the best value
5657#if defined(OSD_WINDOWS)
5758#define SPIN_LOOP_TIME          (osd_ticks_per_second() / 1000)
5859#else
r242719r242720
7475#define end_timing(v)           do { } while (0)
7576#endif
7677
78// TODO: move this in a common place
7779#if __GNUC__ && defined(__i386__) && !defined(__x86_64)
7880#undef YieldProcessor
7981#endif
r242719r242720
167169static void * worker_thread_entry(void *param);
168170static void worker_thread_process(osd_work_queue *queue, work_thread_info *thread);
169171static bool queue_has_list_items(osd_work_queue *queue);
172static void spin_on_queue(work_thread_info *thread, osd_work_queue *queue, osd_ticks_t timeout);
170173
171174
172175//============================================================
r242719r242720
204207   // on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else
205208   if (numprocs == 1)
206209      queue->threads = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0;
210   // TODO: chose either
207211#if defined(OSD_WINDOWS)
208212   // on an n-CPU system, create n threads for multi queues, and 1 thread for everything else
209213   else
r242719r242720
217221   if (osdworkqueuemaxthreads != NULL && sscanf(osdworkqueuemaxthreads, "%d", &threadnum) == 1 && queue->threads > threadnum)
218222      queue->threads = threadnum;
219223
224   // TODO: do we still have the scaling problems?
220225#if defined(OSD_WINDOWS)
221226   // multi-queues with high frequency items should top out at 4 for now
222227   // since we have scaling problems above that
r242719r242720
307312      // if we're a high frequency queue, spin until done
308313      if (queue->flags & WORK_QUEUE_FLAG_HIGH_FREQ && queue->items != 0)
309314      {
310         osd_ticks_t stopspin = osd_ticks() + timeout;
311
312         // spin until we're done
313         begin_timing(thread->spintime);
314
315#if defined(OSD_WINDOWS)
316         while (queue->items != 0 && osd_ticks() < stopspin)
317            osd_yield_processor();
318#else
319         do {
320            int spin = 10000;
321            while (--spin && queue->items != 0)
322               osd_yield_processor();
323         } while (queue->items != 0 && osd_ticks() < stopspin);
324#endif
325
326         end_timing(thread->spintime);
327
315         spin_on_queue(thread, queue, timeout);
328316         begin_timing(thread->waittime);
329317         return (queue->items == 0);
330318      }
r242719r242720
562550   // if we don't have an event, we need to spin (shouldn't ever really happen)
563551   if (item->event == NULL)
564552   {
553      // TODO: merge this with spin_on_queue()
554      // TODO: do we need to measure the spin time here as well? and how can we do it?
565555      osd_ticks_t stopspin = osd_ticks() + timeout;
566556#if defined(OSD_WINDOWS)
567557      while (!item->done && osd_ticks() < stopspin)
r242719r242720
684674      // process work items
685675      for ( ;; )
686676      {
687         osd_ticks_t stopspin;
688
689677         // process as much as we can
690678         worker_thread_process(queue, thread);
691679
692680         // if we're a high frequency queue, spin for a while before giving up
693681         if (queue->flags & WORK_QUEUE_FLAG_HIGH_FREQ && queue->list == NULL)
694682         {
695            // spin for a while looking for more work
696            begin_timing(thread->spintime);
697            stopspin = osd_ticks() + SPIN_LOOP_TIME;
698
699#if defined(OSD_WINDOWS)
700            while (queue->list == NULL && osd_ticks() < stopspin)
701               osd_yield_processor();
702#else
703            do {
704               int spin = 10000;
705               while (--spin && queue->list == NULL)
706                  osd_yield_processor();
707            } while (queue->list == NULL && osd_ticks() < stopspin);
708#endif
709
710            end_timing(thread->spintime);
683            spin_on_queue(thread, queue, SPIN_LOOP_TIME);
711684         }
712685
713686         // if nothing more, release the processor
r242719r242720
822795   osd_scalable_lock_release(queue->lock, lockslot);
823796   return has_list_items;
824797}
798
799void spin_on_queue(work_thread_info *thread, osd_work_queue *queue, osd_ticks_t timeout)
800{
801   osd_ticks_t stopspin = osd_ticks() + timeout;
802
803   begin_timing(thread->spintime);
804   
805   // TODO: chose either
806#if defined(OSD_WINDOWS)
807   while (queue->list == NULL && osd_ticks() < stopspin)
808      osd_yield_processor();
809#else
810   do {
811      int spin = 10000;
812      while (--spin && queue->list == NULL)
813         osd_yield_processor();
814   } while (queue->list == NULL && osd_ticks() < stopspin);
815#endif
816
817   end_timing(thread->spintime);
818}
No newline at end of file


Previous 199869 Revisions Next


© 1997-2024 The MAME Team