void KRB5_CALLCONV krb5int_mutex_report_stats(k5_mutex_t *m) { char *p; /* Tweak this to only record data on "interesting" locks. */ if (m->stats.count < 10) return; if (m->stats.lockwait.valsum < 10 * m->stats.count) return; p = strrchr(m->loc_created.filename, '/'); if (p == NULL) p = m->loc_created.filename; else p++; fprintf(stats_logfile, "mutex @%p: created at line %d of %s\n", (void *) m, m->loc_created.lineno, p); if (m->stats.count == 0) fprintf(stats_logfile, "\tnever locked\n"); else { double sd_wait, sd_hold; sd_wait = get_stddev(m->stats.lockwait, m->stats.count); sd_hold = get_stddev(m->stats.lockheld, m->stats.count); fprintf(stats_logfile, "\tlocked %d time%s; wait %lu/%f/%lu/%fus, hold %lu/%f/%lu/%fus\n", m->stats.count, m->stats.count == 1 ? "" : "s", (unsigned long) m->stats.lockwait.valmin, (double) m->stats.lockwait.valsum / m->stats.count, (unsigned long) m->stats.lockwait.valmax, sd_wait, (unsigned long) m->stats.lockheld.valmin, (double) m->stats.lockheld.valsum / m->stats.count, (unsigned long) m->stats.lockheld.valmax, sd_hold); } }
static enum piglit_result draw(Display *dpy) { enum piglit_result result = PIGLIT_PASS; int64_t last_ust = 0xd0, last_msc = 0xd0, last_sbc = 0xd0; int64_t last_timestamp = -1; struct stats msc_wallclock_duration_stats = {}; struct stats msc_ust_duration_stats = {}; double expected_msc_wallclock_duration = 0.0; int32_t rate_num, rate_den; unsigned int i; if (!glXGetSyncValuesOML(dpy, win, &last_ust, &last_msc, &last_sbc)) { fprintf(stderr, "Initial glXGetSyncValuesOML failed\n"); return PIGLIT_FAIL; } /* Check that the window is fresh */ if (last_sbc != 0) { fprintf(stderr, "Initial SBC for the window should be 0, was " "%" PRId64 "\n", last_sbc); piglit_merge_result(&result, PIGLIT_WARN); } if (!glXGetMscRateOML(dpy, win, &rate_num, &rate_den)) { fprintf(stderr, "glXGetMscRateOML failed, can't test MSC duration\n"); piglit_merge_result(&result, PIGLIT_WARN); } else { expected_msc_wallclock_duration = 1e6 * rate_den / rate_num; } piglit_set_timeout(5, PIGLIT_FAIL); for (i = 0; i < loops; i++) { int64_t new_ust = 0xd0, new_msc = 0xd0, new_sbc = 0xd0; int64_t check_ust = 0xd0, check_msc = 0xd0, check_sbc = 0xd0; int64_t new_timestamp; int64_t expected_msc, target_sbc; int64_t target_msc = 0; if (target_msc_delta) { target_msc = last_msc + target_msc_delta; } if (use_swapbuffers) { glClearColor(0.0, 1.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); target_sbc = glXSwapBuffersMscOML(dpy, win, target_msc, divisor, msc_remainder); if(target_sbc <= 0) { fprintf(stderr, "SwapBuffersMscOML failed\n"); return PIGLIT_FAIL; } if(target_sbc != last_sbc + 1) { fprintf(stderr, "glXSwapBuffersMscOML calculated the" " wrong target sbc: expected %"PRId64 " but got %"PRId64"\n", last_sbc + 1, target_sbc); result = PIGLIT_FAIL; } if(!glXWaitForSbcOML(dpy, win, target_sbc, &new_ust, &new_msc, &new_sbc)) { fprintf(stderr, "glXWaitForSbcOML failed\n"); result = PIGLIT_FAIL; } } else { target_sbc = last_sbc; if(!glXWaitForMscOML(dpy, win, target_msc, divisor, msc_remainder, &new_ust, &new_msc, &new_sbc)) { fprintf(stderr, "glXWaitForSbcOML failed\n"); result = PIGLIT_FAIL; } } new_timestamp = piglit_get_microseconds(); if (!glXGetSyncValuesOML(dpy, win, &check_ust, &check_msc, &check_sbc)) { fprintf(stderr, "Follow-up GetSyncValuesOML failed\n"); return PIGLIT_FAIL; } if (new_ust < last_ust) { fprintf(stderr, "iteration %u: non-monotonic UST went " "backward by %"PRId64" during Wait\n", i, last_ust - new_ust); result = PIGLIT_FAIL; /* Wait returned something bogus, but GetSyncValues * usually works, so try evaluating the rest of the * tests using the check values. */ new_ust = check_ust; } if (check_ust < new_ust) { fprintf(stderr, "iteration %u: non-monotonic UST went " "backward by %"PRId64" across GetSyncValues\n", i, last_ust - check_ust); result = PIGLIT_FAIL; } if (new_msc < last_msc) { fprintf(stderr, "iteration %u: non-monotonic MSC went " "backward by %"PRId64" during Wait\n", i, last_msc - new_msc); result = PIGLIT_FAIL; /* Wait returned something bogus, but GetSyncValues * usually works, so try evaluating the rest of the * tests using the check values. */ new_msc = check_msc; } if (check_msc < new_msc) { fprintf(stderr, "iteration %u: non-monotonic MSC went " "backward by %"PRId64" across GetSyncValues\n", i, last_msc - check_msc); result = PIGLIT_FAIL; } if (new_sbc != target_sbc) { fprintf(stderr, "iteration %u: Wait should have " "returned at SBC %"PRId64" but returned at " "%"PRId64"\n", i, target_sbc, new_sbc); result = PIGLIT_FAIL; } if (check_sbc != new_sbc) { fprintf(stderr, "iteration %u: GetSyncValues " "returned SBC %"PRId64" but Wait returned " "%"PRId64"\n", i, check_sbc, new_sbc); result = PIGLIT_FAIL; } if (new_msc > last_msc) { int64_t delta_msc = new_msc - last_msc; update_stats(&msc_ust_duration_stats, (new_ust - last_ust) / delta_msc); if (last_timestamp >= 0) { if (new_timestamp < 0) { fprintf(stderr, "no monotonic clock\n"); piglit_merge_result(&result, PIGLIT_WARN); } else { update_stats( &msc_wallclock_duration_stats, (new_timestamp - last_timestamp) / delta_msc); } } } expected_msc = target_msc; if (!target_msc) { /* If there is a divisor, the expected MSC is the * next MSC after last_msc such that * MSC % divisor == remainder */ int64_t last_remainder = last_msc % divisor; expected_msc = last_msc - last_remainder + msc_remainder; if (expected_msc <= last_msc) expected_msc += divisor; } if (new_msc < expected_msc) { fprintf(stderr, "iteration %u woke up %"PRId64 " MSCs early\n", i, expected_msc - new_msc); result = PIGLIT_FAIL; } if (new_msc > expected_msc) { fprintf(stderr, "iteration %u woke up %"PRId64 " MSCs later than expected\n", i, new_msc - expected_msc); piglit_merge_result(&result, PIGLIT_WARN); } if (new_msc % divisor != msc_remainder) { fprintf(stderr, "iteration %u woke up at wrong MSC" " remainder %"PRId64", not requested remainder" " %"PRId64"\n", i, new_msc % divisor, msc_remainder); result = PIGLIT_FAIL; } last_ust = new_ust; last_msc = new_msc; last_sbc = new_sbc; last_timestamp = new_timestamp; } if (msc_ust_duration_stats.n < 2) { fprintf(stderr, "Not enough UST timing samples\n"); piglit_merge_result(&result, PIGLIT_WARN); } else if (expected_msc_wallclock_duration > 0.0) { double apparent_ust_rate = msc_ust_duration_stats.mean / expected_msc_wallclock_duration; if (get_stddev(&msc_ust_duration_stats) / apparent_ust_rate > 100) { fprintf(stderr, "UST duration per MSC is surprisingly" " variable (stddev %f USTs), but then it only" " has to be monotonic\n", get_stddev(&msc_ust_duration_stats)); piglit_merge_result(&result, PIGLIT_WARN); } } if (msc_wallclock_duration_stats.n < 2) { fprintf(stderr, "Not enough wallclock timing samples\n"); piglit_merge_result(&result, PIGLIT_WARN); } else if (get_stddev(&msc_wallclock_duration_stats) > 1000) { fprintf(stderr, "Wallclock time between MSCs has stddev > 1ms" " (%fus), driver is probably not syncing to" " vblank\n", get_stddev(&msc_wallclock_duration_stats)); result = PIGLIT_FAIL; } else if (expected_msc_wallclock_duration > 0.0) { if (fabs(expected_msc_wallclock_duration - msc_wallclock_duration_stats.mean) > 50) { fprintf(stderr, "Wallclock time between MSCs %fus" " does not match glXGetMscRateOML %fus\n", msc_wallclock_duration_stats.mean, expected_msc_wallclock_duration); result = PIGLIT_FAIL; } } return result; }
// receive each one block from all sender void* ExpandableBlockStreamExchangeEpoll::receiver(void* arg){ ExpandableBlockStreamExchangeEpoll* Pthis=(ExpandableBlockStreamExchangeEpoll*)arg; struct epoll_event event; struct epoll_event *events; int status; /** create epoll **/ Pthis->epoll_fd_ = epoll_create1(0); if (Pthis->epoll_fd_ == -1) { Pthis->logging_->elog("epoll create error!\n"); return 0; } event.data.fd = Pthis->sock_fd; event.events = EPOLLIN | EPOLLET; status = epoll_ctl(Pthis->epoll_fd_, EPOLL_CTL_ADD, Pthis->sock_fd, &event); if (status == -1) { Pthis->logging_->elog("epoll ctl error!\n"); return 0; } events=(epoll_event*)calloc(Pthis->nlowers,sizeof(epoll_event)); int fd_cur=0; ticks start=curtick(); std::vector<int> finish_times;//in ms while(true){ usleep(1); const int event_count = epoll_wait(Pthis->epoll_fd_, events, Pthis->nlowers, -1); for (int i = 0; i < event_count; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { if (errno == EINTR) { continue; } Pthis->logging_->elog("[%ld] epoll error,reason:%s\n", Pthis->state.exchange_id_, strerror(errno)); FileClose(events[i].data.fd); std::cout << "in " << __FILE__ << ":" << __LINE__; printf("-----for debug:close fd %d.\n", events[i].data.fd); continue; } else if (Pthis->sock_fd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections.*/ while (true) { sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept(Pthis->sock_fd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* all the incoming connections are processed.*/ break; } else { Pthis->logging_->elog("accept error! "); break; } } status=getnameinfo(&in_addr,in_len,hbuf,sizeof(hbuf),sbuf,sizeof(sbuf),NI_NUMERICHOST|NI_NUMERICSERV); if(status==0){ Pthis->logging_->log("[%ld] Accepted connection on descriptor %d (host=%s, port=%s),id=%d\n",Pthis->state.exchange_id_, infd, hbuf, sbuf,Pthis->state.exchange_id_); Pthis->lower_ip_array.push_back(hbuf); Pthis->lower_sock_fd_to_index[infd]=Pthis->lower_ip_array.size()-1; assert(Pthis->lower_ip_array.size()<=Pthis->state.lower_id_list_.size()); } /*Make the incoming socket non-blocking and add it to the list of fds to monitor.*/ if (!Pthis->SetSocketNonBlocking(infd)) { return 0; } event.data.fd = infd; event.events = EPOLLIN | EPOLLET; status = epoll_ctl(Pthis->epoll_fd_, EPOLL_CTL_ADD, infd, &event); if (status == -1) { Pthis->logging_->elog("epoll_ctl"); return 0; } } continue; } else { /* We have data on the fd waiting to be read.*/ int done = 0; while (true) { int byte_received; int socket_fd_index=Pthis->lower_sock_fd_to_index[events[i].data.fd]; byte_received=read(events[i].data.fd, (char*)Pthis->block_for_socket_[socket_fd_index]->getBlock()+Pthis->block_for_socket_[socket_fd_index]->GetCurSize(), Pthis->block_for_socket_[socket_fd_index]->GetRestSize()); if(byte_received==-1){ if(errno==EAGAIN){ /*We have read all the data,so go back to the loop.*/ break; } Pthis->logging_->elog("read error!\n"); done = 1; } else if (byte_received == 0) { /* End of file. The remote has closed the connection.*/ done = 1; break; } /* The data is successfully read.*/ Pthis->block_for_socket_[socket_fd_index]->IncreaseActualSize(byte_received); if (Pthis->block_for_socket_[socket_fd_index]->GetRestSize() > 0) { /** the current block is not read entirely from the sender, so continue the loop to read.**/ continue; } /** a block is completely read. **/ Pthis->logging_->log("[%ld] The %d-th block is received from Lower[%s]", Pthis->state.exchange_id_, Pthis->debug_received_block[socket_fd_index], Pthis->lower_ip_array[socket_fd_index].c_str()); Pthis->debug_received_block[socket_fd_index]++; /** deserialize the data block from sender to the blockstreambase (received_block_stream_) **/ Pthis->received_block_stream_->deserialize((Block*) Pthis->block_for_socket_[socket_fd_index]); /** mark block_for_socket_[socket_fd_index] to be empty so that it can accommodate the subsequent data **/ Pthis->block_for_socket_[socket_fd_index]->reset(); /** In the current implementation, a empty block stream means End-Of-File**/ const bool eof=Pthis->received_block_stream_->Empty(); if(!eof){ /** the newly obtained data block is validate, so we insert it into the buffer and post * sem_new_block_or_eof_ so that all the threads waiting for the semaphore continue. **/ Pthis->buffer->insertBlock(Pthis->received_block_stream_); //??? why is all ,not 1 // multiple threads will still compete with lock Pthis->sem_new_block_or_eof_.post(Pthis->number_of_registered_expanded_threads_); } else { /** The newly obtained data block is the end-of-file. **/ Pthis->logging_->log("[%ld] *****This block is the last one.", Pthis->state.exchange_id_); finish_times.push_back((int)getMilliSecond(start)); /** update the exhausted senders count and post sem_new_block_or_eof_ so that all the * threads waiting for the semaphore continue. **/ Pthis->nexhausted_lowers++; Pthis->sem_new_block_or_eof_.post(Pthis->number_of_registered_expanded_threads_); if (Pthis->nexhausted_lowers == Pthis->nlowers) { /* * When all the exchange lowers are exhausted, notify the buffer * that the input data is completely received. */ Pthis->buffer->setInputComplete(); /* print the finish times */ for(unsigned i=0;i<finish_times.size();i++){ printf("%d\t",finish_times[i]); } printf("\t Var:%5.4f\n",get_stddev(finish_times)); } Pthis->logging_->log( "[%ld] <<<<<<<<<<<<<<<<nexhausted_lowers=%d>>>>>>>>>>>>>>>>exchange=(%d,%d)", Pthis->state.exchange_id_, Pthis->nexhausted_lowers, Pthis->state.exchange_id_, Pthis->partition_offset); /** tell the sender that all the block are consumed so that the sender can close the socket**/ Pthis->SendBlockAllConsumedNotification(events[i].data.fd); Pthis->logging_->log("[%ld] This notification (all the blocks in the socket buffer are consumed) is send to the lower[%s] exchange=(%d,%d).\n", Pthis->state.exchange_id_, Pthis->lower_ip_array[socket_fd_index].c_str(), Pthis->state.exchange_id_, Pthis->partition_offset); } } if (done) { Pthis->logging_->log("[%ld] Closed connection on descriptor %d[%s]\n", Pthis->state.exchange_id_, events[i].data.fd, Pthis->lower_ip_array[Pthis->lower_sock_fd_to_index[events[i].data.fd]].c_str()); /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ FileClose(events[i].data.fd); } } } } }