• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
skynet(void * vargs)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 
main()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 }
91