The Pedigree Project  0.1
Event.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/process/Event.h"
21 #include "pedigree/kernel/LockGuard.h"
22 #include "pedigree/kernel/Log.h"
23 #include "pedigree/kernel/compiler.h"
24 #include "pedigree/kernel/process/Process.h"
25 #include "pedigree/kernel/process/Scheduler.h"
26 #include "pedigree/kernel/process/Thread.h"
27 #include "pedigree/kernel/processor/VirtualAddressSpace.h"
28 #include "pedigree/kernel/utilities/Iterator.h"
29 #include "pedigree/kernel/utilities/utility.h"
30 
32  uintptr_t handlerAddress, bool isDeletable, size_t specificNestingLevel)
33  : m_HandlerAddress(handlerAddress), m_bIsDeletable(isDeletable),
34  m_NestingLevel(specificNestingLevel), m_Magic(EVENT_MAGIC)
35 #ifdef THREADS
36  ,
37  m_Threads(), m_Lock(false)
38 #endif
39 {
40 }
41 
42 Event::~Event()
43 {
44 #ifdef THREADS
46 
47  if (m_Threads.count())
48  {
49  ERROR("UNSAFE EVENT DELETION");
50  for (auto it : m_Threads)
51  {
52  ERROR(
53  " => Pending delivery to thread "
54  << it << " (" << it->getParent()->getId() << ":" << it->getId()
55  << ").");
56  }
57  FATAL(
58  "Unsafe event deletion: " << m_Threads.count()
59  << " threads reference it!");
60 
61  m_Threads.clear();
62  }
63 #endif
64 }
65 
67 {
70 }
71 
73 {
74  return getTrampoline() + 0x100;
75 }
76 
78 {
79  return getTrampoline() + 0x1000;
80 }
81 
83 {
84  return getHandlerBuffer() +
85  ((EVENT_TID_MAX * MAX_NESTED_EVENTS) * EVENT_LIMIT);
86 }
87 
89 {
90  return m_bIsDeletable;
91 }
92 
93 bool Event::unserialize(uint8_t *pBuffer, Event &event)
94 {
95  ERROR("Event::unserialize is abstract, should never be called.");
96  return false;
97 }
98 
99 size_t Event::getEventType(uint8_t *pBuffer)
100 {
101  void *alignedBuffer = ASSUME_ALIGNMENT(pBuffer, sizeof(size_t));
102  size_t *pBufferSize_t = reinterpret_cast<size_t *>(alignedBuffer);
103  return pBufferSize_t[0];
104 }
105 
106 Event::Event(const Event &other)
107  : Event(other.m_HandlerAddress, other.m_bIsDeletable, other.m_NestingLevel){
108 #ifdef THREADS
109  {LockGuard<Spinlock> guard(m_Lock);
110 m_Threads.clear();
111 }
112 #endif
113 }
114 
115 Event &Event::operator=(const Event &other)
116 {
120 #ifdef THREADS
121  {
123  m_Threads.clear();
124  }
125 #endif
126  return *this;
127 }
128 
129 #ifdef THREADS
131 {
133 
134  m_Threads.pushBack(thread);
135 }
136 
138 {
140 
142  it != m_Threads.end();)
143  {
144  if (*it == thread)
145  {
146  it = m_Threads.erase(it);
147  }
148  else
149  {
150  ++it;
151  }
152  }
153 }
154 
156 {
158 
159  return m_Threads.count();
160 }
161 #endif
162 
164 {
165  // no-op if no threads
166 #ifdef THREADS
167  while (pendingCount())
168  {
169  // Each yield will check event states on the new thread(s).
171  }
172 #endif
173 }
void clear()
Definition: List.h:386
void pushBack(const T &value)
Definition: List.h:232
virtual void waitForDeliveries()
Definition: Event.cc:163
Iterator erase(Iterator &Iter)
Definition: List.h:343
static uintptr_t getTrampoline()
Definition: Event.cc:66
virtual uintptr_t getKernelEventBlockStart() const =0
Spinlock m_Lock
Definition: Event.h:158
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
static bool unserialize(uint8_t *pBuffer, Event &event)
Definition: Event.cc:93
size_t m_NestingLevel
Definition: Event.h:148
size_t pendingCount()
Definition: Event.cc:155
Definition: List.h:64
uintptr_t m_HandlerAddress
Definition: Event.h:142
Iterator begin()
Definition: List.h:123
static Scheduler & instance()
Definition: Scheduler.h:48
List< Thread * > m_Threads
Definition: Event.h:155
static uintptr_t getHandlerBuffer()
Definition: Event.cc:77
Definition: Thread.h:54
Definition: Event.h:48
static size_t getEventType(uint8_t *pBuffer)
Definition: Event.cc:99
virtual bool isDeletable()
Definition: Event.cc:88
#define ERROR(text)
Definition: Log.h:82
void yield()
Definition: Scheduler.cc:135
static uintptr_t getLastHandlerBuffer()
Definition: Event.cc:82
#define FATAL(text)
Definition: Log.h:89
bool m_bIsDeletable
Definition: Event.h:145
void registerThread(Thread *thread)
Definition: Event.cc:130
Iterator end()
Definition: List.h:135
static uintptr_t getSecondaryTrampoline()
Definition: Event.cc:72
Event(uintptr_t handlerAddress, bool isDeletable, size_t specificNestingLevel=~0UL)
Definition: Event.cc:31
void deregisterThread(Thread *thread)
Definition: Event.cc:137
size_t count() const
Definition: List.h:227