std::exception_ptr TaskSchedulerTBB::thread_loop(size_t threadIndex) { /* allocate thread structure */ std::unique_ptr<Thread> mthread(new Thread(threadIndex,this)); // too large for stack allocation Thread& thread = *mthread; threadLocal[threadIndex] = &thread; Thread* oldThread = swapThread(&thread); /* main thread loop */ while (anyTasksRunning) { steal_loop(thread, [&] () { return anyTasksRunning > 0; }, [&] () { atomic_add(&anyTasksRunning,+1); while (thread.tasks.execute_local(thread,nullptr)); atomic_add(&anyTasksRunning,-1); }); } threadLocal[threadIndex] = nullptr; swapThread(oldThread); /* remember exception to throw */ std::exception_ptr except = nullptr; if (cancellingException != nullptr) except = cancellingException; /* wait for all threads to terminate */ atomic_add(&threadCounter,-1); while (threadCounter > 0) yield(); return except; }
std::exception_ptr TaskScheduler::thread_loop(size_t threadIndex) { /* allocate thread structure */ std::unique_ptr<Thread> mthread(new Thread(threadIndex,this)); // too large for stack allocation Thread& thread = *mthread; threadLocal[threadIndex].store(&thread); Thread* oldThread = swapThread(&thread); /* main thread loop */ while (anyTasksRunning) { steal_loop(thread, [&] () { return anyTasksRunning > 0; }, [&] () { anyTasksRunning++; while (thread.tasks.execute_local_internal(thread,nullptr)); anyTasksRunning--; }); } threadLocal[threadIndex].store(nullptr); swapThread(oldThread); /* remember exception to throw */ std::exception_ptr except = nullptr; if (cancellingException != nullptr) except = cancellingException; /* wait for all threads to terminate */ threadCounter--; #if defined(__WIN32__) size_t loopIndex = 1; #endif #define LOOP_YIELD_THRESHOLD (4096) while (threadCounter > 0) { #if defined(__WIN32__) if ((loopIndex % LOOP_YIELD_THRESHOLD) == 0) yield(); else _mm_pause(); loopIndex++; #else yield(); #endif } return except; }
/* fog処理する */ void igs::fog::convert( void *in // no margin , void *out // no margin , double *buffer // no margin , const int height, const int width, const int channels, const int bits , const int number_of_thread // 1 ... INT_MAX , const double radius // 25.0(0 ... 100(DOUBLE_MAX)) , const double curve // 1.00(0.01 ... 100) , const int polygon_number // 2(2 ... 16(INT_MAX)) , const double degree // 0(0 ... DOUBLE_MAX) , const double power // 1.00(-2.00 ... 2.00) , const double threshold_min // 0.00(0.00 ... 1.01) , const double threshold_max // 0.00(0.00 ... 1.01) , const bool alpha_rendering_sw // false(true,false) ) { if ((igs::image::rgba::siz != channels) && (igs::image::rgb::siz != channels) && (1 != channels) /* grayscale */ ) { throw std::domain_error("Bad channels,Not rgba/rgb/grayscale"); } if (std::numeric_limits<unsigned char>::digits == bits) { if (0 != buffer) { rgb_to_lightness_image_( static_cast<const unsigned char *>(in), height, width, channels, buffer); } multi_thread_<unsigned char *> mthread( static_cast<unsigned char *>(in), static_cast<unsigned char *>(out), buffer, height, width, channels, number_of_thread, radius, curve, polygon_number, degree, power, threshold_min, threshold_max, alpha_rendering_sw); mthread.run(); mthread.clear(); } else if (std::numeric_limits<unsigned short>::digits == bits) { if (0 != buffer) { rgb_to_lightness_image_( static_cast<const unsigned short *>(in), height, width, channels, buffer); } multi_thread_<unsigned short *> mthread( static_cast<unsigned short *>(in), static_cast<unsigned short *>(out), buffer, height, width, channels, number_of_thread, radius, curve, polygon_number, degree, power, threshold_min, threshold_max, alpha_rendering_sw); mthread.run(); mthread.clear(); } else { throw std::domain_error("Bad bits,Not uchar/ushort"); } }