The Pedigree Project  0.1
MemoryPressureKiller.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/MemoryPressureKiller.h"
21 #include "pedigree/kernel/Log.h"
22 #include "pedigree/kernel/Subsystem.h"
23 #include "pedigree/kernel/process/Process.h"
24 #include "pedigree/kernel/process/Scheduler.h"
25 #include "pedigree/kernel/processor/types.h"
26 
27 static size_t mb(size_t pages)
28 {
29  return (pages * 0x1000) / 0x100000;
30 }
31 
33 {
34  Process *pCandidateProcess = 0;
35  for (size_t i = 0; i < Scheduler::instance().getNumProcesses(); ++i)
36  {
37  Process *pProcess = Scheduler::instance().getProcess(i);
38 
39  // Requires a subsystem to kill.
40  if (!pProcess->getSubsystem())
41  continue;
42 
43  if (!pCandidateProcess)
44  pCandidateProcess = pProcess;
45  else
46  {
47  if (pProcess->getPhysicalPageCount() >
48  pCandidateProcess->getPhysicalPageCount())
49  {
50  pCandidateProcess = pProcess;
51  }
52  }
53  }
54 
55  if (!pCandidateProcess)
56  return false;
57 
58  NOTICE_NOLOCK(
59  "MemoryPressureProcessKiller will kill pid="
60  << Dec << pCandidateProcess->getId() << Hex);
61  NOTICE_NOLOCK(
62  "virt=" << Dec << mb(pCandidateProcess->getVirtualPageCount())
63  << "m phys=" << mb(pCandidateProcess->getPhysicalPageCount())
64  << "m shared=" << mb(pCandidateProcess->getSharedPageCount())
65  << "m" << Hex);
66 
67  // Hard kill the process (SIGKILL, in POSIX terms).
68  // We cannot afford to let the thread do anything else.
69  Subsystem *pSubsystem = pCandidateProcess->getSubsystem();
70  pSubsystem->kill(Subsystem::Unknown, pCandidateProcess->getThread(0));
71 
72  // Give the process time to quit.
74 
75  return true;
76 }
size_t getId()
Definition: Process.h:108
Definition: Log.h:136
size_t getNumProcesses()
Definition: Scheduler.cc:140
static Scheduler & instance()
Definition: Scheduler.h:48
Process * getProcess(size_t n)
Definition: Scheduler.cc:149
Thread * getThread(size_t n)
Definition: Process.cc:225
void yield()
Definition: Scheduler.cc:135
Definition: Log.h:138
virtual bool kill(KillReason killReason, Thread *pThread=0)=0