| 1 | 
 | 
|---|
| 2 | 
 | 
|---|
| 3 | #include <fstream>
 | 
|---|
| 4 | #include <threads>
 | 
|---|
| 5 | 
 | 
|---|
| 6 | #include <unistd.h>                                     // sysconf
 | 
|---|
| 7 | #include <sys/times.h>                                  // times
 | 
|---|
| 8 | #include <time.h>
 | 
|---|
| 9 | 
 | 
|---|
| 10 | inline unsigned long long int Time() {
 | 
|---|
| 11 |     timespec ts;
 | 
|---|
| 12 |     clock_gettime(
 | 
|---|
| 13 | #if defined( __linux__ )
 | 
|---|
| 14 |          CLOCK_THREAD_CPUTIME_ID,
 | 
|---|
| 15 | #elif defined( __freebsd__ )
 | 
|---|
| 16 |          CLOCK_PROF,
 | 
|---|
| 17 | #elif defined( __solaris__ )
 | 
|---|
| 18 |          CLOCK_HIGHRES,
 | 
|---|
| 19 | #else
 | 
|---|
| 20 |     #error uC++ : internal error, unsupported architecture
 | 
|---|
| 21 | #endif
 | 
|---|
| 22 |          &ts );
 | 
|---|
| 23 |     return 1000000000LL * ts.tv_sec + ts.tv_nsec;
 | 
|---|
| 24 | } // Time
 | 
|---|
| 25 | 
 | 
|---|
| 26 | //=======================================
 | 
|---|
| 27 | // time coroutine
 | 
|---|
| 28 | //=======================================
 | 
|---|
| 29 | 
 | 
|---|
| 30 | struct CoroutineResume {
 | 
|---|
| 31 |     int N;
 | 
|---|
| 32 |     coroutine c;
 | 
|---|
| 33 | };
 | 
|---|
| 34 | 
 | 
|---|
| 35 | coroutine* get_coroutine(CoroutineResume* this);
 | 
|---|
| 36 | void co_main(CoroutineResume* this);
 | 
|---|
| 37 | 
 | 
|---|
| 38 | void ?{}(CoroutineResume* this, int N) {
 | 
|---|
| 39 |       this->N = N;
 | 
|---|
| 40 |         prime(this);
 | 
|---|
| 41 | }
 | 
|---|
| 42 | 
 | 
|---|
| 43 | coroutine* get_coroutine(CoroutineResume* this) {
 | 
|---|
| 44 |       return &this->c;
 | 
|---|
| 45 | }
 | 
|---|
| 46 | 
 | 
|---|
| 47 | void co_main(CoroutineResume* this) {
 | 
|---|
| 48 |         for ( int i = 1; i <= this->N; i += 1 ) {
 | 
|---|
| 49 |                 suspend();
 | 
|---|
| 50 |         } // for
 | 
|---|
| 51 | } // CoroutineResume::main
 | 
|---|
| 52 | 
 | 
|---|
| 53 | void resumer(CoroutineResume* this) {
 | 
|---|
| 54 |         long long int StartTime, EndTime;
 | 
|---|
| 55 | 
 | 
|---|
| 56 |         StartTime = Time();
 | 
|---|
| 57 |         for ( int i = 1; i <= this->N; i += 1 ) {
 | 
|---|
| 58 |                 resume(this);
 | 
|---|
| 59 |         } // for
 | 
|---|
| 60 |         EndTime = Time();
 | 
|---|
| 61 |         sout | "\t " | ( EndTime - StartTime ) / this->N;
 | 
|---|
| 62 | } // CoroutineResume::resumer
 | 
|---|
| 63 | 
 | 
|---|
| 64 | 
 | 
|---|
| 65 | int main() {
 | 
|---|
| 66 |         const int NoOfTimes =
 | 
|---|
| 67 | #if defined( __U_DEBUG__ )                              // takes longer so run fewer iterations
 | 
|---|
| 68 |         100000;
 | 
|---|
| 69 | #else
 | 
|---|
| 70 |         1000000;
 | 
|---|
| 71 | #endif // __U_DEBUG__
 | 
|---|
| 72 | 
 | 
|---|
| 73 |         sout | "\t\tcreate\tcreate\t16i/4o\t16i/4o\tresume/\tsignal/" | endl;
 | 
|---|
| 74 |         sout | "(nsecs)";
 | 
|---|
| 75 |         sout | "\t\tdelete/\tdelete/\tbytes\tbytes\tsuspend\twait" | endl;
 | 
|---|
| 76 |         sout | "\t\tblock\tdynamic\tdirect\taccept\tcycle\tcycle" | endl;
 | 
|---|
| 77 | 
 | 
|---|
| 78 |         sout | "class\t";
 | 
|---|
| 79 |         sout | "\t N/A\t N/A\t N/A";
 | 
|---|
| 80 |         sout | "\t N/A\t N/A\t N/A";
 | 
|---|
| 81 |         sout | "\t" | endl;
 | 
|---|
| 82 | 
 | 
|---|
| 83 |         sout | "coroutine";
 | 
|---|
| 84 |         sout | "\t N/A\t N/A\t N/A";
 | 
|---|
| 85 |         sout | "\t N/A";
 | 
|---|
| 86 |         {
 | 
|---|
| 87 |                 CoroutineResume resumer = { NoOfTimes };
 | 
|---|
| 88 |                 resumer(&resumer);
 | 
|---|
| 89 |         }
 | 
|---|
| 90 |         sout | "\t N/A";
 | 
|---|
| 91 | 
 | 
|---|
| 92 |         sout | "\t" | endl;
 | 
|---|
| 93 | }
 | 
|---|