Revision: 43080
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43080
Author:   jbakker
Date:     2012-01-02 16:24:30 +0000 (Mon, 02 Jan 2012)
Log Message:
-----------
Tile branch

implemented the thread queue pattern for work scheduling.
This is stable and has the possibility to do OpenCL threading in the future.
This threading model is selected to be the default one.

Still needed to be tested by other users to make sure it is the right direction.

Jeroen Bakker
 - At Mind - 

Modified Paths:
--------------
    branches/tile/source/blender/compositor/COM_defines.h
    branches/tile/source/blender/compositor/intern/COM_WorkScheduler.cpp
    branches/tile/source/blender/compositor/intern/COM_WorkScheduler.h

Modified: branches/tile/source/blender/compositor/COM_defines.h
===================================================================
--- branches/tile/source/blender/compositor/COM_defines.h       2012-01-02 
16:20:18 UTC (rev 43079)
+++ branches/tile/source/blender/compositor/COM_defines.h       2012-01-02 
16:24:30 UTC (rev 43080)
@@ -76,11 +76,16 @@
 #define COM_TM_WORKER 3
 
 /**
+  * COM_TM_QUEUE is a multithreaded model, which uses the BLI_thread_queue 
pattern. it has the same speed as PTHREAD. Currently this needs to 
+  * be expended with OpenCL. After that it might become the default threading 
model.
+  */
+#define COM_TM_QUEUE 4
+
+/**
   * COM_CURRENT_THREADING_MODEL can be one of the above, COM_PTHREAD is 
currently default.
   */
-#define COM_CURRENT_THREADING_MODEL COM_TM_WORKER
+#define COM_CURRENT_THREADING_MODEL COM_TM_QUEUE
 
-
 // chunk order
 /**
   * @brief The order of chunks to be scheduled

Modified: branches/tile/source/blender/compositor/intern/COM_WorkScheduler.cpp
===================================================================
--- branches/tile/source/blender/compositor/intern/COM_WorkScheduler.cpp        
2012-01-02 16:20:18 UTC (rev 43079)
+++ branches/tile/source/blender/compositor/intern/COM_WorkScheduler.cpp        
2012-01-02 16:24:30 UTC (rev 43080)
@@ -33,6 +33,7 @@
 #if COM_CURRENT_THREADING_MODEL == COM_TM_PTHREAD
 #elif COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD
 #elif COM_CURRENT_THREADING_MODEL == COM_TM_WORKER
+#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
 #else
 #error WorkScheduler: No threading model configured
 #endif
@@ -64,6 +65,12 @@
 ThreadedWorker *cpuworker;
 #endif
 
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+/// @brief list of all thread for every CPUDevice in cpudevices a thread exists
+static ListBase cputhreads;
+static ThreadQueue * cpuqueue;
+#endif
+
 #if COM_OPENCL_ENABLED
 static cl_context context;
 static cl_program program;
@@ -78,6 +85,28 @@
        return NULL;
 }
 #endif
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+void* WorkScheduler::thread_execute_cpu(void* data) {
+       bool continueLoop = true;
+       Device* device = (Device*)data;
+       while (continueLoop) {
+               WorkPackage* work = 
(WorkPackage*)BLI_thread_queue_pop(cpuqueue);
+               if (work) {
+                  device->execute(work);
+                  delete work;
+               }
+               PIL_sleep_ms(10);
+
+               if (WorkScheduler::isStopping()) {
+                       continueLoop = false;
+               }
+       }
+       return NULL;
+}
+
+bool WorkScheduler::isStopping() {return state == COM_WSS_STOPPING;}
+
+#endif
 #if COM_CURRENT_THREADING_MODEL == COM_TM_PTHREAD
 void* WorkScheduler::thread_execute_cpu(void* data) {
        bool continueLoop = true;
@@ -88,6 +117,7 @@
                   device->execute(work);
                   delete work;
                }
+               PIL_sleep_ms(100);
 
                if (WorkScheduler::isStopping()) {
                        continueLoop = false;
@@ -105,6 +135,7 @@
                   device->execute(work);
                   delete work;
                }
+               PIL_sleep_ms(100);
 
                if (WorkScheduler::isStopping()) {
                        continueLoop = false;
@@ -160,18 +191,22 @@
        delete package;
 #elif COM_CURRENT_THREADING_MODEL == COM_TM_WORKER
        BLI_insert_work(cpuworker, package);
+#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+       BLI_thread_queue_push(cpuqueue, package);
 #endif
 }
 
 void WorkScheduler::start(CompositorContext &context) {
 #if COM_CURRENT_THREADING_MODEL == COM_TM_PTHREAD
        unsigned int index;
+       cpuwork.clear();
        BLI_init_threads(&cputhreads, thread_execute_cpu, cpudevices.size());
        for (index = 0 ; index < cpudevices.size() ; index ++) {
                Device* device = cpudevices[index];
                BLI_insert_thread(&cputhreads, device);
        }
        if (context.getHasActiveOpenCLDevices()) {
+               gpuwork.clear();
                BLI_init_threads(&gputhreads, thread_execute_gpu, 
gpudevices.size());
                for (index = 0 ; index < gpudevices.size() ; index ++) {
                        Device* device = gpudevices[index];
@@ -185,18 +220,56 @@
 #if COM_CURRENT_THREADING_MODEL == COM_TM_WORKER
        cpuworker = BLI_create_worker(worker_execute_cpu, cpudevices.size(), 0);
 #endif
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+       unsigned int index;
+       cpuqueue = BLI_thread_queue_init();
+       BLI_thread_queue_nowait(cpuqueue);
+       BLI_init_threads(&cputhreads, thread_execute_cpu, cpudevices.size());
+       for (index = 0 ; index < cpudevices.size() ; index ++) {
+               Device* device = cpudevices[index];
+               BLI_insert_thread(&cputhreads, device);
+       }
+#endif
+       
        state = COM_WSS_STARTED;
 }
 
 void WorkScheduler::stop() {
        state = COM_WSS_STOPPING;
 #if COM_CURRENT_THREADING_MODEL == COM_TM_PTHREAD
+       BLI_mutex_lock(&cpumutex);
+       while (cpuwork.size()>0) {
+          WorkPackage * result = cpuwork.front();
+          cpuwork.pop_front();
+          delete result;
+       }
+       BLI_mutex_unlock(&cpumutex);
        BLI_end_threads(&cputhreads);
+
+       BLI_mutex_lock(&gpumutex);
+       while (gpuwork.size()>0) {
+          WorkPackage * result = gpuwork.front();
+          gpuwork.pop_front();
+          delete result;
+       }
+       BLI_mutex_unlock(&gpumutex);
        BLI_end_threads(&gputhreads);
 #endif
 #if COM_CURRENT_THREADING_MODEL == COM_TM_WORKER
        BLI_destroy_worker(cpuworker);
 #endif
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+       BLI_mutex_lock(&cpumutex);
+       while (cpuwork.size()>0) {
+          WorkPackage * result = cpuwork.front();
+          cpuwork.pop_front();
+          delete result;
+       }
+       BLI_mutex_unlock(&cpumutex);
+       BLI_end_threads(&cputhreads);
+       
+       BLI_thread_queue_free(cpuqueue);
+#endif
        state = COM_WSS_STOPPED;
 }
 
@@ -235,8 +308,15 @@
                device->initialize();
                cpudevices.push_back(device);
        }
+#elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+       int numberOfCPUThreads = BLI_system_thread_count();
+
+       for (int index = 0 ; index < numberOfCPUThreads ; index ++) {
+               CPUDevice *device = new CPUDevice();
+               device->initialize();
+               cpudevices.push_back(device);
+       }
 #endif
-
 #if COM_OPENCL_ENABLED
        context = NULL;
        program = NULL;

Modified: branches/tile/source/blender/compositor/intern/COM_WorkScheduler.h
===================================================================
--- branches/tile/source/blender/compositor/intern/COM_WorkScheduler.h  
2012-01-02 16:20:18 UTC (rev 43079)
+++ branches/tile/source/blender/compositor/intern/COM_WorkScheduler.h  
2012-01-02 16:24:30 UTC (rev 43080)
@@ -68,7 +68,18 @@
          */
        static void* thread_execute_gpu(void* data);
 #endif
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+       /**
+         * @brief are we being stopped.
+         */
+       static bool isStopping();
 
+       /**
+         * @brief main thread loop for cpudevices
+         * inside this loop new work is queried and being executed
+         */
+       static void* thread_execute_cpu(void* data);
+#endif 
 public:
        /**
          * @brief schedule a chunk of a group to be calculated.

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to