TABLE OF CONTENTS
- /Mutex
- Mutex/Os_mutex_settings
- Mutex/Os_mutex_header
- Mutex/Os_mutex_create
- Mutex/Os_mutex_kill
- Mutex/Os_mutex_lock
- Mutex/Os_mutex_unlock
/Mutex [ 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