stdlibc: \!perror()
[meinos.git] / kernel2 / swap.c
blobc7dd5e5a356ec5dd231f6b1ef4cf83752a11f332
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <procm.h>
20 #include <paging.h>
21 #include <memphys.h>
22 #include <memuser.h>
23 #include <swap.h>
24 #include <malloc.h>
25 #include <syscall.h>
27 /**
28 * Initializes swapping
29 * @return Success?
31 int swap_init() {
32 swap_proc = NULL;
33 //if (syscall_create(SYSCALL_SWAP_ENABLE,swap_enable,1)==-1) return -1;
34 return 0;
37 /**
38 * Enables swapping (Syscall)
39 * @return Success?
41 int swap_enable(void *buf) {
42 if (swap_proc!=NULL) return -1;
43 swap_queue = llist_create();
44 swap_proc = proc_current;
45 swap_buf = buf;
46 return 0;
49 /**
50 * Calls a swap function
51 * @param op Operation
52 * @param proc Owner of page
53 * @param page Page
54 * @return Success?
56 int swap_call(int op,proc_t *proc,void *page) {
57 swap_call_t *new = malloc(sizeof(swap_call_t));
58 if (new!=NULL) {
59 new->op = op;
60 new->pid = proc->pid;
61 new->page = page;
62 llist_push(swap_queue,new);
63 return 0;
65 else return -1;
68 /**
69 * Swaps page in
70 * @param proc Onwer of page
71 * @param page Page to swap
73 int swap_in(proc_t *proc,void *page) {
74 if (swap_proc!=NULL) {
75 pte_t pte = paging_getpte_pd(page,proc->addrspace->pagedir);
76 if (!pte.in_memory && pte.swapped) {
77 memuser_load_addrspace(proc->addrspace);
78 if (swap_call(SWAP_IN,proc,page)) {
79 void *phys = memphys_alloc();
80 pte.page = ADDR2PAGE(phys);
81 pte.in_memory = 1;
82 paging_physwrite(phys,swap_buf,PAGE_SIZE);
83 return 0;
87 return -1;
90 /**
91 * Swaps page out
92 * @param proc Owner of page
93 * @param page Page to swap
94 * @return Success?
96 int swap_out(proc_t *proc,void *page) {
97 if (swap_proc!=NULL) {
98 pte_t pte = paging_getpte_pd(page,proc->addrspace->pagedir);
99 if (pte.swappable) {
100 memuser_load_addrspace(proc->addrspace);
101 void *phys = PAGE2ADDR(pte.page);
102 if (phys!=NULL && pte.in_memory) {
103 paging_physread(swap_buf,phys,PAGE_SIZE);
104 if (swap_call(SWAP_OUT,proc,page)!=-1) {
105 pte.in_memory = 0;
106 pte.swapped = 1;
107 memphys_free(page);
108 paging_setpte_pd(page,pte,proc->addrspace->pagedir);
109 return 0;
114 return -1;
118 * Removes a page from swap
119 * @param proc Owner of page
120 * @param page Page
121 * @return Success?
123 int swap_remove(proc_t *proc,void *page) {
124 if (swap_proc!=NULL) return swap_call(SWAP_REM,proc,page);
125 else return -1;