From 1f23fe3fd82898469315b1b817099856051654a7 Mon Sep 17 00:00:00 2001 From: Shuo A Liu Date: Tue, 31 Dec 2019 12:55:01 +0800 Subject: [PATCH] hv: sched: simple event implemention This simple event implemention can only support exclusive waiting at same time. It mainly used by thread who want to wait for special event happens. Thread A who want to wait for some events calls wait_event(struct sched_event *); Thread B who can give the event signal calls signal_event(struct sched_event *); Tracked-On: #4329 Signed-off-by: Shuo A Liu Acked-by: Eddie Dong --- hypervisor/Makefile | 1 + hypervisor/common/event.c | 57 +++++++++++++++++++++++++++++++ hypervisor/include/common/event.h | 16 +++++++++ 3 files changed, 74 insertions(+) create mode 100644 hypervisor/common/event.c create mode 100644 hypervisor/include/common/event.h diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 4a6569d0b..e8694eefc 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -211,6 +211,7 @@ HW_C_SRCS += arch/x86/cat.c HW_C_SRCS += arch/x86/sgx.c HW_C_SRCS += common/softirq.c HW_C_SRCS += common/schedule.c +HW_C_SRCS += common/event.c ifeq ($(CONFIG_SCHED_NOOP),y) HW_C_SRCS += common/sched_noop.c endif diff --git a/hypervisor/common/event.c b/hypervisor/common/event.c new file mode 100644 index 000000000..6c00ed83f --- /dev/null +++ b/hypervisor/common/event.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include + +void init_event(struct sched_event *event) +{ + spinlock_init(&event->lock); + event->set = false; + event->waiting_thread = NULL; +} + +void reset_event(struct sched_event *event) +{ + uint64_t rflag; + + spinlock_irqsave_obtain(&event->lock, &rflag); + event->set = false; + event->waiting_thread = NULL; + spinlock_irqrestore_release(&event->lock, rflag); +} + +/* support exclusive waiting only */ +void wait_event(struct sched_event *event) +{ + uint64_t rflag; + + spinlock_irqsave_obtain(&event->lock, &rflag); + ASSERT((event->waiting_thread == NULL), "only support exclusive waiting"); + while (!event->set) { + event->waiting_thread = sched_get_current(get_pcpu_id()); + sleep_thread(event->waiting_thread); + spinlock_irqrestore_release(&event->lock, rflag); + schedule(); + spinlock_irqsave_obtain(&event->lock, &rflag); + } + event->set = false; + event->waiting_thread = NULL; + spinlock_irqrestore_release(&event->lock, rflag); +} + +void signal_event(struct sched_event *event) +{ + uint64_t rflag; + + spinlock_irqsave_obtain(&event->lock, &rflag); + event->set = true; + if (event->waiting_thread != NULL) { + wake_thread(event->waiting_thread); + } + spinlock_irqrestore_release(&event->lock, rflag); +} diff --git a/hypervisor/include/common/event.h b/hypervisor/include/common/event.h new file mode 100644 index 000000000..c7f398032 --- /dev/null +++ b/hypervisor/include/common/event.h @@ -0,0 +1,16 @@ +#ifndef EVENT_H +#define EVENT_H +#include + +struct sched_event { + spinlock_t lock; + bool set; + struct thread_object* waiting_thread; +}; + +void init_event(struct sched_event *event); +void reset_event(struct sched_event *event); +void wait_event(struct sched_event *event); +void signal_event(struct sched_event *event); + +#endif /* EVENT_H */