int main(void) { REAL8TimeSeries *conv, *data, *response, *exactConv; const UINT4 N = 101; const LIGOTimeGPS zero = {0, 0}; UINT4 i; conv = XLALCreateREAL8TimeSeries("FFT Convolution", &zero, 0.0, 0.01, &lalDimensionlessUnit, N); data = XLALCreateREAL8TimeSeries("data", &zero, 0.0, 0.01, &lalDimensionlessUnit, N); response = XLALCreateREAL8TimeSeries("response function", &zero, 0.0, 0.01, &lalDimensionlessUnit, N); exactConv = XLALCreateREAL8TimeSeries("exact convolution", &zero, 0.0, 0.01, &lalDimensionlessUnit, N); data->data->data[0] = 1.0; for (i = 1; i < N; i++) { /* Data is 1/i */ data->data->data[i] = 1.0 / i; } response->data->data[0] = 1.0; for (i = 1; i <= (N-1)/2; i++) { response->data->data[i] = exp(-(i/10.0)); /* Decaying exponential with time constant 10. */ response->data->data[N-i] = exp(-(i/10.0)); /* Same in the negative, wrapped dimension. */ } if (N % 2 == 0) { response->data->data[N/2] = exp(-(N/20.0)); } /* Exact, O(N^2) convolution */ for (i = 0; i < N; i++) { REAL8 sum = 0.0; UINT4 j; for (j = MAX_INT(0, ((int)i)-((int) N/2)); j <= MIN_INT(i+N/2, N-1); j++) { UINT4 rIndex = (j > i ? i + (N - j) : i - j); sum += data->data->data[j]*response->data->data[rIndex]; } exactConv->data->data[i] = sum; } convolveTimeSeries(conv, data, response); for (i = 0; i < N; i++) { if (fabs(exactConv->data->data[i] - conv->data->data[i]) > 1e-8) { fprintf(stderr, "Index %d differs (exact = %g, FFT = %g)\n", i, exactConv->data->data[i], conv->data->data[i]); } } XLALDestroyREAL8TimeSeries(conv); XLALDestroyREAL8TimeSeries(data); XLALDestroyREAL8TimeSeries(response); XLALDestroyREAL8TimeSeries(exactConv); return 0; }
/** * MAX3421 state change task and interrupt handler. * @return error code or 0 if successful. */ uint8_t max3421e_poll(void) { uint8_t rcode = 0; // Check interrupt. if (MAX_INT() == 0) rcode = max3421e_interruptHandler(); if (MAX_GPX() == 0) max3421e_gpxInterruptHandler(); return (rcode); }
/** * Стартовые статы при любых условиях должны соответствовать границам ролла. * В случае старого ролла тут это всплывет из-за нулевых статов. */ bool bad_start_stats(CHAR_DATA *ch) { if (ch->get_start_stat(G_STR) > MAX_STR(ch) || ch->get_start_stat(G_STR) < MIN_STR(ch) || ch->get_start_stat(G_DEX) > MAX_DEX(ch) || ch->get_start_stat(G_DEX) < MIN_DEX(ch) || ch->get_start_stat(G_INT) > MAX_INT(ch) || ch->get_start_stat(G_INT) < MIN_INT(ch) || ch->get_start_stat(G_WIS) > MAX_WIS(ch) || ch->get_start_stat(G_WIS) < MIN_WIS(ch) || ch->get_start_stat(G_CON) > MAX_CON(ch) || ch->get_start_stat(G_CON) < MIN_CON(ch) || ch->get_start_stat(G_CHA) > MAX_CHA(ch) || ch->get_start_stat(G_CHA) < MIN_CHA(ch) || start_stats_count(ch) != SUM_ALL_STATS) { return 1; } return 0; }
// 计算各种车牌空格宽度 void InitSpaceWidth() { float fSpace1, fSpace2; int iSum, iChar; int iWidth; // baWJSpaceWidth 数组(武警牌上各个空格的宽度)的内容 for (iWidth = MIN_CHAR_WIDTH; iWidth <= MAX_CHAR_WIDTH; iWidth ++ ) { fSpace2 = (float)WJ_SPACE2_WIDTH * iWidth; iSum = round( fSpace2 ); baWJSpaceWidth[iWidth - MIN_CHAR_WIDTH][0] = iSum; fSpace1 = (float)WJ_SPACE1_WIDTH * iWidth; for (iChar = 1; iChar < PLATE_CHAR_NUM - 1; iChar ++ ) { fSpace1 += fSpace2; baWJSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] = MAX_INT( 1, round( fSpace1 ) - iSum ); iSum += MAX_INT( 1, round( fSpace1 ) - iSum ); } fSpace1 += fSpace2 / 2.0f; baWJSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] = MAX_INT( 1, round( fSpace1 ) - iSum ); iSum += MAX_INT( 1, round( fSpace1 ) - iSum ); baWJSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar + 1] = iSum; } // baNormalSpaceWidth 数组(普通牌上各个空格的宽度)的内容 for ( iWidth = MIN_CHAR_WIDTH; iWidth <= MAX_CHAR_WIDTH; iWidth ++ ) { fSpace2 = NORMAL_SPACE2_WIDTH * iWidth; iSum = round( fSpace2 ); baNormalSpaceWidth[iWidth - MIN_CHAR_WIDTH][0] = iSum; fSpace1 = NORMAL_SPACE1_WIDTH * iWidth; for ( iChar = 1; iChar < PLATE_CHAR_NUM - 1; iChar ++ ) { fSpace1 += fSpace2; baNormalSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] = MAX_INT( 1, round( fSpace1 ) - iSum ); iSum += MAX_INT( 1, round( fSpace1 ) - iSum ); } fSpace1 += fSpace2 / 2.0f; baNormalSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] = MAX_INT( 1, round( fSpace1 ) - iSum ); iSum += MAX_INT( 1, round( fSpace1 ) - iSum ); baNormalSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar + 1] = iSum; } // baPoliceSpaceWidth 数组(正规警牌上各个空格的宽度)的内容 for ( iWidth = MIN_CHAR_WIDTH; iWidth <= MAX_CHAR_WIDTH; iWidth ++ ) { fSpace1 = NORMAL_SPACE1_WIDTH * iWidth; iSum = round( fSpace1 ); baPoliceSpaceWidth[iWidth - MIN_CHAR_WIDTH][0] = iSum; fSpace2 = NORMAL_SPACE2_WIDTH * iWidth; for ( iChar = 1; iChar < PLATE_CHAR_NUM - 1; iChar ++ ) { fSpace1 += fSpace2; baPoliceSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] = MAX_INT( 1, round( fSpace1 ) - iSum ); iSum += MAX_INT( 1, round( fSpace1 ) - iSum ); } fSpace1 += fSpace2 / 2.0f; baPoliceSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] = MAX_INT( 1, round( fSpace1 ) - iSum ); iSum += MAX_INT( 1, round( fSpace1 ) - iSum ); baPoliceSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar + 1] = iSum; } for ( iWidth = MIN_CHAR_WIDTH; iWidth <= MAX_CHAR_WIDTH; iWidth ++ ) { iSum = 0; for( iChar=0;iChar<=2;iChar++) { baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] = MAX_INT(1,baNormalSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar+2] - 1); iSum += baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar]; } baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][3] = MAX_INT(1,baNormalSpaceWidth[iWidth - MIN_CHAR_WIDTH][1] - 1); iSum += baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][3]; baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][4] = MAX_INT(1,baNormalSpaceWidth[iWidth - MIN_CHAR_WIDTH][0] - 1); iSum += baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][4]; for(iChar=5;iChar<7;iChar++) { baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] = MAX_INT(1,baNormalSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar] - 1); iSum += baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][iChar]; } baShiGuanSpaceWidth[iWidth - MIN_CHAR_WIDTH][7] = iSum; } }
int worker( struct TcpdaemonEntryParam *pep , struct TcpdaemonServerEnv *pse ) { struct sembuf sb ; fd_set readfds ; struct sockaddr accept_addr ; socklen_t accept_addrlen ; int accept_sock ; int nret = 0 ; while(1) { DebugLog( __FILE__ , __LINE__ , "WORKER(%ld) | waiting for entering accept mutex\n" , pse->index ); /* 进入临界区 */ memset( & sb , 0x00 , sizeof(struct sembuf) ); sb.sem_num = 0 ; sb.sem_op = -1 ; sb.sem_flg = SEM_UNDO ; nret = semop( pse->accept_mutex , & sb , 1 ) ; if( nret == -1 ) { ErrorLog( __FILE__ , __LINE__ , "WORKER(%ld) | enter accept mutex failed , errno[%d]\n" , pse->index , errno ); return -1; } else { DebugLog( __FILE__ , __LINE__ , "WORKER(%ld) | enter accept mutex ok\n" , pse->index ); } /* 监控侦听socket或存活管道事件 */ FD_ZERO( & readfds ); FD_SET( pse->listen_sock , & readfds ); FD_SET( pse->alive_pipe->fd[0] , & readfds ); nret = select( MAX_INT(pse->listen_sock,pse->alive_pipe->fd[0])+1 , & readfds , NULL , NULL , NULL ) ; if( nret == -1 ) { ErrorLog( __FILE__ , __LINE__ , "WORKER(%ld) | select failed , errno[%d]\n" , pse->index , errno ); break; } if( FD_ISSET( pse->alive_pipe->fd[0] , & readfds ) ) { DebugLog( __FILE__ , __LINE__ , "WORKER(%ld) | alive_pipe received quit command\n" , pse->index ); break; } /* 接受新客户端连接 */ accept_addrlen = sizeof(struct sockaddr) ; memset( & accept_addr , 0x00 , accept_addrlen ); accept_sock = accept( pse->listen_sock , & accept_addr , & accept_addrlen ) ; if( accept_sock == -1 ) { ErrorLog( __FILE__ , __LINE__ , "WORKER(%ld) | accept failed , errno[%d]\n" , pse->index , errno ); break; } else { DebugLog( __FILE__ , __LINE__ , "WORKER(%ld) | accept ok , [%d]accept[%d]\n" , pse->index , pse->listen_sock , accept_sock ); } if( pep->tcp_nodelay > 0 ) { setsockopt( accept_sock , IPPROTO_TCP , TCP_NODELAY , (void*) & (pep->tcp_nodelay) , sizeof(int) ); } if( pep->tcp_linger > 0 ) { struct linger lg ; lg.l_onoff = 1 ; lg.l_linger = pep->tcp_linger - 1 ; setsockopt( accept_sock , SOL_SOCKET , SO_LINGER , (void *) & lg , sizeof(struct linger) ); } /* 离开临界区 */ memset( & sb , 0x00 , sizeof(struct sembuf) ); sb.sem_num = 0 ; sb.sem_op = 1 ; sb.sem_flg = SEM_UNDO ; nret = semop( pse->accept_mutex , & sb , 1 ) ; if( nret == -1 ) { ErrorLog( __FILE__ , __LINE__ , "WORKER(%ld) | leave accept mutex failed , errno[%d]\n" , pse->index , errno ); return -1; } else { DebugLog( __FILE__ , __LINE__ , "WORKER(%ld) | leave accept mutex ok\n" , pse->index ); } /* 调用通讯数据协议及应用处理回调函数 */ DebugLog( __FILE__ , __LINE__ , "WORKER(%ld) | 调用tcpmain\n" , pse->index ); nret = pse->pfunc_tcpmain( pep->param_tcpmain , accept_sock , & accept_addr ) ; if( nret < 0 ) { ErrorLog( __FILE__ , __LINE__ , "WORKER(%ld) | tcpmain return[%d]\n" , pse->index , nret ); return -1; } else if( nret > 0 ) { WarnLog( __FILE__ , __LINE__ , "WORKER(%ld) | tcpmain return[%d]\n" , pse->index , nret ); } else { DebugLog( __FILE__ , __LINE__ , "WORKER(%ld) | tcpmain return[%d]\n" , pse->index , nret ); } /* 关闭客户端连接 */ close( accept_sock ); DebugLog( __FILE__ , __LINE__ , "close[%d]\n" , accept_sock ); /* 检查工作进程处理数量 */ pse->requests_per_process++; if( pep->max_requests_per_process != 0 && pse->requests_per_process >= pep->max_requests_per_process ) { InfoLog( __FILE__ , __LINE__ , "WORKER(%ld) | maximum number of processing[%ld][%ld] , ending\n" , pse->index , pse->requests_per_process , pep->max_requests_per_process ); return -1; } } /* 最终离开临界区 */ memset( & sb , 0x00 , sizeof(struct sembuf) ); sb.sem_num = 0 ; sb.sem_op = 1 ; sb.sem_flg = SEM_UNDO ; nret = semop( pse->accept_mutex , & sb , 1 ) ; if( nret == -1 ) { InfoLog( __FILE__ , __LINE__ , "WORKER(%ld) | leave accept mutex finally failed , errno[%d]\n" , pse->index , errno ); return -1; } else { DebugLog( __FILE__ , __LINE__ , "WORKER(%ld) | leave accept mutex finally ok\n" , pse->index ); } return 0; }