mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-23 05:57:33 +00:00
dm: provide timer callback handlers the number of expirations
It is possible for multiple timeouts to occur in one mevent epoll iteration. Providing the number of timer expirations to the timer callback handlers can be useful. E.g., this could improve emulation of timing-sensitive hardware components. Tracked-On: #2319 Signed-off-by: Peter Fang <peter.fang@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
0f7535fdbe
commit
3fe4c3f2a8
@ -6,6 +6,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include "vmmapi.h"
|
||||
@ -28,8 +30,9 @@ timer_handler(int fd __attribute__((unused)),
|
||||
void *arg)
|
||||
{
|
||||
struct acrn_timer *timer = arg;
|
||||
uint64_t buf;
|
||||
int32_t size;
|
||||
uint64_t nexp;
|
||||
ssize_t size;
|
||||
void (*cb)(void *, uint64_t);
|
||||
|
||||
if (timer == NULL) {
|
||||
return;
|
||||
@ -39,19 +42,25 @@ timer_handler(int fd __attribute__((unused)),
|
||||
* Here is a temporary solution, the processing could be moved to
|
||||
* mevent.c once EVF_TIMER is supported.
|
||||
*/
|
||||
size = read(timer->fd, &buf, sizeof(buf));
|
||||
if (size < 1) {
|
||||
fprintf(stderr, "acrn_timer read timerfd error!");
|
||||
size = read(timer->fd, &nexp, sizeof(nexp));
|
||||
|
||||
if (size < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
perror("acrn_timer read timerfd error");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (timer->callback != NULL) {
|
||||
(*timer->callback)(timer->callback_param);
|
||||
assert(size > 0 && nexp > 0);
|
||||
|
||||
if ((cb = timer->callback) != NULL) {
|
||||
(*cb)(timer->callback_param, nexp);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
acrn_timer_init(struct acrn_timer *timer, void (*cb)(void *), void *param)
|
||||
acrn_timer_init(struct acrn_timer *timer, void (*cb)(void *, uint64_t),
|
||||
void *param)
|
||||
{
|
||||
if ((timer == NULL) || (cb == NULL)) {
|
||||
return -1;
|
||||
|
@ -66,7 +66,7 @@ virtio_start_timer(struct acrn_timer *timer, time_t sec, time_t nsec)
|
||||
}
|
||||
|
||||
static void
|
||||
virtio_poll_timer(void *arg)
|
||||
virtio_poll_timer(void *arg, uint64_t nexp)
|
||||
{
|
||||
struct virtio_base *base;
|
||||
struct virtio_ops *vops;
|
||||
|
@ -110,7 +110,7 @@ static void start_wdt_timer(void);
|
||||
* action to guest OS
|
||||
*/
|
||||
static void
|
||||
wdt_expired_handler(void *arg)
|
||||
wdt_expired_handler(void *arg, uint64_t nexp)
|
||||
{
|
||||
struct pci_vdev *dev = (struct pci_vdev *)arg;
|
||||
|
||||
|
@ -660,7 +660,7 @@ vrtc_time_update(struct vrtc *vrtc, time_t newtime, time_t newbase)
|
||||
}
|
||||
|
||||
static void
|
||||
vrtc_periodic_timer(void *arg)
|
||||
vrtc_periodic_timer(void *arg, uint64_t nexp)
|
||||
{
|
||||
struct vrtc *vrtc = arg;
|
||||
|
||||
@ -673,13 +673,14 @@ vrtc_periodic_timer(void *arg)
|
||||
}
|
||||
|
||||
static void
|
||||
vrtc_update_timer(void *arg)
|
||||
vrtc_update_timer(void *arg, uint64_t nexp)
|
||||
{
|
||||
struct vrtc *vrtc = arg;
|
||||
time_t basetime;
|
||||
time_t curtime;
|
||||
|
||||
pthread_mutex_lock(&vrtc->mtx);
|
||||
|
||||
if (aintr_enabled(vrtc) || uintr_enabled(vrtc)) {
|
||||
curtime = vrtc_curtime(vrtc, &basetime);
|
||||
vrtc_time_update(vrtc, curtime, basetime);
|
||||
|
@ -10,12 +10,12 @@ struct acrn_timer {
|
||||
int32_t fd;
|
||||
int32_t clockid;
|
||||
struct mevent *mevp;
|
||||
void (*callback)(void *);
|
||||
void (*callback)(void *, uint64_t);
|
||||
void *callback_param;
|
||||
};
|
||||
|
||||
int32_t
|
||||
acrn_timer_init(struct acrn_timer *timer, void (*cb)(void *), void *param);
|
||||
acrn_timer_init(struct acrn_timer *timer, void (*cb)(void *, uint64_t), void *param);
|
||||
void
|
||||
acrn_timer_deinit(struct acrn_timer *timer);
|
||||
int32_t
|
||||
|
Loading…
Reference in New Issue
Block a user