Library os_mutex
Require Import os_code_defs.
Require Import os_code_notations.
Require Import os_ucos_h.
Open Scope code_scope.
Definition OSMutexAccept_impl :=
Int8u ·OSMutexAccept·(⌞pevent @ OS_EVENT∗⌟)··{
⌞
legal @ Int8u;
pip @ Int8u
⌟;
If(pevent′ ==ₑ NULL){
RETURN ′0
};ₛ
ENTER_CRITICAL;ₛ
legal′ =ᶠ OS_EventSearch(·pevent′·);ₛ
If (legal′ ==ₑ ′0){
EXIT_CRITICAL;ₛ
RETURN ′0
};ₛ
If (pevent′→OSEventType !=ₑ ′OS_EVENT_TYPE_MUTEX){
EXIT_CRITICAL;ₛ
RETURN ′0
};ₛ
pip′ =ₑ 〈Int8u〉(pevent′→OSEventCnt ≫ ′8);ₛ
If ((OSTCBCur′→OSTCBPrio <ₑ pip′) ||ₑ (OSTCBCur′→OSTCBPrio ==ₑ pip′)){
EXIT_CRITICAL;ₛ
RETURN ′0
};ₛ
If ((pevent′→OSEventCnt &ₑ ′OS_MUTEX_KEEP_LOWER_8) ==ₑ ′OS_MUTEX_AVAILABLE){
pevent′→OSEventCnt =ₑ pevent′→OSEventCnt &ₑ ′OS_MUTEX_KEEP_UPPER_8;ₛ
pevent′→OSEventCnt =ₑ pevent′→OSEventCnt |ₑ OSTCBCur′→OSTCBPrio;ₛ
pevent′→OSEventPtr =ₑ OSTCBCur′;ₛ
EXIT_CRITICAL;ₛ
RETURN ′1
};ₛ
EXIT_CRITICAL;ₛ
RETURN ′0
}· .
Definition PlaceHolder:= &ₐ OSPlaceHolder′.
Definition OSMutexCreate_impl :=
OS_EVENT∗ ·OSMutexCreate·(⌞prio @ Int8u⌟)··{
⌞pevent @ OS_EVENT∗⌟;
If (prio′ ≥ ′OS_LOWEST_PRIO) {
RETURN 〈OS_EVENT ∗〉 NULL
};ₛ
ENTER_CRITICAL;ₛ
If (OSTCBPrioTbl′[prio′] !=ₑ NULL) {
EXIT_CRITICAL;ₛ
RETURN 〈OS_EVENT ∗〉 NULL
};ₛ
pevent′ =ₑ OSEventFreeList′;ₛ
If (OSEventFreeList′ !=ₑ NULL){
OSEventFreeList′ =ₑ 〈OS_EVENT∗〉 OSEventFreeList′→OSEventListPtr
};ₛ
IF (pevent′ !=ₑ NULL){
OS_EventWaitListInit(pevent′);ₛ
pevent′→OSEventType =ₑ ′OS_EVENT_TYPE_MUTEX;ₛ
pevent′→OSEventCnt =ₑ ((〈Int16u〉prio′) ≪ ′8) |ₑ ′OS_MUTEX_AVAILABLE;ₛ
pevent′→OSEventPtr =ₑ NULL;ₛ
pevent ′ → OSEventListPtr =ₑ OSEventList ′;ₛ
OSTCBPrioTbl′[prio′] =ₑ 〈OS_TCB ∗〉 PlaceHolder;ₛ
OSEventList′ =ₑ pevent′;ₛ
EXIT_CRITICAL;ₛ
RETURN pevent′
}ELSE{
EXIT_CRITICAL;ₛ
RETURN 〈OS_EVENT ∗〉 NULL
}
}·.
Definition OSMutexDel_impl :=
Int8u ·OSMutexDel·(⌞ pevent @ OS_EVENT ∗⌟)··{
⌞
tasks_waiting @ Int8u;
pip @ Int8u;
legal @ Int8u
⌟;
If (pevent′ ==ₑ NULL){
RETURN ′OS_ERR_PEVENT_NULL
};ₛ
ENTER_CRITICAL;ₛ
legal′ =ᶠ OS_EventSearch(·pevent′·);ₛ
If (legal′ ==ₑ ′0){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_PEVENT_NO_EX
};ₛ
If (pevent′→OSEventType !=ₑ ′OS_EVENT_TYPE_MUTEX){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_EVENT_TYPE
};ₛ
IF (pevent′→OSEventGrp !=ₑ ′0 ||ₑ ( ( pevent′→OSEventCnt &ₑ ′OS_MUTEX_KEEP_LOWER_8 )!=ₑ ′OS_MUTEX_AVAILABLE)){
tasks_waiting′ =ₑ ′1
}ELSE{
tasks_waiting′ =ₑ ′0
};ₛ
IF (tasks_waiting′ ==ₑ ′0){
pip′ =ₑ 〈Int8u〉 (pevent′→OSEventCnt ≫ ′8);ₛ
If ( OSTCBPrioTbl′[pip′] !=ₑ 〈OS_TCB ∗〉 PlaceHolder){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_MUTEXPR_NOT_HOLDER
};ₛ
OS_EventRemove(pevent′);ₛ
OSTCBPrioTbl′[pip′] =ₑ NULL;ₛ
pevent′→OSEventType =ₑ ′OS_EVENT_TYPE_UNUSED;ₛ
pevent′→OSEventListPtr =ₑ OSEventFreeList′;ₛ
pevent′→OSEventCnt =ₑ ′0;ₛ
OSEventFreeList′ =ₑ pevent′;ₛ
EXIT_CRITICAL;ₛ
RETURN ′OS_NO_ERR
}ELSE{
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_TASK_WAITING
}
}· .
Require Import ZArith.
Definition OSMutexPend_impl :=
Int8u ·OSMutexPend·(⌞ pevent @ OS_EVENT ∗; timeout @ Int16u ⌟)··{
⌞
legal @ Int8u;
pip @ Int8u;
mprio @ Int8u;
isrdy @ Int8u;
ptcb @ (Tptr OS_TCB);
pevent2 @ (Tptr OS_EVENT)
⌟;
If (pevent′ ==ₑ NULL){
RETURN ′OS_ERR_PEVENT_NULL
};ₛ
ENTER_CRITICAL;ₛ
legal′ =ᶠ OS_EventSearch(·pevent′·);ₛ
If (legal′ ==ₑ ′0){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_PEVENT_NO_EX
};ₛ
If (pevent′→OSEventType !=ₑ ′OS_EVENT_TYPE_MUTEX){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_EVENT_TYPE
};ₛ
If (OSTCBCur′→OSTCBPrio ==ₑ ′OS_IDLE_PRIO){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_IDLE
};ₛ
If ( (OSTCBCur′→OSTCBStat !=ₑ ′OS_STAT_RDY) ||ₑ (OSTCBCur′→OSTCBDly !=ₑ ′0)){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_STAT
};ₛ
If (OSTCBCur′→OSTCBMsg !=ₑ NULL) {
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_PEVENT_NULL
};ₛ
pip′ =ₑ 〈Int8u〉(pevent′→OSEventCnt ≫ ′8);ₛ
If (OSTCBCur′→OSTCBPrio <ₑ pip′ ||ₑ (OSTCBCur′→OSTCBPrio ==ₑ pip′)){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_MUTEX_PRIO
};ₛ
mprio′ =ₑ 〈Int8u〉(pevent′→OSEventCnt &ₑ ′OS_MUTEX_KEEP_LOWER_8);ₛ
ptcb′ =ₑ pevent′→OSEventPtr;ₛ
If (mprio′ ==ₑ ′OS_MUTEX_AVAILABLE) {
pevent′→OSEventCnt =ₑ pevent′→OSEventCnt &ₑ ′OS_MUTEX_KEEP_UPPER_8;ₛ
pevent′→OSEventCnt =ₑ pevent′→OSEventCnt |ₑ OSTCBCur′→OSTCBPrio;ₛ
pevent′→OSEventPtr =ₑ OSTCBCur′;ₛ
EXIT_CRITICAL;ₛ
RETURN ′OS_NO_ERR
};ₛ
If(ptcb′ ==ₑ OSTCBCur′){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_MUTEX_DEADLOCK
};ₛ
If(ptcb′→OSTCBPrio ==ₑ ′OS_IDLE_PRIO){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_MUTEX_IDLE
};ₛ
If ( (ptcb′→OSTCBStat !=ₑ ′OS_STAT_RDY) ||ₑ (ptcb′→OSTCBDly !=ₑ ′0)){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_NEST
};ₛ
If(mprio′ ==ₑ (OSTCBCur′→OSTCBPrio)){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_MUTEX_DEADLOCK
};ₛ
IF ((ptcb′→OSTCBPrio !=ₑ pip′) &&ₑ (mprio′ >ₑ (OSTCBCur′→OSTCBPrio))){
If ( OSTCBPrioTbl′[pip′] !=ₑ 〈OS_TCB ∗〉 PlaceHolder){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_MUTEXPR_NOT_HOLDER
};ₛ
OSTCBPrioTbl′[ ptcb′→OSTCBPrio ] =ₑ 〈OS_TCB ∗〉 PlaceHolder;ₛ
OSTCBPrioTbl′[pip′] =ₑ 〈OS_TCB ∗〉 ptcb′;ₛ
OSRdyTbl′[ptcb′→OSTCBY] =ₑ OSRdyTbl′[ptcb′→OSTCBY]&ₑ(∼ptcb′→OSTCBBitX);ₛ
If (OSRdyTbl′[ptcb′→OSTCBY] ==ₑ ′0)
{
OSRdyGrp′ =ₑ OSRdyGrp′ &ₑ (∼ptcb′→OSTCBBitY)
};ₛ
ptcb′→OSTCBPrio =ₑ pip′;ₛ
ptcb′→OSTCBY =ₑ ptcb′→OSTCBPrio ≫ ′3;ₛ
ptcb′→OSTCBBitY =ₑ OSMapTbl′[ptcb′→OSTCBY];ₛ
ptcb′→OSTCBX =ₑ (ptcb′→OSTCBPrio) &ₑ ′7;ₛ
ptcb′→OSTCBBitX =ₑ OSMapTbl′[ptcb′→OSTCBX];ₛ
OSRdyGrp′ =ₑ OSRdyGrp′ |ₑ ptcb′→OSTCBBitY;ₛ
OSRdyTbl′[ptcb′→OSTCBY] =ₑ OSRdyTbl′[ptcb′→OSTCBY] |ₑ ptcb′→OSTCBBitX;ₛ
OSTCBCur′→OSTCBStat =ₑ ′OS_STAT_MUTEX;ₛ
OSTCBCur′→OSTCBDly =ₑ timeout′;ₛ
OS_EventTaskWait(pevent′);ₛ
EXIT_CRITICAL;ₛ
OS_Sched();ₛ
ENTER_CRITICAL;ₛ
If (OSTCBCur′→OSTCBMsg !=ₑ NULL){
EXIT_CRITICAL;ₛ
RETURN ′OS_NO_ERR
};ₛ
EXIT_CRITICAL;ₛ
RETURN ′OS_TIMEOUT
} ELSE {
OSTCBCur′→OSTCBStat =ₑ ′OS_STAT_MUTEX;ₛ
OSTCBCur′→OSTCBDly =ₑ timeout′;ₛ
OS_EventTaskWait(pevent′);ₛ
EXIT_CRITICAL;ₛ
OS_Sched();ₛ
ENTER_CRITICAL;ₛ
If (OSTCBCur′→OSTCBMsg !=ₑ NULL){
EXIT_CRITICAL;ₛ
RETURN ′OS_NO_ERR
};ₛ
EXIT_CRITICAL;ₛ
RETURN ′OS_TIMEOUT
}
}· .
Definition OSMutexPost_impl :=
Int8u ·OSMutexPost·(⌞pevent @ OS_EVENT∗ ⌟)··{
⌞
x @ Int8u;
pip @ Int8u;
prio @ Int8u;
legal @ Int8u
⌟;
If (pevent′ ==ₑ NULL){
RETURN ′OS_ERR_PEVENT_NULL
};ₛ
ENTER_CRITICAL;ₛ
legal′ =ᶠ OS_EventSearch(·pevent′·);ₛ
If (legal′ ==ₑ ′0){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_PEVENT_NO_EX
};ₛ
If (pevent′→OSEventType !=ₑ ′OS_EVENT_TYPE_MUTEX){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_EVENT_TYPE
};ₛ
pip′ =ₑ 〈Int8u〉(pevent′→OSEventCnt ≫ ′8);ₛ
prio′ =ₑ 〈Int8u〉(pevent′→OSEventCnt &ₑ ′OS_MUTEX_KEEP_LOWER_8);ₛ
If (OSTCBCur′ !=ₑ pevent′→OSEventPtr) {
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_NOT_MUTEX_OWNER
};ₛ
If (OSTCBCur′→OSTCBPrio <ₑ pip′){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_MUTEX_PRIO
};ₛ
legal′ =ₑ OSUnMapTbl′[pevent′→OSEventGrp];ₛ
x′ =ₑ (legal′≪ ′3) +ₑ OSUnMapTbl′[pevent′→OSEventTbl[legal′]];ₛ
If ( pevent′→OSEventGrp !=ₑ ′0 &&ₑ (x′ <ₑ pip′ ||ₑ x′ ==ₑ pip′)){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_MUTEX_WL_HIGHEST_PRIO
};ₛ
If(OSTCBCur ′ → OSTCBStat !=ₑ ′OS_STAT_RDY ||ₑ OSTCBCur ′ → OSTCBDly !=ₑ ′0){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_ORIGINAL_NOT_HOLDER
};ₛ
If (OSTCBCur′→OSTCBPrio ==ₑ pip′) {
If ( OSTCBPrioTbl′[prio′] !=ₑ 〈OS_TCB ∗〉 PlaceHolder){
EXIT_CRITICAL;ₛ
RETURN ′OS_ERR_ORIGINAL_NOT_HOLDER
};ₛ
OSRdyTbl′[OSTCBCur′→OSTCBY] =ₑ OSRdyTbl′[OSTCBCur′→OSTCBY] &ₑ (∼OSTCBCur′→OSTCBBitX);ₛ
If ( OSRdyTbl′[OSTCBCur′→OSTCBY] ==ₑ ′0) {
OSRdyGrp′ =ₑ OSRdyGrp′ &ₑ ∼OSTCBCur′→OSTCBBitY
};ₛ
OSTCBCur′→OSTCBPrio =ₑ prio′;ₛ
OSTCBCur′→OSTCBY =ₑ prio′ ≫ ′3;ₛ
OSTCBCur′→OSTCBBitY =ₑ OSMapTbl′[OSTCBCur′→OSTCBY];ₛ
OSTCBCur′→OSTCBX =ₑ prio′ &ₑ ′7;ₛ
OSTCBCur′→OSTCBBitX =ₑ OSMapTbl′[OSTCBCur′→OSTCBX];ₛ
OSRdyGrp′ =ₑ OSRdyGrp′ |ₑ OSTCBCur′→OSTCBBitY;ₛ
OSRdyTbl′[OSTCBCur′→OSTCBY] =ₑ OSRdyTbl′[OSTCBCur′→OSTCBY] |ₑ OSTCBCur′→OSTCBBitX;ₛ
OSTCBPrioTbl′[prio′] =ₑ 〈OS_TCB ∗〉 OSTCBCur′;ₛ
OSTCBPrioTbl′[pip′] =ₑ 〈OS_TCB ∗〉 PlaceHolder
};ₛ
If (pevent′→OSEventGrp !=ₑ ′0) {
x′ =ₑ ′OS_STAT_MUTEX;ₛ
prio′ =ᶠ OS_EventTaskRdy(·pevent′, 〈Void ∗〉 pevent′, x′·);ₛ
pevent′→OSEventCnt =ₑ pevent′→OSEventCnt &ₑ ′OS_MUTEX_KEEP_UPPER_8;ₛ
pevent′→OSEventCnt =ₑ pevent′→OSEventCnt |ₑ prio′;ₛ
pevent′→OSEventPtr =ₑ OSTCBPrioTbl′[prio′];ₛ
EXIT_CRITICAL;ₛ
OS_Sched();ₛ
RETURN ′OS_NO_ERR
};ₛ
pevent′→OSEventCnt =ₑ pevent′→OSEventCnt |ₑ ′OS_MUTEX_AVAILABLE;ₛ
pevent′→OSEventPtr =ₑ NULL;ₛ
EXIT_CRITICAL;ₛ
RETURN ′OS_NO_ERR
}· .
Close Scope code_scope.