mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-11-13 09:02:53 +00:00
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>
64 lines
1.7 KiB
C
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);
|
|
}
|