picox
0.1
|
非リアルタイム協調型マルチタスクモジュール [詳解]
![]() |
型定義 | |
typedef void(* | XFiberFunc) (void *) |
タスクのメイン関数ポインタ型です [詳解] | |
typedef int(* | XFiberIdleHook) (void) |
アイドル時に呼び出されるフック関数のポインタ型です [詳解] | |
typedef XIntrusiveNode | XFiberMessage |
fiber_event_mode | |
#define | X_FIBER_EVENT_WAIT_OR (0) |
イベントのどれかを待ちます(OR待ち) | |
#define | X_FIBER_EVENT_WAIT_AND (1) |
イベントの全てが成立するまで待ちます(AND待ち) | |
#define | X_FIBER_EVENT_CLEAR_ON_EXIT (1 << 1) |
イベント成立時に、イベントのクリアを行います | |
fiber_kernel_control | |
XError | xfiber_kernel_init (void *heap, size_t heapsize, XFiberIdleHook idlehook) |
カーネルを初期化します [詳解] | |
XError | xfiber_kernel_start_scheduler (void) |
スケジューリングを開始します | |
void | xfiber_kernel_end_scheduler (void) |
スケジューリングを終了します [詳解] | |
fiber_task_control | |
XError | xfiber_create (XFiber **o_fiber, int priority, const char *name, size_t stack_size, XFiberFunc func, void *arg) |
タスクを生成します [詳解] | |
void | xfiber_delay (XTicks time) |
タスクの実行を指定時間遅延します | |
XError | xfiber_suspend (XFiber *fiber) |
タスクをサスペンド状態に遷移させます [詳解] | |
XError | xfiber_resume (XFiber *fiber) |
タスクのサスペンド状態を解除します | |
void | xfiber_yield () |
タスクの実行を同一優先度の別のタスクにゆずります | |
XFiber * | xfiber_self () |
実行状態のタスクを返します | |
const char * | xfiber_name (const XFiber *fiber) |
タスクの名前を返します | |
fiber_event | |
XError | xfiber_event_create (XFiberEvent **o_event) |
イベントオブジェクトを生成します | |
void | xfiber_event_destroy (XFiberEvent *event) |
イベントオブジェクトを破棄します [詳解] | |
XError | xfiber_event_timed_wait (XFiberEvent *event, XMode mode, XBits wait_pattern, XBits *result, XTicks timeout) |
指定のイベントが成立するのをタイムアウト付きで待ちます [詳解] | |
XError | xfiber_event_wait (XFiberEvent *event, XMode mode, XBits wait_pattern, XBits *result) |
指定のイベントが成立するのを待ちます [詳解] | |
XError | xfiber_event_try_wait (XFiberEvent *event, XMode mode, XBits wait_pattern, XBits *result) |
指定のイベントが成立しているかをポーリングで確認します [詳解] | |
XError | xfiber_event_set (XFiberEvent *event, XBits pattern) |
イベントをセットします | |
XError | xfiber_event_set_isr (XFiberEvent *event, XBits pattern) |
割込みハンドラから呼び出し可能なxfiber_event_set()です | |
XBits | xfiber_event_clear (XFiberEvent *event, XBits pattern) |
指定ビットをクリアします | |
XBits | xfiber_event_clear_isr (XFiberEvent *event, XBits pattern) |
割込みハンドラから呼び出し可能なxfiber_event_clear()です | |
XBits | xfiber_event_get (XFiberEvent *event) |
現在のビットパターンを返します | |
XBits | xfiber_event_get_isr (XFiberEvent *event) |
割込みハンドラから呼び出し可能なxfiber_event_get()です | |
fiber_signal | |
イベントと似ていますが、オブジェクトを生成することなく、タスクに直接イベント を発行できる点が異なります。 簡易的なイベントフラグとして使用できます。 | |
XError | xfiber_signal_timed_wait (XBits sigs, XBits *result, XTicks timeout) |
シグナルが成立するのをタイムアウト付きで待ちます [詳解] | |
XError | xfiber_signal_wait (XBits sigs, XBits *result) |
シグナルが成立するのを待ちます | |
XError | xfiber_signal_try_wait (XBits sigs, XBits *result) |
シグナルが成立するのをポーリングで待ちます | |
XError | xfiber_signal_raise (XFiber *fiber, XBits sigs) |
タスクにシグナルを発行します | |
XError | xfiber_signal_raise_isr (XFiber *fiber, XBits sigs) |
割込みハンドラから呼び出し可能なxfiber_signal_raise()です | |
XBits | xfiber_signal_get (XFiber *fiber) |
現在のビットパターンを返します | |
XBits | xfiber_signal_get_isr (XFiber *fiber) |
割込みハンドラから呼び出し可能なxfiber_signal_get()です | |
fiber_queue | |
XError | xfiber_queue_create (XFiberQueue **o_queue, size_t queue_len, size_t item_size) |
キューを生成します [詳解] | |
void | xfiber_queue_destroy (XFiberQueue *queue) |
キューを破棄します [詳解] | |
XError | xfiber_queue_timed_send_back (XFiberQueue *queue, const void *src, XTicks timeout) |
キューの末尾への要素の転送をタイムアウト付きで試みます | |
XError | xfiber_queue_send_back (XFiberQueue *queue, const void *src) |
キューの末尾への要素の転送を試みます | |
XError | xfiber_queue_try_send_back (XFiberQueue *queue, const void *src) |
キューの末尾への要素の転送をポーリングで試みます | |
XError | xfiber_queue_send_back_isr (XFiberQueue *queue, const void *src) |
割込みハンドラから呼び出し可能なxfiber_queue_try_send_back()です | |
XError | xfiber_queue_timed_send_front (XFiberQueue *queue, const void *src, XTicks timeout) |
キューの先頭への要素の転送をタイムアウト付きで試みます | |
XError | xfiber_queue_send_front (XFiberQueue *queue, const void *src) |
キューの先頭への要素の転送を試みます | |
XError | xfiber_queue_try_send_front (XFiberQueue *queue, const void *src) |
キューの先頭への要素の転送をポーリングで試みます | |
XError | xfiber_queue_send_front_isr (XFiberQueue *queue, const void *src) |
割込みハンドラから呼び出し可能なxfiber_queue_try_send_front()です | |
XError | xfiber_queue_timed_receive (XFiberQueue *queue, void *dst, XTicks timeout) |
キューの先頭から要素の受信をタイムアウト付きで試みます | |
XError | xfiber_queue_receive (XFiberQueue *queue, void *dst) |
キューの先頭から要素の受信を試みます | |
XError | xfiber_queue_try_receive (XFiberQueue *queue, void *dst) |
キューの先頭から要素の受信をポーリングで試みます | |
XError | xfiber_queue_receive_isr (XFiberQueue *queue, void *dst) |
割込みハンドラから呼び出し可能なxfiber_queue_try_receive()です | |
fiber_channel | |
可変長のメッセージの受け渡しに使用します。リングバッファで実装されており、デ ータはバッファにコピーされます。 queueとの違いは以下の通りです
| |
XError | xfiber_channel_create (XFiberChannel **o_channel, size_t capacity, size_t max_item_size) |
void | xfiber_channel_destroy (XFiberChannel *channel) |
XError | xfiber_channel_timed_send (XFiberChannel *channel, const void *src, size_t size, XTicks timeout) |
XError | xfiber_channel_send (XFiberChannel *channel, const void *src, size_t size) |
XError | xfiber_channel_try_send (XFiberChannel *channel, const void *src, size_t size) |
XError | xfiber_channel_send_isr (XFiberChannel *channel, const void *src, size_t size) |
XError | xfiber_channel_timed_receive (XFiberChannel *channel, void *dst, size_t *o_size, XTicks timeout) |
XError | xfiber_channel_receive (XFiberChannel *channel, void *dst, size_t *o_size) |
XError | xfiber_channel_try_receive (XFiberChannel *channel, void *dst, size_t *o_size) |
XError | xfiber_channel_receive_isr (XFiberChannel *channel, void *dst, size_t *o_size) |
fiber_semaphore | |
ミューテックスとの違いは、資源が複数ある場合に使用するカウントを持っているこ とです。 | |
XError | xfiber_semaphore_create (XFiberSemaphore **o_semaphore, int initial_count) |
セマフォを生成します [詳解] | |
void | xfiber_semaphore_destroy (XFiberSemaphore *semaphore) |
セマフォを破棄します [詳解] | |
XError | xfiber_semaphore_timed_take (XFiberSemaphore *semaphore, XTicks timeout) |
セマフォの獲得をタイムアウト付きで試みます | |
XError | xfiber_semaphore_take (XFiberSemaphore *semaphore) |
セマフォの獲得を試みます | |
XError | xfiber_semaphore_try_take (XFiberSemaphore *semaphore) |
セマフォの獲得をポーリングで試みます | |
XError | xfiber_semaphore_give (XFiberSemaphore *semaphore) |
セマフォを返却します | |
XError | xfiber_semaphore_give_isr (XFiberSemaphore *semaphore) |
割込みハンドラで呼び出し可能なxfiber_semaphore_give()です | |
fiber_mutex | |
セマフォとの違いはロックされたままタスクが終了すると、自動的にロック解除を行 う点と、優先度逆転防止機構を持つことです。
| |
XError | xfiber_mutex_create (XFiberMutex **o_mutex) |
ミューテックスを生成します | |
void | xfiber_mutex_destroy (XFiberMutex *mutex) |
ミューテックスを破棄します | |
XError | xfiber_mutex_timed_lock (XFiberMutex *mutex, XTicks timeout) |
ミューテックスを獲得をタイムアウト付きで試みます | |
XError | xfiber_mutex_lock (XFiberMutex *mutex) |
ミューテックスを獲得を試みます | |
XError | xfiber_mutex_try_lock (XFiberMutex *mutex) |
ミューテックスを獲得をタイムアウト付きで試みます | |
XError | xfiber_mutex_unlock (XFiberMutex *mutex) |
ミューテックスのロック解除を行います | |
XError | xfiber_mutex_unlock_isr (XFiberMutex *mutex) |
割込みハンドラから呼び出し可能なxfiber_mutex_unlock()です | |
fiber_mailbox | |
大きなデータの受け渡しに使用する通信機能です。リンクリストで実装しているので 、データのコピーが行われません。また、送信待ちが絶対に発生しないのも大きな特 徴です。 ただし、スタック上のデータを送信することができないという制限があり、データの 寿命管理にも気をつける必要があります。 | |
XError | xfiber_mailbox_create (XFiberMailbox **o_mailbox) |
メールボックスを生成します | |
void | xfiber_mailbox_destroy (XFiberMailbox *mailbox) |
メールボックスを生成します [詳解] | |
XError | xfiber_mailbox_send (XFiberMailbox *mailbox, XFiberMessage *message) |
メールボックス末尾にメッセージを追加します | |
XError | xfiber_mailbox_send_isr (XFiberMailbox *mailbox, XFiberMessage *message) |
割込みハンドラから呼び出し可能なxfiber_mailbox_send()です | |
XError | xfiber_mailbox_timed_receive (XFiberMailbox *mailbox, XFiberMessage **o_message, XTicks timeout) |
メールボックス先頭からメッセージの受信をタイムアウト付きで試みます | |
XError | xfiber_mailbox_receive (XFiberMailbox *mailbox, XFiberMessage **o_message) |
メールボックス先頭からメッセージの受信を試みます | |
XError | xfiber_mailbox_try_receive (XFiberMailbox *mailbox, XFiberMessage **o_message) |
メールボックス先頭からメッセージの受信をポーリングで試みます | |
XError | xfiber_mailbox_receive_isr (XFiberMailbox *mailbox, XFiberMessage **o_message) |
割込みハンドラから呼び出し可能なxfiber_mailbox_try_receive()です | |
fiber_pool | |
メールボックスのメッセージのメモリ確保と相性がいいです。固定長なので、確保と 解放は超高速です。 | |
XError | xfiber_pool_create (XFiberPool **o_pool, size_t block_size, size_t num_blocks) |
プールを生成します [詳解] | |
void | xfiber_pool_destroy (XFiberPool *pool) |
プールを解放します [詳解] | |
XError | xfiber_pool_timed_get (XFiberPool *pool, void **o_mem, XTicks timeout) |
プールからメモリの確保をタイムアウト付きで試みます | |
XError | xfiber_pool_get (XFiberPool *pool, void **o_mem) |
プールからメモリの確保を試みます | |
XError | xfiber_pool_try_get (XFiberPool *pool, void **o_mem) |
プールからメモリの確保をポーリングで試みます | |
XError | xfiber_pool_get_isr (XFiberPool *pool, void **o_mem) |
割込みハンドラから呼び出し可能なxfiber_pool_try_get()です | |
XError | xfiber_pool_release (XFiberPool *pool, void *mem) |
プールにメモリを返却します | |
XError | xfiber_pool_release_isr (XFiberPool *pool, void *mem) |
割込みハンドラから呼び出し可能なxfiber_pool_release()です | |
非リアルタイム協調型マルチタスクモジュール
協調型のマルチタスクをスレッドと区別して、コルーチンやファイバーと呼ぶことが 多いです。
スクリプト言語を中心に、多くの言語でスレッドとは別にコルーチンやファイバーを サポートしています。
[コルーチン]
[ファイバー]
コルーチンやファイバーという用語に明確な定義はありませんが、最低限処理を中断 して、後から再開できる機能を持ちます。
picoxのファイバーでは、RTOS風にタスクの優先順位や待ち合わせ機能を多数用意し ていることが大きな特徴で、RTOSの代替として使用できることを目的としています。
RTOSの実装はC言語の機能だけでは実現不可能なため、CPUごとコンパイラごとにアセ ンブリ言語を記述する必要があり大変です。 移植部分が最小限になるように考慮して実装されたフリーのRTOSもありますが、それ でも敷居は高いものです。
このモジュールはC言語の機能のみでマルチタスクを実現しているため、移植作業な しで即座に使用することができます。
ただし、以下の制限があります。
X_CONF_FIBER_IMPL_TYPE == X_FIBER_IMPL_TYPE_COPY_STACK
である場合、コン テキストスイッチの度に使用中のスタックのコピーが行われます。 これは非力なCPUでは致命的なオーバーヘッドになる可能性があります。RTOSを移植するまでの一時しのぎや、リソースに余裕のあるプロトタイプ段階でご利 用ください。
http://www.atdot.net/~ko1/activities/shiba-prosym2010-paper.pdf
興味のある方は是非ソースコードを覗いてみてください。
typedef void(* XFiberFunc) (void *) |
タスクのメイン関数ポインタ型です
引数のポインタが指すアドレスはスタック以外である必要があります。
typedef int(* XFiberIdleHook) (void) |
アイドル時に呼び出されるフック関数のポインタ型です
0以外を返すと、スケジューリングは終了し、xfiber_kernel_start_scheduler()の呼 び出し直後の地点までジャンプします。
XError xfiber_channel_create | ( | XFiberChannel ** | o_channel, |
size_t | capacity, | ||
size_t | max_item_size | ||
) |
チャンネルを生成します
o_channel | 生成したチャンネルのアドレスの格納先 |
capacity | チャンネルバッファのバイト数 |
max_item_size | 1要素の最大バイト数 |
1要素ごとに管理領域が必要なため、capacity == 格納可能な総バイト数ではありま せん。 要素の受信時は、格納先は暗黙的にmax_item_sizeバイト以上の領域を持つことを前 提とします。
void xfiber_channel_destroy | ( | XFiberChannel * | channel | ) |
チャンネル破棄します
全ての待ちタスクの待ちは解除され、待ちタスクにはX_ERR_CANCELEDが返ります
XError xfiber_channel_receive | ( | XFiberChannel * | channel, |
void * | dst, | ||
size_t * | o_size | ||
) |
チャンネル先頭から要素の受信を試みます
XError xfiber_channel_receive_isr | ( | XFiberChannel * | channel, |
void * | dst, | ||
size_t * | o_size | ||
) |
割込みハンドラから呼び出し可能なxfiber_channel_try_receive()です
XError xfiber_channel_send | ( | XFiberChannel * | channel, |
const void * | src, | ||
size_t | size | ||
) |
チャンネルの末尾へsizeバイトの要素の転送を試みます
XError xfiber_channel_send_isr | ( | XFiberChannel * | channel, |
const void * | src, | ||
size_t | size | ||
) |
割込みハンドラから呼び出し可能なxfiber_channel_try_send()です
XError xfiber_channel_timed_receive | ( | XFiberChannel * | channel, |
void * | dst, | ||
size_t * | o_size, | ||
XTicks | timeout | ||
) |
チャンネル先頭から要素の受信をタイムアウト付きで試みます
XError xfiber_channel_timed_send | ( | XFiberChannel * | channel, |
const void * | src, | ||
size_t | size, | ||
XTicks | timeout | ||
) |
チャンネルの末尾へsizeバイトの要素の転送をタイムアウト付きで試みます
XError xfiber_channel_try_receive | ( | XFiberChannel * | channel, |
void * | dst, | ||
size_t * | o_size | ||
) |
チャンネル先頭から要素の受信をポーリングで試みます
XError xfiber_channel_try_send | ( | XFiberChannel * | channel, |
const void * | src, | ||
size_t | size | ||
) |
チャンネルの末尾へsizeバイトの要素の転送をポーリングで試みます
XError xfiber_create | ( | XFiber ** | o_fiber, |
int | priority, | ||
const char * | name, | ||
size_t | stack_size, | ||
XFiberFunc | func, | ||
void * | arg | ||
) |
タスクを生成します
o_fiber | 生成したタスクのアドレスの格納先 |
priority | タスク優先度 |
name | タスク名 |
stack_size | スタックのバイト数 |
func | メイン関数 |
arg | メイン関数の引数 |
void xfiber_event_destroy | ( | XFiberEvent * | event | ) |
イベントオブジェクトを破棄します
全ての待ちタスクの待ちは解除され、待ちタスクにはX_ERR_CANCELEDが返ります
XError xfiber_event_timed_wait | ( | XFiberEvent * | event, |
XMode | mode, | ||
XBits | wait_pattern, | ||
XBits * | result, | ||
XTicks | timeout | ||
) |
指定のイベントが成立するのをタイムアウト付きで待ちます
mode |
wait_pattern | 待ちビットパターン |
result | 待ち解除時のビットパターンの格納先 |
timeout | タイムアウト時間 |
XError xfiber_event_try_wait | ( | XFiberEvent * | event, |
XMode | mode, | ||
XBits | wait_pattern, | ||
XBits * | result | ||
) |
指定のイベントが成立しているかをポーリングで確認します
xfiber_event_timed_wait()でtimeoutに0を指定した場合と同じです
指定のイベントが成立するのを待ちます
xfiber_event_timed_wait()でtimeoutにX_TICKS_FOREVERを指定した場合と同じです
void xfiber_kernel_end_scheduler | ( | void | ) |
スケジューリングを終了します
呼び出し後はxfiber_kernel_start_scheduler()の呼び出し直後の位置までジャンプ します。
XError xfiber_kernel_init | ( | void * | heap, |
size_t | heapsize, | ||
XFiberIdleHook | idlehook | ||
) |
カーネルを初期化します
heap | ワークバッファのアドレス |
heapsize | ワークバッファのサイズ |
idlehook |
heapにNULLが指定された場合、x_malloc()でメモリを確保します。スタックやファイ バーオブジェクトは全てワークバッファから生成されます。
void xfiber_mailbox_destroy | ( | XFiberMailbox * | mailbox | ) |
メールボックスを生成します
全ての待ちタスクの待ちは解除され、待ちタスクにはX_ERR_CANCELEDが返ります
XError xfiber_pool_create | ( | XFiberPool ** | o_pool, |
size_t | block_size, | ||
size_t | num_blocks | ||
) |
プールを生成します
o_pool | 生成したプールのアドレスの格納先 |
block_size | 1ブロックのサイズ |
num_blocks | ブロック数 |
void xfiber_pool_destroy | ( | XFiberPool * | pool | ) |
プールを解放します
全ての待ちタスクの待ちは解除され、待ちタスクにはX_ERR_CANCELEDが返ります
XError xfiber_queue_create | ( | XFiberQueue ** | o_queue, |
size_t | queue_len, | ||
size_t | item_size | ||
) |
キューを生成します
o_queue | 生成したキューのアドレスの格納先 |
queue_len | 格納可能な要素数 |
item_size | 1要素のバイト数 |
queue_len * item_sizeバイトのバッファが生成されます。
void xfiber_queue_destroy | ( | XFiberQueue * | queue | ) |
キューを破棄します
全ての待ちタスクの待ちは解除され、待ちタスクにはX_ERR_CANCELEDが返ります
XError xfiber_semaphore_create | ( | XFiberSemaphore ** | o_semaphore, |
int | initial_count | ||
) |
セマフォを生成します
o_semaphore | 生成したセマフォのアドレスの格納先 |
initial_count | カウンタの初期値 |
void xfiber_semaphore_destroy | ( | XFiberSemaphore * | semaphore | ) |
セマフォを破棄します
全ての待ちタスクの待ちは解除され、待ちタスクにはX_ERR_CANCELEDが返ります
シグナルが成立するのをタイムアウト付きで待ちます
sigs | 待ちビットパターン |
result | 待ち解除時のビットパターンの格納先 |
timeout | タイムアウト時間 |
XError xfiber_suspend | ( | XFiber * | fiber | ) |
タスクをサスペンド状態に遷移させます
サスペンド中のタスクはリジュームされるまで実行状態にはなりません。
既に待ち状態にあるタスクは、サスペンド・ウエイトという2重待ち状態になります 。この場合、サスペンドだけが解除されてもウエイト状態は継続し、ウエイトだけが 解除されてもサスペンド状態は継続します。