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 <shuo.a.liu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Shuo A Liu 2019-12-31 12:55:01 +08:00 committed by wenlingz
parent 4115dd6241
commit 1f23fe3fd8
3 changed files with 74 additions and 0 deletions

View File

@ -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

57
hypervisor/common/event.c Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <cpu.h>
#include <schedule.h>
#include <event.h>
#include <logmsg.h>
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);
}

View File

@ -0,0 +1,16 @@
#ifndef EVENT_H
#define EVENT_H
#include <spinlock.h>
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 */