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;
|
||||
BBuffer<Key, 16> keys;
|
||||
Semaphore keys_sem;
|
||||
|
||||
Thread* thread_list[32];
|
||||
size_t thread_count = 0;
|
||||
|
||||
|
||||
static constexpr int MAX_SEMS =32;
|
||||
Semaphore sems[MAX_SEMS];
|
||||
|
||||
@@ -91,8 +91,13 @@ extern "C" int main() {
|
||||
uint32_t appsize = (*apps_header)[i];
|
||||
uintptr_t appstart = (0x4000+offset)<<12;
|
||||
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);
|
||||
g.vault().thread_list[thread_ptr->id] = thread_ptr;
|
||||
|
||||
}
|
||||
|
||||
g.vault().scheduler.ready(new Thread(false, (void*)0x4001000, 1));
|
||||
|
||||
@@ -154,6 +154,8 @@ void PageFrameAllocator::free(PageFrame* frame){
|
||||
//TODO ref counter etc...
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PageFrameAllocator::free(uintptr_t addr){
|
||||
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);
|
||||
case Syscall::ID::UNMAP:
|
||||
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);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../debug/output.h"
|
||||
#include "../device/textstream.h"
|
||||
#include "../interrupt/guard.h"
|
||||
#include "../memory/page.h"
|
||||
#include "../sync/semaphore.h"
|
||||
#include "../thread/scheduler.h"
|
||||
#include "../memory/pageframealloc.h"
|
||||
@@ -283,5 +284,107 @@ namespace Syscall {
|
||||
}
|
||||
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 Syscall
|
||||
|
||||
@@ -26,6 +26,11 @@ void kill(Vault &vault, size_t pid);
|
||||
void* map(Vault *vault, size_t size);
|
||||
int unmap(Vault &vault, void* start, size_t size);
|
||||
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 Syscall
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Syscall {
|
||||
/*! \brief Syscall IDs
|
||||
* \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,
|
||||
WRITE = 1,
|
||||
READ = 2,
|
||||
@@ -18,7 +18,11 @@ enum class ID : size_t {
|
||||
SYS_EXIT = 9,
|
||||
SYS_KILL = 10,
|
||||
MAP = 11,
|
||||
UNMAP = 12
|
||||
UNMAP = 12,
|
||||
SEND = 13,
|
||||
RECEIVE = 14,
|
||||
REPLY = 15,
|
||||
// FORK = 16
|
||||
};
|
||||
} // 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) {
|
||||
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 "../object/queue.h"
|
||||
#include "../types.h"
|
||||
#include "../sync/semaphore.h"
|
||||
|
||||
#include "../memory/pagetable.h"
|
||||
|
||||
/// Stack size for each thread
|
||||
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.
|
||||
* \ingroup thread
|
||||
*/
|
||||
@@ -79,6 +91,12 @@ class Thread {
|
||||
pagetable_t* appcode_table;
|
||||
pagetable_t* appstack_table;
|
||||
|
||||
Semaphore ipc_sem;
|
||||
Queue<IpcStruct> ipc_queue;
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Unique thread 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
|
||||
|
||||
|
||||
caller und callee und so nen stuff fit drin sein
|
||||
idee l2 wachsne lassen
|
||||
kernel einklinken mit subtable
|
||||
|
||||
@@ -17,3 +17,7 @@
|
||||
l2 hier erhöhen falls wir mehr als 1gb brauchen.
|
||||
|
||||
l1 512
|
||||
|
||||
|
||||
neue syscalls bei handler.cc skeleton.cc skeleton.h stub.h einbauen
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user