Ejemplo n.º 1
0
int main(int argc, char* argv[]) {
  char token = '!';
  struct timeval ts;
  pthread_t reader;
  int sock;

  gettimeofday(&ts, NULL);

  socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfds);
  sock = sockfds[0];

  pthread_mutex_lock(&lock);

  pthread_create(&reader, NULL, reader_thread, NULL);

  /* Make the reader thread wait on its pthread_mutex_lock() */
  atomic_puts("M: sleeping ...");
  usleep(500000);
  atomic_puts("M: unlocking mutex ...");
  pthread_mutex_unlock(&lock);
  atomic_puts("M:   ... done");

  /* Force a wait on read() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  test_assert(1 == write(sock, &token, sizeof(token)));
  ++token;
  atomic_puts("M:   ... done");
  /* Force a wait on readv() */
  {
    struct iovec v = { .iov_base = &token, .iov_len = sizeof(token) };

    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("r: writev('%c')'ing socket ...\n", token);
    test_assert(1 == writev(sock, &v, 1));
    ++token;
    atomic_puts("M:   ... done");
  }
  /* Force a wait on recv() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: sending '%c' to socket ...\n", token);
  send(sock, &token, sizeof(token), 0);
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on recvfrom() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: sending '%c' to socket ...\n", token);
  send(sock, &token, sizeof(token), 0);
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on recvfrom(&sock) */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: sending '%c' to socket ...\n", token);
  send(sock, &token, sizeof(token), 0);
  ++token;
  atomic_puts("M:   ... done");
  {
    struct mmsghdr mmsg = { { 0 } };
    struct iovec data = { 0 };
    int magic = msg_magic;

    data.iov_base = &magic;
    data.iov_len = sizeof(magic);
    mmsg.msg_hdr.msg_iov = &data;
    mmsg.msg_hdr.msg_iovlen = 1;

    struct cmsghdr* cmptr = (struct cmsghdr*)malloc(CTRLMSG_LEN); // send a fd
    cmptr->cmsg_level = SOL_SOCKET;
    cmptr->cmsg_type = SCM_RIGHTS;
    cmptr->cmsg_len = CTRLMSG_LEN;
    mmsg.msg_hdr.msg_control = cmptr;
    mmsg.msg_hdr.msg_controllen = CTRLMSG_LEN;
    *(int*)CMSG_DATA(cmptr) = STDERR_FILENO; // send stderr as fd

    /* Force a wait on recvmsg() */
    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("M: sendmsg'ing 0x%x to socket ...\n", msg_magic);
    sendmsg(sock, &mmsg.msg_hdr, 0);
    atomic_puts("M:   ... done");

    /* Force a wait on recvmmsg() */
    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("M: sendmmsg'ing 0x%x to socket ...\n", msg_magic);

    breakpoint();

    sendmmsg(sock, &mmsg, 1, 0);
    atomic_printf("M:   ... sent %u bytes\n", mmsg.msg_len);

    /* Force a wait on recvmmsg() */
    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("M: sendmmsg'ing(by socketcall) 0x%x to socket ...\n",
                  msg_magic);

#if defined(SYS_socketcall)
    struct sendmmsg_arg arg = { 0 };
    arg.sockfd = sock;
    arg.msgvec = &mmsg;
    arg.vlen = 1;
    syscall(SYS_socketcall, SYS_SENDMMSG, (void*)&arg);
#elif defined(SYS_sendmmsg)
    syscall(SYS_sendmmsg, sock, &mmsg, 1, 0);
#else
#error unable to call sendmmsg
#endif

    free(cmptr);
  }
  {
    struct msghdr msg = { 0 };
    struct iovec iovs[2];
    char c1 = token++;
    char c2 = token++;

    iovs[0].iov_base = &c1;
    iovs[0].iov_len = sizeof(c1);
    iovs[1].iov_base = &c2;
    iovs[1].iov_len = sizeof(c2);

    msg.msg_iov = iovs;
    msg.msg_iovlen = sizeof(iovs) / sizeof(iovs[0]);

    /* Force a wait on recvmsg(). */
    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("M: writing { '%c', '%c' } to socket ...\n", c1, c2);
    test_assert(2 == sendmsg(sock, &msg, 0));
    atomic_puts("M:   ... done");
  }
  /* Force a wait on poll() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on ppoll() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on select(), raw syscall */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on select(), library call */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on epoll_wait() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on write() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: reading socket ...\n");
  ++token;
  {
    char* buf = (char*)malloc(num_sockbuf_bytes);
    int i;
    for (i = 0; i < 2; ++i) {
      read_all_chunks(sock, buf, num_sockbuf_bytes, token);
      ++token;
    }
    free(buf);
  }
  atomic_puts("M:   ... done");

  /* Force a wait on read() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  atomic_puts("M:   ... done");

  pthread_join(reader, NULL);

  atomic_puts("EXIT-SUCCESS");
  return 0;
}
Ejemplo n.º 2
0
Archivo: block.c Proyecto: KurSh/rr
int main(int argc, char *argv[]) {
	char token = '!';
	struct timeval ts;
	pthread_t reader;
	int sock;

	gettimeofday(&ts, NULL);

	socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfds);
	sock = sockfds[0];

	pthread_barrier_init(&cheater_barrier, NULL, 2);

	pthread_mutex_lock(&lock);

	pthread_create(&reader, NULL, reader_thread, NULL);

	/* Make the reader thread wait on its pthread_mutex_lock() */
	atomic_puts("M: sleeping ...");
	usleep(500000);
	atomic_puts("M: unlocking mutex ...");
	pthread_mutex_unlock(&lock);
	atomic_puts("M:   ... done");

	/* Force a wait on read() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	test_assert(1 == write(sock, &token, sizeof(token)));
	++token;
	atomic_puts("M:   ... done");
	/* Force a wait on readv() */
	{
		struct iovec v = { .iov_base = &token,
				   .iov_len = sizeof(token) };

		atomic_puts("M: sleeping again ...");
		usleep(500000);
		atomic_printf("r: writev('%c')'ing socket ...\n", token);
		test_assert(1 == writev(sock, &v, 1));
		++token;
		atomic_puts("M:   ... done");
	}
	/* Force a wait on recv() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: sending '%c' to socket ...\n", token);
	send(sock, &token, sizeof(token), 0);
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on recvfrom() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: sending '%c' to socket ...\n", token);
	send(sock, &token, sizeof(token), 0);
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on recvfrom(&sock) */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: sending '%c' to socket ...\n", token);
	send(sock, &token, sizeof(token), 0);
	++token;
	atomic_puts("M:   ... done");
	{
		struct mmsghdr mmsg = {{ 0 }};
		struct iovec data = { 0 };
		int magic = msg_magic;

		data.iov_base = &magic;
		data.iov_len = sizeof(magic);
		mmsg.msg_hdr.msg_iov = &data;
		mmsg.msg_hdr.msg_iovlen = 1;

		/* Force a wait on recvmsg() */
		atomic_puts("M: sleeping again ...");
		usleep(500000);
		atomic_printf("M: sendmsg'ing 0x%x to socket ...\n",
			      msg_magic);
		sendmsg(sock, &mmsg.msg_hdr, 0);
		atomic_puts("M:   ... done");

		/* Force a wait on recvmmsg() */
		atomic_puts("M: sleeping again ...");
		usleep(500000);
		atomic_printf("M: sendmmsg'ing 0x%x to socket ...\n",
			      msg_magic);

		breakpoint();

		sendmmsg(sock, &mmsg, 1, 0);
		atomic_printf("M:   ... sent %u bytes\n", mmsg.msg_len);
		pthread_barrier_wait(&cheater_barrier);
	}
	{
		struct msghdr msg = { 0 };
		struct iovec iovs[2];
		char c1 = token++;
		char c2 = token++;

		iovs[0].iov_base = &c1;
		iovs[0].iov_len = sizeof(c1);
		iovs[1].iov_base = &c2;
		iovs[1].iov_len = sizeof(c2);

		msg.msg_iov = iovs;
		msg.msg_iovlen = sizeof(iovs) / sizeof(iovs[0]);

		/* Force a wait on recvmsg(). */
		atomic_puts("M: sleeping again ...");
		usleep(500000);
		atomic_printf("M: writing { '%c', '%c' } to socket ...\n",
			      c1, c2);
		test_assert(2 == sendmsg(sock, &msg, 0));
		atomic_puts("M:   ... done");
	}
	/* Force a wait on poll() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on ppoll() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on select() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on epoll_wait() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on write() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: reading socket ...\n");
	++token;
	{
		char* buf = (char*)malloc(num_sockbuf_bytes);
		int i;
		for (i = 0; i < 2; ++i) {
			read_all_chunks(sock, buf, num_sockbuf_bytes, token);
			++token;
		}
		free(buf);
	}
	atomic_puts("M:   ... done");

	/* Force a wait on read() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	atomic_puts("M:   ... done");

	pthread_join(reader, NULL);

	atomic_puts("EXIT-SUCCESS");
	return 0;
}