DEFINE_CONSTRUCTOR_END /** * @brief simulate class CCycbuffer destructor * * free all the simulate class member variable, * @author hankejia * @date 2012-07-05 * @param[in] pthis the pointer point to the CCycBuffer. * @return NONE */ DEFINE_DESTRUCTOR_BEGIN( CCycBuffer ) { CCycBuffer *this = (CCycBuffer *)pthis; CycBuffer_handle * handle = (CycBuffer_handle *)this->handle; //虚构时,如果当前还有线程在Push流程中等待 //那么首先Pop出Buffer中的所有数据,唤醒在Push //中等待的线程,等待其完成push操作。 Condition_Lock( handle->mDataCon ); if ( !( handle->mPushComplete ) ) { Condition_Unlock( handle->mDataCon ); Clean( this ); //唤醒在Push中等待的线程 Condition_Signal( &(handle->mDataCon) ); Condition_Wait( &(handle->mDataCon) ); Condition_Unlock( handle->mDataCon ); } else Condition_Unlock( handle->mDataCon ); //如果当前还有线程在pop流程中等待,那么首先 //向Buffer中Push数据,唤醒在Pop中等待的线程,等 //待其完成pop操作。 Condition_Lock( handle->mDataCon ); if ( !( handle->mPopComplete ) ) { Condition_Unlock( handle->mDataCon ); FakePushFull( this ); //唤醒在Pop中等待的线程 Condition_Signal( &(handle->mDataCon) ); Condition_Wait( &handle->mDataCon ); Condition_Unlock( handle->mDataCon ); } else Condition_Unlock( handle->mDataCon ); DestroyCycBuffer( this ); Condition_Destroy( &( handle->mDataCon ) ); Condition_Destroy( &( handle->mWriteDataCon ) ); //Condition_Destroy( &( handle->mWaitForPopCon ) ); //Condition_Destroy( &( handle->mWaitForPushCon ) ); free( handle ); }
/* ------------------------------------------------------------------- * Wait for all thread object's execution to complete. Depends on the * thread count being accurate and the threads sending a condition * signal when they terminate. * ------------------------------------------------------------------- */ void thread_joinall( void ) { Condition_Lock( thread_sNum_cond ); while ( thread_sNum > 0 ) { Condition_Wait( &thread_sNum_cond ); } Condition_Unlock( thread_sNum_cond ); } // end Joinall
/** * @brief pop the read point from cyc buffer * * @author hankejia * @date 2012-11-05 * @param[in] pthis the pointer point to the CCycBuffer. * @return T_S32 * @retval return the read point of cycbuffer,if return NULL failed */ static T_CHR * PopSingle( T_pVOID pthis, T_S32 iSize ) { CCycBuffer *this = ( CCycBuffer * )pthis; CycBuffer_handle * handle = (CycBuffer_handle *)this->handle; //the cyc buffer is empty, wait for push Condition_Lock( handle->mDataCon ); handle->mPopComplete = AK_FALSE; while ( ( handle->mUseSize < iSize ) && ( !(handle->mForceQuit) ) ) { //Condition_Unlock( handle->mDataCon ); Condition_Unlock( handle->mWriteDataCon ); //logi( "PopSingle buffer empty!\n" ); Condition_Wait( &(handle->mDataCon) ); //logi( "wake up from push signed!\n" ); Condition_Unlock( handle->mDataCon ); Condition_Lock( handle->mWriteDataCon ); Condition_Lock( handle->mDataCon ); } if ( handle->mForceQuit ) { handle->mPopComplete = AK_TRUE; Condition_Unlock( handle->mDataCon ); return NULL; } assert( ( ( handle->mRead >= handle->mCycBuffer ) && ( handle->mRead < (handle->mCycBuffer + handle->mBufferSize) ) ) ); assert( ( ( handle->mWrite >= handle->mCycBuffer ) && ( handle->mWrite < (handle->mCycBuffer + handle->mBufferSize) ) ) ); Condition_Unlock( handle->mDataCon ); return handle->mRead; }
/* * ReportPacket is called by a transfer agent to record * the arrival or departure of a "packet" (for TCP it * will actually represent many packets). This needs to * be as simple and fast as possible as it gets called for * every "packet". */ void ReportPacket( ReportHeader* agent, ReportStruct *packet ) { if ( agent != NULL ) { int index = agent->reporterindex; /* * First find the appropriate place to put the information */ if ( agent->agentindex == NUM_REPORT_STRUCTS ) { // Just need to make sure that reporter is not on the first // item while ( index == 0 ) { Condition_Signal( &ReportCond ); Condition_Lock( ReportCond ); Condition_Wait( &ReportDoneCond ); Condition_Unlock( ReportCond ); index = agent->reporterindex; } agent->agentindex = 0; } // Need to make sure that reporter is not about to be "lapped" while ( index - 1 == agent->agentindex ) { Condition_Signal( &ReportCond ); Condition_Lock( ReportCond ); Condition_Wait( &ReportDoneCond ); Condition_Unlock( ReportCond ); index = agent->reporterindex; } // Put the information there memcpy( agent->data + agent->agentindex, packet, sizeof(ReportStruct) ); // Updating agentindex MUST be the last thing done agent->agentindex++; #ifndef HAVE_THREAD /* * Process the report in this thread */ process_report ( agent ); #endif } }
/* * This function is called only when the reporter thread * This function is the loop that the reporter thread processes */ void reporter_spawn( thread_Settings *thread ) { do { // This section allows for safe exiting with Ctrl-C Condition_Lock ( ReportCond ); if ( ReportRoot == NULL ) { // Allow main thread to exit if Ctrl-C is received thread_setignore(); Condition_Wait ( &ReportCond ); // Stop main thread from exiting until done with all reports thread_unsetignore(); } Condition_Unlock ( ReportCond ); again: if ( ReportRoot != NULL ) { ReportHeader *temp = ReportRoot; //Condition_Unlock ( ReportCond ); if(temp->report.mThreadMode == kMode_Client){ synchronize(); } if ( reporter_process_report ( temp ) ) { // This section allows for more reports to be added while // the reporter is processing reports without needing to // stop the reporter or immediately notify it Condition_Lock ( ReportCond ); if ( temp == ReportRoot ) { // no new reports ReportRoot = temp->next; } else { // new reports added ReportHeader *itr = ReportRoot; while ( itr->next != temp ) { itr = itr->next; } itr->next = temp->next; } // finished with report so free it free( temp ); Condition_Unlock ( ReportCond ); Condition_Signal( &ReportDoneCond ); if (ReportRoot) goto again; } Condition_Signal( &ReportDoneCond ); usleep(10000); } else { //Condition_Unlock ( ReportCond ); } } while ( 1 ); }
/* * BarrierClient allows for multiple stream clients to be syncronized */ void BarrierClient( ReportHeader *agent ) { Condition_Lock(agent->multireport->barrier); agent->multireport->threads--; if ( agent->multireport->threads == 0 ) { // last one set time and wake up everyone gettimeofday( &(agent->multireport->startTime), NULL ); Condition_Broadcast( &agent->multireport->barrier ); } else { Condition_Wait( &agent->multireport->barrier ); } agent->multireport->threads++; Condition_Unlock( agent->multireport->barrier ); agent->report.startTime = agent->multireport->startTime; agent->report.nextTime = agent->report.startTime; TimeAdd( agent->report.nextTime, agent->report.intervalTime ); }
/* ------------------------------------------------------------------- * Wait for all thread object's execution to complete. Depends on the * thread count being accurate and the threads sending a condition * signal when they terminate. * ------------------------------------------------------------------- */ void thread_joinall( void ) { Condition_Lock( thread_sNum_cond ); #if IPERF_DEBUG int waiting_on = -1; #endif /* IPERF_DEBUG */ IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Waiting on thread_sNum_cond condition.\r\n" ) ); while ( thread_sNum > 0 ) { #if IPERF_DEBUG if ( thread_sNum != waiting_on ) { waiting_on = thread_sNum; IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Waiting on %d threads.\r\n", waiting_on ) ); } #endif /* IPERF_DEBUG */ Condition_Wait( &thread_sNum_cond ); } Condition_Unlock( thread_sNum_cond ); } // end Joinall
static T_S32 PushSingle( T_pVOID pthis, T_CHR * pBuffer, T_S32 iSize ) { CCycBuffer *this = ( CCycBuffer * )pthis; CycBuffer_handle * handle = (CycBuffer_handle *)this->handle; T_S32 iLeavings = 0; T_S32 iWriteSize = 0; T_S32 iLineSize = 0; T_CHR * mTempWrite = NULL; if ( iSize > handle->mBufferSize ) { loge( "CCycBuffer::Push() can't not push %d data to buffer, %d > %d(buffer size)", iSize, iSize, handle->mBufferSize ); return -1; } //the cyc buffer is full. wait for pop Condition_Lock( handle->mDataCon ); handle->mPushComplete = AK_FALSE; while ( ( ( handle->mBufferSize - handle->mUseSize ) < iSize ) && ( !(handle->mForceQuit) ) ) { //Condition_Unlock( handle->mDataCon ); logi( "PushSingle buffer full! %d\n", handle->mBufferSize ); Condition_Wait( &(handle->mDataCon) ); //logi( "wake up from pop signed!\n" ); //Condition_Lock( handle->mDataCon ); } if ( handle->mForceQuit ) { handle->mPushComplete = AK_TRUE; Condition_Unlock( handle->mDataCon ); return 0; } assert( ( pBuffer != NULL ) && ( handle->mCycBuffer != NULL ) && ( iSize > 0 ) ); assert( ( ( handle->mRead >= handle->mCycBuffer ) && ( handle->mRead < (handle->mCycBuffer + handle->mBufferSize) ) ) ); assert( ( ( handle->mWrite >= handle->mCycBuffer ) && ( handle->mWrite < (handle->mCycBuffer + handle->mBufferSize) ) ) ); mTempWrite = handle->mWrite; Condition_Unlock( handle->mDataCon ); iLeavings = iSize; while ( iLeavings > 0 ) { iLineSize = ( handle->mCycBuffer + handle->mBufferSize ) - mTempWrite; iWriteSize = ( iLineSize > iLeavings )?iLeavings:iLineSize; memcpy( mTempWrite, pBuffer, iWriteSize ); if ( iWriteSize == iLineSize ) mTempWrite = handle->mCycBuffer; else mTempWrite += iWriteSize; pBuffer += iWriteSize; iLeavings -= iWriteSize; } Condition_Lock( handle->mDataCon ); handle->mWrite = mTempWrite; handle->mUseSize = ( ( handle->mUseSize + iSize ) > handle->mBufferSize )?handle->mBufferSize:( handle->mUseSize + iSize ); if ( handle->mUseSize == handle->mBufferSize ) handle->mRead = handle->mWrite; handle->mPushComplete = AK_TRUE; Condition_Unlock( handle->mDataCon ); Condition_Signal( &(handle->mDataCon) ); return iSize; }
/** * @brief pop data from cyc buffer * * @author hankejia * @date 2012-07-05 * @param[in] pthis the pointer point to the CCycBuffer. * @param[out] pBuffer the memory to saved the data * @param[in] iSize how many bytes you want to pop from cyc buffer * @return T_S32 * @retval return >=0 the size of bytes pop from cyc buffer, < 0 failed */ static T_S32 Pop( T_pVOID pthis, char * pBuffer, T_S32 iSize ) { CCycBuffer *this = ( CCycBuffer * )pthis; CycBuffer_handle * handle = (CycBuffer_handle *)this->handle; T_S32 iGetSize= 0; T_S32 iLeavings = 0; T_S32 iReadSize = 0; T_S32 iLineSize = 0; if ( iSize > handle->mBufferSize ) { loge( "CCycBuffer::Pop() can't not Pop %d data from buffer, %d > %d(buffer size)", iSize, iSize, handle->mBufferSize ); return -1; } //the cyc buffer is empty, wait for push Condition_Lock( handle->mDataCon ); handle->mPopComplete = AK_FALSE; while ( ( handle->mUseSize < iSize ) && ( !(handle->mForceQuit) ) ) { //Condition_Unlock( handle->mDataCon ); //logi( "buffer empty!\n" ); Condition_Wait( &(handle->mDataCon) ); //logi( "wake up from push signed!\n" ); //Condition_Lock( handle->mDataCon ); } if ( handle->mForceQuit ) { handle->mPopComplete = AK_TRUE; Condition_Unlock( handle->mDataCon ); return 0; } assert( ( pBuffer != NULL ) && ( handle->mCycBuffer != NULL ) && ( iSize > 0 ) ); assert( ( ( handle->mRead >= handle->mCycBuffer ) && ( handle->mRead < (handle->mCycBuffer + handle->mBufferSize) ) ) ); assert( ( ( handle->mWrite >= handle->mCycBuffer ) && ( handle->mWrite < (handle->mCycBuffer + handle->mBufferSize) ) ) ); iGetSize = ( (handle->mUseSize) > iSize )?iSize:(handle->mUseSize); iLeavings = iGetSize; while ( iLeavings > 0 ) { iLineSize = ( handle->mCycBuffer + handle->mBufferSize ) - handle->mRead; iReadSize = ( iLineSize > iLeavings )?iLeavings:iLineSize; memcpy( pBuffer, handle->mRead, iReadSize ); if ( iReadSize == iLineSize ) handle->mRead = handle->mCycBuffer; else handle->mRead += iReadSize; pBuffer += iReadSize; iLeavings -= iReadSize; } handle->mUseSize -= iGetSize; handle->mPopComplete = AK_TRUE; Condition_Unlock( handle->mDataCon ); //logi( "pop signal send!\n" ); Condition_Signal( &(handle->mDataCon) ); return iGetSize; }
static void *photograph_thread(void *param) { //int mount_falg = 0; T_S32 bavail, bsize; signed long long DiskSize = 0; T_pSTR filename; while(1) { Condition_Lock( g_conMangerPh ); Condition_Wait( &g_conMangerPh ); if(g_phsize == 0) continue; Condition_Unlock( g_conMangerPh ); if(sd_mount == 0) { if (access(SDDEV, R_OK) < 0) { //no sd card printf("no SDsard exit \n"); continue; } else { //mount_sd(); } //mount_falg =1; } DiskFreeSize( "/mnt", &bavail, &bsize); DiskSize = (T_S64)(T_U32)(bavail) * (T_S64)(T_U32)(bsize); if ( DiskSize < (T_S64)MIN_FREE_SPACE_SIZE ) { printf( "get %s disk size error!\n", "/mnt" ); //umount_sd(); goto err; } filename = MakeFileName(); printf("filename is %s \n", filename); if(filename == NULL) { printf("filename is NULL \n"); goto err; } long fid = open(filename, O_RDWR | O_CREAT | O_TRUNC); if(fid <= 0) { printf("open file err \n"); free(filename); goto err; } Condition_Lock( g_conMetex ); g_busy = 1; Condition_Unlock( g_conMetex ); write( fid, encbuf, g_phsize); Condition_Lock( g_conMetex ); g_busy = 0; Condition_Unlock( g_conMetex ); close(fid); free(filename); err: g_phsize = 0; //if( mount_falg == 1 ) //{ //umount_sd(); //} //printf("save file ok\n"); } return NULL; }