The Pedigree Project 0.1
SchedulerTimer.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/machine/SchedulerTimer.h"
21#include "pedigree/kernel/machine/SchedulerTimerDispatchCleanup.h"
22#include "pedigree/kernel/process/Thread.h"
23#include "pedigree/kernel/processor/Processor.h"
24#include "pedigree/kernel/processor/ProcessorInformation.h"
25
28
29SchedulerTimerDispatchCleanup::SchedulerTimerDispatchCleanup(
31 : m_Dispatch(dispatch),
32 m_Thread(Processor::information().getCurrentThread()),
33 m_Cleanup(),
34 m_Active(false) {
35 if (!m_Thread) {
36 return;
37 }
38
39 // Publication precedes callback execution, so an abandoned frame cannot
40 // strand the counted admission even at Thread state level zero.
41 m_Thread->armAtomicStateCleanup(m_Cleanup, abandon, this);
42 m_Active = true;
43}
44
45SchedulerTimerDispatchCleanup::~SchedulerTimerDispatchCleanup() {
46 if (!m_Active) {
47 return;
48 }
49
50 // The raw dispatch guard releases immediately after this scope. Disarm
51 // first so ordinary return has exactly one release path.
52 m_Thread->disarmAtomicStateCleanup(m_Cleanup);
53 m_Active = false;
54}
55
56void SchedulerTimerDispatchCleanup::abandon(void* context) {
58 reinterpret_cast<SchedulerTimerDispatchCleanup*>(context);
59 if (cleanup) {
60 cleanup->release();
61 }
62}
63
64void SchedulerTimerDispatchCleanup::release() {
65 if (!m_Active) {
66 return;
67 }
68
69 // Clear the scope before releasing the slot. The guard's destructor may
70 // still execute in hosted model tests after the state has been abandoned.
71 m_Active = false;
72 m_Dispatch.release();
73}
74
76 Thread* current = Processor::information().getCurrentThread();
77 if (!current || Processor::executionContext() != ExecutionContext::WaitableThread) {
78 return false;
79 }
80#if HOSTED
81 if (Processor::inHostedSignalFrame() || current->getHostedSignalDepth()) {
82 return false;
83 }
84#endif
85 return true;
86}
static ProcessorInformation & information()
static ExecutionContext executionContext()
Definition Processor.cc:109
static bool canRemoveHandlerInCurrentContext()
virtual ~SchedulerTimer()