TABLE OF CONTENTS


/Mutex [ Modules ]

[ Top ] [ Modules ]

DESCRIPTION

A Mutex is an object dedicated to Task communication/synchronization. It can be locked by a Task, other tasks trying to lock the same Mutex again are blocked or get an error. Only the locking Task can unlock it.

SEE ALSO

    /Messagequeue, /Pipe, /Semaphore, /Signal, /Syncpipe

Mutex/Os_mutex_settings [ Constants ]

[ Top ] [ Mutex ] [ Constants ]

DESCRIPTION

Settings of the Mutex object. If priority inheritance is enabled, a Task blocking a higher priority Task inherits the higher priority as long as the other Task is blocked.

DECLARATION

#if Varexist( "Os_enable_priority_inheritance") = False
   Const Os_enable_priority_inheritance = True
#endif

Mutex/Os_mutex_header [ Object Headers ]

[ Top ] [ Mutex ] [ Object Headers ]

DESCRIPTION

Header structure of the Mutex object

DECLARATION

Const Os_mutex_hdr_taskqueue_ptr = 0                        ' taskqueue is the first object in header, to use the same address for both the Mutex and its queue   '
Const Os_mutex_hdr_lockcount_ptr = Os_taskqueue_hdr_size + 0       ' counts the times the Mutex has been locked   '
Const Os_mutex_hdr_ownertask_ptr = Os_taskqueue_hdr_size + 1       ' remembers the Task that has locked the Mutex for the first time (owner)   '
Const Os_mutex_hdr_size = Os_taskqueue_hdr_size + 3

Mutex/Os_mutex_create [ Functions ]

[ Top ] [ Mutex ] [ Functions ]

DESCRIPTION

Creates a new Mutex object.

DECLARATION

Function Os_mutex_create() As Word

SEE ALSO

    Mutex/Os_mutex_kill

SOURCE

   Local Mutex As Word

   Mutex = Malloc(os_mutex_hdr_size)
   If Mutex = 0 Then
      Os_mutex_create = 0
      Exit Function
   End If
   Os_mem_clear Mutex , Os_mutex_hdr_size

   Os_mutex_create = Mutex
End Function

Mutex/Os_mutex_kill [ Functions ]

[ Top ] [ Mutex ] [ Functions ]

DESCRIPTION

Kills a Mutex object.

DECLARATION

Sub Os_mutex_kill(byref Mutex As Word)

SEE ALSO

    Mutex/Os_mutex_create

SOURCE

   ' TODO: Task queue not empty?   '
   Free Mutex
End Sub

Mutex/Os_mutex_lock [ Functions ]

[ Top ] [ Mutex ] [ Functions ]

DESCRIPTION

Tries to lock a Mutex. While a Mutex is locked, no other Task can lock it, until it is unlocked by the locking Task.

DECLARATION

Function Os_mutex_lock(byref Mutex As Word , Byval Queuemode As Word) As Byte

SEE ALSO

    Mutex/Os_mutex_unlock

SOURCE

   Local Lockcount As Byte
   Local Ownertask As Word
   Local Nextblock As Word

   ' is the calling Task the owner of the Mutex (locked it) or Mutex is unlocked?   '
   Os_enter_critical
   Ownertask = Getword(Mutex , Os_mutex_hdr_ownertask_ptr)
   If Ownertask <> Os_task_active And Ownertask <> 0 Then
      #if Os_enable_priority_inheritance = True
         Os_sched_priority_inheritance
      #endif
      ' no, suspend the Task   '
      Select Case Queuemode
      Case Os_queuemode_noblock:
         ' return error   '
         Os_mutex_trylock = False
         Exit Function
      Case Os_queuemode_block:
         ' suspend and wait to send a message   '
         Os_task_suspendmode Os_task_active , Os_task_suspend_nowakeup , 0
      Case Else
         ' suspend and wait to send a message or timeout   '
         Os_task_suspendmode Os_task_active , Os_task_suspend_timersingleshot , Queuemode
      End Select

      ' insert into the Mutex waiting queue   '
      Os_sched_taskqueue_insert Mutex , Os_task_active
      Os_exit_critical

      Os_task_suspend Os_task_active

      Os_enter_critical
      Ownertask = Getword(Mutex , Os_mutex_hdr_ownertask_ptr)
      If Ownertask <> 0 Then
         Os_exit_critical
         Os_mutex_trylock = False
         Exit Function
      End If
   End If

   ' yes, increment recursive Mutex lockcount   '
   Lockcount = Getbyte(Mutex , Os_mutex_hdr_lockcount_ptr)
   Incr Lockcount
   'If Lockcount = 1 Then   '
      ' Task has locked the Mutex for the first time, throw scheduler event   '
      'Os_event_task = Os_task_active   '
      'Os_exit_critical   '
      'Gosub Os_sched_event   '
      'Os_enter_critical   '
   'End If   '
   Setbyte Mutex , Os_mutex_hdr_lockcount_ptr , Lockcount
   If Ownertask = 0 Then Setword Mutex , Os_mutex_hdr_ownertask_ptr , Os_task_active
   Os_exit_critical

   Os_mutex_trylock = True
End Sub

Mutex/Os_mutex_unlock [ Functions ]

[ Top ] [ Mutex ] [ Functions ]

DESCRIPTION

Unlocks a previously locked Mutex, only the same Task is able to unlock it.

DECLARATION

Sub Os_mutex_unlock(byref Mutex As Word)

SEE ALSO

    Mutex/Os_mutex_lock

SOURCE

   Local Lockcount As Byte
   Local Ownertask As Word
   Local Nextblock As Word

   ' is the calling Task the owner of the Mutex (locked it)?   '
   Os_enter_critical
   Ownertask = Getword(Mutex , Os_mutex_hdr_ownertask_ptr)
   If Ownertask = Os_task_active Then
      ' yes, decrement recursive Mutex lock count   '
      Lockcount = Getbyte(Mutex , Os_mutex_hdr_lockcount_ptr)
      Decr Lockcount
      Setbyte Mutex , Os_mutex_hdr_lockcount_ptr , Lockcount
      #if Os_enable_priority_inheritance = True
         Os_sched_reset_priority
      #endif
      If Lockcount = 0 Then
         ' Task releases the Mutex lock   '
         Setword Mutex , Os_mutex_hdr_ownertask_ptr , 0

         ' is a Task in the Mutex waiting queue?   '
         Ownertask = Os_sched_taskqueue_remove(Mutex)
         If Ownertask <> 0 Then
            ' Task from queue is new owner of the Mutex   '
            Os_event_task = Ownertask
            Os_exit_critical
            Os_task_event
            Os_enter_critical
         End If
      End If
   End If
   Os_exit_critical
End Sub