diff --git a/.vscode/launch.json b/.vscode/launch.json
index ff5fff91d937e99ff00c5ea1b251d240289baf15..dec5cc032c97c6052a3ec27008e4207fb6a1bc41 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -82,21 +82,41 @@
             "console": "externalTerminal"
         },    
         {
-            "name": "RoundRobinSchedulingTicksOnly",
+            "name": "RoundRobinSchedulingTicksOnlyExample",
             "type": "cppvsdbg",
             "request": "launch",
-            "program": "${workspaceFolder}/build/examples/RoundRobinScheduling/Debug/RoundRobinSchedulingTicksOnly.exe",
-            "args": ["-o" "c:/tmp" "-t" "2000" "-r" "1" "2"],
+            "program": "${workspaceFolder}/build/examples/PriorityScheduling/Debug/RoundRobinSchedulingTicksOnly.exe",
+            "args": ["-o" "${workspaceFolder}/traces" "-t" "2000" "-r" "1" "2"],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",
             "console": "integratedTerminal"
         },
         {
-            "name": "RoundRobinScheduling",
+            "name": "RoundRobinSchedulingExample",
             "type": "cppvsdbg",
             "request": "launch",
-            "program": "${workspaceFolder}/build/examples/RoundRobinScheduling/Debug/RoundRobinScheduling.exe",
-            "args": ["-o" "c:/tmp" "-t" "2000" "-r" "1" "2"],
+            "program": "${workspaceFolder}/build/examples/PriorityScheduling/Debug/RoundRobinScheduling.exe",
+            "args": ["-o" "${workspaceFolder}/traces" "-t" "2000" "-r" "1" "2"],
+            "stopAtEntry": false,
+            "cwd": "${workspaceFolder}",
+            "console": "integratedTerminal"
+        },
+        {
+            "name": "PrioritySchedulingExample",
+            "type": "cppvsdbg",
+            "request": "launch",
+            "program": "${workspaceFolder}/build/examples/PriorityScheduling/Debug/PriorityScheduling.exe",
+            "args": ["-o" "${workspaceFolder}/traces" "-t" "2000" "-r" "1" "2"],
+            "stopAtEntry": false,
+            "cwd": "${workspaceFolder}",
+            "console": "integratedTerminal"
+        },
+        {
+            "name": "PosixRealtimeSchedulingExample",
+            "type": "cppvsdbg",
+            "request": "launch",
+            "program": "${workspaceFolder}/build/examples/PriorityScheduling/Debug/PosixRealtimeScheduling.exe",
+            "args": ["-o" "${workspaceFolder}/traces" "-t" "2000" "-r" "1" "2"],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",
             "console": "integratedTerminal"
diff --git a/app4mc.sim_lib/OsModel/CMakeLists.txt b/app4mc.sim_lib/OsModel/CMakeLists.txt
index e300fad267248e156b1a4b7bf197dd4639b5190a..5c2c317d6805777645a8b064c1376a7102a14475 100644
--- a/app4mc.sim_lib/OsModel/CMakeLists.txt
+++ b/app4mc.sim_lib/OsModel/CMakeLists.txt
@@ -6,4 +6,5 @@ target_sources(app4mc.sim_lib PRIVATE
 	"ExternalSchedulerIF.cpp"
         "SchedulingParameter.cpp"
         "PriorityRoundRobinScheduler.cpp"
+        "PosixRealtimeScheduler.cpp"
         )
\ No newline at end of file
diff --git a/app4mc.sim_lib/OsModel/PosixRealtimeScheduler.cpp b/app4mc.sim_lib/OsModel/PosixRealtimeScheduler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c4cbc64a69697cbb92c62100185659bac8b04c84
--- /dev/null
+++ b/app4mc.sim_lib/OsModel/PosixRealtimeScheduler.cpp
@@ -0,0 +1,110 @@
+/**
+ ********************************************************************************
+ * Copyright (c) 2022 Robert Bosch GmbH
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ * Contributors:
+ * - Robert Bosch GmbH - initial contribution
+ *   Author: Behnaz Pourmohseni <behnaz.pourmohseni@de.bosch.com>
+ ********************************************************************************
+ */
+
+#include "PosixRealtimeScheduler.h"
+#include "Schedulable.h"
+#include "Common.h"
+#include "PriorityScheduler.h"
+#include "PriorityRoundRobinScheduler.h"
+
+using POLICY = PosixRealtimeScheduler::PosixSchedPolicy;
+
+std::string PosixRealtimeScheduler::getSchedulingPolicyName(const POLICY &policy) const {
+    switch(policy){
+        case POLICY::SCHED_FIFO:
+            return "SCHED_FIFO";
+        case POLICY::SCHED_RR:
+            return "SCHED_RR";
+        default:
+            throw std::runtime_error("scheduling policy has no defined name");
+    }
+}
+
+POLICY PosixRealtimeScheduler::getSchedulingPolicy(const std::string &policyName) const {
+    if(getSchedulingPolicyName(POLICY::SCHED_FIFO)== policyName){
+        return POLICY::SCHED_FIFO;
+    }
+    if(getSchedulingPolicyName(POLICY::SCHED_RR)== policyName){
+        return POLICY::SCHED_RR;
+    }
+    throw std::runtime_error("unknown scheduling policy name: " + policyName);
+}
+
+POLICY PosixRealtimeScheduler::getSchedulingPolicy(const std::shared_ptr<Schedulable> &task) const {
+    if(task->getTaskAllocation().isParameterSet("schedulingPolicy")){
+        return getSchedulingPolicy(task->getTaskAllocation().getSchedulingParameter<app4mc::ParameterType::String, false>("schedulingPolicy"));
+    }
+    return POLICY::SCHED_FIFO;
+}
+
+std::shared_ptr<Schedulable> PosixRealtimeScheduler::chooseTask(const std::shared_ptr<ProcessingUnit> &pu) {
+    auto chosenTask = schedule[pu];
+    if(chosenTask){
+        switch(getSchedulingPolicy(chosenTask)){
+        case POLICY::SCHED_FIFO:
+            return PriorityScheduler::chooseTask(pu);
+        case POLICY::SCHED_RR:
+            return PriorityRoundRobinScheduler::chooseTask(pu);
+        default:
+            throw std::runtime_error("scheduling policy not supported");
+        }
+    }
+    return chosenTask;
+}
+
+void PosixRealtimeScheduler::taskStart(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) {
+    switch(getSchedulingPolicy(task)){
+        case POLICY::SCHED_FIFO:
+            return PriorityScheduler::taskStart(task,pu);
+        case POLICY::SCHED_RR:
+            return PriorityRoundRobinScheduler::taskStart(task,pu);
+        default:
+            throw std::runtime_error("scheduling policy not supported");
+    }
+}
+
+void PosixRealtimeScheduler::taskPreemt(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) {
+    switch(getSchedulingPolicy(task)){
+        case POLICY::SCHED_FIFO:
+            return PriorityScheduler::taskPreemt(task,pu);
+        case POLICY::SCHED_RR:
+            return PriorityRoundRobinScheduler::taskPreemt(task,pu);
+        default:
+            throw std::runtime_error("scheduling policy not supported");
+    }
+}
+
+void PosixRealtimeScheduler::taskResume(const std::shared_ptr<Schedulable> &task,  const std::shared_ptr<ProcessingUnit> &pu) {
+    switch(getSchedulingPolicy(task)){
+        case POLICY::SCHED_FIFO:
+            return PriorityScheduler::taskResume(task,pu);
+        case POLICY::SCHED_RR:
+            return PriorityRoundRobinScheduler::taskResume(task,pu);
+        default:
+            throw std::runtime_error("scheduling policy not supported");
+    }
+}
+
+void PosixRealtimeScheduler::taskTerminate(const std::shared_ptr<Schedulable> &task) {
+    switch(getSchedulingPolicy(task)){
+        case POLICY::SCHED_FIFO:
+            return PriorityScheduler::taskTerminate(task);
+        case POLICY::SCHED_RR: 
+            return PriorityRoundRobinScheduler::taskTerminate(task);
+        default:
+            throw std::runtime_error("scheduling policy not supported");
+    }
+}
\ No newline at end of file
diff --git a/app4mc.sim_lib/OsModel/PriorityRoundRobinScheduler.cpp b/app4mc.sim_lib/OsModel/PriorityRoundRobinScheduler.cpp
index 15fc9a94a85fe767ed3452e7c1e80337f2d88236..13388718da1ba8d1b13a65e00cd1c0b9afc84b46 100644
--- a/app4mc.sim_lib/OsModel/PriorityRoundRobinScheduler.cpp
+++ b/app4mc.sim_lib/OsModel/PriorityRoundRobinScheduler.cpp
@@ -14,25 +14,20 @@
  ********************************************************************************
  */
 
-#include "Common.h"
-#include "HardwareModel.h"
 #include "PriorityRoundRobinScheduler.h"
-
+#include <algorithm>
+#include "Schedulable.h"
+#include "HardwareModel.h"
+#include "Event.h"
+#include "Tracer.h"
 
 sc_core::sc_time PriorityRoundRobinScheduler::getTimeSliceLength(){
     return convertTime(getAlgorithmParameter<app4mc::ParameterType::Time, false>("timeSliceLength"));
 }
 
-void PriorityRoundRobinScheduler::addTaskMapping(std::shared_ptr<Schedulable> task) {
-    if(!task->getTaskAllocation().isParameterSet("priority")){
-        throw std::runtime_error("Task \""+task->getName()+"\" uses PriorityRoundRobin Scheduler but has no Priority set");
-    }
-    Scheduler::addTaskMapping(task);
-}
-
 void PriorityRoundRobinScheduler::addResponsibleCore(std::shared_ptr<ProcessingUnit> pu) {
     if(!vectorContains(coresResponsible,pu)){
-        Scheduler::addResponsibleCore(pu);
+        PriorityScheduler::addResponsibleCore(pu);
         // timer event 
         auto exprEv = std::make_shared<Event>(getName() + "_TimerTimeoutEvent_" + pu->getName());
         Event::cancelEvent(exprEv);
@@ -47,8 +42,6 @@ void PriorityRoundRobinScheduler::addResponsibleCore(std::shared_ptr<ProcessingU
         timerOpts->dont_initialize();
         sc_core::sc_spawn( sc_bind(&PriorityRoundRobinScheduler::PuTimerTimeoutService, this, pu), timerName.c_str(), &*timerOpts);
         timerOptions[pu] = timerOpts;
-
-        schedule[pu].reset();
     }
 }
 
@@ -66,7 +59,6 @@ void PriorityRoundRobinScheduler::PuTimerTimeoutService(const std::shared_ptr<Pr
 }
 
 std::shared_ptr<Schedulable> PriorityRoundRobinScheduler::chooseTask(const std::shared_ptr<ProcessingUnit> &pu) {
-
     auto chosenTask = schedule[pu];
     if(runningTasks.count(pu)>0 && runningTasks[pu] == chosenTask){
         if(timerExpired[pu]){
@@ -81,24 +73,15 @@ std::shared_ptr<Schedulable> PriorityRoundRobinScheduler::chooseTask(const std::
     return chosenTask;
 }
 
-void PriorityRoundRobinScheduler::taskActivate(const std::shared_ptr<Schedulable> &task, const Stimulus &stimulus) {
-    printStateUpdateLog(task, "activated");
-    Scheduler::taskActivate(task,stimulus);
-    enqueueTask(task);
-    interruptPUs();
-} 
-
 void PriorityRoundRobinScheduler::taskStart(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) {
-    printStateUpdateLog(task, "start", pu, getTimeSliceLength());
-    Scheduler::taskStart(task,pu);
+    PriorityScheduler::taskStart(task,pu);
     lastPuAssignTime[task] = sc_core::sc_time_stamp();
     usedSlicePortion[task] = sc_core::SC_ZERO_TIME;
     setTimer(pu, getTimeSliceLength());
 }
 
 void PriorityRoundRobinScheduler::taskPreemt(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) {
-    printStateUpdateLog(task, "preempt", pu);
-    Scheduler::taskPreemt(task,pu);
+    PriorityScheduler::taskPreemt(task,pu);
     if(timerExpired[pu]){
         usedSlicePortion[task] = sc_core::SC_ZERO_TIME;
         timerExpired[pu] =false;
@@ -109,70 +92,29 @@ void PriorityRoundRobinScheduler::taskPreemt(const std::shared_ptr<Schedulable>
 }
 
 void PriorityRoundRobinScheduler::taskResume(const std::shared_ptr<Schedulable> &task,  const std::shared_ptr<ProcessingUnit> &pu) {
-    printStateUpdateLog(task, "resume", pu, (getTimeSliceLength() - usedSlicePortion[task]));
-    Scheduler::taskResume(task,pu);
+    PriorityScheduler::taskResume(task,pu);
     lastPuAssignTime[task] = sc_core::sc_time_stamp();
     setTimer(pu, getTimeSliceLength() - usedSlicePortion[task]);
 }
 
 void PriorityRoundRobinScheduler::taskTerminate(const std::shared_ptr<Schedulable> &task) {
-    printStateUpdateLog(task, "terminate");
-    Scheduler::taskTerminate(task);
-    dequeueTask(task);
+    auto it = std::find_if(schedule.begin(), schedule.end(), [&task] (const std::pair<std::shared_ptr<ProcessingUnit>,std::shared_ptr<Schedulable>>& entry) {
+    return entry.second == task;
+    });
+    auto pu = it->first;
+    PriorityScheduler::taskTerminate(task);
+    cancelTimer(pu);
     usedSlicePortion.erase(task);
     lastPuAssignTime.erase(task);
 }
 
-void PriorityRoundRobinScheduler::enqueueTask(const std::shared_ptr<Schedulable> &task){
-    vectorRemove(readyQueue, task);
-    // get an iterator itr to the first location in the readyQueue for which priority(*itr) < priority(task)
-    auto itr = std::lower_bound(readyQueue.begin(), readyQueue.end(), task, comparePrio);
-    readyQueue.insert(itr, task);
-    updateSchedule();
-}   
-
-void PriorityRoundRobinScheduler::dequeueTask(const std::shared_ptr<Schedulable> &task){
-    vectorRemove(readyQueue, task);
-    updateSchedule();
-}
-
 void PriorityRoundRobinScheduler::updateSchedule(){   
-    //log the state of readyQueue
-    printReadyQueueLog();
-
-    int schedSize = std::min(coresResponsible.size(), readyQueue.size());
-    std::vector<std::shared_ptr<Schedulable>> schedVect(readyQueue.begin(), readyQueue.begin() + schedSize);
-    std::vector<std::shared_ptr<ProcessingUnit>> unassignedCores;
-
-    auto schedVectEnd = schedVect.end();
-    for(const auto &pu: coresResponsible) {
-        if(runningTasks.count(pu) && vectorContains(schedVect, runningTasks[pu])){
-            // the task currently running on the core is part of the new schedule too
-            
-            // Note: explicit schedule assignment is necessary to make sure if multiple scheduleUpdate calls
-            // take place at the same sim time, schedule changes in one call which become deprecated in the 
-            // next one will be overwritten   
-            schedule[pu] = runningTasks[pu];
-            schedVectEnd = std::remove(schedVect.begin(), schedVectEnd, runningTasks[pu]);
-        } else {
-            unassignedCores.push_back(pu);
-        }
-    }
-
-    // update the schedule of unassigned cores
-    auto itr = schedVect.begin();
-    for(const auto &pu : unassignedCores){
-        if(itr != schedVectEnd){
-            schedule[pu] = *itr;
-            itr++;
-        } else {
-            schedule[pu].reset();
+    PriorityScheduler::updateSchedule();
+    for(const auto &pu : coresResponsible){
+        if(!schedule[pu]){
             cancelTimer(pu);
         }
     }
-
-    // log the updated schedule
-    printScheduleLog();
 }
 
 void PriorityRoundRobinScheduler::cancelTimer(const std::shared_ptr<ProcessingUnit> &pu){
@@ -181,45 +123,4 @@ void PriorityRoundRobinScheduler::cancelTimer(const std::shared_ptr<ProcessingUn
 
 void PriorityRoundRobinScheduler::setTimer(const std::shared_ptr<ProcessingUnit> &pu, const sc_core::sc_time time){
     Event::notifyEvent(timerTimeoutEvents[pu], time);
-}
-
-bool PriorityRoundRobinScheduler::comparePrio(const std::shared_ptr<Schedulable> &a, const std::shared_ptr<Schedulable> &b){
-    return a->getTaskAllocation().getSchedulingParameter<app4mc::ParameterType::Integer, false>(std::string("priority"))
-            >= b->getTaskAllocation().getSchedulingParameter<app4mc::ParameterType::Integer, false>("priority");
-}
-
-void PriorityRoundRobinScheduler::printLog(const std::string& msg){
-    VLOG_TIME(2) << "[PriorityRoundRobinScheduler] | " << msg;
-}
-
-void PriorityRoundRobinScheduler::printScheduleLog(){
-    std::stringstream buff;
-    buff << "schedule updated: ";
-    for(const auto &pu : coresResponsible){
-        buff << pu->getName() << ":" << ((schedule[pu]) ? (schedule[pu])->getName() : "()") << ", ";
-    }
-    buff << "\b\b";
-    printLog(buff.str());
-}
-
-void PriorityRoundRobinScheduler::printReadyQueueLog() const {
-    std::stringstream buff;
-    buff << "readyQueue updated: [";
-    for(const auto &t: readyQueue){
-        buff << t->getName() << ", ";
-    } 
-    buff << (readyQueue.empty()? " ]" : "\b\b]");
-    printLog(buff.str());
-}
-
-void PriorityRoundRobinScheduler::printStateUpdateLog(const std::shared_ptr<Schedulable> &task, const std::string &_state, const std::shared_ptr<ProcessingUnit> &pu, const sc_core::sc_time &time) const {
-    std::stringstream buff;
-    buff << _state << " " << task->getName();
-    if(pu != NULL) {
-        buff << " on " << pu->getName();
-        if(time.value()){
-            buff << " -- (timeout in " << time << ")";
-        }
-    }
-    printLog(buff.str());
 }
\ No newline at end of file
diff --git a/app4mc.sim_lib/OsModel/PriorityScheduler.cpp b/app4mc.sim_lib/OsModel/PriorityScheduler.cpp
index f7c3e401a82dd91bf118225e08e6c6191ea92b77..216277df018f3687028f02f4b3650e720e86976e 100644
--- a/app4mc.sim_lib/OsModel/PriorityScheduler.cpp
+++ b/app4mc.sim_lib/OsModel/PriorityScheduler.cpp
@@ -1,6 +1,6 @@
 /**
  ********************************************************************************
- * Copyright (c) 2020 University of Rostock and others
+ * Copyright (c) 2022 University of Rostock and others
  * 
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -10,78 +10,153 @@
  * 
  * Contributors:
  * - Benjamin Beichler <Benjamin.Beichler@uni-rostock.de> - initial contribution
+ * - Robert Bosch GmbH
  ********************************************************************************
  */
 
-#include "Common.h"
+#include <memory>
+#include <algorithm>
 #include "PriorityScheduler.h"
-std::shared_ptr<Schedulable> PriorityScheduler::chooseTask(const std::shared_ptr<ProcessingUnit> &requestingPu){
-
-    std::shared_ptr<Schedulable> chosenTask;
-    if(runningTasks.count(requestingPu) > 0){
-        chosenTask = runningTasks[requestingPu];
-    };
-    //find the task with the highest priority and compare to current running task
-
-    
-    //DO NOT CHANGE SEQUENCE: readyTasks -> activeTasks
-    //if a task has been chosen from the ready list, it may only be replaced by higher prio from active list
-    //if both are equal prio, tasks from ready list must be chosen
-    if(readyTasks.size() > 0){
-        auto maxReady = std::max_element(readyTasks.begin(),readyTasks.end(),&comparePrio);
-        if(!chosenTask || comparePrio(chosenTask, *maxReady)) 
-            chosenTask = *maxReady;
+#include "Schedulable.h"
+#include "HardwareModel.h"
+#include "Stimuli.h"
+#include "Common.h"
+
+void PriorityScheduler::addTaskMapping(std::shared_ptr<Schedulable> task) {
+    if(!task->getTaskAllocation().isParameterSet("priority")){
+        throw std::runtime_error("Task \""+task->getName()+"\" uses Priority Scheduler but has no Priority set");
     }
-    if(activeTasks.size() > 0){
-        auto maxActive = std::max_element(activeTasks.begin(), activeTasks.end(),&comparePrio);
-        if(!chosenTask || comparePrio(chosenTask, *maxActive))
-            chosenTask = *maxActive;
+    Scheduler::addTaskMapping(task);
+}
+
+void PriorityScheduler::addResponsibleCore(std::shared_ptr<ProcessingUnit> pu) {
+    if(!vectorContains(coresResponsible,pu)){
+        Scheduler::addResponsibleCore(pu);
+        schedule[pu].reset();
     }
+}
 
+std::shared_ptr<Schedulable> PriorityScheduler::chooseTask(const std::shared_ptr<ProcessingUnit> &pu) {
+    auto chosenTask = schedule[pu];
+    if(runningTasks.count(pu)>0 && runningTasks[pu] == chosenTask){
+        printStateUpdateLog(chosenTask, "continue", pu);
+    }
+    return chosenTask;
+}
 
-    //log decision
-    VLOG_TIME(2) << this->printChooseTask(requestingPu, chosenTask);
+void PriorityScheduler::taskActivate(const std::shared_ptr<Schedulable> &task, const Stimulus &stimulus) {
+    printStateUpdateLog(task, "activated");
+    Scheduler::taskActivate(task,stimulus);
+    enqueueTask(task);
+    interruptPUs();
+} 
 
-    return chosenTask;
+void PriorityScheduler::taskStart(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) {
+    printStateUpdateLog(task, "start", pu);
+    Scheduler::taskStart(task,pu);
 }
 
-std::string PriorityScheduler::printChooseTask(
-        const std::shared_ptr<ProcessingUnit> &requestingPu,
-        const std::shared_ptr<Schedulable> &nextChosenTask)
-    {
-    std::string buf = "\n";
-    buf.append("PriorityScheduler::chooseTask() for : " + requestingPu->getName() + "\n");
-    buf.append("running Task: ");
-    std::shared_ptr<Schedulable> chosenTask;
-    if(runningTasks.count(requestingPu) > 0){
-        chosenTask = runningTasks[requestingPu];
-    }
-    if (chosenTask != nullptr){
-        buf.append(std::dynamic_pointer_cast<HasName>(chosenTask)->getName());
+void PriorityScheduler::taskPreemt(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) {
+    printStateUpdateLog(task, "preempt", pu);
+    Scheduler::taskPreemt(task,pu);
+}
+
+void PriorityScheduler::taskResume(const std::shared_ptr<Schedulable> &task,  const std::shared_ptr<ProcessingUnit> &pu) {
+    printStateUpdateLog(task, "resume", pu);
+    Scheduler::taskResume(task,pu);
+}
+
+void PriorityScheduler::taskTerminate(const std::shared_ptr<Schedulable> &task) {
+    printStateUpdateLog(task, "terminate");
+    Scheduler::taskTerminate(task);
+    dequeueTask(task);
+}
+
+void PriorityScheduler::enqueueTask(const std::shared_ptr<Schedulable> &task){
+    vectorRemove(readyQueue, task);
+    // get an iterator itr to the first location in the readyQueue for which priority(*itr) < priority(task)
+    auto itr = std::lower_bound(readyQueue.begin(), readyQueue.end(), task, comparePrio);
+    readyQueue.insert(itr, task);
+    updateSchedule();
+}   
+
+void PriorityScheduler::dequeueTask(const std::shared_ptr<Schedulable> &task){
+    vectorRemove(readyQueue, task);
+    updateSchedule();
+}
+
+void PriorityScheduler::updateSchedule(){   
+    //log the state of readyQueue
+    printReadyQueueLog();
+
+    int schedSize = std::min(coresResponsible.size(), readyQueue.size());
+    std::vector<std::shared_ptr<Schedulable>> schedVect(readyQueue.begin(), readyQueue.begin() + schedSize);
+    std::vector<std::shared_ptr<ProcessingUnit>> unassignedCores;
+
+    auto schedVectEnd = schedVect.end();
+    for(const auto &pu: coresResponsible) {
+        if(runningTasks.count(pu) && vectorContains(schedVect, runningTasks[pu])){
+            // the task currently running on the core is part of the new schedule too
+            
+            // Note: explicit schedule assignment is necessary to make sure if multiple scheduleUpdate calls
+            // take place at the same sim time, schedule changes in one call which become deprecated in the 
+            // next one will be overwritten   
+            schedule[pu] = runningTasks[pu];
+            schedVectEnd = std::remove(schedVect.begin(), schedVectEnd, runningTasks[pu]);
+        } else {
+            unassignedCores.push_back(pu);
+        }
     }
-    
-    std::string readyTasksString = "\nReady Tasks";
-    for (auto task : readyTasks){
-        readyTasksString.append(std::dynamic_pointer_cast<HasName>(task)->getName());
-        readyTasksString.append (", ");
 
+    // update the schedule of unassigned cores
+    auto itr = schedVect.begin();
+    for(const auto &pu : unassignedCores){
+        if(itr != schedVectEnd){
+            schedule[pu] = *itr;
+            itr++;
+        } else {
+            schedule[pu].reset();
+        }
     }
-    buf.append(readyTasksString);
 
-    std::string activeTasksString = "\nActive Tasks";
-    for (auto task : activeTasks){
-        activeTasksString.append(std::dynamic_pointer_cast<HasName>(task)->getName());
-        activeTasksString.append (", ");
+    // log the updated schedule
+    printScheduleLog();
+}
 
-    }
-    buf.append(activeTasksString);
+bool PriorityScheduler::comparePrio(const std::shared_ptr<Schedulable> &a, const std::shared_ptr<Schedulable> &b){
+    return a->getTaskAllocation().getSchedulingParameter<app4mc::ParameterType::Integer, false>(std::string("priority"))
+            >= b->getTaskAllocation().getSchedulingParameter<app4mc::ParameterType::Integer, false>("priority");
+}
 
-    buf.append("\n---> now running ");
-    if (nextChosenTask != nullptr)
-        buf.append(std::dynamic_pointer_cast<HasName>(nextChosenTask)->getName());
-    else    
-        buf.append("nothing to run");
+void PriorityScheduler::printLog(const std::string& msg) const {
+    VLOG_TIME(2) << "[" + this->getName() + "] | " << msg;
+}
 
-    return buf;
+void PriorityScheduler::printScheduleLog(){
+    std::stringstream buff;
+    buff << "schedule updated: ";
+    for(const auto &pu : coresResponsible){
+        buff << pu->getName() << ":" << ((schedule[pu]) ? (schedule[pu])->getName() : "()") << ", ";
+    }
+    buff << "\b\b";
+    printLog(buff.str());
 }
 
+void PriorityScheduler::printReadyQueueLog() const {
+    std::stringstream buff;
+    buff << "readyQueue updated: [";
+    for(const auto &t: readyQueue){
+        buff << t->getName() << ", ";
+    } 
+    buff << (readyQueue.empty()? " ]" : "\b\b]");
+    printLog(buff.str());
+}
+
+void PriorityScheduler::printStateUpdateLog(const std::shared_ptr<Schedulable> &task, const std::string &_state, const std::shared_ptr<ProcessingUnit> &pu) const {
+    std::stringstream buff;
+    buff << _state << " " << task->getName();
+    if(pu != NULL) {
+        buff << " on " << pu->getName();
+    }
+    printLog(buff.str());
+}
\ No newline at end of file
diff --git a/app4mc.sim_lib/include/APP4MCsim.h b/app4mc.sim_lib/include/APP4MCsim.h
index f8a71cd6fe37d21d752685e23a9162d409552307..5ec30cfaa917eee2699528a896cdb1720cfabf31 100644
--- a/app4mc.sim_lib/include/APP4MCsim.h
+++ b/app4mc.sim_lib/include/APP4MCsim.h
@@ -14,6 +14,7 @@
 #include "RandomScheduler.h"
 #include "OsModel/BudgetScheduler.h"
 #include "OsModel/PriorityRoundRobinScheduler.h"
+#include "OsModel/PosixRealtimeScheduler.h"
 #include "OsModel/Semaphore.h"
 #include "OsModel/SchedulingParameter.h"
 //stimuli model
diff --git a/app4mc.sim_lib/include/OSModel.h b/app4mc.sim_lib/include/OSModel.h
index f22d8d017fc2380c410a6c9ffba554176ef2f39d..9e491c1c28ab0a3bb06e1626d2aa10858553fda8 100644
--- a/app4mc.sim_lib/include/OSModel.h
+++ b/app4mc.sim_lib/include/OSModel.h
@@ -70,7 +70,7 @@ protected:
 
 	  // this map uses pu as key, therefore need linear search
 	  for (auto &i : runningTasks) {
-	    auto &[pu, putask] = i;
+	    auto [pu, putask] = i;
 	    if (putask == task) {
 		  runningTasks.erase(pu);
 		  return pu;
diff --git a/app4mc.sim_lib/include/OsModel/PosixRealtimeScheduler.h b/app4mc.sim_lib/include/OsModel/PosixRealtimeScheduler.h
new file mode 100644
index 0000000000000000000000000000000000000000..a346a834314ea17a9343c013ec07002e6ca654f5
--- /dev/null
+++ b/app4mc.sim_lib/include/OsModel/PosixRealtimeScheduler.h
@@ -0,0 +1,49 @@
+/**
+ ********************************************************************************
+ * Copyright (c) 2022 Robert Bosch GmbH
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ * Contributors:
+ * - Robert Bosch GmbH - initial contribution
+ *   Author: Behnaz Pourmohseni <behnaz.pourmohseni@de.bosch.com>
+ ********************************************************************************
+ */
+
+#pragma once
+#include <systemc>
+#include <memory>
+#include <algorithm>
+#include "Common.h"
+#include "PriorityRoundRobinScheduler.h"
+
+class Schedulable;
+class ProcessingUnit;
+class Event;
+
+class PosixRealtimeScheduler: public PriorityRoundRobinScheduler {
+
+public: 
+
+    PosixRealtimeScheduler(std::string name): PriorityRoundRobinScheduler(std::move(name)) { }
+
+    std::shared_ptr<Schedulable> chooseTask(const std::shared_ptr<ProcessingUnit> &pu) override;
+
+    void taskStart(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) override;
+    void taskPreemt(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) override;
+    void taskResume(const std::shared_ptr<Schedulable> &task,  const std::shared_ptr<ProcessingUnit> &pu) override;
+    void taskTerminate(const std::shared_ptr<Schedulable> &task) override;
+    
+    enum class PosixSchedPolicy {SCHED_FIFO, SCHED_RR};
+    std::string getSchedulingPolicyName(const PosixSchedPolicy &policy) const;
+    PosixSchedPolicy getSchedulingPolicy(const std::string &policyName) const;
+
+protected:
+
+    PosixSchedPolicy getSchedulingPolicy(const std::shared_ptr<Schedulable> &task) const;
+    typedef std::map<std::shared_ptr<Schedulable>,PosixSchedPolicy> schedulingPolicy;
+};
\ No newline at end of file
diff --git a/app4mc.sim_lib/include/OsModel/PriorityRoundRobinScheduler.h b/app4mc.sim_lib/include/OsModel/PriorityRoundRobinScheduler.h
index f6dc316ddafd41dc09065b2a39f054fd4c888aec..b61487a7a42857c6eec6f2b822fade2788250693 100644
--- a/app4mc.sim_lib/include/OsModel/PriorityRoundRobinScheduler.h
+++ b/app4mc.sim_lib/include/OsModel/PriorityRoundRobinScheduler.h
@@ -18,15 +18,16 @@
 #include <systemc>
 #include <memory>
 #include <algorithm>
-#include "OSModel.h"
-#include "SoftwareModel.h"
+#include "Common.h"
+#include "PriorityScheduler.h"
 
-class PriorityRoundRobinScheduler: public Scheduler {
+class Schedulable;
+class ProcessingUnit;
+class Event;
 
-protected:    
+class PriorityRoundRobinScheduler: public PriorityScheduler {
 
-    std::vector<std::shared_ptr<Schedulable>> readyQueue;
-    std::map<std::shared_ptr<ProcessingUnit>,std::shared_ptr<Schedulable>> schedule;
+protected:    
     
     std::map<std::shared_ptr<Schedulable>,sc_core::sc_time> lastPuAssignTime; // start, resume, or continue to execute
     std::map<std::shared_ptr<Schedulable>,sc_core::sc_time> usedSlicePortion;
@@ -36,34 +37,21 @@ protected:
     std::map<std::shared_ptr<ProcessingUnit>,bool> timerExpired;
     std::map<std::shared_ptr<ProcessingUnit>,std::shared_ptr<sc_core::sc_spawn_options>> timerOptions;
 
-
-    void enqueueTask(const std::shared_ptr<Schedulable> &task);
-    void dequeueTask(const std::shared_ptr<Schedulable> &task);
-    void updateSchedule();
-
-    static bool comparePrio(const std::shared_ptr<Schedulable> &a, const std::shared_ptr<Schedulable> &b);
-
     void PuTimerTimeoutService(const std::shared_ptr<ProcessingUnit> &pu);
     void cancelTimer(const std::shared_ptr<ProcessingUnit> &pu);
     void setTimer(const std::shared_ptr<ProcessingUnit> &pu, const sc_core::sc_time time);
-
-    static void printLog(const std::string& msg);
-    void printScheduleLog();
-    void printReadyQueueLog() const;
-    void printStateUpdateLog(const std::shared_ptr<Schedulable> &task, const std::string &_state, const std::shared_ptr<ProcessingUnit> &pu=NULL, const sc_core::sc_time &time=sc_core::sc_time()) const;
+    
+    void updateSchedule() override;
+    
+    sc_core::sc_time getTimeSliceLength();
 
 public: 
 
-    PriorityRoundRobinScheduler(std::string name): Scheduler(std::move(name)) {  }
-
-    sc_core::sc_time getTimeSliceLength();
+    PriorityRoundRobinScheduler(std::string name): PriorityScheduler(std::move(name)) { }
 
-    void addTaskMapping(std::shared_ptr<Schedulable> task) override;
+    std::shared_ptr<Schedulable> chooseTask(const std::shared_ptr<ProcessingUnit> &pu) override;
     void addResponsibleCore(std::shared_ptr<ProcessingUnit> pu) override;
 
-    std::shared_ptr<Schedulable> chooseTask(const std::shared_ptr<ProcessingUnit> &pu) override;
-    
-    void taskActivate(const std::shared_ptr<Schedulable> &task, const Stimulus &stimulus) override;
     void taskStart(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) override;
     void taskPreemt(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) override;
     void taskResume(const std::shared_ptr<Schedulable> &task,  const std::shared_ptr<ProcessingUnit> &pu) override;
diff --git a/app4mc.sim_lib/include/OsModel/PriorityScheduler.h b/app4mc.sim_lib/include/OsModel/PriorityScheduler.h
index 91d20a43cd4f6579a84cf0e32866ea6eb56a095a..e22f0b918c0829444f04441659035bc9c25f7069 100644
--- a/app4mc.sim_lib/include/OsModel/PriorityScheduler.h
+++ b/app4mc.sim_lib/include/OsModel/PriorityScheduler.h
@@ -1,6 +1,6 @@
 /**
  ********************************************************************************
- * Copyright (c) 2020 University of Rostock and others
+ * Copyright (c) 2022 University of Rostock and others
  * 
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -10,47 +10,47 @@
  * 
  * Contributors:
  * - Benjamin Beichler <Benjamin.Beichler@uni-rostock.de> - initial contribution
+ * - Robert Bosch GmbH 
  ********************************************************************************
  */
 
 #pragma once
-#include <systemc>
 #include <memory>
-#include <algorithm>
-#include "OSModel.h"
-#include "Task.h"
-#include "HardwareModel.h"
-#include "SchedulingParameter.h"
-
-    /**
-	 *  Sets for every state of a Task *
-	 * 	See task model definition 
-	 *		https://www.eclipse.org/app4mc/help/latest/index.html#section3.7 
-	 */
-
-class PriorityScheduler : public Scheduler{
-public:  
-    //returns true: if priority of a < priority of b
-    static bool comparePrio(const std::shared_ptr<Schedulable> &a, const std::shared_ptr<Schedulable> &b){
-	  return a->getTaskAllocation().getSchedulingParameter<app4mc::ParameterType::Integer, false>(std::string("priority"))
-	            < b->getTaskAllocation().getSchedulingParameter<app4mc::ParameterType::Integer, false>("priority");
-    };
-
-    std::shared_ptr<Schedulable> chooseTask(const std::shared_ptr<ProcessingUnit> &requestingPu) override;
-
-    void taskActivate(const std::shared_ptr<Schedulable> &task, const Stimulus &stimulus) override {
-        Scheduler::taskActivate(task,stimulus);
-        interruptPUs();
-    };
+#include "OSModel.h" // provides the declaration of the Scheduler class
+
+class Schedulable;
+class ProcessingUnit;
+class Stimulus;
+
+class PriorityScheduler: public Scheduler {
+
+protected:    
+
+    std::vector<std::shared_ptr<Schedulable>> readyQueue;
+    std::map<std::shared_ptr<ProcessingUnit>,std::shared_ptr<Schedulable>> schedule;
+
+    virtual void enqueueTask(const std::shared_ptr<Schedulable> &task);
+    virtual void dequeueTask(const std::shared_ptr<Schedulable> &task);
+    virtual void updateSchedule();
+
+    static bool comparePrio(const std::shared_ptr<Schedulable> &a, const std::shared_ptr<Schedulable> &b);
+
+    void printScheduleLog();
+    void printReadyQueueLog() const;
+    void printStateUpdateLog(const std::shared_ptr<Schedulable> &task, const std::string &_state, const std::shared_ptr<ProcessingUnit> &pu=NULL) const;
+    virtual void printLog(const std::string& msg) const;
+
+public: 
+
+    PriorityScheduler(std::string name): Scheduler(std::move(name)) { }
+
+    void addTaskMapping(std::shared_ptr<Schedulable> task) override;
+    void addResponsibleCore(std::shared_ptr<ProcessingUnit> pu) override;
+    std::shared_ptr<Schedulable> chooseTask(const std::shared_ptr<ProcessingUnit> &pu) override;
     
-    PriorityScheduler(std::string name) : Scheduler(std::move(name)){};
-    void addTaskMapping(std::shared_ptr<Schedulable> task) override {
-        if(!task->getTaskAllocation().isParameterSet("priority")){
-            auto namePtr = std::dynamic_pointer_cast<HasName>(task);
-            throw std::runtime_error("Task \""+namePtr->getName()+"\" uses Priority Scheduler but has no Priority set");
-        }
-        Scheduler::addTaskMapping(task);
-    };
-private:
-    std::string printChooseTask(const std::shared_ptr<ProcessingUnit> &, const std::shared_ptr<Schedulable> &);
+    void taskActivate(const std::shared_ptr<Schedulable> &task, const Stimulus &stimulus) override;
+    void taskStart(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) override;
+    void taskPreemt(const std::shared_ptr<Schedulable> &task, const std::shared_ptr<ProcessingUnit> &pu) override;
+    void taskResume(const std::shared_ptr<Schedulable> &task,  const std::shared_ptr<ProcessingUnit> &pu) override;
+    void taskTerminate(const std::shared_ptr<Schedulable> &task) override;
 };
\ No newline at end of file
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 2240cac7de32433a6088acce6345a68efc24218e..07d912745d31a9f3f2f53344c00ab6944e327e70 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -26,4 +26,4 @@ add_subdirectory("Semaphore")
 add_subdirectory("Parameter")
 add_subdirectory("ExternalScheduler")
 add_subdirectory("ExternalEvents")
-add_subdirectory("RoundRobinScheduling")
+add_subdirectory("PriorityScheduling")
diff --git a/examples/PriorityScheduling/CMakeLists.txt b/examples/PriorityScheduling/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f7f3672f0bcf22ce536d6f4f150679fb460ce4a3
--- /dev/null
+++ b/examples/PriorityScheduling/CMakeLists.txt
@@ -0,0 +1,24 @@
+add_executable (PriorityScheduling "PriorityScheduling.cpp")
+target_link_libraries(PriorityScheduling app4mc.sim_lib)
+target_precompile_headers(PriorityScheduling REUSE_FROM app4mc.sim_lib)
+add_test(NAME PriorityScheduling COMMAND PriorityScheduling ${ADDITIONAL_TEST_ARGS})
+
+add_executable (RoundRobinScheduling "RoundRobinScheduling.cpp")
+target_link_libraries(RoundRobinScheduling app4mc.sim_lib)
+target_precompile_headers(RoundRobinScheduling REUSE_FROM app4mc.sim_lib)
+add_test(NAME Run_RoundRobinScheduling COMMAND RoundRobinScheduling ${ADDITIONAL_TEST_ARGS})
+
+add_executable (RoundRobinSchedulingTicksOnly "RoundRobinSchedulingTicksOnly.cpp")
+target_link_libraries(RoundRobinSchedulingTicksOnly app4mc.sim_lib)
+target_precompile_headers(RoundRobinSchedulingTicksOnly REUSE_FROM app4mc.sim_lib)
+add_test(NAME RoundRobinSchedulingTicksOnly COMMAND RoundRobinSchedulingTicksOnly ${ADDITIONAL_TEST_ARGS})
+
+add_executable (PosixRealtimeScheduling "PosixRealtimeScheduling.cpp")
+target_link_libraries(PosixRealtimeScheduling app4mc.sim_lib)
+target_precompile_headers(PosixRealtimeScheduling REUSE_FROM app4mc.sim_lib)
+add_test(NAME PosixRealtimeScheduling COMMAND PosixRealtimeScheduling ${ADDITIONAL_TEST_ARGS})
+
+install(
+    TARGETS PriorityScheduling RoundRobinScheduling RoundRobinSchedulingTicksOnly PosixRealtimeScheduling
+    RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/examples/PriorityScheduling
+)
\ No newline at end of file
diff --git a/examples/PriorityScheduling/PosixRealtimeScheduling.cpp b/examples/PriorityScheduling/PosixRealtimeScheduling.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bfbf53027e64ae5b3da8b67f8a22bfcfb6fa6986
--- /dev/null
+++ b/examples/PriorityScheduling/PosixRealtimeScheduling.cpp
@@ -0,0 +1,201 @@
+  /**
+ ********************************************************************************
+ * Copyright (c) 2022 Robert Bosch GmbH
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * - Robert Bosch GmbH - initial contribution
+ *   Author: Behnaz Pourmohseni <behnaz.pourmohseni@de.bosch.com>
+ ********************************************************************************
+ */
+
+#include <systemc>
+#include <memory>
+#include "APP4MCsim.h"
+#include "BTFTracer.h"
+#include "Common.h"
+
+INITIALIZE_EASYLOGGINGPP
+
+int sc_main(int argc, char *argv[]) {
+  sc_core::sc_set_time_resolution(1.0, sc_core::SC_NS);
+  SimParam args;
+  SimParamParser::parse(argc, argv, args);
+  START_EASYLOGGINGPP(argc, argv);
+
+  /* Hardware */
+  sc_core::sc_time ECU_Freq_Domain_CycleTime(10, sc_core::SC_NS);
+  ProcessingUnitDefinition pudef("CoreDef");
+  HwStructure ECU("ECU");
+
+  auto mainMem = ECU.createModule<Memory>("Memory", 1 * 1024 * 1024 * 1024);
+  mainMem->clock_period = ECU_Freq_Domain_CycleTime;
+
+  auto core1 = ECU.createModule<ProcessingUnit>("Core1", pudef);
+  core1->clock_period = ECU_Freq_Domain_CycleTime;
+  
+  HwAccessElement mainMemC1Access;
+  mainMemC1Access.dest = mainMem;
+  mainMemC1Access.setDataRate({100, DataRateUnit::kbitPerSecond});
+  mainMemC1Access.setReadLatency(DiscreteValueConstant(0));
+  core1->addHWAccessElement(mainMemC1Access);
+
+  auto core2 = ECU.createModule<ProcessingUnit>("Core2", pudef);
+  core2->clock_period = ECU_Freq_Domain_CycleTime;
+
+  HwAccessElement mainMemC2Access;
+  mainMemC2Access.dest = mainMem;
+  mainMemC2Access.setDataRate({100, DataRateUnit::kbitPerSecond});
+  mainMemC2Access.setReadLatency(DiscreteValueConstant(0));
+  core2->addHWAccessElement(mainMemC2Access);
+
+  /* Stimuli */
+  auto stimuli0 = std::make_shared<FixedPeriodicStimulus>("Stim0", 100_ms);
+  auto stimuli1 = std::make_shared<FixedPeriodicStimulus>("Stim1", 100_ms, 2_ms);
+  auto stimuli2 = std::make_shared<FixedPeriodicStimulus>("Stim2", 100_ms, 5_ms);
+  auto stimuli3 = std::make_shared<FixedPeriodicStimulus>("Stim3", 100_ms, 12_ms);
+  auto stimuli4 = std::make_shared<FixedPeriodicStimulus>("Stim4", 100_ms, 78_ms);
+  auto stimuli5 = std::make_shared<FixedPeriodicStimulus>("Stim5", 100_ms, 79_ms);
+
+
+  /* Software */
+  auto label0 = std::make_shared<DataLabel>("label0", 30);
+  auto label1 = std::make_shared<DataLabel>("label1", 60);
+  auto label2 = std::make_shared<DataLabel>("label2", 80);
+  auto label3 = std::make_shared<DataLabel>("label3", 100);
+  auto label4 = std::make_shared<DataLabel>("label4", 180);
+
+
+  auto task1 = Task::createTask("Task1");
+  task1->addStimulus(stimuli0);
+	task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(380000)});
+	task1->addActivityGraphItem<LabelAccess>({label1, 1, tlm::TLM_READ_COMMAND});
+	task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(380000)});
+	task1->addActivityGraphItem<LabelAccess>({label3, 1, tlm::TLM_READ_COMMAND});
+	task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(1400000)});
+  
+  auto task2 = Task::createTask("Task2");
+  task2->addStimulus(stimuli0);
+	task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(180000)});
+	task2->addActivityGraphItem<LabelAccess>({label2, 1, tlm::TLM_READ_COMMAND});
+	task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(50000)});
+	task2->addActivityGraphItem<LabelAccess>({label1, 1, tlm::TLM_READ_COMMAND});
+  task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(2400000)});
+
+  auto task3 = Task::createTask("Task3");
+  task3->addStimulus(stimuli1);
+	task3->addActivityGraphItem<Ticks>({DiscreteValueConstant(4200000)});
+  
+  auto task4 = Task::createTask("Task4");
+  task4->addStimulus(stimuli3);
+	task4->addActivityGraphItem<Ticks>({DiscreteValueConstant(370000)});
+	task4->addActivityGraphItem<LabelAccess>({label1, 1, tlm::TLM_READ_COMMAND});
+	task4->addActivityGraphItem<Ticks>({DiscreteValueConstant(1800000)});
+
+  auto task5 = Task::createTask("Task5");
+  task5->addStimulus(stimuli2);
+	task5->addActivityGraphItem<Ticks>({DiscreteValueConstant(1100000)});
+	task5->addActivityGraphItem<LabelAccess>({label4, 1, tlm::TLM_READ_COMMAND});
+	task5->addActivityGraphItem<Ticks>({DiscreteValueConstant(1500000)});
+
+  auto task6 = Task::createTask("Task6");
+  task6->addStimulus(stimuli3);
+	task6->addActivityGraphItem<Ticks>({DiscreteValueConstant(2300000)});
+
+  auto task7 = Task::createTask("Task7");
+  task7->addStimulus(stimuli4);
+	task7->addActivityGraphItem<Ticks>({DiscreteValueConstant(900000)});
+
+  auto task8 = Task::createTask("Task8");
+  task8->addStimulus(stimuli5);
+	task8->addActivityGraphItem<Ticks>({DiscreteValueConstant(900000)});
+  
+  TaskAllocation ta_task1;
+  ta_task1.setSchedulingParameter("priority", 0);
+  ta_task1.setSchedulingParameter("schedulingPolicy", "SCHED_FIFO"); // optional
+  task1->setTaskAllocation(ta_task1);
+
+  TaskAllocation ta_task2;
+  ta_task2.setSchedulingParameter("priority", 0);
+  ta_task2.setSchedulingParameter("schedulingPolicy", "SCHED_RR");
+  task2->setTaskAllocation(ta_task2);
+
+  TaskAllocation ta_task3;
+  ta_task3.setSchedulingParameter("priority", 1);
+  ta_task3.setSchedulingParameter("schedulingPolicy", "SCHED_RR");
+  task3->setTaskAllocation(ta_task3);
+
+  TaskAllocation ta_task4;
+  ta_task4.setSchedulingParameter("priority", 0);
+  ta_task4.setSchedulingParameter("schedulingPolicy", "SCHED_RR");
+  task4->setTaskAllocation(ta_task4);
+
+  TaskAllocation ta_task5;
+  ta_task5.setSchedulingParameter("priority", 1);
+  task5->setTaskAllocation(ta_task5);
+
+  TaskAllocation ta_task6;
+  ta_task6.setSchedulingParameter("priority", 2);
+  task6->setTaskAllocation(ta_task6);
+
+  TaskAllocation ta_task7;
+  ta_task7.setSchedulingParameter("priority", 1);
+  task7->setTaskAllocation(ta_task7);
+
+  TaskAllocation ta_task8;
+  ta_task8.setSchedulingParameter("priority", 1);
+  task8->setTaskAllocation(ta_task8);
+
+
+  /* OS and mapping */
+  auto posixSched = std::make_shared<PosixRealtimeScheduler>("posixSched");
+  posixSched->setAlgorithmSchedulingParameter("timeSliceLength", 4_ms);
+  posixSched->setExecutionCore(core1);
+  posixSched->addResponsibleCore(core1);
+  posixSched->addResponsibleCore(core2);
+  posixSched->addTaskMapping(task1);
+  posixSched->addTaskMapping(task2);
+  posixSched->addTaskMapping(task3);
+  posixSched->addTaskMapping(task4);
+  posixSched->addTaskMapping(task5);
+  posixSched->addTaskMapping(task6);
+  posixSched->addTaskMapping(task7);
+  posixSched->addTaskMapping(task8);
+
+
+	MappingModel::addMemoryMapping(label0, mainMem);
+	MappingModel::addMemoryMapping(label1, mainMem);
+	MappingModel::addMemoryMapping(label2, mainMem);
+	MappingModel::addMemoryMapping(label3, mainMem);
+	MappingModel::addMemoryMapping(label4, mainMem);
+
+  VLOG(0) << "simulation model created";
+
+  /* tracing */
+  auto vcdPath = TraceManager::createTraceFilePath("trace").string();
+	sc_core::sc_trace_file *tf = sc_core::sc_create_vcd_trace_file(vcdPath.c_str());
+  sc_trace(tf, &*core1, "Core1");
+  sc_trace(tf, &*core2, "Core2");
+  sc_trace(tf, &*mainMem, "Memory");
+
+  try {
+    VLOG(0) << "starting simulation";
+	  sc_core::sc_start(2000, sc_core::SC_MS);
+  } catch (sc_core::sc_report &e) {
+    const char *file = e.get_file_name();
+    const int line   = e.get_line_number();
+    const char *msg  = e.get_msg();
+    VLOG(0) << msg << "\nin file: " << file << "\nline: " << line;
+    return -1;
+  }
+
+  sc_core::sc_close_vcd_trace_file(tf);
+
+  VLOG(0) << "simulation done";
+  return 0;
+}
\ No newline at end of file
diff --git a/examples/PriorityScheduling/PriorityScheduling.cpp b/examples/PriorityScheduling/PriorityScheduling.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..29542dfb434e1104929fda0033afa6bffd5603fa
--- /dev/null
+++ b/examples/PriorityScheduling/PriorityScheduling.cpp
@@ -0,0 +1,195 @@
+/**
+ ********************************************************************************
+ * Copyright (c) 2022 Robert Bosch GmbH
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * - Robert Bosch GmbH - initial contribution
+ *   Author: Behnaz Pourmohseni <behnaz.pourmohseni@de.bosch.com>
+ ********************************************************************************
+ */
+
+#include <systemc>
+#include <memory>
+#include "APP4MCsim.h"
+#include "BTFTracer.h"
+#include "Common.h"
+
+INITIALIZE_EASYLOGGINGPP
+
+int sc_main(int argc, char *argv[]) {
+  sc_core::sc_set_time_resolution(1.0, sc_core::SC_NS);
+  SimParam args;
+  SimParamParser::parse(argc, argv, args);
+  START_EASYLOGGINGPP(argc, argv);
+
+  /* Hardware */
+  sc_core::sc_time ECU_Freq_Domain_CycleTime(10, sc_core::SC_NS);
+  ProcessingUnitDefinition pudef("CoreDef");
+  HwStructure ECU("ECU");
+
+  auto mainMem = ECU.createModule<Memory>("Memory", 1 * 1024 * 1024 * 1024);
+  mainMem->clock_period = ECU_Freq_Domain_CycleTime;
+
+  auto core1 = ECU.createModule<ProcessingUnit>("Core1", pudef);
+  core1->clock_period = ECU_Freq_Domain_CycleTime;
+  
+  HwAccessElement mainMemC1Access;
+  mainMemC1Access.dest = mainMem;
+  mainMemC1Access.setDataRate({100, DataRateUnit::kbitPerSecond});
+  mainMemC1Access.setReadLatency(DiscreteValueConstant(0));
+  core1->addHWAccessElement(mainMemC1Access);
+
+  auto core2 = ECU.createModule<ProcessingUnit>("Core2", pudef);
+  core2->clock_period = ECU_Freq_Domain_CycleTime;
+
+  HwAccessElement mainMemC2Access;
+  mainMemC2Access.dest = mainMem;
+  mainMemC2Access.setDataRate({100, DataRateUnit::kbitPerSecond});
+  mainMemC2Access.setReadLatency(DiscreteValueConstant(0));
+  core2->addHWAccessElement(mainMemC2Access);
+
+  /* Stimuli */
+  auto stimuli0 = std::make_shared<FixedPeriodicStimulus>("Stim0", 100_ms);
+  auto stimuli1 = std::make_shared<FixedPeriodicStimulus>("Stim1", 100_ms, 2_ms);
+  auto stimuli2 = std::make_shared<FixedPeriodicStimulus>("Stim2", 100_ms, 5_ms);
+  auto stimuli3 = std::make_shared<FixedPeriodicStimulus>("Stim3", 100_ms, 12_ms);
+  auto stimuli4 = std::make_shared<FixedPeriodicStimulus>("Stim4", 100_ms, 78_ms);
+  auto stimuli5 = std::make_shared<FixedPeriodicStimulus>("Stim5", 100_ms, 79_ms);
+
+
+  /* Software */
+  auto label0 = std::make_shared<DataLabel>("label0", 30);
+  auto label1 = std::make_shared<DataLabel>("label1", 60);
+  auto label2 = std::make_shared<DataLabel>("label2", 80);
+  auto label3 = std::make_shared<DataLabel>("label3", 100);
+  auto label4 = std::make_shared<DataLabel>("label4", 180);
+
+
+  auto task1 = Task::createTask("Task1");
+  task1->addStimulus(stimuli0);
+	task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(380000)});
+	task1->addActivityGraphItem<LabelAccess>({label1, 1, tlm::TLM_READ_COMMAND});
+	task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(380000)});
+	task1->addActivityGraphItem<LabelAccess>({label3, 1, tlm::TLM_READ_COMMAND});
+	task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(1400000)});
+  
+  auto task2 = Task::createTask("Task2");
+  task2->addStimulus(stimuli0);
+	task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(180000)});
+	task2->addActivityGraphItem<LabelAccess>({label2, 1, tlm::TLM_READ_COMMAND});
+	task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(50000)});
+	task2->addActivityGraphItem<LabelAccess>({label1, 1, tlm::TLM_READ_COMMAND});
+  task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(2400000)});
+
+  auto task3 = Task::createTask("Task3");
+  task3->addStimulus(stimuli1);
+	task3->addActivityGraphItem<Ticks>({DiscreteValueConstant(4200000)});
+  
+  auto task4 = Task::createTask("Task4");
+  task4->addStimulus(stimuli3);
+	task4->addActivityGraphItem<Ticks>({DiscreteValueConstant(370000)});
+	task4->addActivityGraphItem<LabelAccess>({label1, 1, tlm::TLM_READ_COMMAND});
+	task4->addActivityGraphItem<Ticks>({DiscreteValueConstant(1800000)});
+
+  auto task5 = Task::createTask("Task5");
+  task5->addStimulus(stimuli2);
+	task5->addActivityGraphItem<Ticks>({DiscreteValueConstant(1100000)});
+	task5->addActivityGraphItem<LabelAccess>({label4, 1, tlm::TLM_READ_COMMAND});
+	task5->addActivityGraphItem<Ticks>({DiscreteValueConstant(1500000)});
+
+  auto task6 = Task::createTask("Task6");
+  task6->addStimulus(stimuli3);
+	task6->addActivityGraphItem<Ticks>({DiscreteValueConstant(2300000)});
+
+  auto task7 = Task::createTask("Task7");
+  task7->addStimulus(stimuli4);
+	task7->addActivityGraphItem<Ticks>({DiscreteValueConstant(900000)});
+
+  auto task8 = Task::createTask("Task8");
+  task8->addStimulus(stimuli5);
+	task8->addActivityGraphItem<Ticks>({DiscreteValueConstant(900000)});
+  
+  TaskAllocation ta_task1;
+  ta_task1.setSchedulingParameter("priority", 0);
+  task1->setTaskAllocation(ta_task1);
+
+  TaskAllocation ta_task2;
+  ta_task2.setSchedulingParameter("priority", 0);
+  task2->setTaskAllocation(ta_task2);
+
+  TaskAllocation ta_task3;
+  ta_task3.setSchedulingParameter("priority", 1);
+  task3->setTaskAllocation(ta_task3);
+
+  TaskAllocation ta_task4;
+  ta_task4.setSchedulingParameter("priority", 0);
+  task4->setTaskAllocation(ta_task4);
+
+  TaskAllocation ta_task5;
+  ta_task5.setSchedulingParameter("priority", 1);
+  task5->setTaskAllocation(ta_task5);
+
+  TaskAllocation ta_task6;
+  ta_task6.setSchedulingParameter("priority", 2);
+  task6->setTaskAllocation(ta_task6);
+
+  TaskAllocation ta_task7;
+  ta_task7.setSchedulingParameter("priority", 1);
+  task7->setTaskAllocation(ta_task7);
+
+  TaskAllocation ta_task8;
+  ta_task8.setSchedulingParameter("priority", 1);
+  task8->setTaskAllocation(ta_task8);
+
+
+  /* OS and mapping */
+  auto fifoScheduler = std::make_shared<PriorityScheduler>("fifoSched");
+  fifoScheduler->setExecutionCore(core1);
+  fifoScheduler->addResponsibleCore(core1);
+  fifoScheduler->addResponsibleCore(core2);
+  fifoScheduler->addTaskMapping(task1);
+  fifoScheduler->addTaskMapping(task2);
+  fifoScheduler->addTaskMapping(task3);
+  fifoScheduler->addTaskMapping(task4);
+  fifoScheduler->addTaskMapping(task5);
+  fifoScheduler->addTaskMapping(task6);
+  fifoScheduler->addTaskMapping(task7);
+  fifoScheduler->addTaskMapping(task8);
+  
+  MappingModel::addMemoryMapping(label0, mainMem);
+  MappingModel::addMemoryMapping(label1, mainMem);
+  MappingModel::addMemoryMapping(label2, mainMem);
+  MappingModel::addMemoryMapping(label3, mainMem);
+  MappingModel::addMemoryMapping(label4, mainMem);
+
+  VLOG(0) << "simulation model created";
+
+  /* tracing */
+  auto vcdPath = TraceManager::createTraceFilePath("trace").string();
+	sc_core::sc_trace_file *tf = sc_core::sc_create_vcd_trace_file(vcdPath.c_str());
+  sc_trace(tf, &*core1, "Core1");
+  sc_trace(tf, &*core2, "Core2");
+  sc_trace(tf, &*mainMem, "Memory");
+
+  try {
+    VLOG(0) << "starting simulation";
+	  sc_core::sc_start(2000, sc_core::SC_MS);
+  } catch (sc_core::sc_report &e) {
+    const char *file = e.get_file_name();
+    const int line   = e.get_line_number();
+    const char *msg  = e.get_msg();
+    VLOG(0) << msg << "\nin file: " << file << "\nline: " << line;
+    return -1;
+  }
+
+  sc_core::sc_close_vcd_trace_file(tf);
+
+  VLOG(0) << "simulation done";
+  return 0;
+}
\ No newline at end of file
diff --git a/examples/RoundRobinScheduling/RoundRobinScheduling.cpp b/examples/PriorityScheduling/RoundRobinScheduling.cpp
similarity index 95%
rename from examples/RoundRobinScheduling/RoundRobinScheduling.cpp
rename to examples/PriorityScheduling/RoundRobinScheduling.cpp
index c593f61d8558cd33ad9db839a73e97f9da0e0e77..a45ef4cc845b73f0b3641232264527ca138b01ab 100644
--- a/examples/RoundRobinScheduling/RoundRobinScheduling.cpp
+++ b/examples/PriorityScheduling/RoundRobinScheduling.cpp
@@ -42,6 +42,7 @@ int sc_main(int argc, char *argv[]) {
   HwAccessElement mainMemC1Access;
   mainMemC1Access.dest = mainMem;
   mainMemC1Access.setDataRate({100, DataRateUnit::kbitPerSecond});
+  mainMemC1Access.setReadLatency(DiscreteValueConstant(0));
   core1->addHWAccessElement(mainMemC1Access);
 
   auto core2 = ECU.createModule<ProcessingUnit>("Core2", pudef);
@@ -50,6 +51,7 @@ int sc_main(int argc, char *argv[]) {
   HwAccessElement mainMemC2Access;
   mainMemC2Access.dest = mainMem;
   mainMemC2Access.setDataRate({100, DataRateUnit::kbitPerSecond});
+  mainMemC2Access.setReadLatency(DiscreteValueConstant(0));
   core2->addHWAccessElement(mainMemC2Access);
 
   /* Stimuli */
@@ -76,9 +78,6 @@ int sc_main(int argc, char *argv[]) {
 	task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(380000)});
 	task1->addActivityGraphItem<LabelAccess>({label3, 1, tlm::TLM_READ_COMMAND});
 	task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(1400000)});
-	//task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(1000000)});
-	//task1->addActivityGraphItem<LabelAccess>({label1, 50000, tlm::TLM_READ_COMMAND});
-	//task1->addActivityGraphItem<Ticks>({DiscreteValueConstant(400000)});
   
   auto task2 = Task::createTask("Task2");
   task2->addStimulus(stimuli0);
@@ -86,7 +85,6 @@ int sc_main(int argc, char *argv[]) {
 	task2->addActivityGraphItem<LabelAccess>({label2, 1, tlm::TLM_READ_COMMAND});
 	task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(50000)});
 	task2->addActivityGraphItem<LabelAccess>({label1, 1, tlm::TLM_READ_COMMAND});
-	//task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(1700000)});
   task2->addActivityGraphItem<Ticks>({DiscreteValueConstant(2400000)});
 
   auto task3 = Task::createTask("Task3");
diff --git a/examples/RoundRobinScheduling/RoundRobinSchedulingTicksOnly.cpp b/examples/PriorityScheduling/RoundRobinSchedulingTicksOnly.cpp
similarity index 97%
rename from examples/RoundRobinScheduling/RoundRobinSchedulingTicksOnly.cpp
rename to examples/PriorityScheduling/RoundRobinSchedulingTicksOnly.cpp
index 78c09e89dad6fbe414f9802801814c9d6884a359..e4542fd6ddfc903e6fea3a1d24403489b189cb17 100644
--- a/examples/RoundRobinScheduling/RoundRobinSchedulingTicksOnly.cpp
+++ b/examples/PriorityScheduling/RoundRobinSchedulingTicksOnly.cpp
@@ -42,6 +42,7 @@ int sc_main(int argc, char *argv[]) {
   HwAccessElement mainMemC1Access;
   mainMemC1Access.dest = mainMem;
   mainMemC1Access.setDataRate({100, DataRateUnit::kbitPerSecond});
+  mainMemC1Access.setReadLatency(DiscreteValueConstant(0));
   core1->addHWAccessElement(mainMemC1Access);
 
   auto core2 = ECU.createModule<ProcessingUnit>("Core2", pudef);
@@ -50,6 +51,7 @@ int sc_main(int argc, char *argv[]) {
   HwAccessElement mainMemC2Access;
   mainMemC2Access.dest = mainMem;
   mainMemC2Access.setDataRate({100, DataRateUnit::kbitPerSecond});
+  mainMemC2Access.setReadLatency(DiscreteValueConstant(0));
   core2->addHWAccessElement(mainMemC2Access);
 
   /* Stimuli */
diff --git a/examples/RoundRobinScheduling/CMakeLists.txt b/examples/RoundRobinScheduling/CMakeLists.txt
deleted file mode 100644
index eac2da7d9780a2de2264d99c2064cb90220c02e0..0000000000000000000000000000000000000000
--- a/examples/RoundRobinScheduling/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-add_executable (RoundRobinScheduling "RoundRobinScheduling.cpp")
-target_link_libraries(RoundRobinScheduling app4mc.sim_lib)
-target_precompile_headers(RoundRobinScheduling REUSE_FROM app4mc.sim_lib)
-add_test(NAME Run_RoundRobinScheduling COMMAND RoundRobinScheduling ${ADDITIONAL_TEST_ARGS})
-
-add_executable (RoundRobinSchedulingTicksOnly "RoundRobinSchedulingTicksOnly.cpp")
-target_link_libraries(RoundRobinSchedulingTicksOnly app4mc.sim_lib)
-target_precompile_headers(RoundRobinSchedulingTicksOnly REUSE_FROM app4mc.sim_lib)
-add_test(NAME RoundRobinSchedulingTicksOnly COMMAND RoundRobinSchedulingTicksOnly ${ADDITIONAL_TEST_ARGS})
-
-install(
-    TARGETS RoundRobinScheduling RoundRobinSchedulingTicksOnly
-    RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/examples/RoundRobinScheduling
-)
\ No newline at end of file