このドキュメントはXTAL RT(DEC/14/1995)のC言語インターフェースを 説明しています。
XTALでは、すべてのオブジェクトには名前が必要です。 特に意味を持たせなくてもよい名前は name_generate() でつくり出して下さい。
時間の単位は tick (system 依存)です。
tick は基本的に1/60秒ですが、ハードウェアの都合により
必ずしも 1/60を保証できない場合があります。
tickに関してはXTALのポーティング者に照会ください。
一般に、時間に -1 を指定した場合は無限を表します。
また、未来のバージョンにおいて、 プログラム・コードを外部から読み込むプリミティブ(code_load() 等)が サポートされた場合、code_create() は、使えなくなる可能性があります。
XTAL RT では特に断らない限りプロセスがスケジューリングされることは ありません。 (SystemCallを呼び出したり、割り込みが起こってもプロセスの スケジューリングは一切起こりません。もちろん Task は、時間によって スケジュールされますが、その他は thread と同じ条件です。)
プロセスはその状態が「WAIT」か「SLEEP」となった場合、CPUを失い、 スケジューリングの対象となります。
スケジューリングの優先度において thread と Task は同等に扱われます。 I/Oなどの処理を高速に行ないたい thread は優先度を高くしておくべきです。
ただし、同じ優先度の thread と Task が READY であるときは、 同じ優先度の全ての thread が処理されるまで、Task の実行は起こりません。
queue 待ち状態のプロセスが queue の待ち行列から外され READY になる 順序は、優先度その他の要素に関係なく、queue 待ちに来た順序の通りです。
threadは近い将来、CPUをグラブするプロセスと表現されるようになります。
すべてのプロセスはCPUを動的にグラブしたり、開放したりできます。 プロセス生成時にthreadを指定した場合は、かならず CPUをグラブします。 TaskもCPUをグラブできます。
#include "crystal.h"
BYTE4 sys_gettime()
OBJECT_NAME name_generate()
プロセスには次の5つの状態がある。
プロセス・オブジェクトが生成されている。実行は始まっていない | |
プロセスは code を実行可能 (「READY」状態のプロセスは「ACTIVE」になる可能性を常に持っている) | |
プロセスは code を実行中(CPUを得ている) | |
プロセスは sleep 中 | |
プロセスはイベント、キューなどを待っている |
Task はそれぞれ固有の timeslice 値というものを持っている。
timeslice 値とは「何 tick で timeslice されるか」というものである。
PROC_INI 構造体struct Proc_ini { PROC_TYPE type; /* thread or Task */ PRIO priority; /* priority 初期値*/ OBJECT_NAME code; /* プログラム・コードの名前 */ BYTE4 stack_size; /* 使用するスタックの大きさ */ OBJECT_NAME data; /* 将来バージョンで使用 */ }; #define PROC_INI struct Proc_iniPROC_INI メンバーの意味
thread/Task/SystemThreadのいずれかを設定 | |
優先度の初期値 | |
Codeオブジェクトの名前を入れる | |
プロセスが使用するスタックのサイズ(Bytesで) | |
将来バージョンで使用 |
int proc_create(name, pdata) OBJECT_NAME name; PROC_INI *pdata;
int proc_delete(name) OBJECT_NAME name;
int proc_start(name) OBJECT_NAME name;
int proc_stop(name) OBJECT_NAME name;
int proc_wakeup(name) OBJECT_NAME name;
int proc_sleep(naem,timeout) OBJECT_NAME name; BYTE4 timeout;
int proc_setslice(name,s) OBJECT_NAME name; BYTE4 s;
int proc_setpriority(name,s) OBJECT_NAME name; BYTE4 s;
int self_sleep(timeout) BYTE4 timeout;
void self_end()
int self_getname()
int self_setslice(s) BYTE4 s;
int self_setpriority(s) BYTE4 s;
int self_grab_cpu()
int self_ungrab_cpu()
キューはプロセス間で、ある程度の大きさを持つデータを通信するための FIFOである。
プロセスがキューを queue_write() に来た時に、キューが一杯ならば、 そのプロセスはデータを書き込めるか、タイムアウトになるまで「WAIT」状態に される。
プロセスがキューを queue_read() に来た時に、キューが空ならば、 そのプロセスはデータが得られるか、 タイムアウトになるまで「WAIT」状態にされる。
タイムアウトの場合を除き、queue 待ち状態のプロセスが queue の 待ち行列から外され READY になる順序は、優先度その他の要素に関係なく、 queue 待ちに来た順序のままである。
タイムアウトが0と指定された時は、どんな場合もスケジュールされない。
注意:
データの大きさ0のキューは create できない。
struct Queue_pbox { BYTE *data; BYTE4 size; BYTE4 timeout; OBJECT_NAME sender; BYTE4 when; }; #define QUEUE_PBOX struct Queue_pboxQUEUE_PBOX メンバーの意味
データへのポインタ | |
データの大きさ(in Byte) | |
timeout の時間 | |
queue_read() において、データの送り主の名前 queue_write() では意味無し |
|
queue_read() において、送り主がデータをキューイングしたときの
システム時刻 queue_write() では意味無し |
int queue_create(name, len, data_max_size) OBJECT_NAME name; BYTE4 len; BYTE4 data_max_size;
int queue_delete(name) OBJECT_NAME name;
int queue_read(name, pbox) OBJECT_NAME name; QUEUE_PBOX *pbox;
int queue_write(name, pbox) OBJECT_NAME name; QUEUE_PBOX *pbox;
int queue_peek(name) OBJECT_NAME name;
int queue_npeek(name) OBJECT_NAME name;
イベントを event_wait() に来たプロセスは、待ち条件が満たされるか、 タイムアウトになるまで、「WAIT」状態にされる。
タイムアウトが0と指定された時は、どんな場合もスケジュールされない。
EVENT_PBOX構造体struct Event_pbox { BYTE4 value; BYTE4 mask; BYTE4 op; BYTE4 timeout; BYTE4 result; OBJECT_NAME sender; BYTE4 when ; }; #define EVENT_PBOX struct Event_pboxEvent-PBOX構造体メンバーの意味
op のオペランド | |
ソースとオペランドのマスク | |
セットの演算 | |
無意味 | |
演算後セットした値 | |
無意味 | |
無意味 |
result = (old_value & ~mask) | (value & mask) | |
result = (old_value & ~mask) | ((old_value & value) & mask) | |
result = old_value | (value & mask) | |
result = (old_value & ~mask) | ((old_value ^ value) & mask) | |
result = (old_value & ~mask) | (~(old_value & value) & mask) | |
result = (old_value & ~mask) | (~(old_value | value) & mask) | |
result = (old_value & ~mask) | (~(old_value ^ value) & mask) | |
result = (old_value & ~mask) | ((~old_value & value) & mask) |
wait からもどる時にイベントにセットする値 | |
waitのマスク・パターン | |
wait の演算(or/and のみ) | |
timeout の時間 | |
戻り時の event の値 | |
最新のイベントの送り主の名前 | |
最新のイベントがポストされたときのシステム時刻 |
mask パターンに指定した全ての bit が 1 になるまで待つ | |
mask パターンの中のいずれかの bit が 1 になるまで待つ |
int event_create(name) OBJECT_NAME name;
int event_delete(name) OBJECT_NAME name;
int event_set(name, pbox) OBJECT_NAME name; EVENT_PBOX *pbox;
int event_wait(name, pbox) OBJECT_NAME name; EVENT_PBOX *pbox;
BYTE4 event_get(name) OBJECT_NAME name;
int object_join_event(obj_name, mode, event_name, evpbox) OBJECT_NAME obj_name; int mode; OBJECT_NAME event_name; EVENT_PBOX *evpbox;
obj_nameで示されたオブジェクトにmodeで示された変化が生じたとき、 結び付けられたeventにevpboxの情報を使って、event_set()を行なう。
evpboxの、op,value,maskのみが有効。
mode :JOEV_QWRITE | queueに書き込みがあった時event_set()する |
JOEV_QREAD | queueから読みだしがあった時event_set()する |
JOEV_SEM_SIGNAL | semaphoreにsemaphore_signal()された時event_set()する |
JOEV_SEM_WAIT | semaphoreに対し誰かがsemaphore_wait()に成功時event_set()する |
セマフォを semaphore_wait() に来たプロセスは、セマフォが得られるか、 タイムアウトになるまで、「WAIT」状態にされる。
タイムアウトが0と指定された時は、どんな場合もスケジュールされない。
int semaphore_create(name) OBJECT_NAME name;
int semaphore_delete(name) OBJECT_NAME name;
int semaphore_signal(name) OBJECT_NAME name;
int semaphore_wait(name, timeout,pbox) OBJECT_NAME name; BYTE4 timeout; SEMAPHORE_PBOX *pbox;
struct Semaphore_pbox { OBJECT_NAME owner; BYTE4 when ; }; #define SEMAPHORE_PBOX struct Semaphore_pboxSEMAPHORE_PBOX構造体メンバーの意味
現在セマフォを得ているプロセスの名前 | |
現在のownerがセマフォを得たときのシステム時刻 |
通常のプロセスはメモリ空間が分離されているため、 共有メモリ・プリミティブを使用しなければ、共有メモリを実現できない。
unsigned int memory_page_size()
int memory_common_create(name, n) OBJECT_NAME name; unsigned int n;
int memory_common_delete(name) OBJECT_NAME name;
unsigned int memory_common_size(name) OBJECT_NAME name;
void * memory_window_create(name, n) OBJECT_NAME name; unsigned int n;
int memory_window_delete(name) OBJECT_NAME name;
unsigned int memory_window_size(name) OBJECT_NAME name;
int memory_common_map_window(cm_name, win_name) OBJECT_NAME cm_name, win_name;
void dbg_putstr(s) char *s;
void dbg_write(c) BYTE4 c;
void object_dbgdump(name) OBJECT_NAME name;
オブジェクトの名前に使用できる文字セットは、XTALの実装に依存する。 また、オブジェクト名の表現は、XTALの実装に依存する。
オブジェクト名<->文字列の変換には、必ず、str_to_name(),name_to_str()を 使用しなければ、アプリケーションのソース・コード互換性が保証されない。
XTALのいかなるバージョンでも、少なくとも、 以下の文字がオブジェクト名に使用できる。
{ '_' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' , '!' , '+' , '-' , '$' , '%' };
OBJECT_NAME str_to_name(s) char *s;
void name_to_str(s,name) char *s; OBJECT_NAME name;