16 #ifndef INCLUDE_NN_NLIB_THREADING_THREAD_H_ 17 #define INCLUDE_NN_NLIB_THREADING_THREAD_H_ 20 #include "nn/nlib/Swap.h" 33 if (is_initialized_) {
52 return (detached != 0);
82 return is_initialized_ ? &attr_ :
nullptr;
87 if (!is_initialized_) {
91 is_initialized_ =
true;
94 mutable bool is_initialized_;
98 template<
class T1 = None,
class T2 = None,
class T3 = None,
class T4 = None,
class T5 = None>
111 static void Call(ArgType& ptr) { ptr->func(ptr); }
123 struct ThreadArg<None, None, None, None, None> {
125 typedef void ArgType;
126 typedef void (*Func)();
130 struct ThreadArg<T1, None, None, None, None> {
131 typedef ThreadArg<T1> ThisType;
133 typedef void (*Func)(ArgType& ptr);
134 NLIB_CEXPR ThreadArg() : func(nullptr), arg1() {}
135 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_) : func(func_), arg1(arg1_) {}
136 static void Call(ArgType& ptr) { ptr->func(ptr); }
143 template<
class T1,
class T2>
144 struct ThreadArg<T1, T2, None, None, None> {
145 typedef ThreadArg<T1, T2> ThisType;
146 typedef UniquePtr<ThisType> ArgType;
147 typedef void (*Func)(ArgType& ptr);
148 NLIB_CEXPR ThreadArg() : func(nullptr), arg1(), arg2() {}
149 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_) : func(func_), arg1(arg1_), arg2(arg2_) {}
150 static void Call(ArgType& ptr) { ptr->func(ptr); }
158 template<
class T1,
class T2,
class T3>
159 struct ThreadArg<T1, T2, T3, None, None> {
160 typedef ThreadArg<T1, T2, T3> ThisType;
161 typedef UniquePtr<ThisType> ArgType;
162 typedef void (*Func)(ArgType& ptr);
163 NLIB_CEXPR ThreadArg() : func(nullptr), arg1(), arg2(), arg3() {}
164 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_, T3 arg3_) :
169 static void Call(ArgType& ptr) { ptr->func(ptr); }
178 template<
class T1,
class T2,
class T3,
class T4>
179 struct ThreadArg<T1, T2, T3, T4, None> {
180 typedef ThreadArg<T1, T2, T3, T4> ThisType;
181 typedef UniquePtr<ThisType> ArgType;
182 typedef void (*Func)(ArgType& ptr);
183 NLIB_CEXPR ThreadArg() : func(nullptr), arg1(), arg2(), arg3(), arg4() {}
184 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_, T3 arg3_, T4 arg4_) :
190 static void Call(ArgType& ptr) { ptr->func(ptr); }
201 #pragma warning(push) 202 #pragma warning(disable : 4180) 212 typedef void (*ThreadFunc)(
void* arg);
217 #ifdef __cpp_rvalue_references 222 thread_id_ = rhs.thread_id_;
231 thread_id_ = rhs.thread_id_;
238 if (!thread_id_)
return ESRCH;
277 errno_t e = this->StartRaw(Thread::Exec, reinterpret_cast<void*>(func), settings);
281 errno_t e = this->StartRaw(Thread::Exec, reinterpret_cast<void*>(func));
284 template<
class ThArg>
286 if (!ptr)
return EINVAL;
287 errno_t e = this->StartRaw((ThreadFunc)Thread::Exec<ThArg>,
288 reinterpret_cast<void*>(ptr.get()), settings);
289 if (e == 0) ptr.release();
292 template<
class ThArg>
294 if (!ptr)
return EINVAL;
296 this->StartRaw((ThreadFunc)Thread::Exec<ThArg>, reinterpret_cast<void*>(ptr.get()));
297 if (e == 0) ptr.release();
302 static void Exec(
void* p) {
307 static void Exec(
void* p) {
312 #define NLIB_THFUNC_USESWAP_NO(tp) \ 313 typename EnableIf<!IsSame<None, typename RemoveCv<B>::type>::value && \ 314 (IsSame<FalseType, typename RemoveCv<B>::type>::value || \ 315 !IsSwappable<tp>::value), \ 317 #define NLIB_THFUNC_USESWAP_YES(tp) \ 318 typename EnableIf<!IsSame<None, typename RemoveCv<B>::type>::value && \ 319 IsSame<TrueType, typename RemoveCv<B>::type>::value && \ 320 IsSwappable<tp>::value, \ 324 struct ArgType :
public Conditional<IsArithmetic<T>::value || IsPointer<T>::value ||
325 IsMemberPointer<T>::value,
326 FalseType, TrueType> {};
330 typedef typename RemoveRef<FUNC>::type FUNC_;
332 Args0(NLIB_THFUNC_USESWAP_NO(FUNC_) func_, B) : func(func_) {}
334 Args0(NLIB_THFUNC_USESWAP_YES(FUNC_) func_, B) : func() {
336 swap(const_cast<FUNC&>(func_), func);
339 Args0(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
348 template<
class FUNC,
class T1>
349 struct Args1 :
public Args0<FUNC> {
350 typedef Args0<FUNC> BaseType;
351 typedef typename RemoveRef<T1>::type T1_;
353 Args1(
const FUNC& func_, NLIB_THFUNC_USESWAP_NO(T1) arg1_, B) :
354 BaseType(func_, typename IsSwappable<FUNC>::type()),
357 Args1(
const FUNC& func_, NLIB_THFUNC_USESWAP_YES(T1) arg1_, B) :
358 BaseType(func_, typename IsSwappable<FUNC>::type()),
361 swap(const_cast<T1&>(arg1_), arg1);
364 Args1(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
366 const T1& arg1_, B b) :
371 template<
class FUNC,
class T1,
class T2>
372 struct Args2 :
public Args1<FUNC, T1> {
373 typedef Args1<FUNC, T1> BaseType;
374 typedef typename RemoveRef<T2>::type T2_;
376 Args2(
const FUNC& func_,
const T1& arg1_, NLIB_THFUNC_USESWAP_NO(T2) arg2_, B) :
377 BaseType(func_, arg1_, typename ArgType<T1>::type()),
380 Args2(
const FUNC& func_,
const T1& arg1_, NLIB_THFUNC_USESWAP_YES(T2) arg2_, B) :
381 BaseType(func_, arg1_, typename ArgType<T1>::type()),
384 swap(const_cast<T2&>(arg2_), arg2);
387 Args2(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
389 const T1& arg1_,
const T2& arg2_, B b) :
390 BaseType(func_, arg1_, b),
394 template<
class FUNC,
class T1,
class T2,
class T3>
395 struct Args3 :
public Args2<FUNC, T1, T2> {
396 typedef Args2<FUNC, T1, T2> BaseType;
397 typedef typename RemoveRef<T3>::type T3_;
399 Args3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_, NLIB_THFUNC_USESWAP_NO(T3) arg3_,
401 BaseType(func_, arg1_, arg2_, typename ArgType<T2>::type()),
404 Args3(
const FUNC& func,
const T1& arg1_,
const T2& arg2_, NLIB_THFUNC_USESWAP_YES(T3) arg3_,
406 BaseType(func, arg1_, arg2_, typename ArgType<T2>::type()),
409 swap(const_cast<T3&>(arg3_), arg3);
412 Args3(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
414 const T1& arg1_,
const T2& arg2_,
const T3& arg3_, B b) :
415 BaseType(func_, arg1_, arg2_, b),
419 template<
class FUNC,
class T1,
class T2,
class T3,
class T4>
420 struct Args4 :
public Args3<FUNC, T1, T2, T3> {
421 typedef Args3<FUNC, T1, T2, T3> BaseType;
422 typedef typename RemoveRef<T4>::type T4_;
424 Args4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
425 NLIB_THFUNC_USESWAP_NO(T4) arg4_, B) :
426 BaseType(func_, arg1_, arg2_, arg3_, typename ArgType<T3>::type()),
429 Args4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
430 NLIB_THFUNC_USESWAP_YES(T4) arg4_, B) :
431 BaseType(func_, arg1_, arg2_, arg3_, typename ArgType<T3>::type()),
434 swap(const_cast<T4&>(arg4_), arg4);
437 Args4(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
439 const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_, B b) :
440 BaseType(func_, arg1_, arg2_, arg3_, b),
444 template<
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
445 struct Args5 :
public Args4<FUNC, T1, T2, T3, T4> {
446 typedef Args4<FUNC, T1, T2, T3, T4> BaseType;
447 typedef typename RemoveRef<T5>::type T5_;
449 Args5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
450 NLIB_THFUNC_USESWAP_NO(T5) arg5_, B) :
451 BaseType(func_, arg1_, arg2_, arg3_, arg4_, typename ArgType<T4>::type()),
454 Args5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
455 NLIB_THFUNC_USESWAP_YES(T4) arg5_, B) :
456 BaseType(func_, arg1_, arg2_, arg3_, arg4_, typename ArgType<T4>::type()),
459 swap(const_cast<T5&>(arg5_), arg5);
462 Args5(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
464 const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
const T5& arg5_,
466 BaseType(func_, arg1_, arg2_, arg3_, arg4_, b),
470 #undef NLIB_THFUNC_USESWAP_NO 471 #undef NLIB_THFUNC_USESWAP_YES 474 struct ThreadFuncX0 :
public Args0<FUNC> {
475 typedef ThreadFuncX0<FUNC> ThisType;
476 typedef Args0<FUNC> BaseType;
478 ThreadFuncX0(
const FUNC& func_, B b) : BaseType(func_, b) {}
479 explicit ThreadFuncX0(
const FUNC& func_) : BaseType(func_, None()) {}
480 static void Call(UniquePtr<ThisType>& ptr) { ptr->func(); }
482 template<
class FUNC,
class T1>
483 struct ThreadFuncX1 :
public Args1<FUNC, T1> {
484 typedef ThreadFuncX1<FUNC, T1> ThisType;
485 typedef Args1<FUNC, T1> BaseType;
487 ThreadFuncX1(
const FUNC& func_,
const T1& arg1_, B b) : BaseType(func_, arg1_, b) {}
488 ThreadFuncX1(
const FUNC& func_,
const T1& arg1_) : BaseType(func_, arg1_, None()) {}
489 static void Call(UniquePtr<ThisType>& ptr) { ptr->func(NLIB_MOVE(ptr->arg1)); }
491 template<
class FUNC,
class T1,
class T2>
492 struct ThreadFuncX2 :
public Args2<FUNC, T1, T2> {
493 typedef ThreadFuncX2<FUNC, T1, T2> ThisType;
494 typedef Args2<FUNC, T1, T2> BaseType;
496 ThreadFuncX2(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_, B b) :
497 BaseType(func_, arg1_, arg2_, b) {}
498 ThreadFuncX2(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_) :
499 BaseType(func_, arg1_, arg2_, None()) {}
500 static void Call(UniquePtr<ThisType>& ptr) {
501 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2));
504 template<
class FUNC,
class T1,
class T2,
class T3>
505 struct ThreadFuncX3 :
public Args3<FUNC, T1, T2, T3> {
506 typedef ThreadFuncX3<FUNC, T1, T2, T3> ThisType;
507 typedef Args3<FUNC, T1, T2, T3> BaseType;
509 ThreadFuncX3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_, B b) :
510 BaseType(func_, arg1_, arg2_, arg3_, b) {}
511 ThreadFuncX3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_) :
512 BaseType(func_, arg1_, arg2_, arg3_, None()) {}
513 static void Call(UniquePtr<ThisType>& ptr) {
514 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3));
517 template<
class FUNC,
class T1,
class T2,
class T3,
class T4>
518 struct ThreadFuncX4 :
public Args4<FUNC, T1, T2, T3, T4> {
519 typedef ThreadFuncX4<FUNC, T1, T2, T3, T4> ThisType;
520 typedef Args4<FUNC, T1, T2, T3, T4> BaseType;
522 ThreadFuncX4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
523 const T4& arg4_, B b) :
524 BaseType(func_, arg1_, arg2_, arg3_, arg4_, b) {}
525 ThreadFuncX4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
527 BaseType(func_, arg1_, arg2_, arg3_, arg4_, None()) {}
528 static void Call(UniquePtr<ThisType>& ptr) {
529 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3),
530 NLIB_MOVE(ptr->arg4));
533 template<
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
534 struct ThreadFuncX5 :
public Args5<FUNC, T1, T2, T3, T4, T5> {
535 typedef ThreadFuncX5<FUNC, T1, T2, T3, T4, T5> ThisType;
536 typedef Args5<FUNC, T1, T2, T3, T4, T5> BaseType;
538 ThreadFuncX5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
539 const T4& arg4_,
const T5& arg5_, B b) :
540 BaseType(func_, arg1_, arg2_, arg3_, arg4_, arg5_, b) {}
541 ThreadFuncX5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
542 const T4& arg4_,
const T5& arg5_) :
543 BaseType(func_, arg1_, arg2_, arg3_, arg4_, arg5_, None()) {}
544 static void Call(UniquePtr<ThisType>& ptr) {
545 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3),
546 NLIB_MOVE(ptr->arg4), NLIB_MOVE(ptr->arg5));
554 new (std::nothrow) ThreadFuncX0<FUNC>(f,
typename IsSwappable<FUNC>::type()));
555 if (!ptr)
return ENOMEM;
556 return this->StartRaw(settings, ptr);
561 new (std::nothrow) ThreadFuncX0<FUNC>(f,
typename IsSwappable<FUNC>::type()));
562 if (!ptr)
return ENOMEM;
563 return this->StartRaw(ptr);
565 template<
class FUNC,
class T1>
568 new (std::nothrow) ThreadFuncX1<FUNC, T1>(f, arg1,
typename ArgType<T1>::type()));
569 if (!ptr)
return ENOMEM;
570 return this->StartRaw(settings, ptr);
572 template<
class FUNC,
class T1>
575 new (std::nothrow) ThreadFuncX1<FUNC, T1>(f, arg1,
typename ArgType<T1>::type()));
576 if (!ptr)
return ENOMEM;
577 return this->StartRaw(ptr);
579 template<
class FUNC,
class T1,
class T2>
583 f, arg1, arg2,
typename ArgType<T2>::type()));
584 if (!ptr)
return ENOMEM;
585 return this->StartRaw(settings, ptr);
587 template<
class FUNC,
class T1,
class T2>
590 f, arg1, arg2,
typename ArgType<T2>::type()));
591 if (!ptr)
return ENOMEM;
592 return this->StartRaw(ptr);
594 template<
class FUNC,
class T1,
class T2,
class T3>
599 ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3,
typename ArgType<T3>::type()));
600 if (!ptr)
return ENOMEM;
601 return this->StartRaw(settings, ptr);
603 template<
class FUNC,
class T1,
class T2,
class T3>
607 ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3,
typename ArgType<T3>::type()));
608 if (!ptr)
return ENOMEM;
609 return this->StartRaw(ptr);
611 template<
class FUNC,
class T1,
class T2,
class T3,
class T4>
613 const T3& arg3,
const T4& arg4,
move_tag) {
615 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4,
616 typename ArgType<T4>::type()));
617 if (!ptr)
return ENOMEM;
618 return this->StartRaw(settings, ptr);
620 template<
class FUNC,
class T1,
class T2,
class T3,
class T4>
622 Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
move_tag) {
624 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4,
625 typename ArgType<T4>::type()));
626 if (!ptr)
return ENOMEM;
627 return this->StartRaw(ptr);
629 template<
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
631 const T3& arg3,
const T4& arg4,
const T5& arg5,
move_tag) {
633 new (std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(
634 f, arg1, arg2, arg3, arg4, arg5,
typename ArgType<T5>::type()));
635 if (!ptr)
return ENOMEM;
636 return this->StartRaw(settings, ptr);
638 template<
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
639 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
642 new (std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(
643 f, arg1, arg2, arg3, arg4, arg5,
typename ArgType<T5>::type()));
644 if (!ptr)
return ENOMEM;
645 return this->StartRaw(ptr);
650 if (!ptr)
return ENOMEM;
651 return this->StartRaw(settings, ptr);
656 if (!ptr)
return ENOMEM;
657 return this->StartRaw(ptr);
659 template<
class FUNC,
class T1>
662 if (!ptr)
return ENOMEM;
663 return this->StartRaw(settings, ptr);
665 template<
class FUNC,
class T1>
668 if (!ptr)
return ENOMEM;
669 return this->StartRaw(ptr);
671 template<
class FUNC,
class T1,
class T2>
674 ThreadFuncX2<FUNC, T1, T2>(f, arg1, arg2));
675 if (!ptr)
return ENOMEM;
676 return this->StartRaw(settings, ptr);
678 template<
class FUNC,
class T1,
class T2>
681 ThreadFuncX2<FUNC, T1, T2>(f, arg1, arg2));
682 if (!ptr)
return ENOMEM;
683 return this->StartRaw(ptr);
685 template<
class FUNC,
class T1,
class T2,
class T3>
689 new (std::nothrow) ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3));
690 if (!ptr)
return ENOMEM;
691 return this->StartRaw(settings, ptr);
693 template<
class FUNC,
class T1,
class T2,
class T3>
694 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3) {
696 new (std::nothrow) ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3));
697 if (!ptr)
return ENOMEM;
698 return this->StartRaw(ptr);
700 template<
class FUNC,
class T1,
class T2,
class T3,
class T4>
702 const T3& arg3,
const T4& arg4) {
704 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4));
705 if (!ptr)
return ENOMEM;
706 return this->StartRaw(settings, ptr);
708 template<
class FUNC,
class T1,
class T2,
class T3,
class T4>
709 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4) {
711 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4));
712 if (!ptr)
return ENOMEM;
713 return this->StartRaw(ptr);
715 template<
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
717 const T3& arg3,
const T4& arg4,
const T5& arg5) {
719 std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(f, arg1, arg2, arg3, arg4, arg5));
720 if (!ptr)
return ENOMEM;
721 return this->StartRaw(settings, ptr);
723 template<
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
724 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
727 std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(f, arg1, arg2, arg3, arg4, arg5));
728 if (!ptr)
return ENOMEM;
729 return this->StartRaw(ptr);
742 struct Thread::Args0<void()> {
744 Args0(
void (*func_)(), X) : func(func_) {}
745 Args0(
void (*func_)()) : func(func_) {}
753 struct Thread::Args0<void(T1)> {
755 Args0(
void (*func_)(T1), X) : func(func_) {}
756 Args0(
void (*func_)(T1)) : func(func_) {}
763 template<
class T1,
class T2>
764 struct Thread::Args0<void(T1, T2)> {
766 Args0(
void (*func_)(T1, T2), X) : func(func_) {}
767 Args0(
void (*func_)(T1, T2)) : func(func_) {}
768 void (*func)(T1, T2);
774 template<
class T1,
class T2,
class T3>
775 struct Thread::Args0<void(T1, T2, T3)> {
777 Args0(
void (*func_)(T1, T2, T3), X) : func(func_) {}
778 Args0(
void (*func_)(T1, T2, T3)) : func(func_) {}
779 void (*func)(T1, T2, T3);
785 template<
class T1,
class T2,
class T3,
class T4>
786 struct Thread::Args0<void(T1, T2, T3, T4)> {
788 Args0(
void (*func_)(T1, T2, T3, T4), X) : func(func_) {}
789 Args0(
void (*func_)(T1, T2, T3, T4)) : func(func_) {}
790 void (*func)(T1, T2, T3, T4);
796 template<
class T1,
class T2,
class T3,
class T4,
class T5>
797 struct Thread::Args0<void(T1, T2, T3, T4, T5)> {
799 Args0(
void (*func_)(T1, T2, T3, T4, T5), X) : func(func_) {}
800 Args0(
void (*func_)(T1, T2, T3, T4, T5)) : func(func_) {}
801 void (*func)(T1, T2, T3, T4, T5);
808 unsigned int num_cpu;
813 namespace this_thread {
826 return e == 0 ? id : -1;
834 if (e != 0)
return e;
845 NLIB_DEFINE_STD_SWAP(::nlib_ns::threading::Thread)
847 #endif // INCLUDE_NN_NLIB_THREADING_THREAD_H_ errno_t GetCpu(int *cpuid) noexcept
呼び出したスレッドが実行されているCPUを取得します。
errno_t YieldThread() noexcept
他のスレッドに制御を譲ります。
errno_t Start(const ThreadSettings &settings, const FUNC &f, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, move_tag)
引数を2つもつ関数を別スレッドで実行開始します。 引数を2つ持つこと以外は、引数が1つのバージョンと同じ...
nlib_thread GetNativeHandle() const noexcept
実装依存のスレッド識別子を取得します。
static errno_t Sleep(const TimeSpan &span) noexcept
span の期間だけスリープします。
constexpr Thread() noexcept
デフォルトコンストラクタです。
int GetStackSize() const noexcept
設定されているスタックサイズを返します。
errno_t Sleep(const TimeSpan &span) noexcept
スリープします。
constexpr ThreadArg(Func func_, T1 arg1_, T2 arg2_, T3 arg3_, T4 arg4_, T5 arg5_)
コンストラクタで構造体のフィールドを初期化します。
C++11の標準ヘッダとなるtype_traitsの代用定義です。 コンパイラや標準ライブラリによってサポートされてい...
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
bool operator!=(const Thread &rhs) noexcept
nlib_thread_equal()を用いてスレッドを比較します。
constexpr ThreadArg()
デフォルトコンストラクタです。
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
T1 arg1
別スレッドで実行する関数に渡されるオブジェクトです。
errno_t Detach() noexcept
スレッドをデタッチします。
Func func
別スレッドで実行する関数へのポインタです。
bool GetDetachState() const noexcept
デタッチ状態でスレッドを起動する設定かどうかを返します。
errno_t GetPriority(int32_t *priority) noexcept
スレッドの優先度を取得します。
T3 arg3
別スレッドで実行する関数に渡されるオブジェクトです。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, move_tag)
引数を5つもつ関数を別スレッドで実行開始します。引数を5つ持つこと以外は、引数が1つのバージョンと同じで...
~Thread() noexcept
デストラクタです。 スレッドがJoinされていない場合はJoinします。
errno_t ChangePriority(int32_t priority) noexcept
スレッドの優先度を設定します。
T5 arg5
別スレッドで実行する関数に渡されるオブジェクトです。
void SetDetachState(bool detached) noexcept
デタッチした状態でスレッドを起動するかどうかを設定します。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2)
引数を2つもつ関数を別スレッドで実行開始します。引数を2つ持つこと以外は、引数が1つのバージョンと同じで...
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3)
引数を3つもつ関数を別スレッドで実行開始します。引数を3つ持つこと以外は、引数が1つのバージョンと同じで...
C++11環境(エイリアステンプレートが可能な環境)においてはstd::unique_ptrにエイリアステンプレートされま...
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5)
引数を5つもつ関数を別スレッドで実行開始します。引数を5つ持つこと以外は、引数が1つのバージョンと同じで...
std::unique_ptrに相当するクラスが定義されています。
Threadクラスでスレッドを実行するために利用できる構造体です。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, move_tag)
引数を3つもつ関数を別スレッドで実行開始します。 引数を3つ持つこと以外は、引数が1つのバージョンと同じ...
int GetPriority() const noexcept
スレッドの優先度を取得します。
bool IsJoinable() const noexcept
join可能かどうか調べます。
Thread(Thread &rhs, move_tag) noexcept
ムーブコンストラクタに相当します。
errno_t SetStackSize(int size) noexcept
スタックサイズを設定します。
errno_t Start(const FUNC &f, const T1 &arg1, move_tag)
引数を1つもつ関数を別スレッドで実行開始します。
errno_t StartRaw(UniquePtr< ThArg > &ptr) noexcept
別スレッドの実行を開始します。
errno_t SetName(const char *literal_string) noexcept
スレッドに名前をつけます。
nlib_thread_attrをラップするクラスです。必要に応じて自動的にnlib_thread_attr_init()とnlib_thread_attr...
errno_t StartRaw(const ThreadSettings &settings, UniquePtr< ThArg > &ptr) noexcept
別スレッドの実行を開始します。
Thread & assign(Thread &rhs, move_tag) noexcept
ムーブ代入演算子に相当します。
static errno_t YieldThread() noexcept
nlib_yield()を呼び出します。
errno_t Join() noexcept
スレッドの実行完了を待ちます。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
空の構造体で、関数の引数をムーブすべきことを示すために利用されます。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
bool operator==(const Thread &rhs) noexcept
nlib_thread_equal()を用いてスレッドを比較します。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4)
引数を4つもつ関数を別スレッドで実行開始します。引数を4つ持つこと以外は、引数が1つのバージョンと同じで...
errno_t Start(const FUNC &f, const T1 &arg1)
引数を1つもつ関数を別スレッドで実行開始します。
errno_t Start(const ThreadSettings &settings, const FUNC &f)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t SetPriority(int priority) noexcept
スレッドの優先度を設定します。優先度の値はプラットフォーム依存です。
nlib_thread_id GetId() noexcept
カレントスレッドのIDを取得します。
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
Thread & operator=(Thread &&rhs) noexcept
ムーブ代入演算子です。
errno_t Start(const FUNC &f)
引数を持たない関数を別スレッドで実行開始します。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
size_t GetHardwareConcurrency() noexcept
ハードウェアスレッドの数を返します。
errno_t SetAffinity(uint32_t affinity) noexcept
スレッドのプロセッサアフィニティマスクを設定します。
ThreadArg< T1, T2, T3, T4, T5 > ThisType
この構造体の型へのtypedefです。
errno_t StartRaw(const ThreadSettings &settings, ThreadArg<>::Func func) noexcept
引数を持たない関数を別スレッドで実行開始します。
UniquePtr< ThisType > ArgType
スレッド関数の引数型のtypedefです。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
Thread(Thread &&rhs) noexcept
ムーブコンストラクタです。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t SleepMilliSeconds(unsigned int millisec) noexcept
スリープします。
errno_t StartRaw(ThreadArg<>::Func func) noexcept
引数を持たない関数を別スレッドで実行開始します。
T4 arg4
別スレッドで実行する関数に渡されるオブジェクトです。
errno_t GetPriority(int32_t *priority) noexcept
nlib_thread_getpriority()を呼び出して、スレッドの実行優先順位を取得します。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
T2 arg2
別スレッドで実行する関数に渡されるオブジェクトです。
errno_t Start(const FUNC &f, move_tag)
引数を持たない関数を別スレッドで実行開始します。 引数を持たないこと以外は、引数が1つのバージョンと同...
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, move_tag)
引数を4つもつ関数を別スレッドで実行開始します。 引数を4つ持つこと以外は、引数が1つのバージョンと同じ...
errno_t ChangePriority(int32_t priority) noexcept
nlib_thread_setpriority()を呼び出して、スレッドの実行優先順位を設定します。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。