Files
acrn-hypervisor/hypervisor/common/event.c
Jian Jun Chen e5831fec1e hv: multi-arch: abstract some pcpu related interfaces and macros
The following pcpu related interfaces are moved into common:
- common/cpu.c::start_pcpus
- include/common/cpu.h::get_pcpu_id
- include/common/cpu.h::set_current_pcpu_id
Their arch specific implementations are moved into arch/$(ARCH):
- arch/$(ARCH)/cpu.c::arch_start_pcpu
- include/arch/$(ARCH)/asm/cpu.h::arch_get_pcpu_id
- include/arch/$(ARCH)/asm/cpu.h::arch_set_current_pcpu_id
The following interface is moved into common:
- pcpu_set_current_state (from arch/x86/cpu.c -> common/cpu.c)
The following MACROs are moved into include/common/cpu.h:
- CPU_UP_TIMEOUT
- CPU_DOWN_TIMEOUT
- BSP_CPU_ID
- INVALID_CPU_ID

Tracked-On: #8791
Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
2025-09-23 11:30:38 +08:00

64 lines
1.7 KiB
C

/*
* Copyright (C) 2018-2022 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <schedule.h>
#include <event.h>
#include <logmsg.h>
#include <cpu.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
*
* During wait, the pCPU could be scheduled to run the idle thread when run queue
* is empty. Signal_event() can happen when schedule() is in process.
* This signal_event is not going to be lost, for the idle thread will always
* check need_reschedule() after it is switched to at schedule().
*/
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");
event->waiting_thread = sched_get_current(get_pcpu_id());
while (!event->set && (event->waiting_thread != NULL)) {
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);
}