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_) {
43 NLIB_THREAD_ATTR_KEY_DETACHSTATE,
53 NLIB_THREAD_ATTR_KEY_DETACHSTATE,
57 return (detached != 0);
63 NLIB_THREAD_ATTR_KEY_STACKSIZE,
72 NLIB_THREAD_ATTR_KEY_STACKSIZE,
82 NLIB_THREAD_ATTR_KEY_PRIORITY,
91 NLIB_THREAD_ATTR_KEY_PRIORITY,
98 return is_initialized_ ? &attr_ :
nullptr;
101 return is_initialized_ ? &attr_ :
nullptr;
106 if (!is_initialized_) {
108 NLIB_ASSERT_NOERR(e);
110 is_initialized_ =
true;
113 mutable bool is_initialized_;
117 template <
class T1 = None,
class T2 = None,
class T3 = None,
class T4 = None,
class T5 = None>
121 typedef void (*Func)(ArgType& ptr);
124 : func(func_), arg1(arg1_), arg2(arg2_), arg3(arg3_), arg4(arg4_), arg5(arg5_) {}
125 static void Call(ArgType& ptr) { ptr->func(ptr); }
136 struct ThreadArg<None, None, None, None, None> {
139 typedef void (*Func)();
143 struct ThreadArg<T1, None, None, None, None> {
146 typedef void (*Func)(ArgType& ptr);
148 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_) : func(func_), arg1(arg1_) {}
149 static void Call(ArgType& ptr) { ptr->func(ptr); }
155 template <
class T1,
class T2>
156 struct ThreadArg<T1, T2, None, None, None> {
159 typedef void (*Func)(ArgType& ptr);
161 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_) : func(func_), arg1(arg1_), arg2(arg2_) {}
162 static void Call(ArgType& ptr) { ptr->func(ptr); }
169 template <
class T1,
class T2,
class T3>
170 struct ThreadArg<T1, T2, T3, None, None> {
173 typedef void (*Func)(ArgType& ptr);
175 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_, T3 arg3_)
176 : func(func_), arg1(arg1_), arg2(arg2_), arg3(arg3_) {}
177 static void Call(ArgType& ptr) { ptr->func(ptr); }
185 template <
class T1,
class T2,
class T3,
class T4>
189 typedef void (*Func)(ArgType& ptr);
191 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_, T3 arg3_, T4 arg4_)
192 : func(func_), arg1(arg1_), arg2(arg2_), arg3(arg3_), arg4(arg4_) {}
193 static void Call(ArgType& ptr) { ptr->func(ptr); }
203 #pragma warning(push) 204 #pragma warning(disable : 4180) 214 typedef void (*ThreadFunc)(
void* arg);
219 #ifdef __cpp_rvalue_references 224 thread_id_ = rhs.thread_id_;
233 thread_id_ = rhs.thread_id_;
239 swap(thread_id_, rhs.thread_id_);
244 if (!thread_id_)
return ESRCH;
283 errno_t e = this->StartRaw(Thread::Exec, reinterpret_cast<void*>(func), settings);
287 errno_t e = this->StartRaw(Thread::Exec, reinterpret_cast<void*>(func));
290 template <
class ThArg>
293 if (!ptr)
return EINVAL;
294 errno_t e = this->StartRaw((ThreadFunc)Thread::Exec<ThArg>,
295 reinterpret_cast<void*>(ptr.get()), settings);
296 if (e == 0) ptr.release();
299 template <
class ThArg>
301 if (!ptr)
return EINVAL;
302 errno_t e = this->StartRaw((ThreadFunc)Thread::Exec<ThArg>,
303 reinterpret_cast<void*>(ptr.get()));
304 if (e == 0) ptr.release();
309 static void Exec(
void* p) {
314 static void Exec(
void* p) {
319 #define NLIB_THFUNC_USESWAP_NO(tp) \ 321 !IsSame<None, typename RemoveCv<B>::type>::value && \ 322 (IsSame<FalseType, typename RemoveCv<B>::type>::value || !IsSwappable<tp>::value), \ 324 #define NLIB_THFUNC_USESWAP_YES(tp) \ 325 typename EnableIf<!IsSame<None, typename RemoveCv<B>::type>::value && \ 326 IsSame<TrueType, typename RemoveCv<B>::type>::value && \ 327 IsSwappable<tp>::value, \ 331 struct ArgType :
public Conditional<
332 IsArithmetic<T>::value || IsPointer<T>::value || IsMemberPointer<T>::value,
333 FalseType, TrueType> {};
335 template <
class FUNC>
337 typedef typename RemoveRef<FUNC>::type FUNC_;
339 Args0(NLIB_THFUNC_USESWAP_NO(FUNC_) func_, B)
342 Args0(NLIB_THFUNC_USESWAP_YES(FUNC_) func_, B)
345 swap(const_cast<FUNC&>(func_), func);
348 Args0(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
357 template <
class FUNC,
class T1>
358 struct Args1 :
public Args0<FUNC> {
359 typedef Args0<FUNC> BaseType;
360 typedef typename RemoveRef<T1>::type T1_;
362 Args1(
const FUNC& func_, NLIB_THFUNC_USESWAP_NO(T1) arg1_, B)
363 : BaseType(func_,
typename IsSwappable<FUNC>::type()), arg1(arg1_) {}
365 Args1(
const FUNC& func_, NLIB_THFUNC_USESWAP_YES(T1) arg1_, B)
366 : BaseType(func_,
typename IsSwappable<FUNC>::type()), arg1() {
368 swap(const_cast<T1&>(arg1_), arg1);
371 Args1(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
373 const T1& arg1_, B b)
374 : BaseType(func_, b), arg1(arg1_) {}
377 template <
class FUNC,
class T1,
class T2>
378 struct Args2 :
public Args1<FUNC, T1> {
379 typedef Args1<FUNC, T1> BaseType;
380 typedef typename RemoveRef<T2>::type T2_;
382 Args2(
const FUNC& func_,
const T1& arg1_, NLIB_THFUNC_USESWAP_NO(T2) arg2_, B)
383 : BaseType(func_, arg1_,
typename ArgType<T1>::type()), arg2(arg2_) {}
385 Args2(
const FUNC& func_,
const T1& arg1_, NLIB_THFUNC_USESWAP_YES(T2) arg2_, B)
386 : BaseType(func_, arg1_,
typename ArgType<T1>::type()), arg2() {
388 swap(const_cast<T2&>(arg2_), arg2);
391 Args2(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
393 const T1& arg1_,
const T2& arg2_, B b)
394 : BaseType(func_, arg1_, b), arg2(arg2_) {}
397 template <
class FUNC,
class T1,
class T2,
class T3>
398 struct Args3 :
public Args2<FUNC, T1, T2> {
399 typedef Args2<FUNC, T1, T2> BaseType;
400 typedef typename RemoveRef<T3>::type T3_;
402 Args3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_, NLIB_THFUNC_USESWAP_NO(T3) arg3_,
404 : BaseType(func_, arg1_, arg2_,
typename ArgType<T2>::type()), arg3(arg3_) {}
406 Args3(
const FUNC& func,
const T1& arg1_,
const T2& arg2_, NLIB_THFUNC_USESWAP_YES(T3) arg3_,
408 : BaseType(func, arg1_, arg2_,
typename ArgType<T2>::type()), arg3() {
410 swap(const_cast<T3&>(arg3_), arg3);
413 Args3(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
415 const T1& arg1_,
const T2& arg2_,
const T3& arg3_, B b)
416 : BaseType(func_, arg1_, arg2_, b), arg3(arg3_) {}
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()), arg4(arg4_) {}
428 Args4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
429 NLIB_THFUNC_USESWAP_YES(T4) arg4_, B)
430 : BaseType(func_, arg1_, arg2_, arg3_,
typename ArgType<T3>::type()), arg4() {
432 swap(const_cast<T4&>(arg4_), arg4);
435 Args4(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
437 const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_, B b)
438 : BaseType(func_, arg1_, arg2_, arg3_, b), arg4(arg4_) {}
441 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
442 struct Args5 :
public Args4<FUNC, T1, T2, T3, T4> {
443 typedef Args4<FUNC, T1, T2, T3, T4> BaseType;
444 typedef typename RemoveRef<T5>::type T5_;
446 Args5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
447 NLIB_THFUNC_USESWAP_NO(T5) arg5_, B)
448 : BaseType(func_, arg1_, arg2_, arg3_, arg4_,
typename ArgType<T4>::type()),
451 Args5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
452 NLIB_THFUNC_USESWAP_YES(T4) arg5_, B)
453 : BaseType(func_, arg1_, arg2_, arg3_, arg4_,
typename ArgType<T4>::type()), arg5() {
455 swap(const_cast<T5&>(arg5_), arg5);
458 Args5(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
460 const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
const T5& arg5_,
462 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, b), arg5(arg5_) {}
465 #undef NLIB_THFUNC_USESWAP_NO 466 #undef NLIB_THFUNC_USESWAP_YES 468 template <
class FUNC>
469 struct ThreadFuncX0 :
public Args0<FUNC> {
470 typedef ThreadFuncX0<FUNC> ThisType;
471 typedef Args0<FUNC> BaseType;
473 ThreadFuncX0(
const FUNC& func_, B b)
474 : BaseType(func_, b) {}
475 explicit ThreadFuncX0(
const FUNC& func_) : BaseType(func_, None()) {}
480 template <
class FUNC,
class T1>
481 struct ThreadFuncX1 :
public Args1<FUNC, T1> {
482 typedef ThreadFuncX1<FUNC, T1> ThisType;
483 typedef Args1<FUNC, T1> BaseType;
485 ThreadFuncX1(
const FUNC& func_,
const T1& arg1_, B b)
486 : BaseType(func_, arg1_, b) {}
487 ThreadFuncX1(
const FUNC& func_,
const T1& arg1_) : BaseType(func_, arg1_, None()) {}
489 ptr->func(NLIB_MOVE(ptr->arg1));
492 template <
class FUNC,
class T1,
class T2>
493 struct ThreadFuncX2 :
public Args2<FUNC, T1, T2> {
494 typedef ThreadFuncX2<FUNC, T1, T2> ThisType;
495 typedef Args2<FUNC, T1, T2> BaseType;
497 ThreadFuncX2(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_, B b)
498 : BaseType(func_, arg1_, arg2_, b) {}
499 ThreadFuncX2(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_)
500 : BaseType(func_, arg1_, arg2_, None()) {}
502 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2));
505 template <
class FUNC,
class T1,
class T2,
class T3>
506 struct ThreadFuncX3 :
public Args3<FUNC, T1, T2, T3> {
507 typedef ThreadFuncX3<FUNC, T1, T2, T3> ThisType;
508 typedef Args3<FUNC, T1, T2, T3> BaseType;
510 ThreadFuncX3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_, B b)
511 : BaseType(func_, arg1_, arg2_, arg3_, b) {}
512 ThreadFuncX3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_)
513 : BaseType(func_, arg1_, arg2_, arg3_, None()) {}
515 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3));
518 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
519 struct ThreadFuncX4 :
public Args4<FUNC, T1, T2, T3, T4> {
520 typedef ThreadFuncX4<FUNC, T1, T2, T3, T4> ThisType;
521 typedef Args4<FUNC, T1, T2, T3, T4> BaseType;
523 ThreadFuncX4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
524 const T4& arg4_, B b)
525 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, b) {}
526 ThreadFuncX4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
528 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, None()) {}
530 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3),
531 NLIB_MOVE(ptr->arg4));
534 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
535 struct ThreadFuncX5 :
public Args5<FUNC, T1, T2, T3, T4, T5> {
536 typedef ThreadFuncX5<FUNC, T1, T2, T3, T4, T5> ThisType;
537 typedef Args5<FUNC, T1, T2, T3, T4, T5> BaseType;
539 ThreadFuncX5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
540 const T4& arg4_,
const T5& arg5_, B b)
541 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, arg5_, b) {}
542 ThreadFuncX5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
543 const T4& arg4_,
const T5& arg5_)
544 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, arg5_, None()) {}
546 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3),
547 NLIB_MOVE(ptr->arg4), NLIB_MOVE(ptr->arg5));
552 template <
class FUNC>
555 new (std::nothrow) ThreadFuncX0<FUNC>(f,
typename IsSwappable<FUNC>::type()));
556 if (!ptr)
return ENOMEM;
557 return this->StartRaw(settings, ptr);
559 template <
class FUNC>
562 new (std::nothrow) ThreadFuncX0<FUNC>(f,
typename IsSwappable<FUNC>::type()));
563 if (!ptr)
return ENOMEM;
564 return this->StartRaw(ptr);
566 template <
class FUNC,
class T1>
569 new (std::nothrow) ThreadFuncX1<FUNC, T1>(f, arg1,
typename ArgType<T1>::type()));
570 if (!ptr)
return ENOMEM;
571 return this->StartRaw(settings, ptr);
573 template <
class FUNC,
class T1>
576 new (std::nothrow) ThreadFuncX1<FUNC, T1>(f, arg1,
typename ArgType<T1>::type()));
577 if (!ptr)
return ENOMEM;
578 return this->StartRaw(ptr);
580 template <
class FUNC,
class T1,
class T2>
584 f, arg1, arg2,
typename ArgType<T2>::type()));
585 if (!ptr)
return ENOMEM;
586 return this->StartRaw(settings, ptr);
588 template <
class FUNC,
class T1,
class T2>
591 f, arg1, arg2,
typename ArgType<T2>::type()));
592 if (!ptr)
return ENOMEM;
593 return this->StartRaw(ptr);
595 template <
class FUNC,
class T1,
class T2,
class T3>
600 ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3,
typename ArgType<T3>::type()));
601 if (!ptr)
return ENOMEM;
602 return this->StartRaw(settings, ptr);
604 template <
class FUNC,
class T1,
class T2,
class T3>
608 ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3,
typename ArgType<T3>::type()));
609 if (!ptr)
return ENOMEM;
610 return this->StartRaw(ptr);
612 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
614 const T3& arg3,
const T4& arg4,
move_tag) {
616 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4,
617 typename ArgType<T4>::type()));
618 if (!ptr)
return ENOMEM;
619 return this->StartRaw(settings, ptr);
621 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
622 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
625 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4,
626 typename ArgType<T4>::type()));
627 if (!ptr)
return ENOMEM;
628 return this->StartRaw(ptr);
630 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
632 const T3& arg3,
const T4& arg4,
const T5& arg5,
move_tag) {
634 new (std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(
635 f, arg1, arg2, arg3, arg4, arg5,
typename ArgType<T5>::type()));
636 if (!ptr)
return ENOMEM;
637 return this->StartRaw(settings, ptr);
639 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
640 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
643 new (std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(
644 f, arg1, arg2, arg3, arg4, arg5,
typename ArgType<T5>::type()));
645 if (!ptr)
return ENOMEM;
646 return this->StartRaw(ptr);
648 template <
class FUNC>
651 if (!ptr)
return ENOMEM;
652 return this->StartRaw(settings, ptr);
654 template <
class FUNC>
657 if (!ptr)
return ENOMEM;
658 return this->StartRaw(ptr);
660 template <
class FUNC,
class T1>
663 if (!ptr)
return ENOMEM;
664 return this->StartRaw(settings, ptr);
666 template <
class FUNC,
class T1>
669 if (!ptr)
return ENOMEM;
670 return this->StartRaw(ptr);
672 template <
class FUNC,
class T1,
class T2>
675 ThreadFuncX2<FUNC, T1, T2>(f, arg1, arg2));
676 if (!ptr)
return ENOMEM;
677 return this->StartRaw(settings, ptr);
679 template <
class FUNC,
class T1,
class T2>
682 ThreadFuncX2<FUNC, T1, T2>(f, arg1, arg2));
683 if (!ptr)
return ENOMEM;
684 return this->StartRaw(ptr);
686 template <
class FUNC,
class T1,
class T2,
class T3>
690 new (std::nothrow) ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3));
691 if (!ptr)
return ENOMEM;
692 return this->StartRaw(settings, ptr);
694 template <
class FUNC,
class T1,
class T2,
class T3>
695 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3) {
697 new (std::nothrow) ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3));
698 if (!ptr)
return ENOMEM;
699 return this->StartRaw(ptr);
701 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
703 const T3& arg3,
const T4& arg4) {
705 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4));
706 if (!ptr)
return ENOMEM;
707 return this->StartRaw(settings, ptr);
709 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
710 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4) {
712 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4));
713 if (!ptr)
return ENOMEM;
714 return this->StartRaw(ptr);
716 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
718 const T3& arg3,
const T4& arg4,
const T5& arg5) {
720 std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(f, arg1, arg2, arg3, arg4, arg5));
721 if (!ptr)
return ENOMEM;
722 return this->StartRaw(settings, ptr);
724 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
725 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
728 std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(f, arg1, arg2, arg3, arg4, arg5));
729 if (!ptr)
return ENOMEM;
730 return this->StartRaw(ptr);
743 struct Thread::Args0<void()> {
745 Args0(
void (*func_)(), X)
747 Args0(
void (*func_)()) : func(func_) {}
755 struct Thread::Args0<void(T1)> {
757 Args0(
void (*func_)(T1), X)
759 Args0(
void (*func_)(T1)) : func(func_) {}
766 template <
class T1,
class T2>
767 struct Thread::Args0<void(T1, T2)> {
769 Args0(
void (*func_)(T1, T2), X)
771 Args0(
void (*func_)(T1, T2)) : func(func_) {}
772 void (*func)(T1, T2);
778 template <
class T1,
class T2,
class T3>
779 struct Thread::Args0<void(T1, T2, T3)> {
781 Args0(
void (*func_)(T1, T2, T3), X)
783 Args0(
void (*func_)(T1, T2, T3)) : func(func_) {}
784 void (*func)(T1, T2, T3);
790 template <
class T1,
class T2,
class T3,
class T4>
791 struct Thread::Args0<void(T1, T2, T3, T4)> {
793 Args0(
void (*func_)(T1, T2, T3, T4), X)
795 Args0(
void (*func_)(T1, T2, T3, T4)) : func(func_) {}
796 void (*func)(T1, T2, T3, T4);
802 template <
class T1,
class T2,
class T3,
class T4,
class T5>
803 struct Thread::Args0<void(T1, T2, T3, T4, T5)> {
805 Args0(
void (*func_)(T1, T2, T3, T4, T5), X)
807 Args0(
void (*func_)(T1, T2, T3, T4, T5)) : func(func_) {}
808 void (*func)(T1, T2, T3, T4, T5);
815 unsigned int num_cpu;
820 namespace this_thread {
831 return e == 0 ? id : -1;
837 if (e != 0)
return e;
848 NLIB_DEFINE_STD_SWAP(::nlib_ns::threading::Thread)
850 #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つのバージョンと同じで...
UniquePtrはポインタの所有権を保持し、UniquePtrがスコープから出るときにデストラクタでポインタをDELで指...
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クラスでスレッドを実行するために利用できる構造体です。
void swap(Thread &rhs) noexcept
オブジェクトの内容をスワップします。
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
ムーブ代入演算子です。C++11の利用時に有効です。
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
ムーブコンストラクタです。C++11の利用時に有効です。
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)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。