Ejemplo n.º 1
0
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);
  }
}
Ejemplo n.º 2
0
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);
				}
			}
		}
	}

}