高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technical Note TN1104
Interrupt-Safe Routines

目次

Mac OS 9 までの Mac OS には、定義が不明確なプログラミング環境がいくつかあります。このような環境で使用できるシステムサービスと使用できないサービスがあります。これら環境の呼び名は複数の違うものを指す場合があって、まぎらわしいのです。このためプログラマを混乱させてきました。

このテクニカルノートではこの混乱を払拭しようとするものです。それぞれの実行レベルにユニークな名前を与え、プログラムコードが特定の実行レベルに入る方法とその理由を説明し、特定の実行レベルにあるプログラムコードが直面する制約について説明します。

このテクニカルノートは割り込み時に実行するコードを書くプログラマやシステムレベルで実行するプログラムを開発するデベロッパにとって、必見です。

 Updated: November 8, 2000






はじめに

ツールボックスコールのうち、割り込み時に使用可能なものと使用できないものについて多くの混乱がありました。このテクニカルノートでは割り込み時に使用可能なツールボックスコールについて説明します。

このテクニカルノートでは割り込み時に呼び出しても安全なシステムコールを掲載します。割り込み時に呼び出すと危険なコールは取り上げません。それは次のような理由からです。Mac OS のシステムコールは増える一方です。また、既存のシステムコールに手を加えることもありますので、過去に割り込み時に呼び出しても安全だったルーチンが、割り込み時には使用できなくなる場合があります。割り込み時に呼び出しても安全なシステムコールだけを掲載することで、そのリストが今後も正確である可能性が高いです。

DTS では、このテクニカルノートに掲載されていないシステムコールを割り込み時に呼び出さないよう推奨しています。ただし、これはガイドラインであり、他にも安全なシステムコールが存在するかもしれません。割り込み時に呼び出しても安全だと思っていたシステムコールがこのテクニカルノートに掲載されていないようでしたら、フィードバックをお送り下さい。一つの例として、このテクニカルノートの最初のバージョンでは SetCursor が掲載されていませんでしたが、デベロッパからのフィードバックにより、割り込み時に呼び出しても安全なシステムコールとして追加されました。

割り込み時に呼び出しても安全なルーチンでも、不適当なパッチをあてると、危険なコールになってしまいます。安全なルーチンのパッチは割り込み時に実行するので、割り込み時にしてはならないことを避けなければなりません。

註:
DTS では、パッチはどんな場合でも避けるように推奨してまいりましたが、どうしてもパッチをあてる場合は正しくパッチをあてて下さい。



旧版の Inside Macintosh の Volume 6 の Appendix B には、割り込み時に呼び出してもよいルーチンの一覧が掲載されています。このテクニカルノートはその一覧を置き換えるもので、さらに必要に応じて説明も加えました。Inside Macintosh の Volume 6 の Appendix B の一覧はもう使用しないでください。

トップに戻る



実行レベル

Mac OS 9 までの Mac OS は次の実行レベルをサポートします。

  • ハードウェア割り込み
  • 遅延タスク(Deferred Task)
  • システムタスク(System Task)

ネイティブデバイスドライバモデルは上記に加えて次のレベルも定義しています。

  • ネイティブハードウェア割り込み
  • 二次割り込み
  • タスク
  • ソフトウェア割り込み

これら実行レベルは、Copland の実行レベルをモデルに作成されたものですが、従来のモデルともおおまかに対応しています。

  • ネイティブハードウェア割り込みはハードウェア割り込みと似ています
  • 二次割り込みは遅延タスク(Deferred Task)と似ています
  • タスクはシステムタスク(System Task)と似ています
  • ソフトウェア割り込みはサポートされていません

しかしながら、明確に区別する必要のある場合もあります。


註:
ネイティブデバイスドライバの実行レベルの詳細については、Designing PCI Cards and Drivers for Power Macintosh Computers の 67 ページを参照してください。



重要:
ここでは PowerPC のネイティブな割り込みメカニズムについては説明しません。Mac OS 9 までの Mac OS が動作する PowerPC Macintosh コンピュータでは、PowerPC のネイティブな割り込み処理はナノカーネルが行い、割り込みは 68K エミュレータに転送されます。このテクニカルノートで 68K 固有の概念を説明した場、PowerPC プロセッサを搭載したマシンでも、PowerPC の低レベルのシステムソフトウェアが同じ動作をエミュレートしている、と考えて差し支えありません。



重要:
実行レベルは、プロセッサの割り込みマスク(680x0 SR レジスタに保存された値)とは独立しています。プロセッサの割り込みマスクによる、割り込み時であるかどうかの判断は正確ではありません。詳しくは実行レベルの取得方法をご覧下さい。



この節では、それぞれの実行レベルについて詳しく説明します。



ハードウェア割り込み

このレベルの定義

ハードウェア割り込みレベルの実行は、ハードウェア割り込み要求の直接の結果として起こります。ハードウェア割り込みレベルで実行されるソフトウェアには、アップルが提供する割り込みハンドラだけでなく、NuBus や他のデバイスのインストール可能割り込みハンドラも含まれます。

このレベルに入る方法

ハードウェア割り込みレベルに入るには、ハードウェア割り込みハンドラをインストールして直接、呼び出される場合(SIntInstall またはローメモリの割り込みベクタテーブルを変更してインストールされた NuBus ハンドラ)と、ハードウェア割り込みハンドラから間接的に呼び出される場合(SCSI Manager 4.3 の完了ルーチン)とがあります。Time Manager タスクや VBL もハードウェア割り込みレベルで実行されますので注意してください。

環境の制約

ハードウェア割り込みは、ツールボックス、仮想メモリ、Open Transport で定義される「割り込みレベル」に該当します。これらの制約については他の文書で記述されている実行レベルで説明します。

さらに、ハードウェア割り込みレベルでは、できるだけ実行時間を短くしなければなりません。ハードウェア割り込みレベルでは、あるハードウェア割り込みハンドラの実行中には、それより優先順位の低い割り込みはすべて禁止されます。ハードウェア割り込みハンドラの実行時間が長くなると、それだけコンピュータの割り込み遅延が大きくなります。割り込み遅延が大きくなると、音声がとぎれたり、カーソルのトラッキングがにぶくなるなど、ユーザに悪影響を与えます。割り込み時に多くの処理を必要とする場合は、DTInstall で遅延タスクをスケジュールしてください。

ページングの安全性

ハードウェア割り込みレベルのページングは、DeferUserFn で割り込みを遅らせないかぎり、安全ではありません。システムの割り込みハンドラのなかには(Device Manager 完了ルーチン、VBL、スロット VBL、Time Manager タスク)、仮想メモリが動作しても安全になるまで自動的に処理を遅らせるものもありますが、その他のハードウェア割り込みハンドラは、ページフォルトを起こさないよう保証しなければなりません。ページフォルトを起こす可能性のあるメモリにアクセスする必要がある場合は、DeferUserFn で処理を遅らせなければなりません。



註:
DeferUserFn と DTInstall は混乱させないで下さい。前者はパージングが安全になるまでハードウェア割り込みを遅延しますが、後者は遅延タスク(Deferred Task)を割り込みが可能になるまで遅延するものです。



遅延タスク(Deferred Task)

このレベルの定義

遅延タスク(Deferred Task)とは、ハードウェア割り込みレベルのコードが、割り込み可能状態に戻した後、その割り込みから戻る前に実行すべきルーチンをスケジュールするしくみです。ハードウェア割り込みハンドラは、ハンドラ自身の中で実行される時間を最小にして、システムの割り込み遅延を最小にするため、この方法を取ります。

このレベルに入る方法

遅延タスクレベルに入る最も一般的な方法は、ハードウェア割り込みハンドラから DTInstall を実行することです。割り込み処理システムは、その割り込みから戻る直前、ただし再び割り込み可能になった後に、遅延タスクを実行します。

遅延タスクレベルで実行されているコードから間接的に呼び出されて、遅延タスクレベルに入る場合があります。このよい例は、Open Transport の通知関数で、これはしばしば遅延タスクレベルから呼び出されます。

環境の制約

遅延タスクは、ツールボックスや仮想メモリで定義される「割り込みレベル」に該当します。これらの制約については他の文書で記述されている実行レベルで説明します。

ページングの安全性

遅延タスクレベルでは、ページングは安全です。

Special Considerations

遅延タスクのもうひとつの利点は、順に実行されることです。システムは、ある遅延タスクの実行を中断して他の遅延タスクを実行することはしません。これは便利な排他制御機構として使えます。



システムタスク(System Task)

このレベルの定義

システムタスク(System Task)レベルは、もっとも一般的なアプリケーションコードが実行されるレベルです。

この名前は Macintosh の古いシステムコール SystemTask が由来です。MultiFinder(今では Process Manager と呼ばれています)が登場する前は、アプリケーションは、定期的に SystemTask を呼び出して、割り込み時には実行できない処理を行うため、デバイスドライバが実行できるようにする必要がありました。



註:
現在、SystemTask は不要です。WaitNextEvent が自動的に呼び出してくれます。



このレベルに入る方法

アプリケーションのメインエントリポイントはシステムタスクレベルで呼び出されます。協調スレッドとしてスケジュールされた Thread Manager のスレッドもシステムタスクレベルで実行されます。その他のコードについては、Technote 1033: Interrupts in Need of (a Good) Time に、割り込みレベルからシステムタスクレベルに入る方法が説明されています。

環境の制約

システムタスクレベルで動作するコードは、どの環境においても「割り込みレベル」ではありません。システムタスクレベルでは事実上何でもできます。

ページングの安全性

デフォルトではシステムタスクレベルではページングは安全です。例外は、システムがページングのサポートのために必要とするリソースに、アプリケーションのコードがアクセスする場合です。たとえば、SCSIGet を使って SCSI バスを占有した場合は、システムタスクレベルであってもページフォルトを起こしてはなりません。



ネイティブハードウェア割り込み

このレベルの定義

ネイティブハードウェア割り込みレベルは、ネイティブドライバアーキテクチャのマシンにのみ存在するという点を除けば、普通のハードウェア割り込みレベルと同一です。



註:
ここで「ネイティブ」というのは、ネイティブな割り込み処理のことをいっているのではないので注意してください。Mac OS 9 までの環境では、68K の割り込み優先順位を保証したり、68K の命令が割り込まれることのないよう、ナノカーネルがすべての割り込みを 68K エミュレータへ転送します。したがって、ネイティブ割り込みといえども、ミックスモードスイッチの対象となります。



このレベルに入る方法

ネイティブハードウェア割り込みレベルに入るのは、ネイティブな割り込みの処理を担当する Interrupt Manager でハードウェア割り込みハンドラをインストールするか、このようなハンドラから直接呼び出されたコードから呼ばれる場合です。

環境の制約

ネイティブハードウェア割り込みは、ツールボックス、仮想メモリ、Open Transport で定義される「割り込みレベル」に該当します。これらの制約については他の文書で記述されている実行レベルで説明します。

従来のハードウェア割り込みと同様、ネイティブハードウェア割り込みレベルでも動作時間を最小にしなければなりません。ネイティブハードウェア割り込みの応答処理を長くする必要がある場合は、QueueSecondaryInterruptHandler で二次割り込みをスケジュールしてください。

ページングの安全性

ネイティブハードウェア割り込みレベルではページングは安全ではありません。



二次割り込み

このレベルの定義

ネイティブドライバモデルには二次割り込みがあります。従来の遅延タスクと同様、ネイティブドライバが複雑な処理を後回しにして、割り込み遅延を最小にするためのものです。

このレベルに入る方法

二次割り込みレベルに入るには、QueueSecondaryInterruptHandler を使って二次割り込みハンドラをスケジュールするか、そのようなハンドラから呼び出される場合です。二次割り込みは割り込みが可能になった直後、遅延タスク(Deferred Task)が実行される前、そして、割り込みハンドラが返る前に実行されます。

CallSecondaryInterruptHandler2 を使って、二次割り込みハンドラをタスクレベルから呼び出すこともできます。

環境の制約

二次割り込みは、ツールボックス、仮想メモリ、Open Transport で定義される「割り込みレベル」に該当します。これらの制約については他の文書で記述されている実行レベルで説明します。

ページングの安全性

二次割り込みレベルではページングは安全ではありません。



タスク

このレベルの定義

Mac OS 9 までのネイティブドライバモデルは、ネイティブハードウェア割り込みレベルでもなく、二次割り込みレベルでもないコードをタスクレベルと定義します。

このレベルに入る方法

タスクレベルで実行されるコードは、ほとんどの場合、標準のシステムタスクレベル、つまり通常のアプリケーションコードです。しかし、従来は割り込みレベルとされていた、ネイティブ以外のハードウェア割り込みや遅延タスクなどの実行レベルも、タスクレベルになります。Mac OS 9 までは、ネイティブ割り込みまたは二次割り込みレベル以外のコードはすべてタスクレベルだからです。

環境の制約

タスクレベル環境の制約は、従来のどのレベルで実行されていたかで決まります。

ページングの安全性

ネイティブドライバモデルでは、タスクレベルにおけるページングは常に安全です。しかし、それ以外の Mac OS では、ページングは従来のどのレベルで実行されていたかで安全かどうかが決まります。



ソフトウェア割り込み

このレベルの定義

ネイティブドライバモデルはソフトウェア割り込み(タスクをそのタスクの環境内で強制的に実行させる機能)を定義しています。これは一見二次割り込みレベルと同じように見えますが、異なる機能です。

このレベルに入る方法

ソフトウェア割り込みは Mac OS ではサポートされていません。これは Designing PCI Cards and Drivers for Power Macintosh Computers の 262 ページではっきり書かれています。

現在 SendSoftwareInterrupt は同じ実行レベルでコードを呼び出します。将来は割り込み時に実行できないコードを強制的に実行させるために使用できるようになるかもしれません。

例えば、実行レベルXで SendSoftwareInterrupt を呼び出すと、ソフトウェア割り込みも実行レベルXで実行されます。つまり、現在の Mac OS では使い物にならないシステムコールです。

環境の制約

ソフトウェア割り込みの環境の制約は、従来のどのレベルで実行されていたかで決まります。

ページングの安全性

ネイティブドライバモデルでは、ソフトウェア割り込みレベルにおけるページングは常に安全です。



註:
ネイティブドライバモデルは Copland を念頭において設計されました。同じドライバが従来の Mac OS と Copland の両方で同じバイナリが実行できることを目的としていました。このことを実現するために多くの苦労がありました。

従来の Mac OS におけるネイティブドライバモデルのサポートは使用に耐えるようなものですが、Copland の一部の機能は従来の Mac OS に移植することが不可能です。この一例として、ソフトウェア割り込みがありますが、マイクロカーネルの設計を大幅に変更しないとこの機能は従来の Mac OS では実現できません。

Copland が過去のものとなった現在、ソフトウェア割り込みは Copland の“痕跡盲腸”として生き残っています。



トップに戻る



他の文書で記述されている実行レベル

一般的に、以下の実行レベルは「割り込みレベル」に該当します。

  • ハードウェア割り込み
  • 遅延タスク(Deferred Task)
  • ネイティブハードウェア割り込み
  • 二次割り込み

しかし、「割り込みレベル」の定義は文献によって、微妙に異なります。ここではもっとも混乱の原因となる記述をあげています。

ツールボックス

上記で定義される「割り込みレベル」では、ほとんどのツールボックス関数は使えません。

ツールボックス関数が使えない理由は様々です。例えば、Memory Manager はグローバルなデータ構造を扱いますので、割り込み時に呼び出すことは安全ではありません。多くの関数はメモリを移動/パージするので、Memory Manager を呼び出すのと同じ結果になります。File Manager にあるような同期的な関数は構造上使用できません。一部の関数(ReadDateTime など)は実行するために割り込みを使いますので、割り込みが不可な環境では使用できません。

つまり、ある関数がメモリを移動/パージしないからと言って、その関数を割り込み時に呼び出すことが安全だとは言えません。

Virtual Memory Manager

Virtual Memory Manager に関する文書 (Inside Macintosh: Memory の第 3 章および Technote ME09: Coping with VM and Memory Mappings には、「割り込み時」のページフォルトは許されない、と書かれています。このことからたとえば、Device Manager の完了ルーチンは「割り込み時」であるため、MacTCP 完了ルーチンではページングが危険である、と誤解していたプログラマもいました。これまでの説明を読めば、この誤解は簡単に解けるはずです。

Virtual Memory Manager に関しては、「割り込み時」とは、仮想メモリそのものまたは DeferUserFn で後回しにされていないハードウェア割り込みのことであり、したがって、他の文書では実行レベルに関して「割り込み時」とされていても、Device Manager 完了ルーチンでページフォルトを起こしても安全です。

Mac OS 9 までの仮想メモリシステムについては Technote 1094: Virtual Memory Application Compatibility をご覧下さい。

Open Transport

Open Transport の文書には、Open Transport は「割り込み時」に呼び出してはいけないと書かれているため、混乱を引き起こしました。この意味は、Open Transport はシステムタスク時または遅延タスク時にのみ呼び出すことができる、ということなのです。したがって、ハードウェア割り込みレベル(ネーティブハードウェア割り込みレベル、二次割り込みレベル)でなければ、通常は「割り込み時」と考えれらるような実行レベル(遅延タスク)からでも、Open Transport を呼び出すことはできるのです。

Open Transport の最新の技術文献(Inside Macintosh: Networking with Open Transport)はこの説明を反映しています。さらに、どのシステムコールがどの実行レベルでサポートされているか、詳しく解説されています。

トップに戻る

 

実行レベルの取得方法

現在の実行レベルを一般的に取得する方法はありません。プログラムを書く時に、予め実行レベルを知った上で書く必要があります。しかし、特定の環境においては、実行レベルを知る手段はあります。ここではそのテクニックと弱点について解説します。

割り込みのトラッキングによる実行レベルの判断

現在の実行レベルを判断する方法の1つとして、割り込みをすべてトラッキングする方法(リスト1を参照)があります。



 リスト1 割り込みのトラッキングによる実行レベルの判断

static SInt32 gMyInterruptDepth = 0;
                           
static void MyIOCompletion(ParmBlkPtr pb)
{
    (void) AddAtomic(1, &gMyInterruptDepth);
                           
    ... ここに実行コードを挿入する ...
                           
    (void) AddAtomic(-1, &gMyInterruptDepth);
}
                           
static OSStatus MyCommonCode(void)
    // この関数は割り込み時や、そうでない時も実行されます
{
    if (gMyInterruptDepth == 0) {
        ... 割り込み時に実行可能なコード ...
    } else {
        ... システムタスクレベルのコード ...
    }
}



重要:
リスト1のコードは、atomic な操作によって gMyInterruptCountDepth を変更しますので、例え割り込みがあっても、正しい値が保証されます。



このテクニックは、自分のコードが呼ばれる可能性のある実行レベルをすべて把握している場合に有効ですが、不明の実行レベルで呼ばれるようなコードでは使えません。例えば、ディスクドライバの Prime エントリ関数は様々な実行レベルで呼ばれる可能性があるので、このテクニックは使えません。

割り込みマスクを確認する

68K の割り込みマスク(680x0 SR レジスタの 8〜10 ビット)がゼロ以外だと、割り込み中であると勘違いされることがあります。これは間違っています。

  • 遅延タスク(Deferred Task)や二次割り込みを実行中の場合、割り込み中に割り込みマスクがゼロになることがあります。
  • システムタスク(System Task)時でも、割り込みマスクがゼロ以外の値となる場合があります。例えば、Enqueue などの旧いコードは割り込みを使用不可能にすることがあります。

Open Transport

Open Transport は実行レベルを取得するための API(OTIsAtInterruptLevel、OTCanLoadLibraries、OTCanMakeSyncCall)を提供しています。しかし、これらのルーチンは Open Transport を呼び出しても良い場合のみに使えます。具体的には、以下の場合に利用できます。

  • システムタスク(System Task)から呼び出す場合
  • 遅延タスク(Deferred Task)から呼び出す場合
  • OT Notifier から呼び出す場合(OT Notifier は遅延タスク(Deferred Task)時に実行します)
  • 任意の割り込み時(ただし、遅延タスク(Deferred Task)以外の割り込みルーチンはすべて OTEnterInterrupt と OTLeaveInterrupt を呼ぶと言うルールに守った場合のみ)

上記関数が間違った値を返す例として、二次割り込み時に OTCanMakeSyncCall を古いシステムで呼び出すと、true を返します!

つまり、Open Transport の関数は Open Transport を使う分には便利だが、一般的な解決方法ではありません。

CurrentExecutionLevel

PCI Power Macintosh コンピュータで登場した DriverServicesLib は CurrentExecutionLevel とルーチンを提供します。CurrentExecutionLevel はネイティブドライバモデル内においては正しい結果を返しますが、その他のコンテキストでは正しい値を返しません。

初代 CurrentExecutionLevel はリスト2のようなアルゴリズムとなっていました。



 リスト2 初代 CurrentExecutionLevel のアルゴリズム。

if ネイティブハードウェア割り込み中の場合...
  return kHardwareInterruptLevel
else 二次割り込み中の場合は...
  return kSecondaryInterruptLevel
else
  return kTaskLevel
end if



このアルゴリズムは DriverServicesLib の提供する実行レベルに限って、問題なく動作しますが、ネイティブドライバモデル外の実行レベルには無効です。例えば、遅延タスク(Deferred Task)や Time Manager タスク内から初代 CurrentExecutionLevel を呼び出すと、ネイティブドライバが実行していない限り、kTaskLevel と言う結果を返してしまいます。このルーチンが正しい値を返さない理由についてはテクニカル Q&A DV 43 InterfaceLib and Native Drivers をご覧下さい。

最近のシステムでは、CurrentExecutionLevel は DriverServicesLib 以外の環境でも動作するように変更(2323165)されています。最近のシステムはすべての割り込み(ネイティブハードウェア割り込み、Time Manager などの古い形式のものを含む)をトラッキングしています。CurrentExecutionLevel はこのことを利用して、リスト3のように、アルゴリズムが変更されました。



 リスト3 今日の CurrentExecutionLevel のアルゴリズム。

if ネイティブハードウェア割り込み中の場合...
  return kHardwareInterruptLevel
else 二次割り込み中の場合は...
  return kSecondaryInterruptLevel
else
  if 割り込み depth がゼロの場合は...
    return kTaskLevel
  else
    return kHardwareInterruptLevel
  end if 
end if



結論として、CurrentExecutionLevel は最近のシステムで正しい実行レベルを返しますが、古いシステム(すべての ROM-in-RAM でないシステム)は古いアルゴリズムが使われているため、これらのシステムでは正しい値を返しませんので、CurrentExecutionLevel は一般的な解決方法ではありません。



註:
あるシステムで CurrentExecutionLevel のどのバージョンが実装されているか、調べる方法はありますが、複雑です。新しい CurrentExecutionLevel を含むシステムが最初に出荷されたのは、Mac OS 9.0.4 と一緒でしたが、実際の変更は System ファイルではなく、Mac OS ROM(NewWorld ROM)ファイルの中です。詳しくは最後のダウンロードをご覧下さい。



TaskLevel

Mac OS 9.0 は新しいシステムコール TaskLevel を提供しています。これは主にデバッグの手助けが目的なので、"Debugging.h" で定義されています。また、ライブラリは DebugLib に入っています。関数と定数の定義はリスト4の通りです。



 リスト4 TaskLevel の関数と定数の定義。

enum {
    k68kInterruptLevelMask      = 0x00000007,
    kInVBLTaskMask              = 0x00000010,
    kInDeferredTaskMask         = 0x00000020,
    kInSecondaryIntHandlerMask  = 0x00000040
};
                           
extern pascal UInt32 TaskLevel(void);



WARNING:
TaskLevel の結果はおおよそ正しいですが、デバッグ以外の目的(ファイルを同期的に読むか、非同期に読むか判断する)には使用しないで下さい。



TaskLevel の目的は、不正に呼ばれた場合に、それを感知して、デバッグできるためです。例えば、システムヒープ内にメモリを確保するようなドライバを書いている場合、それはシステムタスク(System Task)レベルのみで実行できるものですが、TaskLevel を使えば、誤って割り込み時に呼ばれた場合は、それを感知して、必要な処理をすることができます。詳細についてはリスト5をご覧下さい。



 リスト5 TaskLevel のデバッグ例

static DrvQElPtr MyCreateDriveQueueElement(DeviceIdent id)
{
    DrvQElPtr result;
                           
    assert(TaskLevel() == 0);
                           
    result = (DrvQElPtr) NewPtrSysClear(sizeof(MyDrvQEl));
    if (result != nil) {
        ... フィールドを記入 ...
    }
                           
    return result;
}


トップに戻る

割り込み時にしてはならないこと

割り込み時に実行するコードはシステムタスク(System Task)に実行するコードと比較して、様々な制限事項があります。割り込み時に実行するコードは以下のことをしてはいけません。以下に従わない割り込みルーチンはシステムクラッシュを起こす可能性があります。

  • 割り込みルーチンは Mac OS Memory Manager を使って、メモリを割り当てたり、移動したり、パージしてはいけません。
  • 割り込みルーチンはロックされていないハンドルの状態に頼ってはいけません。
  • 割り込みルーチンはローメモリのグローバル変数 MemErr を変更する Memory Manager ルーチンを呼び出してはいけません。
  • 割り込みルーチンは上記のルールに従わない Mac OS ルーチンを呼び出してはいけません。
  • 割り込みルーチンは同期的な I/O を行ってはいけません。これは File Manager、Device Manager、PPC Toolbox、Open Transport を含みます。
  • 割り込みルーチンは、68K コードの場合、アプリケーションの A5 領域を正しく設定しない限り、アプリケーションのグローバル変数を利用することができません。このテクニックは Inside Macintosh: MemoryAccessing Application Globals in a VBL Task で説明されています。
  • 割り込みルーチンは、68K コードの場合、異なるコードセグメントのコードを実行してはいけません。ただし、そのコードセグメントがメモリにロードされており、ジャンプテーブルが正しく初期化されて、しかも A5 領域が正しく設定されている場合に限り、実行することができます。
  • 上記に関連する注意事項として、Inside Macintosh で定義されている一部のシステムコール(BitAnd、HiWord など)はプログラムに static リンクされる glue コードです。このコードは異なるセグメントに存在する可能性がありますので、システムコールがメモリを移動させなくても、呼び出す行為自体がメモリを移動させる可能性があります。
  • 割り込みルーチンは、CFM-68K コードの場合、テクニカルノート 1084: Running CFM-68K Code at Interrupt Time: Is Your Code at Risk? に記述されている条件を満たさなければなりません。

トップに戻る

 

割り込み時に呼び出し可能なルーチン(マネージャ)

このでは、割り込み時に呼び出し可能なルーチンをマネージャごとに集めています。



重要:
ここでは、割り込み時に呼び出して安全だと保証されているルーチンを紹介しています。ここで紹介されていないルーチンの中には、割り込み時に使える場合があります。しかし、ここで紹介されていないルーチンは将来のシステムやサードパーティのパッチによって、予告なく変更される場合がありますので、割り込み時に呼び出さないで下さい。



Memory Manager

一般的には、よく使用される Memory Manager コールのうち、割り込み時に安全に呼び出せるものはほとんどありません。主要な例外は BlockMove(BlockMoveData などを含む)と StripAddress です。これらのコールは割り込み時でも、実行レベルに関わらず、安全に使用することができます。割り込み時には、直接/間接を問わず、メモリの割り当て、移動、パージはできません。また、ロックされていないハンドルを有効なものと仮定してもいけません。

Inside Macintosh: Memory に書かれているシステムコールのうち安全なものもあります。デバッガコールはすべて割り込み時でも安全です。これには、DebuggerEnter、DebuggerExit、DebuggerGetMax、DebuggerLockMemory、DebuggerPoll、PageFaultFatal、DebuggerUnlockMemory が含まれます。SwapMMUMode と Translate24to32 は割り込み時に呼び出してもかまいません。

Virtual Memory Manager 関数 GetPageState、GetPhysical、DeferUserFN、UnholdMemory、UnlockMemory は割り込み時でも安全です。

Virtual Memory Manager 関数 HoldMemory、LockMemory、LockMemoryContiguous、LockMemoryForOutput はページフォルトが発生しても良いのであれば、呼び出すことができます。また、ページフォルトが発生しないことが確約できれば、呼び出しても構いません。例えば、物理的メモリ内にあることが保証できるメモリに対しては LockMemory を呼び出すことができます。

他の Memory Manager 関数は、以下の理由により、安全ではありません。

  1. ローメモリのグローバル変数 MemErr を変更します。MemErr は MemError が返す値ですが、アプリケーションは常に MemError を見ることで、事前に行った作業の結果を知ります。MemErr が割り込み中に変更されてしまっては、正しい結果を得ることができません。
  2. メモリを割り当て、移動、パージします。はできません。また、ロックされていないハンドルを有効なものと仮定しています。
  3. 割り込み時に内容が定義されていないデータ構造を参照しています。


重要:
一部のデベロッパは、MemErr の値を保存して、後で元に戻せば、DisposeHandle のようにメモリを移動させない関数を呼び出しても大丈夫だと思われるかもしれませんが、上記の3つ目の理由により、これはできません



割り込み時には StackSpace を呼び出してはいけません。StackSpace は、現在のプロセスのローメモリの 2 つのグローバル変数を比較します。割り込み時には、有効なプロセス内にいることさえ保証されていません。残念なことに、StackSpace は、Memory Manager の MemError が返す、ローメモリのグローバル変数 MemErr を変更します。多くのアプリケーションは MemErr 依存しますので、割り込み中に変更されることは誤動作の原因となります。



註:
残念なことに、割り込み時に StackSpace を呼び出すソフトウェアが世の中に出回っています。さらに残念なことに、アップルが出荷したソフトウェアも含まれています。

アップルでは、このようなバグをすべてシステムから排除するよう努力しています。DTS では MemError の返す値を引き続き信じるよう、推奨しています。しかし、疑い深いデベロッパは以下のようなラッパー関数を用意することで、この問題を回避できます。

static OSErr MyNewHandle(Size byteCount, Handle *result)
{
    OSErr err;
 
    Assert(result != nil);
    err = noErr;
    *result = NewHandle(byteCount);
    if (*result == nil) {
        err = MemError();
        Assert(err != noErr);
        if (err == noErr) {
            err = memFullErr;
        }
    }
    return err;
}



Operating System Utilities

Enqueue と Dequeue は割り込み時でも安全です。いつ呼び出してもかまいません。FormatRecToString(以前は Format2Str)、StringToExtended(以前は FormatX2Str)、ExtendedToString(以前は FormatStr2X)も安全です。



註:
割り込み時には ReadLocation を呼び出さないでください。ReadLocation は、文書化されていない ReadXPRAM を使って、パラメータ RAM から情報を取得します。Macintosh コンピュータの中には、割り込み経由でパラメータ RAM と通信するものがあります。ReadXPRAM や ReadXPRAM を呼び出すルーチンを割り込み時に呼び出すと、システムをハングさせる場合があります。



Device Manager

Device Manager の主要トラップ(_Open、_Read、_Write、_Control、_Status、_Close)は呼び出しても安全な場合があります。一部のトラップ(_Open、_Read、_Write、_Close)は File Manager と共有されていますが、各々の動作は以下のように若干異なります。

  • 同期的に呼び出す関数は使えません。
  • 非同期的に呼び出す関数は、使用可能な状態であれば、割り込み時に呼び出しても安全です。
  • Immediate 関数は割り込み時に使用できますが、受け取り側のドライバも割り込み時に immediate リクエストを受け取る用意が必要です。ファイルについては immediate 関数は使えません。
  • デベイスドライバのオープン/クローズは必ずシステムタスク(System Task)から OpenDriver と CloseDriver 使用します。
  • ファイルを開く時は必ず OpenDF 系の関数(FSpOpenDF、PBOpenDF、PBHOpenDF)を使用します。これらの関数の非同期バージョンは割り込み時に使用可能です。
  • その他の Open 系の関数の非同期バージョン(PBOpen、PBHOpen)はファイルを開く時に、割り込み時でも有効ですが、注意が必要です。例えば、“.Sony”と言うファイルを開こうとすると、間違ってフロッピードライブのデバイスドライバを開くことになってしまいます。

Device Manager と共有されない File Manager 関数については File Manager をご覧下さい。

上記の Device Manager トラップをパッチする場合、割り込み時のリクエストも正しく処理しなければなりません。トラップが同期的に呼ばれたと判断できない場合は、割り込み時にしてはいけないことを避けなければなりません。

デバイスドライバは3種類のリクエスト(同期、非同期、immediate)を処理しなければなりません。非同期的に呼ばれることをサポートするドライバは、同期的に呼ばれた場合も、非同期的に呼ばれた場合も、非同期的に処理を行い、割り込み時にしてはいけないことを避けなければなりません。この点はテクニカルノート 1067: Traditional Device Drivers: Sync or Swim で詳しく解説されています。一方、immediate なリクエストは呼ばれた時の実行レベルで処理されますので、クライエント側がシステムタスク(System Task)時にしか呼び出さないとわかっている場合は、システムタスク時であると仮定することは構いません。

最後の点に関連しますが、accRun コントロールルーチンは常にシステムタスク(System Task)時に呼ばれますので、accRun についてはメモリの移動、パージなどが許されます。

File Manager

File Manager への非同期呼び出しは割り込み時でも安全です。例えば、PBOpenDFAsync は割り込み時に呼び出して構いません。

File System Manager

File System Manager の関数 GetFSInfo と SetFSInfo は割り込み時でも安全です。その他の File System Manager 関数(InstallFS、RemoveFS、InformFSM、InformFFS)は安全ではありません。

File System Manager のプラグインは割り込み時であると仮定して実行する必要があります。そして、File System Manager に別途記述がない限り、このテクニカルノートの内容に従う必要があります。UTAllocateVCB と UTDisposeVCB は割り込み時に呼び出しても安全ではありません。その他の File System Manager ユーティリティ関数(UTCacheReadIP など)は安全ですが、環境による制約があります。

Driver Services

ネイティブドライバサービスライブラリ(DriverServicesLib)は多くの安全な関数を提供しています。これらの関数の呼ばれる実行レベルは Designing PCI Cards and Drivers for Power Macintosh Computers の 283 ページにあるテーブル 9-2 で定義されています。

このテーブルを読むにあたって、以下の注意事項があります。

  • “Software interrupt level”と明記されている行は二次割り込みレベルのことです。
  • “Hardware interrupt level”と明記されている行はネイティブハードウェア割り込みレベルのことです。
  • メモリを割り当てるような関数はタスクレベルで実行しなければなりません。また、その下の実行環境もシステムタスク(System Task)レベルでなければなりません。
  • ネイティブハードウェア割り込みから呼び出し可能な関数はハードウェア割り込みレベルからも呼び出し可能です。

PrepareMemoryForIO で有効な実行レベルは テクニカル Q&A DV 32: PrepareMemoryForIO and Execution Levels で定義されています。

従来のネットワーク関数

従来の AppleTalk は、デバイスドライバの集まりとして実装されているため、非同期呼び出しであれば、割り込み時に呼び出すことが可能です。

MacTCP は 2 つの部分に分割されました。TCP、UDP、ICMP をサポートするコア部分はデバイスドライバとして実装されています。非同期呼び出しであれば、割り込み時に呼び出すことが可能です。

Domain Name Resolver (DNR) は glue コードとして実装されており、割り込み時に呼び出せません。MacTCP では、StrToAddr、AddrToName、HInfo、MXInfo は割り込み時でも安全です。しかし、これらのコールは Open Transport TCP/IP では、はじめて呼び出されるのが割り込み時だと、呼び出しはすべて失敗します。これらのコールは割り込み時に呼び出さない方が良いでしょう。

Open Transport

Inside Macintosh: Networking with Open Transport の最新版は、実行レベルごとに使用できる関数が詳しく掲載されています。

Power Manager

スリープキューエントリのインストールおよび削除(SleepQInstall や SleepQRemove を使用する場合)は割り込み時でも安全です。BatteryStatus と SetWUTime も安全です。



註:
一部の場合、スリープキューエントリが前面プロセスのない状態で呼ばれる場合があります。つまり、スリープキューエントリ内からユーザインタフェースを表示することは危険です。たとえば、PowerBook Duo や PowerBook の一部の機種では、ふたについたスリープスイッチを、Process Manager のパッチがプロセスの切り替えの最中に検出する場合があります。ここで ModalDialog のようなルーチンを呼び出すと、前面プロセスが存在ないため、Process Manager はダイアログ用のイベントを送ることができません。モーダルダイアログフィルタは何もイベントを受け取れないため、ハングしてしまいます。



Notification Manager

NMInstall および NMRemove は割り込み時でも呼び出せます。



註:
通知への応答プロシージャ(notification response procedure)は、システムタスク時に呼び出されるので、ほとんどの処理は安全に行えます。しかし、前面プロセスのコンテキストで動作するため、ユーザとの対話はむずかしいでしょう。



Desktop Manager

すべての非同期呼び出しは安全です。例えば、PBDTAddAPPLAsync などは割り込み時でも呼び出せます。

Gestalt

Gestalt を割り込み時に呼び出すことに関して、Inside Macintosh: Operating System Utilities は次のように述べています。

When passed one of the Apple-defined selector codes, the Gestalt function does not move or purge memory and therefore may be called at any time, even at interrupt time. However, selector functions associated with non-Apple selector codes might move or purge memory, and third-party software can alter the Apple-defined selector functions.

これは基本的に正しいですが、以下の注意点があります。

  1. アップルが定義する Gestalt セレクタはすべてが安全ではありません。しかも、どのセレクタが安全かを知る確実な方法はありません。
  2. Mac OS 8.5 以前のシステムでは、Gestalt Manager は Gestalt テーブルを拡張する際に割り込み時に安全ではないことをしていました。この問題のため、Gestalt は理論的に安全ではありません。しかし、Gestalt テーブルは実際には、ほとんど拡張されることがありません。また、アップルではこの問題に遭遇したことはありません。

要約すると、

  • 新規コードを書く時は、割り込み時に Gestalt を使わない
  • 古いコードのメンテナンスやバージョンアップを行う際は Gestalt を使わないように変更する

アップルでは、このことだけのためにバージョンアップをするほどの問題ではないと考えています。

Sound Manager

MACEVersion、SndGetSysBeepState、SndManagerStatus、SndPauseFilePlay、SndSetSysBeepState、SndSoundManagerVersion はすべて割り込み時に使用可能です。

SndDoImmediate と SndDoCommand は割り込み時に安全なコマンドなら、安全です。具体的に言うと、bufferCmd はサウンドの出力チャンネルが初期化されるので、安全ではありません。サウンドの出力チャンネルの初期化は、サウンドの形式が次のバッファで変わってしまう場合に発生します。(つまり、サウンドがモノラルからステレオに変わった時やその逆、サウンドが8ビットから16ビットに変わった時やその逆、サウンドの圧縮形式が変わった時やその逆。)

1つの例外を除き、割り込み時にサウンドの再生を開始することはできません。しかし、割り込み時にサウンドの継続をすることは安全です。例外とは、タスクレベルで soundCmd を使って、サウンドチャンネルの準備を事前に行った場合です。



重要:
SysBeep は一覧にありません。SysBeep はメモリの転送や割り当てを行う場合があります。割り込み時には SysBeep を呼び出してはいけません。



Process Manager

GetFrontProcess、GetCurrentProcess、GetNextProcess、SameProcess、WakeUpProcess は割り込み時でも安全です。

Multiprocessing Services

既存の技術文献(Adding Multitasking to Applications Using Multiprocessing Services, version 2.1)では、MPCurrentTaskID、MPYield、UpTime、MPSignalSemaphore、MPSetEvent、MPNotifyQueue が安全であると記述されています。



重要:
MPNotifyQueue は予め MPSetQueueReserve でキューに領域を確保した場合のみ、安全です。



MPTaskIsPreemptive、MPBlockCopy、MPBlockClear、MPDataToCode は技術文献に含まれていませんが、割り込み時に呼び出しても安全です。技術文献はこれらの関数を加えるよう、改正される予定(2456896)です。

Time Manager

InsTime、InsXTime、PrimeTime、RmvTime は割り込み時に実行できます。

Process to Process Communications Toolbox

非同期で実行されるすべての PPC Toolbox 関数は割り込み時に実行できます。

Communications Toolbox

Connection Manager ルーチン CMRead、CMWrite、CMStatus は割り込み時に使えますが、その他の Connection Manager、Terminal Manager、File Transfer Manager、Communications Resource Manager、Communications Toolbox Utilities のルーチンは安全ではありません。

Deferred Task Manager

遅延タスク(Deferred task)のインストールは DTInstall によって、割り込み時でも行えます。遅延タスクは割り込み時に実行し、割り込み時にしてはならないことに従わなければなりません。

Vertical Retrace Manager

SlotVInstall、VRemove、SlotVRemove、AttachVBL、DoVBLTask、GetVBLQHdr はすべて割り込み時に利用できます。

ライブラリ

SetupA5、SetupA4、SetCurrentA5、SetCurrentA4 は安全ですが、、そのセグメントがロードされていることが条件です。開発環境によって生成されているコードを確認した上で使用して下さい。

PLStringFuncs.h に含まれている関数はすべて安全ですが、そのセグメントがロードされていることが条件です。

パッケージ

割り込み時にはパッケージとして実装されているルーチン(List Manager、Disk Initialization、Standard File、SANE、International Utilities、Apple Event Manager、PPC Browser、Edition Manager、Color Picker、Database Access Manager、Help Manager、Picture Utilities)を呼び出してはいけません。そのパッケージはメモリ上にないかもしれないので、パッケージに含まれるルーチンはすべて割り込み時には安全ではありません。

Component Manager

コンポーネントのオープンとクローズは割り込み時にできません。しかし、多くのコンポーネント内のルーチンは割り込み時に呼び出しても安全です。実状はコンポーネントのによりますので、詳細についてはコンポーネントの技術情報をご覧下さい。

Event Manager

Event Manager の中で、唯一使える関数は PostEvent と PPostEvent です。その他の関数(OSEventAvail、TickCount、GetKeys を含む)は安全ではありません。



重要:
TickCount と GetKeys は安全ではありません。これは Inside Macintosh I の 261 ページに記述されている Journaling Mechanism をサポートしていることが原因です。Journaling Mechanism はもう存在しませんが、サードパーティのソフトウェアがこれらの関数をパッチしていることがあります。

OSEventAvail はヘルプマネージャのためのパッチ以来、System 7.0 以降は安全ではありません。これはヘルプマネージャのバグとも言えますが、ここまでくれば OSEventAvail は安全ではありません。

割り込み時に実行するコードを書く場合はテーブル1のルーチンをかわりに使って下さい。

 テーブル1 TickCount と GetKeys のかわりに、割り込み時に使えるルーチン

関数名

従来の Mac OS

Carbon

TickCount

LMGetTicks

TickCount [1]

GetKeys (モディファイアのみ)

KeyMap ($174) [3]

GetCurrentKeyModifiers

GetKeys (other keys)

KeyMap ($174) [3]

none/GetKeys [2]

 註:

  1. Carbon を使って、従来の Mac OS で TickCount を呼び出す場合は LMGetTicks が直接呼ばれますので、割り込み時に呼ぶことは安全です。
  2. GetKeys は Carbon 1.1 以降に限り、従来の Mac OS で割り込み時に利用できます。Mac OS X では常に安全です。
  3. KeyMap は GetKeys の返すデータが保存されているローメモリグローバル変数($174)です。


QuickDraw

QuickDraw 関数は基本的に割り込み時に使えません。例外は SetCursor です。SetCursor をパッチする場合は、パッチが割り込み時に呼ばれても安全であることを保証しなければなりません。



重要:
SetCCursor は割り込み時に使えません。まず、SetCCursor が参照するデータ構造 CCrsr はロックされていないハンドルを含みます。さらに、多くのサードパーティ製品は SetCCursor をパッチしていますが、多くのパッチは割り込み時に呼び出すことができません。

アップルでは、割り込み時に呼ばれてもいいような SetCCursor 関数の必要性は理解しています。現在、実現方法を検討しています。



SetRect、Random のように単純な関数でも安全ではありません。割り込み時に呼び出してはいけません。

Text Utilities

EqualString と RelString(_CmpString($A03C)と _RelString($A050)トラップが元になっている他の関数を含む)は割り込み時に呼び出すことが可能です。この関数は Mac OS(File Manager や旧 AppleTalk スタック)で使われているので、安全です。



重要:
EqualString と RelString はスクリプトや言語情報を適応しないので、ユーザの目に触れるような文字列に使ってはいけません。ユーザの目に触れるような文字列の比較には "StringOrder.h" で定義されている関数(IdenticalString、CompareString、StringOrder など)をご使用下さい。ただし、これらは割り込み時には使用できません。



註:
EqualString と RelString は以下の文字列を比較するために使います。

  • File Manager が返すファイル名(ただし、HFS と同じ並び順を実現したい場合のみ)
  • リソース名
  • AppleTalk NBP エンティティ名、タイプ名、ゾーン名

Unicode Converter

制限付きですが、Unicode Converter を割り込み時に呼び出すことが可能です。このように Unicode Converter を呼び出す必要がある場合は DTS にご連絡下さい。

トップに戻る

 

割り込み時に呼び出し可能なルーチン

表1は割り込み時に呼び出し可能なルーチンです。アスタリスク(*)が付いたルーチンは、使用に際して何らかの制約があります。詳細はこのテクニカルノートの本文を参照してください。


表1 割り込み時に呼び出し可能なルーチン


AddrToName *
AttachVBL
BatteryStatus
BlockMove
PBControlAsync
CMRead
CMStatus
CMWrite
DebuggerEnter
DebuggerExit
DebuggerGetMax
DebuggerLockMemory
DebuggerPoll
DebuggerUnlockMemory
DeferUserFN
Dequeue
DoVBLTask
Enqueue
EqualString
ExtendedToString
Format2Str
FormatRecToString
FormatStr2X
FormatX2Str
GetCurrentProcess
GetFrontProcess
GetFSInfo
GetNextProcess
GetPageState
GetPhysical
GetVBLQHdr
HInfo *
HoldMemory *
InsTime
InsXTime
LockMemory *
LockMemoryContiguous *
LockMemoryForOutput *
MACEVersion
MPBlockClear
MPBlockCopy
MPCurrentTaskID
MPDataToCode
MPNotifyQueue *
MPSetEvent
MPSignalSemaphore
MPTaskIsPreemptive
MPYield
MXInfo *
NMInstall
NMRemove
         Open Transport 関数 *
PBAllocContigAsync
PBAllocateAsync
PBCatMoveAsync
PBCatSearchAsync
PBCloseAsync *
PBCloseWDAsync
PBControlAsync
PBControlImmed *
PBCreateAsync
PBCreateFileIDRefAsync
PBDTAddAPPLAsync
PBDTAddIconAsync
PBDTDeleteAsync
PBDTFlushAsync
PBDTGetAPPLAsync
PBDTGetCommentAsync
PBDTGetIconAsync
PBDTGetIconInfoAsync
PBDTGetInfoAsync
PBDTRemoveAPPLAsync
PBDTRemoveCommentAsync
PBDTResetAsync
PBDTSetCommentAsync
PBDeleteAsync
PBDeleteFileIDRefAsync
PBDirCreateAsync
PBExchangeFilesAsync
PBFlushFileAsync
PBFlushVolAsync
PBGetAltAccessAsync
PBGetCatInfoAsync
PBGetEOFAsync
PBGetFCBInfoAsync
PBGetFInfoAsync
PBGetFPosAsync
PBGetForeignPrivsAsync
PBGetUGEntryAsync
PBGetVInfoAsync
PBGetVolAsync
PBGetWDInfoAsync
PBGetXCatInfoAsync
PBHCopyFileAsync
PBHCreateAsync
PBHDeleteAsync
PBHGetDirAccessAsync
PBHGetFInfoAsync
PBHGetLogInInfoAsync
PBHGetVInfoAsync
PBHGetVolAsync
PBHGetVolParmsAsync
PBHMapIDAsync
PBHMapNameAsync
PBHMoveRenameAsync
PBHOpenAsync *
PBHOpenDFAsync
PBHOpenDenyAsync
PBHOpenRFAsync
PBHOpenRFDenyAsync
PBHRenameAsync
PBHRstFLockAsync
PBHSetDirAccessAsync
PBHSetFInfoAsync
PBHSetFLockAsync
PBHSetVolAsync
PBLockRangeAsync
PBMakeFSSpecAsync
PBOpenAsync *
PBOpenDFAsync
PBOpenRFAsync
PBOpenWDAsync
PBReadAsync
PBReadImmed *
PBRenameAsync
PBResolveFileIDRefAsync
PBRstFLockAsync
PBSetAltAccessAsync
PBSetCatInfoAsync
PBSetEOFAsync
PBSetFInfoAsync
PBSetFLockAsync
PBSetFPosAsync
PBSetFVersAsync
PBSetForeignPrivsAsync
PBSetVInfoAsync
PBSetVolAsync
PBStatusAsync
PBStatusImmed *
PBShareAsync
PBUnlockRangeAsync
PBUnshareAsync
PBWriteAsync
PBWriteImmed *
PBXGetVolInfoAsync
PageFaultFatal
PostEvent
PPostEvent
PrimeTime
RelString
RmvTime
SameProcess
SetCursor
SetFSInfo
SetWUTime
SleepQInstall
SleepQRemove
SlotVInstall
SlotVRemove
SndDoCommand *
SndGetSysBeepState
SndManagerStatus
SndPauseFilePlay
SndSetSysBeepState
SndSoundManagerVersion
PBStatusAsync
StrToAddr *
StringToExtended
StripAddress
SwapMMUMode
Translate24to32
UnholdMemory
UnlockMemory
UpTime
UTAllocateFCB
UTReleaseFCB
UTLocateFCB
UTLocateNextFCB
UTIndexFCB
UTResolveFCB
UTAddNewVCB
UTLocateVCBByRefNum
UTLocateVCBByName
UTLocateNextVCB
UTAllocateWDCB
UTReleaseWDCB
UTResolveWDCB
UTFindDrive
UTAdjustEOF
UTSetDefaultVol
UTGetDefaultVol
UTEjectVol
UTCheckWDRefNum
UTCheckFileRefNum
UTCheckVolRefNum
UTCheckPermission
UTCheckVolOffline
UTCheckVolModifiable
UTCheckFileModifiable
UTCheckDirBusy
UTParsePathname
UTGetPathComponentName
UTDetermineVol
UTGetBlock
UTReleaseBlock
UTFlushCache
UTMarkDirty
UTTrashVolBlocks
UTTrashFileBlocks
UTTrashBlocks
UTCacheReadIP
UTCacheWriteIP
UTBlockInFQHashP
UTVolCacheReadIP
UTVolCacheWriteIP
VRemove
WakeUpProcess


参考文献

Inside Macintosh: Memory

File System Manager SDK

Designing PCI Cards and Drivers for Power Macintosh Computers

Technote 1033: "Interrupts in Need of (a Good) Time"

Technote 1067: "Traditional Device Drivers: Sync or Swim"

Technote 1084: "Running CFM-68K Code at Interrupt Time: Is Your Code at Risk"

Technote 1094: "Virtual Memory Application Compatibility".

Technote ME 09: "Coping with VM and Memory Mappings

トップに戻る

 

変更暦



1998年2月

初版

1998年7月

以下の部分を追加/更新

1999年11月

Event Manager に OSEventAvail を追加しましたが、以後の変更でこれは撤回されました。

1999年12月

Text Utilities を追加しました。

2000年1月

Unicode Converter を追加しました。また、OSEventAvail の記述を更新(2418891)しました。

2000年2月

Communications Toolbox を追加しました。

2000年4月

Multiprocessing Services を追加しました。

2000年10月

実行レベルの取得方法を追加しました。Event Manager のところを更新し、GetKeys が CarbonLib 1.1 以降に限り、割り込み時に呼び出しても安全であるとの記述を加えました。



トップに戻る



ダウンロード

実行レベル(CurrentExecutionLevel)の取得方法サンプルコード

Download

 

トップに戻る

Choose your language: