Extended synchronization and communication functions use objects independent of tasks to realize more sophisticated synchronization and communication between tasks. The functions specified here include mutex and message buffer functions.
A mutex is an object for mutual exclusion control among tasks that use shared resources. Priority inheritance mutexes and priority ceiling mutexes are supported, as a mechanism to prevent the problem of unbounded priority inversion that can occur in mutual exclusion control.
Functions are provided for creating and deleting a mutex, locking and unlocking a mutex, and referencing mutex status. A mutex is identified by an ID number. The ID number for the mutex is called a mutex ID.
A mutex has a status (locked or unlocked) and a queue for tasks waiting to lock the mutex. For each mutex, T-Kernel keeps track of the tasks locking it; and for each task, it keeps track of the mutexes it has locked. Before a task uses a resource, it locks a mutex associated with that resource. If the mutex is already locked by another task, the task waits for the mutex to become unlocked. Tasks in mutex lock waiting state are put in the mutex queue. When a task finishes with a resource, it unlocks the mutex.
A mutex with TA_INHERIT (= 0x02) specified as mutex attribute supports priority inheritance protocol while one with TA_CEILING (= 0x03) specified supports priority ceiling protocol. When a mutex with TA_CEILING attribute is created, a ceiling priority is assigned to it, indicating the base priority of the task having the highest base priority among the tasks that will lock that mutex. If a task having a higher base priority than the ceiling priority of the mutex with TA_CEILING attribute tries to lock it, error code E_ILUSE is returned. If tk_chg_pri is issued in an attempt to set the base priority of a task having locked a mutex with TA_CEILING attribute to a value higher than the ceiling priority of that mutex, E_ILUSE is returned by the tk_chg_pri system call.
When these protocols are used, unbounded priority inversion is prevented by automatically changing the current priority of a task in a mutex operation. Strict adherence to the priority inheritance protocol and priority ceiling protocol requires that the task current priority must always be changed to match the peak value of the following priorities. This is called strict priority control.
Task base priority
When tasks lock mutexes with TA_INHERIT attribute, the current priority of the task having the highest current priority of the tasks waiting for those mutexes.
When tasks lock mutexes with TA_CEILING attribute, the highest ceiling priority of the mutex among those mutexes.
Note that when the current priority of a task waiting for a mutex with TA_INHERIT attribute changes as the result of a base priority change brought about by mutex operation or tk_chg_pri, it may become necessary to change the current priority of the task locking that mutex. This is called dynamic priority inheritance. Further, if this task is waiting for another mutex with TA_INHERIT attribute, dynamic priority inheritance processing may become necessary also for the task locking that mutex.
The T-Kernel defines, in addition to the above strict priority control, a simplified priority control limiting the situations in which the current priority is changed. The choice between the two is implementation-dependent. In the simplified priority control, whereas all changes in the direction of raising the task current priority are carried out, changes in the direction of lowering that priority are made only when a task is no longer locking any mutexes. (In this case the task current priority reverts to the base priority.) More specifically, processing to change the current priority is needed only in the following circumstances.
When a task with a higher current priority than that of the task locking a mutex with TA_INHERIT attribute starts waiting for that mutex.
When task B is waiting for a mutex with TA_INHERIT attribute being locked by another task called A, and if the current priority of B is changed to a higher one than that of task A.
When a task locks a mutex with TA_CEILING attribute having a higher ceiling priority than the task's current priority.
When a task is no longer locking any mutexes.
When the current priority of a task is changed in connection with a mutex operation, the following processing is performed.
If the task whose priority changed is in a run state, the task precedence is changed in accordance with the new priority. Its precedence among other tasks having the same priority is implementation-dependent. Likewise, if the task whose priority changes is waiting in a queue of some kind, its order in that queue is changed based on its new priority. Its order among other tasks having the same priority is implementation-dependent. When a task terminates and there are mutexes still locked by that task, all the mutexes are unlocked. The order in which multiple locked mutexes are unlocked is implementation-dependent. See the description of tk_unl_mtx for the specific processing involved.
Additional Notes | |
---|---|
TA_TFIFO attribute mutex or TA_TPRI attribute mutex has functionality equivalent to that of a semaphore with a maximum of one resource (binary semaphore). The main differences are that a mutex can be unlocked only by the task that locked it, and a mutex is automatically unlocked when the task locking it terminates. The term "priority ceiling protocol" is used here in a broad sense. The protocol described here is not the same as the algorithm originally proposed. Strictly speaking, it is what is otherwise referred to as a highest locker protocol or by other names. When the change in current priority of a task due to a mutex operation results in that task's order being changed in a priority-based queue, it may be necessary to release the waiting state of other tasks waiting for that task or for that queue. |
Rationale for the Specification | |
---|---|
The precedence of tasks having the same priority as the result of a change in task current priority in a mutex operation is left as implementation-dependent, for the following reason. Depending on the application, the mutex function may lead to frequent changes in current priority. It would not be desirable for this to result in constant task switching, which is what would happen if the precedence were made the lowest each time among tasks of the same priority. Ideally task precedence rather than priority should be inherited, but that results in large overhead in implementation. This aspect of the specification is therefore made an implementation-dependent matter. |
pk_cmtx
Detail:
Creates a mutex, assigning to it a mutex ID. This system call allocates a control block, etc. for the created mutex.
exinf
can be used freely by the user to set miscellaneous information about the created mutex. The information set in this parameter can be referenced by tk_ref_mtx. If a larger area is needed for indicating user information, or if the information may need to be changed after the message buffer is created, this can be done by allocating separate memory for this purpose and putting the memory packet address in exinf
. The kernel pays no attention to the contents of exinf
.
mtxatr
indicates system attributes in its lower bits and implementation-dependent attributes in its higher bits. The system attribute part of mtxatr
is specified as follows.
mtxatr := (TA_TFIFO || TA_TPRI || TA_INHERIT || TA_CEILING) | [TA_DSNAME] | [TA_NODISWAI]
TA_TFIFO | Tasks are queued in FIFO order |
TA_TPRI | Tasks are queued in priority order |
TA_INHERIT | Priority inheritance protocol |
TA_CEILING | Priority ceiling protocol |
TA_DSNAME | Specifies DS object name |
TA_NODISWAI | Disabling of wait by tk_dis_wai is prohibited |
When the TA_TFIFO attribute is specified, the order of the mutex task queue is FIFO. If TA_TPRI, TA_INHERIT, or TA_CEILING is specified, tasks are ordered by their priority. TA_INHERIT indicates that priority inheritance protocol is used, and TA_CEILING specifies priority ceiling protocol.
Only when TA_CEILING is specified, ceilpri
is valid and specifies the mutex ceiling priority.
When TA_DSNAME is specified, dsname
is valid and specifies the DS object name. DS object name is used to identify objects by debugger, and it is handled only by T-Kernel/DS API, td_ref_dsname and td_set_dsname. For more details, see the description of td_ref_dsname and td_set_dsname. If TA_DSNAME is not specified, dsname
is ignored. Then td_ref_dsname and td_set_dsname return E_OBJ error.
#define TA_TFIFO 0x00000000 /* manage queue by FIFO */ #define TA_TPRI 0x00000001 /* manage queue by priority */ #define TA_INHERIT 0x00000002 /* priority inheritance protocol */ #define TA_CEILING 0x00000003 /* priority ceiling protocol */ #define TA_DSNAME 0x00000040 /* DS object name */ #define TA_NODISWAI 0x00000080 /* reject request to disable wait */
Deletes the mutex specified in mtxid
.
Issuing this system call releases the mutex ID and control block memory space allocated to the mutex.
This system call completes normally even if there are tasks waiting to lock the deleted mutex, but error code E_DLT is returned to each of the tasks in WAITING state.
When a mutex is deleted, a task locking the mutex will have one fewer locked mutexes. If the mutex to be deleted was a priority inheritance mutex (TA_INHERIT) or priority ceiling mutex (TA_CEILING), then deleting the mutex might change the priority of the task that has locked it.
E_OK | Normal completion |
E_ID | Invalid ID number (mtxid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the mutex specified in mtxid does not exist) |
E_PAR | Parameter error (tmout ≦ (-2)) |
E_DLT | The object being waited for was deleted (the mutex was deleted while waiting for a lock) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
E_ILUSE | Illegal use (multiple lock, or upper priority limit exceeded) |
Locks the mutex specified in mtxid
. If the mutex can be locked immediately, the task issuing this system call continue executing without entering WAITING state, and the mutex goes to locked status. If the mutex cannot be locked, the task issuing this system call enters WAITING state. That is, the task is put in the queue of this mutex.
A maximum wait time (timeout) can be set in tmout
. The time unit for tmout
is the same as that for system time (= 1 ms). If the tmout
time elapses before the wait release condition is met, the system call terminates, returning timeout error code E_TMOUT.
When TMO_POL=0 is set in tmout
, this means 0 was specified as the timeout value, and E_TMOUT is returned without entering WAITING state even if the resource cannot be locked. When TMO_FEVR=(-1) is set in tmout
, this means infinity was specified as the timeout value, and the task continues wait to until the resource is locked.
If the invoking task has already locked the specified mutex, error code E_ILUSE (multiple lock) is returned.
If the specified mutex is a priority ceiling mutex (TA_CEILING) and the base priority[1]of the invoking task is higher than the ceiling priority of the mutex, error code E_ILUSE (upper priority limit exceeded) is returned.
Priority inheritance mutex (TA_INHERIT attribute)
If the invoking task is waiting to lock a mutex and the current priority of the task currently locking that mutex is lower than that of the invoking task, the priority of the locking task is raised to the same level as the invoking task. If the wait ends before the waiting task can obtain a lock (timeout or other reason), the priority of the task locking that mutex can be lowered to the highest of the following three priorities. Whether this lowering takes place is implementation-dependent.
The highest priority among the current priorities of tasks waiting to lock the mutex.
The highest priority among all the other mutexes locked by the task currently locking this mutex.
The base priority of the locking task.
Priority ceiling mutex (TA_CEILING attribute)
If the invoking task obtains a lock and its current priority is lower than the mutex ceiling priority, the priority of the invoking task is raised to the mutex ceiling priority.
E_OK | Normal completion |
E_ID | Invalid ID number (mtxid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the mutex specified in mtxid does not exist) |
E_PAR | Parameter error (tmout_u ≦ (-2)) |
E_DLT | The object being waited for was deleted (the mutex was deleted while waiting for a lock) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
E_ILUSE | Illegal use (multiple lock, or upper priority limit exceeded) |
Only when all the service profile items below are set to be effective, this system call can be used.
This system call takes 64-bit tmout_u
in microseconds instead of the parameter tmout
of tk_loc_mtx.
The specification of this system call is same as that of tk_loc_mtx, except that the parameter is replaced with tmout_u
. For more details, see the description of tk_loc_mtx.
Unlocks the mutex specified in mtxid
.
If there are tasks waiting to lock the mutex, the WAITING state of the task at the head of the queue for that mutex is released and that task locks the mutex.
If a mutex that was not locked by the invoking task is specified, error code E_ILUSE is returned.
If the unlocked mutex is a priority inheritance mutex (TA_INHERIT) or priority ceiling mutex (TA_CEILING), task priority must be lowered as follows.
If as a result of this operation the invoking task no longer has any locked mutexes, the invoking task priority is lowered to its base priority.
If the invoking task continues to have locked mutexes after the operation above, the invoking task priority is lowered to whichever of the following priority is highest.
The highest priority among the current priority of the tasks in the queue of the mutex with the TA_INHERIT attribute locked by the invoking task
The highest priority among the ceiling priority of the mutexes with the TA_CEILING attribute locked by the invoking task
Base priority of the invoking task
Note that the lowering of priority when locked mutexes remain is implementation-dependent.
If a task terminates (goes to DORMANT state or NON-EXISTENT state) without explicitly unlocking mutexes, all its locked mutexes are automatically unlocked by μT-Kernel.
pk_rmtx
Detail:
References the status of the mutex specified in mtxid
, passing in the return parameters the task currently locking the mutex (htsk
), tasks waiting to lock the mutex (wtsk
), and extended information (exinf
).
htsk
indicates the ID of the task locking the mutex. If no task is locking it, htsk
= 0 is returned.
wtsk
indicates the ID of a task waiting to lock the mutex. If there are two or more such tasks, the ID of the task at the head of the queue is returned. If there are no waiting tasks, wtsk
= 0 is returned.
If the specified mutex does not exist, error code E_NOEXS is returned.
A message buffer is an object for achieving synchronization and communication by the passing of variable-size messages. Functions are provided for creating and deleting a message buffer, sending and receiving messages using a message buffer, and referencing message buffer status. A message buffer is an object identified by an ID number. The ID number for the message buffer is called a message buffer ID.
A message buffer keeps a queue of tasks waiting to send a message (send queue) and a queue of tasks waiting for receive a message (receive queue). It also has a message buffer space for holding sent messages. The message sender (the side posting event notification) copies a message it wants to send to the message buffer. If there is insufficient space in the message buffer area, the task trying to send the message is queued for sending until enough space is available.
A task waiting to send a message to the message buffer is put in the send queue. On the message receive side (waiting for event notification), one message is fetched from the message buffer. If the message buffer has no messages, the task enters WAITING state until the next message is sent. A task waiting for receiving a message from a message buffer is put in the receive queue of that message buffer.
A synchronous message function can be realized by setting the message buffer space size to 0. In that case both the sending task and receiving task wait for a system call to be invoked by each other, and the message is passed when both sides issue system calls.
Additional Notes | |
---|---|
The message buffer behavior when the size of the message buffer space is set to 0 is explained here using the example in Figure 3. In this example Task A and Task B run asynchronously.
Tasks waiting to send to a message buffer send messages in their queued order. Suppose Task A wanting to send a 40-byte message to a message buffer, and Task B wanting to send a 10-byte message, are queued in that order. If another task receives a message opening 20 bytes of space in the message buffer, Task B is still required to wait until Task A sends its message. A message buffer is used to pass variable-size messages by copying them. It is the copying of messages that makes this function different from the mailbox function. It is assumed that the message buffer will be implemented as a ring buffer. |
pk_cmbf
Detail:
void* |
exinf
| Extended Information | Extended information |
ATR |
mbfatr
| Message Buffer Attribute | Message buffer attribute |
SZ |
bufsz
| Buffer Size | Message buffer size (in bytes) |
INT |
maxmsz
| Max Message Size | Maximum message size (in bytes) |
UB |
dsname[8]
| DS Object name | DS object name |
void* |
bufptr
| Buffer Pointer | User buffer pointer |
(Other implementation-dependent parameters may be added beyond this point.) |
E_NOMEM | Insufficient memory (memory for control block or ring buffer area cannot be allocated) |
E_LIMIT | Number of message buffers exceeds the system limit |
E_RSATR | Reserved attribute (mbfatr is invalid or cannot be used) |
E_PAR | Parameter error (pk_cmbf is illegal, bufsz , maxmsz is negative or invalid, bufptr is illegal) |
TK_SUPPORT_USERBUF | Support for specifying TA_USERBUF for message buffer attribute |
TK_SUPPORT_AUTOBUF | Automatic buffer allocation is supported (by not specifying TA_USERBUF to message buffer attribute) |
TK_SUPPORT_DISWAI | Support for specifying TA_NODISWAI (reject request to disable wait) to message buffer attribute |
TK_SUPPORT_DSNAME | Support for specifying TA_DSNAME for message buffer attribute |
Creates a message buffer, assigning to it a message buffer ID. This system call allocates a control block to the created message buffer. Based on the information specified in bufsz
, it allocates a ring buffer area for message queue use (for messages waiting to be received).
A message buffer is an object for managing the sending and receiving of variable-size messages. If differs from a mailbox (mbx) in that the contents of the variable-size messages are copied when the message is sent and received. It also has a function for putting the sending task in WAITING state when the buffer is full.
exinf
can be used freely by the user to set miscellaneous information about the created message buffer. The information set in this parameter can be referenced by tk_ref_mbf. If a larger area is needed for indicating user information, or if the information may need to be changed after the message buffer is created, this can be done by allocating separate memory for this purpose and putting the memory packet address in exinf
. The kernel pays no attention to the contents of exinf
.
mbfatr
indicates system attributes in its lower bits and implementation-dependent attributes in its higher bits. The system attribute part of mbfatr
is specified as follows.
mbfatr := (TA_TFIFO || TA_TPRI) | [TA_DSNAME] | [TA_USERBUF] | [TA_NODISWAI]
TA_TFIFO | Tasks waiting on call are queued in FIFO order |
TA_TPRI | Tasks waiting on call are queued in priority order |
TA_DSNAME | Specifies DS object name |
TA_USERBUF | Support of user-specified memory area as message buffer area |
TA_NODISWAI | Disabling of wait by tk_dis_wai is prohibited |
The queuing order of tasks waiting for sending a message when the buffer is full can be specified in TA_TFIFO or TA_TPRI. If the attribute is TA_TFIFO, tasks are ordered by FIFO, whereas TA_TPRI specifies queuing of tasks in order of their priority setting. Messages themselves are queued in FIFO order only.
Tasks waiting for receiving a message from a message buffer are queued in FIFO order only.
When TA_USERBUF is specified, bufptr
becomes effective, and the memory area starting at bufptr
and containing bufsz
octets is used as message buffer area. In this case, the message buffer area is not provided by he OS, but must be allocated by the caller. When TA_USERBUF is not specified, bufptr
is ineffective、and the message buffer area is provided by the kernel.
When TA_DSNAME is specified, dsname
is valid and specifies the DS object name. DS object name is used to identify objects by debugger, and it is handled only by T-Kernel/DS API, td_ref_dsname and td_set_dsname. For more details, see the description of td_ref_dsname and td_set_dsname. If TA_DSNAME is not specified, dsname
is ignored. Then td_ref_dsname and td_set_dsname return E_OBJ error.
#define TA_TFIFO 0x00000000 /* manage task queue by FIFO */ #define TA_TPRI 0x00000001 /* manage task queue by priority */ #define TA_USERBUF 0x00000020 /* Use user-specified buffer */ #define TA_DSNAME 0x00000040 /* DS object name */ #define TA_NODISWAI 0x00000080 /* reject request to disable wait */
When there are multiple tasks waiting to send messages, the order in which their messages are sent when buffer space becomes available is always in their queued order.
If, for example, a Task A wanting to send a 30-byte message is queued with a Task B wanting to send a 10-byte message, in the order A-B, even if 20 bytes of message buffer space becomes available, Task B never sends its message before Task A.
The ring buffer in which messages are queued also contains information for managing each message. For this reason the total size of queued messages will ordinarily not be identical to the ring buffer size specified in bufsz
. Normally the total message size will be smaller than bufsz. In this sense bufsz
does not strictly represent the total message capacity.
It is possible to create a message buffer with bufsz
= 0. In this case communication using the message buffer is completely synchronous between the sending and receiving tasks. That is, if either tk_snd_mbf or tk_rcv_mbf is executed ahead of the other, the task executing the first system call goes to WAITING state. When the other system call is executed, the message is passed (copied), then both tasks resume running.
In the case of a bufsz
= 0 message buffer, the specific functioning is as follows.
In Figure 4, Task A and Task B operate asynchronously. If Task A arrives at point (1) first and executes tk_snd_mbf(mbfid
), Task A goes to send waiting state until Task B arrives at point (2). If tk_ref_tsk is issued for Task A in this state, tskwait
=TTW_SMBF is returned. If, on the other hand, Task B gets to point (2) first and calls tk_rcv_mbf(mbfid
), Task B goes to receive waiting state until Task A gets to point (1). If tk_ref_tsk is issued for Task B in this state, tskwait
=TTW_RMBF is returned.
At the point where both Task A has executed tk_snd_mbf(mbfid
) and Task B has executed tk_rcv_mbf(mbfid
), a message is passed from Task A to Task B, their wait states are released and both tasks resume running.
Note that member, maxmsz
, of T_CMBF is INT type, and its value range is implementation-dependent, so care must be taken.
The T-Kernel 2.0 specification does not define TA_USERBUF and its associated notion of bufptr
. So if this feature is used, a modification is necessary to port the software to T-Kernel 2.0. However, if bufsz
is properly set already, simply removing TA_USERBUF and bufptr
will complete the modification for porting.
Deletes the message buffer specified in mbfid
.
Issuing this system call releases the corresponding message buffer and control block memory space, as well as the message buffer space.
This system call completes normally even if there were tasks queued in the message buffer for message receipt or message sending, but error code E_DLT is returned to the tasks in WAITING state. If there are messages left in the message buffer when it is deleted, the message buffer is deleted anyway. No error code is returned and the messages are discarded.
E_OK | Normal completion |
E_ID | Invalid ID number (mbfid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the message buffer specified in mbfid does not exist) |
E_PAR | Parameter error (msgsz ≦ 0, msgsz > maxmsz , invalid msg , or tmout ≦ (-2)) |
E_DLT | The object being waited for was deleted (message buffer was deleted while waiting) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
tk_snd_mbf sends the message at the address specified in msg
to the message buffer indicated in mbfid
. The message size is specified in msgsz
. This system call copies msgsz
bytes starting from msg
to the message queue of message buffer mbfid
. The message queue is assumed to be implemented as a ring buffer.
If msgsz
is larger than the maxmsz
specified in tk_cre_mbf, error code E_PAR is returned.
If there is not enough available buffer space to accommodate message msg
in the message queue, the task issuing this system call goes to send waiting state and is put in the send queue of the message buffer waiting for buffer space to become available. Waiting tasks are queued in either FIFO or priority order, depending on the attribute specified in tk_cre_mbf.
A maximum wait time (timeout) can be set in tmout
. The time unit for tmout
is the same as that for system time (= 1 ms). If the tmout
time elapses before the wait release condition is met (before there is sufficient buffer space), the system call terminates, returning timeout error code E_TMOUT.
When TMO_POL=0 is specified in tmout
, it means 0 is specified as the timeout value, and if there is not enough buffer space, then E_TMOUT is returned without entering WAITING state. When TMO_FEVR=(-1) is specified in tmout
, this means infinity was specified as the timeout value, and the task continues to wait for buffer space to become available, without timing out.
A message of size 0 cannot be sent. When msgsz
≦ 0, error code E_PAR is returned.
When this system call is invoked from a task-independent portion or in dispatch disabled state, error code E_CTX is returned; but in the case of tmout
= TMO_POL, there may be implementations where execution from a task-independent portion or in dispatch disabled state is possible.
Note that msgsz
is INT type, and its value range is implementation-dependent, so care must be taken. For example, there is a chance that the message size that can sent at once might be limited to 32767 octets on 16-bit CPU.
E_OK | Normal completion |
E_ID | Invalid ID number (mbfid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the message buffer specified in mbfid does not exist) |
E_PAR | Parameter error (msgsz ≦ 0, msgsz > maxmsz , invalid msg , or tmout_u ≦ (-2)) |
E_DLT | The object being waited for was deleted (message buffer was deleted while waiting) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
Only when all the service profile items below are set to be effective, this system call can be used.
This system call takes 64-bit tmout_u
in microseconds instead of the parameter tmout
of tk_snd_mbf.
The specification of this system call is same as that of tk_snd_mbf, except that the parameter is replaced with tmout_u
. For more details, see the description of tk_snd_mbf.
Note that msgsz
is INT type, and its value range is implementation-dependent, so care must be taken. For example, there is a chance that the message size that can sent at once might be limited to 32767 octets on 16-bit CPU.
E_ID | Invalid ID number (mbfid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the message buffer specified in mbfid does not exist) |
E_PAR | Parameter error (invalid msg , or tmout ≦ (-2)) |
E_DLT | The object being waited for was deleted (message buffer was deleted while waiting) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
tk_rcv_mbf receives a message from the message buffer specified in mbfid
, copying it in the location specified in msg
. This system call copies the contents of the first queued message in the message buffer specified in mbfid
, and copies it to an area of msgsz
bytes starting at address msg
.
If no message has been sent to the message buffer specified in mbfid
(the message queue is empty), the task issuing this system call goes to WAITING state and is put in the receive queue of the message buffer to wait for message arrival. Tasks in the receive queue are ordered by FIFO only.
A maximum wait time (timeout) can be set in tmout
. The time unit for tmout
is the same as that for system time (= 1 ms). If the tmout
time elapses before the wait release condition is met (before a message arrives), the system call terminates, returning timeout error code E_TMOUT.
When TMO_POL=0 is set in tmout
, this means 0 was specified as the timeout value, and E_TMOUT is returned without entering WAITING state even if there is no message. When TMO_FEVR=(-1) is set in tmout
, this means infinity was specified as the timeout value, and the task continues to wait for message arrival without timing out.
E_ID | Invalid ID number (mbfid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the message buffer specified in mbfid does not exist) |
E_PAR | Parameter error (invalid msg , or tmout_u ≦ (-2)) |
E_DLT | The object being waited for was deleted (message buffer was deleted while waiting) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
Only when all the service profile items below are set to be effective, this system call can be used.
This system call takes 64-bit tmout_u
in microseconds instead of the parameter tmout
of tk_rcv_mbf.
The specification of this system call is same as that of tk_rcv_mbf, except that the parameter is replaced with tmout_u
. For more details, see the description of tk_rcv_mbf.
pk_rmbf
Detail:
void* |
exinf
| Extended Information | Extended information |
ID |
wtsk
| Waiting Task ID | Receive waiting task ID |
ID |
stsk
| Send Waiting Task ID | Send waiting task ID |
INT |
msgsz
| Message Size | Size of the next message to be received (in bytes) |
SZ |
frbufsz
| Free Buffer Size | Free buffer size (in bytes) |
INT |
maxmsz
| Maximum Message Size | Maximum message size (in bytes) |
(Other implementation-dependent parameters may be added beyond this point.) |
References the status of the message buffer specified in mbfid
, passing in the return parameters the send waiting task ID( stsk
), the size of the next message to be received (msgsz
), free buffer size (frbufsz
), maximum message size (maxmsz
), receive waiting task ID (wtsk
), and extended information (exinf
).
wtsk
indicates the ID of a task waiting to receive a message from the message buffer. stsk
indicates the ID of a task waiting to send a message to the message buffer. If multiple tasks are waiting in the message buffer queues, the ID of the task at the head of the queue is returned. If no tasks are waiting, 0 is returned.
If the specified message buffer does not exist, error code E_NOEXS is returned.
The size of the message at the head of the queue (the next message to be received) is returned in msgsz
. If there are no queued messages, msgsz
= 0 is returned. A message of size 0 cannot be sent.
At least one of msgsz
= 0 and wtsk
= 0 is always true for this system call.
frbufsz
indicates the free space in the ring buffer of which the message queue consists. This value indicates the approximate size of messages that can be sent.
The maximum message size as specified in tk_cre_mbf is returned to maxmsz
.
[1] | Base priority: The task priority before it is automatically raised by the mutex. This is the priority last set by tk_chg_pri (including while the mutex is locked), or if tk_chg_pri has never been issued, the priority that was set when the task was created. |