void * getThread(void *arg) { CObList <CMsgObj> *pQueue = (CObList <CMsgObj> *)arg; int64 _s, _e; int cc = 0; CMsgObj p(1); _s = GetAbsTime(); for( int i=0; i<loopnum; ++i) { // pQueue->release(&p); CMsgObj *a = pQueue->get(); if ( NULL == a ) break; ++cc; /* if ( NULL != p ) printf("thread[%lu], seq=%d, num=%d, idle_num=%d\n", pthread_self(), p->seq, myPool->get_num(), myPool->get_idle_num() ); else printf("thread[%lu], no more obj\n", pthread_self() ); */ // usleep(1); } _e = GetAbsTime(); // printf("thread[%lu], num=%d, idle_num=%d\n", pthread_self(), myPool->get_num(), myPool->get_idle_num()); printf("get thread[%lu], cc=%d, speed=%.3f\n", pthread_self(), cc, (int64)loopnum*1000.0*1000.0/(_e-_s)); return 0; }
void * putThread(void *arg) { TArg *pa = (TArg *)arg; CMyTT *ptt = pa->pMyTT; pa->ii = pa->nStartNum; printf("\tput thread#%d(%lu), from %u to %u\n", pa->seq, pthread_self(), pa->nStartNum, pa->nEndNum); while( pa->ii < pa->nEndNum) { for(int j=0; (j<speed)&&(pa->ii<pa->nEndNum); ++j ) { CMsgObj *p = new CMsgObj(pa->ii); p->_time = GetAbsTime(); p->h = (nToMsec(p->_time/1000)+1)%(600*1000u); ptt->nPut(p->seq, (void*)p); ++pa->ii; if ( 0 == pa->ii%10000 ) { printf("\tput thread#%d(%lu), ii=%u\n", pa->seq, pthread_self(), pa->ii); } } sleep(1); } exitflag = 1; sleep(1); printf("\tput thread#%d(%lu), total cc=%u\n", pa->seq, pthread_self(), pa->ii-pa->nStartNum); return 0; }
void * getThread(void *arg) { TArg *pa = (TArg *)arg; CMyTT *ptt = pa->pMyTT; while( 0 == exitflag ) { int64 _s = GetAbsTime(); int k = pa->ii-_s%100; if ( k < 0 ) continue; CMsgObj *ptr = (CMsgObj *)ptt->pvGet(k); if ( NULL != ptr ) { delete ptr; ptr = NULL; ++pa->cc; } usleep(1); } printf("\tget thread#%d(%lu), total cc=%u\n", pa->seq, pthread_self(), pa->cc); return 0; }
bool cRwLock::Lock(bool Write, int TimeoutMs) { int Result = 0; struct timespec abstime; if (TimeoutMs) { if (!GetAbsTime(&abstime, TimeoutMs)) TimeoutMs = 0; } if (Write) Result = TimeoutMs ? pthread_rwlock_timedwrlock(&rwlock, &abstime) : pthread_rwlock_wrlock(&rwlock); else Result = TimeoutMs ? pthread_rwlock_timedrdlock(&rwlock, &abstime) : pthread_rwlock_rdlock(&rwlock); return Result == 0; }
bool cCondVar::TimedWait(cMutex &Mutex, int TimeoutMs) { bool r = true; // true = condition signaled, false = timeout if (Mutex.locked) { struct timespec abstime; if (GetAbsTime(&abstime, TimeoutMs)) { int locked = Mutex.locked; Mutex.locked = 0; // have to clear the locked count here, as pthread_cond_timedwait // does an implicit unlock of the mutex. if (pthread_cond_timedwait(&cond, &Mutex.mutex, &abstime) == ETIMEDOUT) r = false; Mutex.locked = locked; } } return r; }
bool cCondWait::Wait(int TimeoutMs) { pthread_mutex_lock(&mutex); if (!signaled) { if (TimeoutMs) { struct timespec abstime; if (GetAbsTime(&abstime, TimeoutMs)) { while (!signaled) { if (pthread_cond_timedwait(&cond, &mutex, &abstime) == ETIMEDOUT) break; } } } else pthread_cond_wait(&cond, &mutex); } bool r = signaled; signaled = false; pthread_mutex_unlock(&mutex); return r; }
void vHandleTimeout(void *p) { CMsgObj *ptr = (CMsgObj *)p; ++timeout; int64 n = GetAbsTime(); timeout2[toi] = n-ptr->_time; if ( timeout2[toi] < 1000 ) { printf("h=%d, %llu - %llu = %llu\n", ptr->h, n, ptr->_time, n-ptr->_time); } ++toi; delete ptr; ptr = NULL; if ( 0 == timeout%100000 ) { // printf("CMyTT::vHandleTimeout(). timeout num=%d\n", timeout); } }
void mexFunction( int num_output_args, // Number of left hand side (output) arguments mxArray *output_arg[], // Array of left hand side arguments int num_input_args, // Number of right hand side (input) arguments const mxArray *input_arg[]) // Array of right hand side arguments { int opcode; MODULE_ID ModuleID, DestModID; HOST_ID DestHostID; short *HostAddress_raw; char HostAddress[MAX_HOST_ADDR_LENGTH]; int HostAddressLength = 0; MSG_TYPE MessageType; double timeout; int status; unsigned int SnoozeTime; int TimerID; int logger_status; void *pData; int NumDataBytes; const mxArray *Template; mxArray *ReturnData; bool try_again; double begin_time, end_time, elapsed_time; try { if( num_input_args < 1) { Error( "MatlabDragonfly takes at least 1 argument!"); } // // Get the "opcode" argument to determine what needs to be done // opcode = (int) mxGetScalar( input_arg[0]); switch( opcode) { case CONNECT_TO_MMM: if( num_input_args < 4) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { mexPrintf( "Disconnecting...\n"); TheModule.DisconnectFromMMM(); mexPrintf( "Re-connecting...\n"); } ModuleID = (MODULE_ID) mxGetScalar( input_arg[1]); HostAddressLength = mxGetNumberOfElements( input_arg[2]); logger_status = (int) mxGetScalar( input_arg[3]); TheModule.InitVariables( ModuleID, 0); try{ if( HostAddressLength > 0) { // Convert unicode matlab string to regular character string if( HostAddressLength > MAX_HOST_ADDR_LENGTH-1) Error( "Server name exceeds maximum allowed length"); HostAddress_raw = (short*) mxGetData( input_arg[2]); int i; for( i = 0; i < HostAddressLength; i++) HostAddress[i] = (char) HostAddress_raw[i]; HostAddress[i] = 0; // zero-terminate the string status = TheModule.ConnectToMMM( HostAddress, logger_status); } else { status = TheModule.ConnectToMMM( logger_status); } }catch(MyCException &E){ MyCString err("Failed to connect to MM:"); E.AppendTraceToString(err); Error(err.GetContent()); } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case DISCONNECT_FROM_MMM: if( num_input_args < 1) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { status = TheModule.DisconnectFromMMM( ); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case SUBSCRIBE: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); status = TheModule.Subscribe( MessageType); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case UNSUBSCRIBE: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); status = TheModule.Unsubscribe( MessageType); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case PAUSE_SUBSCRIPTION: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); status = TheModule.PauseSubscription( MessageType); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case RESUME_SUBSCRIPTION: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); status = TheModule.ResumeSubscription( MessageType); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case SEND_MESSAGE: if( num_input_args < 5) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); pData = SerializeData( input_arg[2], &NumDataBytes); M.Set( MessageType, pData, NumDataBytes); DestModID = (MODULE_ID) mxGetScalar( input_arg[3]); DestHostID = (HOST_ID) mxGetScalar( input_arg[4]); status = TheModule.SendMessage( &M, DestModID, DestHostID); mxFree( pData); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); output_arg[1] = mxCreateDoubleScalar( M.send_time); output_arg[2] = mxCreateDoubleScalar( (double) M.msg_count); break; case SEND_SIGNAL: if( num_input_args < 4) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); DestModID = (MODULE_ID) mxGetScalar( input_arg[2]); DestHostID = (HOST_ID) mxGetScalar( input_arg[3]); M.Set( MessageType); status = TheModule.SendMessage( &M, DestModID, DestHostID); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); output_arg[1] = mxCreateDoubleScalar( M.send_time); output_arg[2] = mxCreateDoubleScalar( (double) M.msg_count); break; case READ_MESSAGE_HDR: if( num_input_args < 3) Error( "incorrect number of arguments"); if( !TheModule.IsConnected( )) { output_arg[0] = EmptyMatrix( ); break; } timeout = mxGetScalar( input_arg[2]); begin_time = GetAbsTime(); do { try_again = false; try { status = TheModule.ReadMessage( &M, timeout); } catch( UPipeSignalException &e) { end_time = GetAbsTime(); elapsed_time = end_time - begin_time; timeout = timeout - elapsed_time; if( timeout < 0) timeout = 0; //mexPrintf("\nSignal caught and ignored!\n"); try_again = true; } } while( try_again); if( status > 0) { Template = input_arg[1]; ReturnData = C2Matlab( Template, &M, sizeof(DF_MSG_HEADER)); output_arg[0] = ReturnData; } else { output_arg[0] = EmptyMatrix( ); } break; case READ_MESSAGE_DATA: if( num_input_args < 2) Error( "incorrect number of arguments"); Template = input_arg[1]; ReturnData = C2Matlab( Template, M.GetDataPointer(), M.num_data_bytes); output_arg[0] = ReturnData; break; case SET_TIMER: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { SnoozeTime = (unsigned int) mxGetScalar( input_arg[1]); TimerID = TheModule.SetTimer( SnoozeTime); } else { TimerID = -1; } output_arg[0] = mxCreateDoubleScalar( (double) TimerID); break; case CANCEL_TIMER: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { TimerID = (unsigned int) mxGetScalar( input_arg[1]); status = TheModule.CancelTimer( TimerID); } else { status = -1; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case SEND_MODULE_READY: if( TheModule.IsConnected( )) { status = TheModule.SendModuleReady( ); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case GET_TIME: output_arg[0] = mxCreateDoubleScalar( GetAbsTime()); break; case GET_MODULE_ID: output_arg[0] = mxCreateDoubleScalar( TheModule.GetModuleID()); break; default: Error( "Invalid opcode"); } } catch( MyCException &e) { MyCString S; e.AppendTraceToString( S); char *s = S.GetContent( ); Error( s); } } // mexFunction
int main(int argc, char *argv[]) { int64 ccc = 0; int _max=0, _min=999999; if ( argc < 5 ) { printf("Usage: %s <hash size> <bucket> <pthread put speed> <total put num>\n", argv[0]); printf("\nexample:\t./%s 1000000 1000000 100 100000 \n", argv[0]); printf("\n"); return 0; } int count = atoi(argv[1]); int bucket = atoi(argv[2]); speed = atoi(argv[3]); loopnum = atoi(argv[4]); timeout2 = new int[count]; memset(timeout2,0,sizeof(int)*count); int i; CMyTT tt(count, bucket); int64 _s, _e; tt.Start(); /* // test put CMsgObj *p = new CMsgObj(0); p->_time = GetAbsTime(); p->h = (nToMsec(p->_time/1000)+1)%(600*1000); tt.nPut(p->seq, (void*)p); */ CMsgObj **pp; pp = new CMsgObj*[count]; for( i=0; i<count; ++i) pp[i] = new CMsgObj(i); // 1.test put speed printf("1. test put speed\n"); _s = GetAbsTime(); for( i=0; i<count; ++i) { pp[i]->_time = GetAbsTime(); pp[i]->h = (nToMsec(pp[i]->_time/1000)+1)%(600*1000u); tt.nPut(pp[i]->seq, (void*)pp[i]); } _e = GetAbsTime(); if ( _e != _s ) { printf("\telapse=%lld(usec), avg(%d) put speed=%.3f\n", _e-_s, count, (int64)count*1000.*1000./(_e-_s)); } printf("\ttotal put num=%d\n\n", count); // 2.test get speed // 由于get与put不同步,可能get不到数据 printf("2. test get speed\n"); int cc = 0; _s = GetAbsTime(); for( i=0; i<count; ++i) { CMsgObj *ptr = (CMsgObj *)tt.pvGet(i); if ( NULL != ptr ) { delete ptr; ptr = NULL; ++cc; } } _e = GetAbsTime(); if ( _e != _s ) { printf("\telapse=%lld(usec), avg(%d) get speed=%.3f\n", _e-_s, count, (int64)count*1000.*1000./(_e-_s)); } printf("\ttotal get num=%d\n\n", cc); printf("\tsleep 2s, wait for all node timeout\n\n"); sleep(2); // 计算延时 ccc = 0; _max=0; _min=999999; for(int m=0; m<timeout; ++m) { if ( timeout2[m] > _max ) _max = timeout2[m]; if ( timeout2[m] < _min ) _min = timeout2[m]; ccc += timeout2[m]; } printf("\ttimeout=%d, avg=%.3f(usec), max=%d(usec), min=%d(usec)\n", timeout, ccc*1.0/timeout, _max, _min); printf("\n"); // 3.test threads put&get speed memset(timeout2,0,sizeof(int)*count); timeout = 0; toi = 0; printf("3.test random put&get speed\n"); #define MacThreadNum 20 pthread_t t[MacThreadNum], t1[MacThreadNum]; TArg a[MacThreadNum]; for(int m=0;m<MacThreadNum;++m) { a[m].seq = m; a[m].pMyTT = &tt; a[m].nStartNum = m*loopnum/MacThreadNum; a[m].nEndNum = loopnum/MacThreadNum*(m+1); a[m].ii = 0; a[m].cc = 0; pthread_create(&t[m], NULL, putThread, &a[m]); pthread_create(&t1[m], NULL, getThread, &a[m]); } printf("\twaiting for thread exit!\n"); for(int m=0;m<MacThreadNum;++m) { pthread_join( t[m] , NULL ); pthread_join( t1[m] , NULL ); } printf("\tall thread exit!\n"); ccc = 0; for(int m=0;m<MacThreadNum;++m) { ccc += a[m].cc; } printf("\tget=%lld\n", ccc); // 计算延时 ccc = 0; _max=0; _min=999999; for(int m=0; m<timeout; ++m) { if ( timeout2[m] > _max ) _max = timeout2[m]; if ( timeout2[m] < _min ) _min = timeout2[m]; ccc += timeout2[m]; } printf("\ttimeout=%d, avg=%.3f(usec), max=%d(usec), min=%d(usec)\n", timeout, ccc*1.0/timeout, _max, _min); // 等待退出 printf("\tsleep 2s\n"); sleep(2); printf("\ttest done\n"); return 0; }