Merge branch 'master' of gitlab.ibr.cs.tu-bs.de:vss/teaching/ws25/v_bsb2/Gruppe_003
This commit is contained in:
@@ -23,6 +23,10 @@ struct Vault {
|
|||||||
Bellringer bellringer;
|
Bellringer bellringer;
|
||||||
BBuffer<Key, 16> keys;
|
BBuffer<Key, 16> keys;
|
||||||
Semaphore keys_sem;
|
Semaphore keys_sem;
|
||||||
|
|
||||||
|
Thread* thread_list[32];
|
||||||
|
size_t thread_count = 0;
|
||||||
|
|
||||||
|
|
||||||
static constexpr int MAX_SEMS =32;
|
static constexpr int MAX_SEMS =32;
|
||||||
Semaphore sems[MAX_SEMS];
|
Semaphore sems[MAX_SEMS];
|
||||||
|
|||||||
@@ -91,8 +91,13 @@ extern "C" int main() {
|
|||||||
uint32_t appsize = (*apps_header)[i];
|
uint32_t appsize = (*apps_header)[i];
|
||||||
uintptr_t appstart = (0x4000+offset)<<12;
|
uintptr_t appstart = (0x4000+offset)<<12;
|
||||||
DBG << "app " << i << " size " << appsize << " at " << appstart << endl;
|
DBG << "app " << i << " size " << appsize << " at " << appstart << endl;
|
||||||
g.vault().scheduler.ready(new Thread(false, (void*)appstart, (appsize/4096)+1)); //TODO fix edgecase on size=4096
|
|
||||||
|
Thread* thread_ptr= new Thread(false, (void*)appstart, (appsize/4096)+1); //TODO fix edgecase on size=4096
|
||||||
|
|
||||||
|
g.vault().scheduler.ready(thread_ptr); //TODO fix edgecase on size=4096
|
||||||
offset += 1+(appsize/4096);
|
offset += 1+(appsize/4096);
|
||||||
|
g.vault().thread_list[thread_ptr->id] = thread_ptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g.vault().scheduler.ready(new Thread(false, (void*)0x4001000, 1));
|
g.vault().scheduler.ready(new Thread(false, (void*)0x4001000, 1));
|
||||||
|
|||||||
@@ -154,6 +154,8 @@ void PageFrameAllocator::free(PageFrame* frame){
|
|||||||
//TODO ref counter etc...
|
//TODO ref counter etc...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PageFrameAllocator::free(uintptr_t addr){
|
void PageFrameAllocator::free(uintptr_t addr){
|
||||||
free(&PageFrames[addr>>12]);
|
free(&PageFrames[addr>>12]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,17 @@ extern "C" size_t syscall_handler(size_t sysnum, size_t p1, size_t p2,
|
|||||||
return (size_t) Skeleton::map(&(Guard::enter().vault()), p1);
|
return (size_t) Skeleton::map(&(Guard::enter().vault()), p1);
|
||||||
case Syscall::ID::UNMAP:
|
case Syscall::ID::UNMAP:
|
||||||
return (int) Skeleton::unmap(Guard::enter().vault(), (void*) (p1), p2);
|
return (int) Skeleton::unmap(Guard::enter().vault(), (void*) (p1), p2);
|
||||||
|
case Syscall::ID::SEND:
|
||||||
|
return Skeleton::send(Guard::enter().vault(), static_cast<int>(p1), reinterpret_cast<const void*>(p2), p3, reinterpret_cast<void*>(p4), p5);
|
||||||
|
case Syscall::ID::RECEIVE:
|
||||||
|
return Skeleton::receive(Guard::enter().vault(), (void*)(p1), p2);
|
||||||
|
case Syscall::ID::REPLY:
|
||||||
|
return Skeleton::reply(Guard::enter().vault(), (void*)(p1), p2);
|
||||||
|
// case Syscall::ID::FORK:
|
||||||
|
// return Skeleton::fork(v, user);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<size_t>(-1);
|
return static_cast<size_t>(-1);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "../debug/output.h"
|
#include "../debug/output.h"
|
||||||
#include "../device/textstream.h"
|
#include "../device/textstream.h"
|
||||||
#include "../interrupt/guard.h"
|
#include "../interrupt/guard.h"
|
||||||
|
#include "../memory/page.h"
|
||||||
#include "../sync/semaphore.h"
|
#include "../sync/semaphore.h"
|
||||||
#include "../thread/scheduler.h"
|
#include "../thread/scheduler.h"
|
||||||
#include "../memory/pageframealloc.h"
|
#include "../memory/pageframealloc.h"
|
||||||
@@ -283,5 +284,107 @@ namespace Syscall {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool copy_from_phys(Vault& vault, uintptr_t phys_ptr, void* virt_ptr, size_t size) {
|
||||||
|
Thread* current_thread = vault.scheduler.active();
|
||||||
|
|
||||||
|
size_t offset = Page::offset(phys_ptr);
|
||||||
|
size_t total_size = size + offset;
|
||||||
|
four_lvl_paging_t* search_table = vault.scheduler.active()->paging_tree;
|
||||||
|
|
||||||
|
void* page_ptr = getFreeVirtSpace(search_table, total_size); // page aligned pointer
|
||||||
|
if (page_ptr == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t virt_addr = (uintptr_t)(page_ptr) + offset;
|
||||||
|
for(uint8_t i =0; i<size/4096; i++){
|
||||||
|
setMapping(virt_addr, (void*)phys_ptr, vault.scheduler.active()->paging_tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(virt_ptr, (void*)(virt_addr), size);
|
||||||
|
PageFrameAllocator::free((uintptr_t)(page_ptr));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool send(Vault& v, int pid, const void* sbuffer, size_t ssize, void* rbuffer, size_t rsize) {
|
||||||
|
Thread* current_thread = v.scheduler.active();
|
||||||
|
Thread* target_thread = v.thread_list[pid];
|
||||||
|
|
||||||
|
uintptr_t sbuffer_ptr = (uintptr_t) target_thread->paging_tree;
|
||||||
|
|
||||||
|
// Erstelle Nachichtenobjekt
|
||||||
|
IpcStruct msg = {sbuffer_ptr, ssize, current_thread->id, false, nullptr};
|
||||||
|
|
||||||
|
target_thread->ipc_queue.enqueue(msg);
|
||||||
|
target_thread->ipc_sem.v(v);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
current_thread->ipc_sem.p(v);
|
||||||
|
if (msg.is_answer) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBG_VERBOSE << "" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kopiere Antwort
|
||||||
|
if (!copy_from_phys(v, msg.ptr, rbuffer, rsize)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int receive(Vault& v, void* buffer, size_t size) {
|
||||||
|
|
||||||
|
// DBG_VERBOSE << "Receive syscall for thread " << dec << v.scheduler.active()->id << endl;
|
||||||
|
Thread* thread = v.scheduler.active();
|
||||||
|
|
||||||
|
// Warte auf Nachricht
|
||||||
|
if (thread->ipc_queue.is_empty()) {
|
||||||
|
thread->ipc_sem.p(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcStruct* ipc = thread->ipc_queue.first();
|
||||||
|
if (ipc == nullptr) return -1;
|
||||||
|
|
||||||
|
// Buffer holen
|
||||||
|
if (!copy_from_phys(v, ipc->ptr, buffer, size)) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipc->pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool reply(Vault& v, const void* buffer, size_t size) {
|
||||||
|
|
||||||
|
Thread* current_thread = v.scheduler.active();
|
||||||
|
IpcStruct* ipc = current_thread->ipc_queue.dequeue();
|
||||||
|
|
||||||
|
// if (!ipc || ipc->pid < 0 || static_cast<size_t>(ipc->pid) >= v.thread_count) return false;
|
||||||
|
|
||||||
|
Thread* other_thread = v.thread_list[ipc->pid];
|
||||||
|
if (other_thread == nullptr) return false;
|
||||||
|
|
||||||
|
uintptr_t phys_ptr = (uintptr_t) current_thread->paging_tree;
|
||||||
|
|
||||||
|
ipc->ptr = phys_ptr;
|
||||||
|
ipc->size = size;
|
||||||
|
ipc->pid = current_thread->id;
|
||||||
|
ipc->is_answer = true;
|
||||||
|
|
||||||
|
// Sender aufwecken
|
||||||
|
other_thread->ipc_sem.v(v);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Skeleton
|
} // namespace Skeleton
|
||||||
} // namespace Syscall
|
} // namespace Syscall
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ void kill(Vault &vault, size_t pid);
|
|||||||
void* map(Vault *vault, size_t size);
|
void* map(Vault *vault, size_t size);
|
||||||
int unmap(Vault &vault, void* start, size_t size);
|
int unmap(Vault &vault, void* start, size_t size);
|
||||||
void invlpg(uintptr_t virt_addr);
|
void invlpg(uintptr_t virt_addr);
|
||||||
|
bool send(Vault &vault, int pid, const void* sbuffer, size_t ssize, void* rbuffer, size_t rsize);
|
||||||
|
int receive(Vault &vault, void* buffer, size_t size);
|
||||||
|
bool reply(Vault &vaul, const void* buffer, size_t size);
|
||||||
|
//int fork(Vault &vault, InterruptContext *user);
|
||||||
|
|
||||||
|
|
||||||
} // namespace Skeleton
|
} // namespace Skeleton
|
||||||
} // namespace Syscall
|
} // namespace Syscall
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace Syscall {
|
|||||||
/*! \brief Syscall IDs
|
/*! \brief Syscall IDs
|
||||||
* \note the syscall number must correspond to the values in the syscall stub!
|
* \note the syscall number must correspond to the values in the syscall stub!
|
||||||
*/
|
*/
|
||||||
enum class ID : size_t {
|
enum class ID : size_t {
|
||||||
TEST = 0,
|
TEST = 0,
|
||||||
WRITE = 1,
|
WRITE = 1,
|
||||||
READ = 2,
|
READ = 2,
|
||||||
@@ -18,7 +18,11 @@ enum class ID : size_t {
|
|||||||
SYS_EXIT = 9,
|
SYS_EXIT = 9,
|
||||||
SYS_KILL = 10,
|
SYS_KILL = 10,
|
||||||
MAP = 11,
|
MAP = 11,
|
||||||
UNMAP = 12
|
UNMAP = 12,
|
||||||
|
SEND = 13,
|
||||||
|
RECEIVE = 14,
|
||||||
|
REPLY = 15,
|
||||||
|
// FORK = 16
|
||||||
};
|
};
|
||||||
} // namespace Syscall
|
} // namespace Syscall
|
||||||
|
|
||||||
@@ -81,3 +85,15 @@ extern "C" ssize_t sys_safe_call(Syscall::ID id, size_t p1, size_t p2,
|
|||||||
[[gnu::always_inline]] static inline int unmap(void* start, size_t size) {
|
[[gnu::always_inline]] static inline int unmap(void* start, size_t size) {
|
||||||
return sys_call(Syscall::ID::UNMAP, (size_t) start, size,0,0,0);
|
return sys_call(Syscall::ID::UNMAP, (size_t) start, size,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]] static inline bool send(int pid, const void* sbuffer, size_t ssize, void* rbuffer, size_t rsize) {
|
||||||
|
return sys_call(Syscall::ID::SEND, pid, (size_t)sbuffer, ssize, (size_t)rbuffer, rsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]] static inline int receive(void* buffer, size_t size) {
|
||||||
|
return sys_call(Syscall::ID::RECEIVE, (size_t)buffer, size,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]] static inline bool reply(const void* buffer, size_t size) {
|
||||||
|
return sys_call(Syscall::ID::REPLY, (size_t)buffer, size,0,0,0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,12 +16,24 @@
|
|||||||
#include "../arch/context.h"
|
#include "../arch/context.h"
|
||||||
#include "../object/queue.h"
|
#include "../object/queue.h"
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
#include "../sync/semaphore.h"
|
||||||
|
|
||||||
#include "../memory/pagetable.h"
|
#include "../memory/pagetable.h"
|
||||||
|
|
||||||
/// Stack size for each thread
|
/// Stack size for each thread
|
||||||
constexpr uint32_t STACK_SIZE = 3072;
|
constexpr uint32_t STACK_SIZE = 3072;
|
||||||
|
|
||||||
|
|
||||||
|
struct IpcStruct {
|
||||||
|
uintptr_t ptr;
|
||||||
|
size_t size;
|
||||||
|
int pid;
|
||||||
|
bool is_answer;
|
||||||
|
IpcStruct* queue_link = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief The Thread is an object used by the scheduler.
|
/*! \brief The Thread is an object used by the scheduler.
|
||||||
* \ingroup thread
|
* \ingroup thread
|
||||||
*/
|
*/
|
||||||
@@ -79,6 +91,12 @@ class Thread {
|
|||||||
pagetable_t* appcode_table;
|
pagetable_t* appcode_table;
|
||||||
pagetable_t* appstack_table;
|
pagetable_t* appstack_table;
|
||||||
|
|
||||||
|
Semaphore ipc_sem;
|
||||||
|
Queue<IpcStruct> ipc_queue;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Unique thread id */
|
/*! \brief Unique thread id */
|
||||||
const int id;
|
const int id;
|
||||||
|
|
||||||
|
|||||||
6
notes
6
notes
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
pagetable baum weniger bottom heavy machen, cr4 zur unterscheidung von kernel/user space
|
pagetable baum weniger bottom heavy machen, cr4 zur unterscheidung von kernel/user space
|
||||||
|
|
||||||
|
caller und callee und so nen stuff fit drin sein
|
||||||
idee l2 wachsne lassen
|
idee l2 wachsne lassen
|
||||||
kernel einklinken mit subtable
|
kernel einklinken mit subtable
|
||||||
|
|
||||||
@@ -17,3 +17,7 @@
|
|||||||
l2 hier erhöhen falls wir mehr als 1gb brauchen.
|
l2 hier erhöhen falls wir mehr als 1gb brauchen.
|
||||||
|
|
||||||
l1 512
|
l1 512
|
||||||
|
|
||||||
|
|
||||||
|
neue syscalls bei handler.cc skeleton.cc skeleton.h stub.h einbauen
|
||||||
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user