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_EventSearchpevent·);ₛ
          If (legal ==ₑ 0){
              EXIT_CRITICAL;ₛ
              RETURN 0
          };ₛ
          If (peventOSEventType !=ₑ OS_EVENT_TYPE_MUTEX){
            EXIT_CRITICAL;ₛ
            RETURN 0
          };ₛ
          pip =ₑ Int8u〉(peventOSEventCnt 8);ₛ
          If ((OSTCBCurOSTCBPrio <ₑ pip) ||ₑ (OSTCBCurOSTCBPrio ==ₑ pip)){
            EXIT_CRITICAL;ₛ
            RETURN 0
          };ₛ
          If ((peventOSEventCnt &ₑ OS_MUTEX_KEEP_LOWER_8) ==ₑ OS_MUTEX_AVAILABLE){
            peventOSEventCnt =ₑ peventOSEventCnt &ₑ OS_MUTEX_KEEP_UPPER_8;ₛ
            peventOSEventCnt =ₑ peventOSEventCnt |ₑ OSTCBCurOSTCBPrio;ₛ
            peventOSEventPtr =ₑ 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 OSEventFreeListOSEventListPtr
            };ₛ
            IF (pevent !=ₑ NULL){
                OS_EventWaitListInitpevent­);ₛ
                peventOSEventType =ₑ OS_EVENT_TYPE_MUTEX;ₛ
                peventOSEventCnt =ₑ ((Int16uprio) 8) |ₑ OS_MUTEX_AVAILABLE;ₛ
                peventOSEventPtr =ₑ 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_EventSearchpevent·);ₛ
        If (legal ==ₑ 0){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_PEVENT_NO_EX
        };ₛ
        If (peventOSEventType !=ₑ OS_EVENT_TYPE_MUTEX){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_EVENT_TYPE
        };ₛ
        IF (peventOSEventGrp !=ₑ 0 ||ₑ ( ( peventOSEventCnt &ₑ OS_MUTEX_KEEP_LOWER_8 )!=ₑ OS_MUTEX_AVAILABLE)){
            tasks_waiting =ₑ 1
        }ELSE{
            tasks_waiting =ₑ 0
        };ₛ
        IF (tasks_waiting ==ₑ 0){
            pip =ₑ Int8u (peventOSEventCnt 8);ₛ
            If ( OSTCBPrioTbl[pip] !=ₑ OS_TCB PlaceHolder){
                EXIT_CRITICAL;ₛ
                RETURN OS_ERR_MUTEXPR_NOT_HOLDER
            };ₛ
            OS_EventRemovepevent­);ₛ
            OSTCBPrioTbl[pip] =ₑ NULL;ₛ
            peventOSEventType =ₑ OS_EVENT_TYPE_UNUSED;ₛ
            peventOSEventListPtr =ₑ OSEventFreeList;ₛ
            peventOSEventCnt =ₑ 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_EventSearchpevent·);ₛ
        If (legal ==ₑ 0){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_PEVENT_NO_EX
        };ₛ
        If (peventOSEventType !=ₑ OS_EVENT_TYPE_MUTEX){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_EVENT_TYPE
        };ₛ
        If (OSTCBCurOSTCBPrio ==ₑ OS_IDLE_PRIO){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_IDLE
        };ₛ
        If ( (OSTCBCurOSTCBStat !=ₑ OS_STAT_RDY) ||ₑ (OSTCBCurOSTCBDly !=ₑ 0)){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_STAT
        };ₛ
        If (OSTCBCurOSTCBMsg !=ₑ NULL) {
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_PEVENT_NULL
        };ₛ
           
        pip =ₑ Int8u〉(peventOSEventCnt 8);ₛ
        If (OSTCBCurOSTCBPrio <ₑ pip ||ₑ (OSTCBCurOSTCBPrio ==ₑ pip)){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_MUTEX_PRIO
        };ₛ
        mprio =ₑ Int8u〉(peventOSEventCnt &ₑ OS_MUTEX_KEEP_LOWER_8);ₛ
        ptcb =ₑ peventOSEventPtr;ₛ
       
        If (mprio ==ₑ OS_MUTEX_AVAILABLE) {
            peventOSEventCnt =ₑ peventOSEventCnt &ₑ OS_MUTEX_KEEP_UPPER_8;ₛ
            peventOSEventCnt =ₑ peventOSEventCnt |ₑ OSTCBCurOSTCBPrio;ₛ
            peventOSEventPtr =ₑ OSTCBCur;ₛ
            EXIT_CRITICAL;ₛ
            RETURN OS_NO_ERR
        };ₛ

        If(ptcb ==ₑ OSTCBCur){
          EXIT_CRITICAL;ₛ
          RETURN OS_ERR_MUTEX_DEADLOCK
        };ₛ
        If(ptcbOSTCBPrio ==ₑ OS_IDLE_PRIO){
          EXIT_CRITICAL;ₛ
          RETURN OS_ERR_MUTEX_IDLE
        };ₛ
        If ( (ptcbOSTCBStat !=ₑ OS_STAT_RDY) ||ₑ (ptcbOSTCBDly !=ₑ 0)){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_NEST
        };ₛ
        If(mprio ==ₑ (OSTCBCurOSTCBPrio)){
          EXIT_CRITICAL;ₛ
          RETURN OS_ERR_MUTEX_DEADLOCK
        };ₛ
        
        IF ((ptcbOSTCBPrio !=ₑ pip) &&ₑ (mprio >ₑ (OSTCBCurOSTCBPrio))){
            If ( OSTCBPrioTbl[pip] !=ₑ OS_TCB PlaceHolder){
                EXIT_CRITICAL;ₛ
                RETURN OS_ERR_MUTEXPR_NOT_HOLDER
            };ₛ
           
            OSTCBPrioTbl[ ptcbOSTCBPrio ] =ₑ OS_TCB PlaceHolder;ₛ
            OSTCBPrioTbl[pip] =ₑ OS_TCB ptcb;ₛ

                OSRdyTbl[ptcbOSTCBY] =ₑ OSRdyTbl[ptcbOSTCBY]&ₑ(ptcbOSTCBBitX);ₛ
                If (OSRdyTbl[ptcbOSTCBY] ==ₑ 0)
                {
                    OSRdyGrp =ₑ OSRdyGrp &ₑ (ptcbOSTCBBitY)
                };ₛ
                ptcbOSTCBPrio =ₑ pip;ₛ
                ptcbOSTCBY =ₑ ptcbOSTCBPrio 3;ₛ
                ptcbOSTCBBitY =ₑ OSMapTbl[ptcbOSTCBY];ₛ
                ptcbOSTCBX =ₑ (ptcbOSTCBPrio) &ₑ 7;ₛ
                ptcbOSTCBBitX =ₑ OSMapTbl[ptcbOSTCBX];ₛ
                OSRdyGrp =ₑ OSRdyGrp |ₑ ptcbOSTCBBitY;ₛ
                OSRdyTbl[ptcbOSTCBY] =ₑ OSRdyTbl[ptcbOSTCBY] |ₑ ptcbOSTCBBitX;ₛ
                 
                OSTCBCurOSTCBStat =ₑ OS_STAT_MUTEX;ₛ
                OSTCBCurOSTCBDly =ₑ timeout;ₛ
                OS_EventTaskWaitpevent­);ₛ
                EXIT_CRITICAL;ₛ
                OS_Sched(­);ₛ
                ENTER_CRITICAL;ₛ
                If (OSTCBCurOSTCBMsg !=ₑ NULL){
                   EXIT_CRITICAL;ₛ
                   RETURN OS_NO_ERR
                };ₛ
                EXIT_CRITICAL;ₛ
                RETURN OS_TIMEOUT
          
        } ELSE {
          OSTCBCurOSTCBStat =ₑ OS_STAT_MUTEX;ₛ
          OSTCBCurOSTCBDly =ₑ timeout;ₛ
          OS_EventTaskWaitpevent­);ₛ
          EXIT_CRITICAL;ₛ
          OS_Sched(­);ₛ
          ENTER_CRITICAL;ₛ
          If (OSTCBCurOSTCBMsg !=ₑ 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_EventSearchpevent·);ₛ
        If (legal ==ₑ 0){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_PEVENT_NO_EX
           };ₛ
        If (peventOSEventType !=ₑ OS_EVENT_TYPE_MUTEX){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_EVENT_TYPE
        };ₛ
        
        pip =ₑ Int8u〉(peventOSEventCnt 8);ₛ
        prio =ₑ Int8u〉(peventOSEventCnt &ₑ OS_MUTEX_KEEP_LOWER_8);ₛ
        If (OSTCBCur !=ₑ peventOSEventPtr) {
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_NOT_MUTEX_OWNER
        };ₛ
        If (OSTCBCurOSTCBPrio <ₑ pip){
            EXIT_CRITICAL;ₛ
            RETURN OS_ERR_MUTEX_PRIO
        };ₛ
        legal =ₑ OSUnMapTbl[peventOSEventGrp];ₛ
        x =ₑ (legal 3) +ₑ OSUnMapTbl[peventOSEventTbl[legal]];ₛ
        If ( peventOSEventGrp !=ₑ 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 (OSTCBCurOSTCBPrio ==ₑ pip) {
          
          
          
            If ( OSTCBPrioTbl[prio] !=ₑ OS_TCB PlaceHolder){
                EXIT_CRITICAL;ₛ
                RETURN OS_ERR_ORIGINAL_NOT_HOLDER
               };ₛ
            
            OSRdyTbl[OSTCBCurOSTCBY] =ₑ OSRdyTbl[OSTCBCurOSTCBY] &ₑ (OSTCBCurOSTCBBitX);ₛ
            If ( OSRdyTbl[OSTCBCurOSTCBY] ==ₑ 0) {
                OSRdyGrp =ₑ OSRdyGrp &ₑ OSTCBCurOSTCBBitY
            };ₛ
            OSTCBCurOSTCBPrio =ₑ prio;ₛ
            OSTCBCurOSTCBY =ₑ prio 3;ₛ
            OSTCBCurOSTCBBitY =ₑ OSMapTbl[OSTCBCurOSTCBY];ₛ
            OSTCBCurOSTCBX =ₑ prio &ₑ 7;ₛ
            OSTCBCurOSTCBBitX =ₑ OSMapTbl[OSTCBCurOSTCBX];ₛ
            OSRdyGrp =ₑ OSRdyGrp |ₑ OSTCBCurOSTCBBitY;ₛ
            OSRdyTbl[OSTCBCurOSTCBY] =ₑ OSRdyTbl[OSTCBCurOSTCBY] |ₑ OSTCBCurOSTCBBitX;ₛ
            OSTCBPrioTbl[prio] =ₑ OS_TCB OSTCBCur;ₛ
            OSTCBPrioTbl[pip] =ₑ OS_TCB PlaceHolder
        };ₛ
        If (peventOSEventGrp !=ₑ 0) {
            x =ₑ OS_STAT_MUTEX;ₛ
            prio =ᶠ OS_EventTaskRdypevent, Void pevent, x·);ₛ
            peventOSEventCnt =ₑ peventOSEventCnt &ₑ OS_MUTEX_KEEP_UPPER_8;ₛ
            peventOSEventCnt =ₑ peventOSEventCnt |ₑ prio;ₛ
            peventOSEventPtr =ₑ OSTCBPrioTbl[prio];ₛ
     
            EXIT_CRITICAL;ₛ
            OS_Sched(­);ₛ
            RETURN OS_NO_ERR
        };ₛ
        peventOSEventCnt =ₑ peventOSEventCnt |ₑ OS_MUTEX_AVAILABLE;ₛ
        peventOSEventPtr =ₑ NULL;ₛ
   
        EXIT_CRITICAL;ₛ
        RETURN OS_NO_ERR
  .

Close Scope code_scope.