T-Kernel/SMの機能

この章では、T-Kernel/SM(System Manager)で提供している機能の詳細について説明を行う。

注意全般的な注意・補足事項
 

  • T-Kernel/SMの仕様で定義されているAPIには、tk_~の名称を持つものと、それ以外の名称を持つものがある。原則として、tk_~の名称を持つAPIは拡張SVCで実装され、それ以外の名称を持つAPIはライブラリ関数(インライン関数を含む)またはC言語のマクロで実装されている。なお、T-Kernel/SMで定義されるAPIに対しては、「システムコール」の名称を用いておらず、「システムコール」と呼んだ場合には、T-Kernel/OSやT-Kernel/DSで定義されているAPIを指す。

  • ライブラリまたはマクロであっても、間接的に拡張SVCやシステムコールを呼び出している場合がある。

  • 常に発生する可能性のあるエラー E_PAR, E_MACV, E_NOMEM などは、特に説明を必要とする場合以外は省略している。

  • T-Kernel/SMの拡張SVCおよびライブラリは、特に明記されているものを除き、タスク独立部およびディスパッチ禁止中・割込み禁止中状態から呼び出すことはできない(E_CTX)。

  • T-Kernel/SMの拡張SVCおよびライブラリは、特に明記されているものを除き、T-Kernel/OSのシステムコールの呼出可能な保護レベルより低い保護レベル(TSVCLimit より低い保護レベル)から呼び出すことはできない(E_OACV)。

  • T-Kernel/SMの拡張SVCおよびライブラリは、特に明記されているものを除き、再入可能(reentrant)である。ただし、内部で排他制御を行っている場合がある。

  • E_PAR, E_MACV, E_CTX の検出は実装依存でありエラーとして検出されない場合もあるため、このようなエラーを発生する可能性のある呼出を行ってはいけない。

システムメモリ管理機能

システムメモリ管理機能は、T-Kernelが動的に割り当てるすべてのメモリ(システムメモリ)を管理するための機能である。T-Kernel内部で使用しているメモリやタスクのスタック、メッセージバッファ、メモリプールなどもここから割り当てる。

システムメモリは、ブロック単位で管理される。ブロックサイズは、通常MMUで定義されるページサイズであり、現在の実装では4KB程度を想定している。MMUを使用しないシステムでは任意のサイズでよいが、MMUのページサイズと同程度を推奨する。ブロックサイズは、tk_ref_smb により取得できる。

システムメモリは、共有空間のメモリである。T-Kernelではタスク固有空間のメモリの管理は行わない。

システムメモリ管理機能は、システムメモリからのメモリの割当てや解放をブロック単位で行うシステムメモリ操作用の拡張SVCと、ブロック単位で確保されたシステムメモリをさらに細分化して管理するメモリ割当てライブラリからなる。

システムメモリ管理機能は、T-Kernel内部で利用する他、アプリケーションやサブシステム、デバイスドライバなどからも利用可能である。なお、T-Kernel内部での利用は拡張SVCを経由しない方法でもよく、実装定義とする。

システムメモリ割当て

システムメモリ割当ての機能では、システムメモリからのメモリの割当て、解放と、システムメモリ情報を参照する機能を拡張SVCで提供する。

tk_get_smb - システムメモリの割当て

C言語インタフェース

#include <tk/tkernel.h>

ER ercd = tk_get_smb (void **addr , INT nblk , UINT attr );

パラメータ

void** addr Pointer to Memory Start Address割り当てたメモリの先頭アドレスを返す領域へのポインタ
INT nblk Number of Block割り当てるメモリブロック数
UINT attr Attribute割り当てるメモリの属性

リターンパラメータ

ER ercd Error Codeエラーコード
void* addr Memory Start Address割り当てたメモリの先頭アドレス

エラーコード

E_OK 正常終了
E_PAR パラメータエラー((nblk≦0)または attr が不正)
E_NOMEM メモリ不足(システムメモリが不足している)
E_MACV メモリアクセス権違反(attr に書込みができない)

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

nblk で指定したブロック数分の連続したメモリ領域を attr で指定した属性で割り当てる。割り当てたメモリの先頭アドレスを addr に返す。

attr では、以下の属性を指定する。

attr := (TA_RNG0 || TA_RNG1 || TA_RNG2 || TA_RNG3) | [TA_NORESIDENT]

TA_RNG0 保護レベル0のメモリを指定する
TA_RNG1 保護レベル1のメモリを指定する
TA_RNG2 保護レベル2のメモリを指定する
TA_RNG3 保護レベル3のメモリを指定する
TA_NORESIDENT 非常駐メモリを指定する

TA_RNGn では、メモリのアクセスを制限する保護レベルを指定する。割り当てられたメモリは、指定された保護レベルと同じかより高い保護レベルで実行しているタスク等からのみアクセス可能である。

TA_NORESIDENT が指定された場合、割り当てられたメモリは非常駐メモリとなる。MMUのないシステムでは、非常駐メモリの属性を指定した場合でも、実際には常駐メモリと同様の動作をすることになるが、エラーとはしない。

nblk に負の値が指定された場合や、attr に指定できない属性が指定された場合には、E_PAR のエラーを返す。また、addr の指すメモリ(割り当てたメモリの先頭アドレスを返す領域)への書込みアクセスが禁止されている場合には、E_MACV のエラーを返す。

nblk で指定したブロック数分の連続したメモリ領域の割当てができない場合、E_NOMEM のエラーを返す。この場合、addr の指すメモリには NULL が返される。

補足事項

MMUを使用しないシステムでは、実装上、メモリの保護レベルに違反したアクセスがあった場合にも、アクセス権違反の例外を検出することができず、正常なメモリアクセスができてしまう。しかし、プログラムの移植性や拡張性を考慮し、割り当てるメモリに対しては、アクセスするタスク等の保護レベルからアクセス可能な適切な保護レベルを指定することが推奨される。

tk_rel_smb - システムメモリの解放

C言語インタフェース

#include <tk/tkernel.h>

ER ercd = tk_rel_smb (void *addr );

パラメータ

void* addr Memory Start Address解放するメモリの先頭アドレス

リターンパラメータ

ER ercd Error Codeエラーコード

エラーコード

E_OK 正常終了
E_PAR パラメータエラー(addr が不正)

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

addr で指定したメモリを解放する。addr は、tk_get_smb() で得たアドレスでなければならない。

addr に指定されたアドレスが不正であることが検出された場合は、E_PAR のエラーが返る。具体的には、addr がT-Kernelが管理しているメモリの範囲外を指している場合や、既に tk_rel_smb() で解放したメモリを再度解放しようとした場合に、E_PAR エラーが返る。ただし、実装上の制約により、addr が不正であってもエラーの検出ができない場合があり、その場合の動作は保証されない。そのため、addr の正当性は呼出側で保証しなければならない。

tk_ref_smb - システムメモリ情報取得

C言語インタフェース

#include <tk/tkernel.h>

ER ercd = tk_ref_smb (T_RSMB *pk_rsmb );

パラメータ

T_RSMB* pk_rsmb Packet to Refer System Memory Blockシステムメモリ情報を返す領域へのポインタ

リターンパラメータ

ER ercd Error Codeエラーコード

pk_rsmb の内容

INT blksz Block Sizeブロックサイズ(バイト数)
INT total Total Block Count全ブロック数
INT free Free Block Count残りブロック数
──(以下に実装独自に他の情報を追加してもよい)──

エラーコード

E_OK 正常終了
E_MACV メモリアクセス権違反(pk_rsmb に書込みができない)

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

システムメモリに関する情報を取得する。

仮想記憶を行っているシステムでは、非常駐のメモリを割り当てることにより、物理的なメモリよりも大きなサイズのメモリを使うことができる。このため、全ブロック数や残りブロック数が一意に決定できないことがある。そのような場合の total, free の内容は実装依存とするが、free÷total が残りメモリ容量の割合の参考値となるような値とすることが望ましい。

メモリ割当てライブラリ

tk_get_smb() によるシステムメモリの割当てはブロック単位であるため、より細分化して効率的にメモリを使用するために、メモリ割当てライブラリを使用する。

メモリ割当てライブラリの内部では、tk_get_smb() によって確保されたシステムメモリを管理しており、その中からアプリケーションの要求したサイズのメモリを割り当てる。メモリ割当てライブラリが管理するメモリに、アプリケーションが要求するサイズの空きメモリが無い場合には、再度 tk_get_smb() を呼び出して追加のシステムメモリを割り当てる。

一方、アプリケーションからメモリが返却された際に、そのメモリが含まれるメモリブロックのすべてが未割当てとなった場合には、tk_rel_smb() によってそのメモリブロックを解放する。ただし、メモリブロックの確保や解放の厳密なタイミングなどは実装依存である。

メモリ割当てライブラリは、C言語標準ライブラリの malloccallocreallocfree と同等の機能が提供される。対象とするメモリが非常駐メモリの場合は V~ のAPI名、常駐メモリの場合は K~ のAPI名である。

これらのメモリは、すべて TSVCLimit で指定された保護レベルのメモリとして割り当てられる。

Vmalloc - 非常駐メモリの割当て

C言語インタフェース

#include <tk/tkernel.h>

void* Vmalloc (size_t size );

パラメータ

size_t size Size割り当てるメモリサイズ(バイト数)

リターンパラメータ

void* addr Memory Start Address割り当てたメモリの先頭アドレス

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

size で指定したバイト数の非常駐メモリを割り当て、その先頭アドレスを addr に返す。

指定したサイズのメモリの割当てができなかった場合や、size に0が指定された場合は、addrNULL が返る。

Vmalloc を含むメモリ割当てライブラリのAPIは、タスク独立部およびディスパッチ禁止中、割込み禁止中に呼び出すことはできない。呼び出した場合の動作は、システムダウンの可能性も含めて不定であり、呼出時の状態を保証するのは、呼出側の責任である。

補足事項

size には任意の値を指定できるが、管理領域の確保や、割り当てるメモリアドレスのアラインメントの調整といった理由により、内部的には、size で指定したバイト数よりも大きなメモリが割り当てられる場合がある。たとえば、割当て可能なメモリサイズの最低が16バイトで、アラインメントが8バイト単位という実装の場合には、size に16バイト未満の値を指定した場合でも、内部的には16バイトのメモリが割り当てられる。また、size に20バイトの値を指定した場合でも、内部的には24バイトのメモリが割り当てられる。

したがって、メモリ割当てライブラリ全体で使用するシステムメモリのサイズと、メモリ割当てライブラリの各APIで割り当てられたメモリのサイズの合計を比較すると、前者の方が大きな値をとる場合がある。

Vcalloc - 非常駐メモリの割当て

C言語インタフェース

#include <tk/tkernel.h>

void* Vcalloc (size_t nmemb , size_t size );

パラメータ

size_t nmemb Number of Memory Block割り当てるメモリブロックの個数
size_t size Size割り当てるメモリブロックのサイズ(バイト数)

リターンパラメータ

void* addr Memory Start Address割り当てたメモリの先頭アドレス

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

size で指定したバイト数のメモリブロックを、nmemb で指定された個数だけ連続して割り当て、0クリアしてから、その先頭アドレスを addr に返す。メモリ割当ての動作は、sizenmemb を乗じたバイト数のメモリブロック1個を割り当てるのと同じである。割り当てられるメモリは、非常駐メモリである。

指定した個数のメモリブロックの割当てができなかった場合や、nmemb または size に0が指定された場合は、addrNULL が返る。

Vcalloc を含むメモリ割当てライブラリのAPIは、タスク独立部およびディスパッチ禁止中、割込み禁止中に呼び出すことはできない。呼び出した場合の動作は、システムダウンの可能性も含めて不定であり、呼出時の状態を保証するのは、呼出側の責任である。

補足事項

内部的には、sizenmemb を乗じたバイト数よりも大きなメモリが割り当てられる場合がある。詳細は Vmalloc() の補足事項を参照のこと。

Vrealloc - 非常駐メモリの再割当て

C言語インタフェース

#include <tk/tkernel.h>

void* Vrealloc (void *ptr , size_t size );

パラメータ

void* ptr Pointer to Memory再割当て対象のメモリアドレス
size_t size Size再割当て後のメモリサイズ(バイト数)

リターンパラメータ

void* addr Memory Start Address再割当てされたメモリの先頭アドレス

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

ptr で指定した割当て済の非常駐メモリのサイズを、size で指定されたサイズに変更する。その際にメモリの再割当てを行い、再割当て後のメモリの先頭アドレスを addr に返す。

サイズ変更をともなうメモリの再割当てにより、一般にはメモリの先頭アドレスが移動し、addrptr と異なった値になる。ただし、その場合でも、再割当ての対象となったメモリの内容は保存される。このため、Vrealloc の処理の中でメモリ内容のコピーを行う。また、再割当てにより不要になったメモリは解放される。

ptr には、VmallocVcallocVrealloc で割り当てられたメモリの先頭アドレスを指定する必要がある。ptr の正当性は呼出側で保証しなければならない。

ptrNULL を指定した場合は、新しいメモリの割当てのみを行う。この場合の動作は Vmalloc() と同一である。

指定したサイズのメモリの再割当てができなかった場合や、size に0が指定された場合は、addrNULL が返る。このとき、ptrNULL 以外が指定されていれば、ptr のメモリの解放だけを行う。この場合の動作は Vfree() と同一である。

Vrealloc を含むメモリ割当てライブラリのAPIは、タスク独立部およびディスパッチ禁止中、割込み禁止中に呼び出すことはできない。呼び出した場合の動作は、システムダウンの可能性も含めて不定であり、呼出時の状態を保証するのは、呼出側の責任である。

補足事項

再割当てによりメモリサイズが小さくなる場合や、ptr で指定されるメモリの周辺に未割当てのメモリが残っている場合など、状況によっては、addr に返るメモリアドレスが ptr と同一となることがある。

内部的には、sizeで指定したバイト数よりも大きなメモリが割り当てられる場合がある。詳細は Vmalloc() の補足事項を参照のこと。

Vfree - 非常駐メモリの解放

C言語インタフェース

#include <tk/tkernel.h>

void Vfree (void *ptr );

パラメータ

void* ptr Pointer to Memory解放するメモリの先頭アドレス

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

ptr で指定した非常駐メモリを解放する。

ptr には、VmallocVcallocVrealloc で割り当てられたメモリの先頭アドレスを指定する必要がある。ptr の正当性は呼出側で保証しなければならない。

Vfree を含むメモリ割当てライブラリのAPIは、タスク独立部およびディスパッチ禁止中、割込み禁止中に呼び出すことはできない。呼び出した場合の動作は、システムダウンの可能性も含めて不定であり、呼出時の状態を保証するのは、呼出側の責任である。

Kmalloc - 常駐メモリの割当て

C言語インタフェース

#include <tk/tkernel.h>

void* Kmalloc (size_t size );

パラメータ

size_t size Size割り当てるメモリサイズ(バイト数)

リターンパラメータ

void* addr Memory Start Address割り当てたメモリの先頭アドレス

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

size で指定したバイト数の常駐メモリを割り当て、その先頭アドレスを addr に返す。

指定したサイズのメモリの割当てができなかった場合や、size に0が指定された場合は、addrNULL が返る。

Kmalloc を含むメモリ割当てライブラリのAPIは、タスク独立部およびディスパッチ禁止中、割込み禁止中に呼び出すことはできない。呼び出した場合の動作は、システムダウンの可能性も含めて不定であり、呼出時の状態を保証するのは、呼出側の責任である。

補足事項

内部的には、size で指定したバイト数よりも大きなメモリが割り当てられる場合がある。詳細は Vmalloc() の補足事項を参照のこと。

Kcalloc - 常駐メモリの割当て

C言語インタフェース

#include <tk/tkernel.h>

void* Kcalloc (size_t nmemb , size_t size );

パラメータ

size_t nmemb Number of Memory Block割り当てるメモリブロック個数
size_t size Size割り当てるメモリブロックのサイズ(バイト数)

リターンパラメータ

void* addr Memory Start Address割り当てたメモリの先頭アドレス

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

size で指定したバイト数のメモリブロックを、nmemb で指定された個数だけ連続して割り当て、0クリアしてから、その先頭アドレスを addr に返す。メモリ割当ての動作は、sizenmemb を乗じたバイト数のメモリブロック1個を割り当てるのと同じである。割り当てられるメモリは、常駐メモリである。

指定した個数のメモリブロックの割当てができなかった場合や、nmemb または size に0が指定された場合は、addrNULL が返る。

Kcalloc を含むメモリ割当てライブラリのAPIは、タスク独立部およびディスパッチ禁止中、割込み禁止中に呼び出すことはできない。呼び出した場合の動作は、システムダウンの可能性も含めて不定であり、呼出時の状態を保証するのは、呼出側の責任である。

補足事項

内部的には、sizenmemb を乗じたバイト数よりも大きなメモリが割り当てられる場合がある。詳細は Vmalloc() の補足事項を参照のこと。

Krealloc - 常駐メモリの再割当て

C言語インタフェース

#include <tk/tkernel.h>

void* Krealloc (void *ptr , size_t size );

パラメータ

void* ptr Pointer to Memory再割当て対象のメモリアドレス
size_t size Size再割当て後のメモリサイズ(バイト数)

リターンパラメータ

void* addr Memory Start Address再割当てされたメモリの先頭アドレス

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

ptr で指定した割当て済の常駐メモリのサイズを、size で指定されたサイズに変更する。その際にメモリの再割当てを行い、再割当て後のメモリの先頭アドレスを addr に返す。

サイズ変更をともなうメモリの再割当てにより、一般にはメモリの先頭アドレスが移動し、addrptr と異なった値になる。ただし、その場合でも、再割当ての対象となったメモリの内容は保存される。このため、Krealloc の処理の中でメモリ内容のコピーを行う。また、再割当てにより不要になったメモリは解放される。

ptr には、KmallocKcallocKrealloc で割り当てられたメモリの先頭アドレスを指定する必要がある。ptr の正当性は呼出側で保証しなければならない。

ptrNULL を指定した場合は、新しいメモリの割当てのみを行う。この場合の動作は Kmalloc() と同一である。

指定したサイズのメモリの再割当てができなかった場合や、size に0が指定された場合は、addrNULL が返る。このとき、ptrNULL 以外が指定されていれば、ptr のメモリの解放だけを行う。この場合の動作は Kfree() と同一である。

Krealloc を含むメモリ割当てライブラリのAPIは、タスク独立部およびディスパッチ禁止中、割込み禁止中に呼び出すことはできない。呼び出した場合の動作は、システムダウンの可能性も含めて不定であり、呼出時の状態を保証するのは、呼出側の責任である。

補足事項

再割当てによりメモリサイズが小さくなる場合や、ptr で指定されるメモリの周辺に未割当てのメモリが残っている場合など、状況によっては、addr に返るメモリアドレスが ptr と同一となることがある。

内部的には、sizeで指定したバイト数よりも大きなメモリが割り当てられる場合がある。詳細は Vmalloc() の補足事項を参照のこと。

Kfree - 常駐メモリの解放

C言語インタフェース

#include <tk/tkernel.h>

void Kfree (void *ptr );

パラメータ

void* ptr Pointer to Memory解放するメモリの先頭アドレス

利用可能なコンテキスト

タスク部準タスク部タスク独立部
×

解説

ptr で指定した常駐メモリを解放する。

ptr には、KmallocKcallocKrealloc で割り当てられたメモリの先頭アドレスを指定する必要がある。ptr の正当性は呼出側で保証しなければならない。

Kfree を含むメモリ割当てライブラリのAPIは、タスク独立部およびディスパッチ禁止中、割込み禁止中に呼び出すことはできない。呼び出した場合の動作は、システムダウンの可能性も含めて不定であり、呼出時の状態を保証するのは、呼出側の責任である。