#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <pthread.h>
timespec start, running, joined, sorted, sent, received;
std:: vector < int > v( 1000 , 1 ) ;
pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
int msg, ready;
template < typename C>
double avg( const C& v)
{
return std:: accumulate ( v.begin ( ) , v.end ( ) , 0.0 ) / v.size ( ) ;
}
// result in us
double diff( timespec x, timespec y)
{
return ( y.tv_sec * 1000000.0 + y.tv_nsec / 1000.0 )
- ( x.tv_sec * 1000000.0 + x.tv_nsec / 1000.0 ) ;
}
extern "C" void * f1( void * )
{
clock_gettime( CLOCK_REALTIME, & running) ;
return NULL ;
}
extern "C" void * f2( void * )
{
pthread_mutex_lock( & mx) ;
ready = 1 ;
pthread_cond_signal( & cv) ;
while ( msg == 0 )
pthread_cond_wait( & cv, & mx) ;
clock_gettime( CLOCK_REALTIME, & received) ;
pthread_mutex_unlock( & mx) ;
return NULL ;
}
int main( )
{
std:: partial_sum ( v.begin ( ) , v.end ( ) , v.begin ( ) ) ; // poor man's std::iota
pthread_t hndl;
std:: vector < double > starts, joins, sorts, sends;
for ( int n = 0 ; n < 100000 ; ++ n)
{
std:: random_shuffle ( v.begin ( ) , v.end ( ) ) ;
clock_gettime( CLOCK_REALTIME, & start) ;
pthread_create( & hndl, NULL , f1, NULL ) ;
pthread_join( hndl, NULL ) ;
clock_gettime( CLOCK_REALTIME, & joined) ;
std:: sort ( v.begin ( ) , v.end ( ) ) ;
clock_gettime( CLOCK_REALTIME, & sorted) ;
pthread_create( & hndl, NULL , f2, NULL ) ;
pthread_mutex_lock( & mx) ;
while ( ! ready)
pthread_cond_wait( & cv, & mx) ;
msg= 1 ;
clock_gettime( CLOCK_REALTIME, & sent) ;
pthread_cond_signal( & cv) ;
pthread_mutex_unlock( & mx) ;
pthread_join( hndl, NULL ) ;
msg= ready= 0 ;
starts.push_back ( diff( start, running) ) ;
joins.push_back ( diff( running, joined) ) ;
sorts.push_back ( diff( joined, sorted) ) ;
sends.push_back ( diff( sent, received) ) ;
}
std:: cout << "average time to spawn a thread: " << avg( starts) << " us\n "
<< "average time to join a thread: " << avg( joins) << " us\n "
<< "average time to sort 1000 ints: " << avg( sorts) << " us\n "
<< "average time to message a thread: " << avg( sends) << " us\n " ;
pthread_mutex_destroy( & mx) ;
pthread_cond_destroy( & cv) ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bnVtZXJpYz4KI2luY2x1ZGUgPHB0aHJlYWQuaD4KCnRpbWVzcGVjIHN0YXJ0LCBydW5uaW5nLCBqb2luZWQsIHNvcnRlZCwgc2VudCwgcmVjZWl2ZWQ7CnN0ZDo6dmVjdG9yPGludD4gdigxMDAwLCAxKTsKcHRocmVhZF9tdXRleF90IG14ID0gUFRIUkVBRF9NVVRFWF9JTklUSUFMSVpFUjsKcHRocmVhZF9jb25kX3QgY3YgPSBQVEhSRUFEX0NPTkRfSU5JVElBTElaRVI7CmludCBtc2csIHJlYWR5OwoKdGVtcGxhdGU8dHlwZW5hbWUgQz4KZG91YmxlIGF2Zyhjb25zdCBDJiB2KQp7CiAgIHJldHVybiBzdGQ6OmFjY3VtdWxhdGUodi5iZWdpbigpLCB2LmVuZCgpLCAwLjApL3Yuc2l6ZSgpOwp9CgovLyByZXN1bHQgaW4gdXMKZG91YmxlIGRpZmYodGltZXNwZWMgeCwgdGltZXNwZWMgeSkKewogICAgcmV0dXJuICAoeS50dl9zZWMqMTAwMDAwMC4wICsgeS50dl9uc2VjLzEwMDAuMCkgCiAgICAgICAgICAtICh4LnR2X3NlYyoxMDAwMDAwLjAgKyB4LnR2X25zZWMvMTAwMC4wKTsKfQoKZXh0ZXJuICJDIiB2b2lkKiBmMSh2b2lkKikKewogICAgY2xvY2tfZ2V0dGltZShDTE9DS19SRUFMVElNRSwgJnJ1bm5pbmcpOwogICAgcmV0dXJuIE5VTEw7Cn0KCmV4dGVybiAiQyIgdm9pZCogZjIodm9pZCopCnsKICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmbXgpOwogICAgcmVhZHkgPSAxOwogICAgcHRocmVhZF9jb25kX3NpZ25hbCgmY3YpOwogICAgCiAgICB3aGlsZShtc2cgPT0gMCkKICAgICAgICBwdGhyZWFkX2NvbmRfd2FpdCgmY3YsICZteCk7CiAgICBjbG9ja19nZXR0aW1lKENMT0NLX1JFQUxUSU1FLCAmcmVjZWl2ZWQpOwogICAgcHRocmVhZF9tdXRleF91bmxvY2soJm14KTsKICAgIHJldHVybiBOVUxMOwp9CgppbnQgbWFpbigpCnsKICAgIHN0ZDo6cGFydGlhbF9zdW0odi5iZWdpbigpLCB2LmVuZCgpLCB2LmJlZ2luKCkpOyAvLyBwb29yIG1hbidzIHN0ZDo6aW90YQoKICAgIHB0aHJlYWRfdCBobmRsOwogICAgc3RkOjp2ZWN0b3I8ZG91YmxlPiBzdGFydHMsIGpvaW5zLCBzb3J0cywgc2VuZHM7CiAgICBmb3IoaW50IG4gPSAwOyBuIDwgMTAwMDAwOyArK24pCiAgICB7CiAgICAgICAgc3RkOjpyYW5kb21fc2h1ZmZsZSh2LmJlZ2luKCksIHYuZW5kKCkpOwoKICAgICAgICBjbG9ja19nZXR0aW1lKENMT0NLX1JFQUxUSU1FLCAmc3RhcnQpOwogICAgICAgIHB0aHJlYWRfY3JlYXRlKCZobmRsLCBOVUxMLCBmMSwgTlVMTCk7CiAgICAgICAgcHRocmVhZF9qb2luKGhuZGwsIE5VTEwpOwogICAgICAgIGNsb2NrX2dldHRpbWUoQ0xPQ0tfUkVBTFRJTUUsICZqb2luZWQpOwogICAgICAgIHN0ZDo6c29ydCh2LmJlZ2luKCksIHYuZW5kKCkpOwogICAgICAgIGNsb2NrX2dldHRpbWUoQ0xPQ0tfUkVBTFRJTUUsICZzb3J0ZWQpOwoKICAgICAgICBwdGhyZWFkX2NyZWF0ZSgmaG5kbCwgTlVMTCwgZjIsIE5VTEwpOwogICAgICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmbXgpOwogICAgICAgIHdoaWxlKCFyZWFkeSkKICAgICAgICAgICAgcHRocmVhZF9jb25kX3dhaXQoJmN2LCAmbXgpOwogICAgICAgIG1zZz0xOwogICAgICAgIGNsb2NrX2dldHRpbWUoQ0xPQ0tfUkVBTFRJTUUsICZzZW50KTsKICAgICAgICBwdGhyZWFkX2NvbmRfc2lnbmFsKCZjdik7CiAgICAgICAgcHRocmVhZF9tdXRleF91bmxvY2soJm14KTsKICAgICAgICBwdGhyZWFkX2pvaW4oaG5kbCwgTlVMTCk7CiAgICAgICAgbXNnPXJlYWR5PTA7CgogICAgICAgIHN0YXJ0cy5wdXNoX2JhY2soZGlmZihzdGFydCwgcnVubmluZykpOwogICAgICAgIGpvaW5zLnB1c2hfYmFjayhkaWZmKHJ1bm5pbmcsIGpvaW5lZCkpOwogICAgICAgIHNvcnRzLnB1c2hfYmFjayhkaWZmKGpvaW5lZCwgc29ydGVkKSk7CiAgICAgICAgc2VuZHMucHVzaF9iYWNrKGRpZmYoc2VudCwgcmVjZWl2ZWQpKTsKICAgIH0KICAgIHN0ZDo6Y291dCA8PCAiYXZlcmFnZSB0aW1lIHRvIHNwYXduIGEgdGhyZWFkOiAiIDw8IGF2ZyhzdGFydHMpIDw8ICIgdXNcbiIKICAgICAgICAgICAgICA8PCAiYXZlcmFnZSB0aW1lIHRvIGpvaW4gYSB0aHJlYWQ6ICIgPDwgYXZnKGpvaW5zKSA8PCAiIHVzXG4iCiAgICAgICAgICAgICAgPDwgImF2ZXJhZ2UgdGltZSB0byBzb3J0IDEwMDAgaW50czogIiA8PCBhdmcoc29ydHMpIDw8ICIgdXNcbiIKICAgICAgICAgICAgICA8PCAiYXZlcmFnZSB0aW1lIHRvIG1lc3NhZ2UgYSB0aHJlYWQ6ICIgPDwgYXZnKHNlbmRzKSA8PCAiIHVzXG4iOwogICAgcHRocmVhZF9tdXRleF9kZXN0cm95KCZteCk7CiAgICBwdGhyZWFkX2NvbmRfZGVzdHJveSgmY3YpOwp9Cg==