forked from panda-re/panda
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Port qemu-kvm's signalfd compat code. commit 5a7fdd0abd7cd24dac205317a4195446ab8748b5 Author: Anthony Liguori <aliguori@us.ibm.com> Date: Wed May 7 11:55:47 2008 -0500 Use signalfd() in io-thread This patch reworks the IO thread to use signalfd() instead of sigtimedwait() This will eliminate the need to use SIGIO everywhere. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
- Loading branch information
Showing
4 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* signalfd/eventfd compatibility | ||
* | ||
* Copyright IBM, Corp. 2008 | ||
* | ||
* Authors: | ||
* Anthony Liguori <aliguori@us.ibm.com> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2. See | ||
* the COPYING file in the top-level directory. | ||
* | ||
*/ | ||
|
||
#include "qemu-common.h" | ||
#include "compatfd.h" | ||
|
||
#include <sys/syscall.h> | ||
#include <pthread.h> | ||
|
||
struct sigfd_compat_info | ||
{ | ||
sigset_t mask; | ||
int fd; | ||
}; | ||
|
||
static void *sigwait_compat(void *opaque) | ||
{ | ||
struct sigfd_compat_info *info = opaque; | ||
int err; | ||
sigset_t all; | ||
|
||
sigfillset(&all); | ||
sigprocmask(SIG_BLOCK, &all, NULL); | ||
|
||
do { | ||
siginfo_t siginfo; | ||
|
||
err = sigwaitinfo(&info->mask, &siginfo); | ||
if (err == -1 && errno == EINTR) { | ||
err = 0; | ||
continue; | ||
} | ||
|
||
if (err > 0) { | ||
char buffer[128]; | ||
size_t offset = 0; | ||
|
||
memcpy(buffer, &err, sizeof(err)); | ||
while (offset < sizeof(buffer)) { | ||
ssize_t len; | ||
|
||
len = write(info->fd, buffer + offset, | ||
sizeof(buffer) - offset); | ||
if (len == -1 && errno == EINTR) | ||
continue; | ||
|
||
if (len <= 0) { | ||
err = -1; | ||
break; | ||
} | ||
|
||
offset += len; | ||
} | ||
} | ||
} while (err >= 0); | ||
|
||
return NULL; | ||
} | ||
|
||
static int qemu_signalfd_compat(const sigset_t *mask) | ||
{ | ||
pthread_attr_t attr; | ||
pthread_t tid; | ||
struct sigfd_compat_info *info; | ||
int fds[2]; | ||
|
||
info = malloc(sizeof(*info)); | ||
if (info == NULL) { | ||
errno = ENOMEM; | ||
return -1; | ||
} | ||
|
||
if (pipe(fds) == -1) { | ||
free(info); | ||
return -1; | ||
} | ||
|
||
qemu_set_cloexec(fds[0]); | ||
qemu_set_cloexec(fds[1]); | ||
|
||
memcpy(&info->mask, mask, sizeof(*mask)); | ||
info->fd = fds[1]; | ||
|
||
pthread_attr_init(&attr); | ||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | ||
|
||
pthread_create(&tid, &attr, sigwait_compat, info); | ||
|
||
pthread_attr_destroy(&attr); | ||
|
||
return fds[0]; | ||
} | ||
|
||
int qemu_signalfd(const sigset_t *mask) | ||
{ | ||
#if defined(CONFIG_SIGNALFD) | ||
int ret; | ||
|
||
ret = syscall(SYS_signalfd, -1, mask, _NSIG / 8); | ||
if (ret != -1) { | ||
qemu_set_cloexec(ret); | ||
return ret; | ||
} | ||
#endif | ||
|
||
return qemu_signalfd_compat(mask); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* signalfd/eventfd compatibility | ||
* | ||
* Copyright IBM, Corp. 2008 | ||
* | ||
* Authors: | ||
* Anthony Liguori <aliguori@us.ibm.com> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2. See | ||
* the COPYING file in the top-level directory. | ||
* | ||
*/ | ||
|
||
#ifndef QEMU_COMPATFD_H | ||
#define QEMU_COMPATFD_H | ||
|
||
#include <signal.h> | ||
|
||
struct qemu_signalfd_siginfo { | ||
uint32_t ssi_signo; /* Signal number */ | ||
int32_t ssi_errno; /* Error number (unused) */ | ||
int32_t ssi_code; /* Signal code */ | ||
uint32_t ssi_pid; /* PID of sender */ | ||
uint32_t ssi_uid; /* Real UID of sender */ | ||
int32_t ssi_fd; /* File descriptor (SIGIO) */ | ||
uint32_t ssi_tid; /* Kernel timer ID (POSIX timers) */ | ||
uint32_t ssi_band; /* Band event (SIGIO) */ | ||
uint32_t ssi_overrun; /* POSIX timer overrun count */ | ||
uint32_t ssi_trapno; /* Trap number that caused signal */ | ||
int32_t ssi_status; /* Exit status or signal (SIGCHLD) */ | ||
int32_t ssi_int; /* Integer sent by sigqueue(2) */ | ||
uint64_t ssi_ptr; /* Pointer sent by sigqueue(2) */ | ||
uint64_t ssi_utime; /* User CPU time consumed (SIGCHLD) */ | ||
uint64_t ssi_stime; /* System CPU time consumed (SIGCHLD) */ | ||
uint64_t ssi_addr; /* Address that generated signal | ||
(for hardware-generated signals) */ | ||
uint8_t pad[48]; /* Pad size to 128 bytes (allow for | ||
additional fields in the future) */ | ||
}; | ||
|
||
int qemu_signalfd(const sigset_t *mask); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters