]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/performance/thread/skynet_pthread.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / fiber / performance / thread / skynet_pthread.cpp
1 #include <algorithm>
2 #include <cassert>
3 #include <chrono>
4 #include <cstddef>
5 #include <cstdint>
6 #include <cstdlib>
7 #include <iostream>
8 #include <memory>
9 #include <numeric>
10 #include <stdexcept>
11 #include <vector>
12
13 extern "C" {
14 #include <pthread.h>
15 #include <signal.h>
16 }
17
18 #include "buffered_channel.hpp"
19
20 using channel_type = buffered_channel< std::uint64_t >;
21 using clock_type = std::chrono::steady_clock;
22 using duration_type = clock_type::duration;
23 using time_point_type = clock_type::time_point;
24
25 struct thread_args {
26 channel_type & c;
27 std::size_t num;
28 std::size_t size;
29 std::size_t div;
30 };
31
32 // microbenchmark
33 void * skynet( void * vargs) {
34 thread_args * args = static_cast< thread_args * >( vargs);
35 if ( 1 == args->size) {
36 args->c.push( args->num);
37 } else {
38 channel_type rc{ 16 };
39 for ( std::size_t i = 0; i < args->div; ++i) {
40 auto sub_num = args->num + i * args->size / args->div;
41 auto sub_size = args->size / args->div;
42 auto size = 8 * 1024;
43 pthread_attr_t tattr;
44 if ( 0 != ::pthread_attr_init( & tattr) ) {
45 std::runtime_error("pthread_attr_init() failed");
46 }
47 if ( 0 != ::pthread_attr_setstacksize( & tattr, size) ) {
48 std::runtime_error("pthread_attr_setstacksize() failed");
49 }
50 thread_args * targs = new thread_args{ rc, sub_num, sub_size, args->div };
51 pthread_t tid;
52 if ( 0 != ::pthread_create( & tid, & tattr, & skynet, targs) ) {
53 std::runtime_error("pthread_create() failed");
54 }
55 if ( 0 != ::pthread_detach( tid) ) {
56 std::runtime_error("pthread_detach() failed");
57 }
58 }
59 std::uint64_t sum{ 0 };
60 for ( std::size_t i = 0; i < args->div; ++i) {
61 sum += rc.value_pop();
62 }
63 args->c.push( sum);
64 }
65 delete args;
66 return nullptr;
67 }
68
69 int main() {
70 try {
71 std::size_t size{ 10000 };
72 std::size_t div{ 10 };
73 std::uint64_t result{ 0 };
74 duration_type duration{ duration_type::zero() };
75 channel_type rc{ 2 };
76 thread_args * targs = new thread_args{ rc, 0, size, div };
77 time_point_type start{ clock_type::now() };
78 skynet( targs);
79 result = rc.value_pop();
80 duration = clock_type::now() - start;
81 std::cout << "Result: " << result << " in " << duration.count() / 1000000 << " ms" << std::endl;
82 std::cout << "done." << std::endl;
83 return EXIT_SUCCESS;
84 } catch ( std::exception const& e) {
85 std::cerr << "exception: " << e.what() << std::endl;
86 } catch (...) {
87 std::cerr << "unhandled exception" << std::endl;
88 }
89 return EXIT_FAILURE;
90 }