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

spacer image

Technote 1069

System 7.5.5

内容

System 7.5.5の特徴について

将来のシステムソフトウェアのサポートについて

System 7.5.4に何が起こったのか?

System 7.5.5の判別
System 7.5.5は、Virtual Memory Managerの変更やCode Fragment Managerに対する何点かの本質的な改善、そして、その他さまざまな拡張や改善を含んでいます。AppleはこのアップデートをSystem 7.5.3が動作しているすべての機種に対して推奨します。System 7.5.5は、System 7.5.3(とそのいくつかのリビジョン)が動作しているすべてのMacintoshとMac OS互換のコンピュータにのみインストール可能です。もしそれ以前のシステムソフトウェアで動作している場合、System 7.5.5をインストールする前にSystem 7.5.3にアップグレードする必要があります。



System 7.5.5の特徴について

Virtual Memory
System 7.5.5では、仮想記憶をサポートしている全機種に対して、Virtual Memory Managerの一部が書き直されました。仮想記憶使用時のパフォーマンスを大幅に改善する必要があったからです。現在搭載されている仮想記憶と比較した場合、システムのブートがより速くなり、Power Macintoshアプリケーションの起動が速くなり、QuickTimeムービーはよりスムーズに再生されるようになります。以下のセクションでは、VMの新たな機能について説明します。

VMのパフォーマンスに関する問題
System 7.5.5では、ページのエイジング(aging)アルゴリズムが改善されています。

従来のシステムでは、ページフォルトが8回発生する毎に物理メモリのページをエイジングし、「犠牲者」リスト("victim" list、それ以降8回のページフォルトでページアウトされるページのリスト)に追加していました。この機能は、RAMを48MB搭載したPower Macintosh 7500で46ミリ秒かかっていました。
System 7.5.5では、この機能に用いているアルゴリズムを、よりシンプルで高速なものに変更しました。新しいアルゴリズムは、すべての物理ページに対して1回しか参照しないので、最悪の場合でも従来のアルゴリズムと同等のパフォーマンスとなります。これにより、ページフォルト8回毎に発生していた中断(pause)は解消されました。

ページをディスクに書き込む動作は仮想記憶ページを「変更済み」(dirty)とマークするので、書き込みが複数回行われます。

「変更済み」論理ページをページングする場合、仮想メモリのオプティマイザはバッキング・ストア・ファイル中にさらに6ページ分の連続したページを探し、それらのページを「変更無し」(clean)とマークし、一回のwrite要求でディスクに書き出します。ある「変更済み」論理ページに近接している「変更済み」論理ページはほぼ同様にエイジングされているはずであり、したがって、それらはすぐにページングされることが予測されます。そのため、この最適化はその後に行われるページフォルトを高速にします。

しかしながら、LockMemoryはロックされたページをすべて「変更済み」とマークしてしまい、また、LockMemoryはDMA入出力機器からデータが書き込まれるページに対しても実行されるので、「変更無し」のページも「変更済み」とマークされてしまいます。その結果、仮想記憶のバッキング・ストア・ファイルをI/Oトレーサーで見たとすると、本来「7ページ書き出し、1ページ読み込み、1ページ読み込み、1ページ読み込み、1ページ読み込み、1ページ読み込み、1ページ読み込み、1ページ読み込み、7ページ書き出し、1ページ読み込み...」となるべきところが、「7ページ書き出し、1ページ読み込み、7ページ書き出し、1ページ読み込み」というようになるでしょう。

新たに追加されたVM APIコール
LockMemoryForOutputという新しいAPIコールが_MemoryDispatchトラップに追加されました。この新しいルーチンは、ロックされたページを「変更済み」とマークしない点以外は、LockMemoryとまったく同じ動作をします。LockMemoryForOutputは、メモリを読み出すDMA操作時に使用することを想定しています。メモリへの書き込みが行われるDMA操作には、そのページが「変更済み」とマークされることを確実にするために、LockMemoryを使用しなければなりません。LockMemoryForOutputは、_MemoryDispatchにセレクタ値10を渡すことによりコールされます。

Meomry.hには、この新しいコールのために以下のグルーコードが追加されます。

/* Lock memory for output */
#pragma parameter __D0 LockMemoryForOutput(__A0, __S1)
extern pascal OSErr LockMemoryForOutput(void *address, unsigned long count)
TWOWORDINLINE(0x700A, 0xA05C);


プログラマは、gestaltVMAttrセレクタのgestaltVMHasLockMemoryForOutputビット(bit 1)を調べることにより、LockMemoryForOutputが使用可能かどうかを判断することができます。bit 1がセットされていれば、LockMemoryForOutputは使用可能です。

VMのバグフィックス

システムの安定性の向上

System 7.5.5では、内部コールに不正なパラメータを渡したときにハングアップやクラッシュを生じるという潜在的な問題を解決しました。VMのバグのため、CFMはファイルをオープンしたままにしておいてはならないにも関わらず、オープンしたままにするということがときとしてありました。HoldMemoryLockMemory中のクラッシュを引き起こす部分が修正されました。また、いままでPowerPC版VMに施されたフィックスが68K版VMにも反映されています。 新たに2つのSysError値を追加
従来のシステムでは、VMのユーザー定義遅延関数テーブル(deferred user function table)のエントリが足りなくなると、VMは0番地から始まる低位メモリの内容を破壊してしまいました。 System 7.5.5では、NULLアドレス以降を破壊するかわりにSysErrordsVMDeferredFuncTableFull(112)を渡します。このエラーを発生させるには、いくつかの方法があります。そのうちのひとつは、すでに遅延されている(already-deferred)I/O要求を遅延させることです。もう一つの方法は、すでにインストールされているTime Managerタスクを再度インストールすることです。
VMが"VM Storage"バッキング・ストア・ファイルを読み書きしている最中に発生したエラーは無視されます。もしエラーが発生した場合、システムはしばらくしてから一件なんら関係のない問題でクラッシュするでしょう。この問題が発生した場合には、システムの実行を継続したり、回復する方法はありません。そこで、VMはページやメモリが正しくない状態のまま継続するかわりに、SysErrordsVMBadBackingStore(113)を渡します。このエラーは、バッキング・ストア・ボリュームがエラーを返したときに発生します。ディスクのI/Oエラーそのものや(genuine disk i/o errors)や、PowerBookをSCSIディスクモードで使用していたときのバッテリー切れ、バッキングストアを含んでいる外部ディスクを停止した場合等が例として挙げられます。
VM安全時に遅延されるコール
以下に挙げるシステムの部分は仮想記憶によりパッチされており、その実行はVM安全時(VM safe time)まで遅延されます。

PostEvent
Time Managerタスク
driverに対するRead、Write、ControlならびにStatusコール
VBLタスク
Slot VBLタスク
ADBOp
SCSIDispatch


Inside Macintosh:Memoryの3-11には、ページフォルトとページングデバイスが動作している間のユーザコードの遅延に関する記述があります。3-12のリストは不完全であり、現在のVMのソースをもとにした上記のリストのほうがより完全です。
ControlとStatusコール時にVMがスタックの一部をホールドすることについて
VMは、_Controlコールと_Statusコールに際して2KBのスタックを(訳注:HoldMemory()を使用して)ホールドします。この2KBのスタックは以前は_Readコールと_Writeコールの際にホールドされていました。 これらの変更は、仮想記憶を実行可能な機種(以下の機種を除くすべてのMacintosh:Macintosh Plus、SE、Classic、LC、Portable、PowerBook 100、ならびにPMMUを実装していないMacintosh II)に適用されます。

Code Fragment Manager
仮想記憶がオフで、かつ、未使用メモリが少ない状態でも、ライブラリのロードがより確実に行えるようになりました。この変更は、メモリ搭載量の少ない構成のMacintoshのエントリーモデルでメモリを多く消費するプロダクト(例えばマルチメディア・ゲーム)を実行する場合に役立つでしょう。特に、テンポラリ・メモリやシステム・ヒープに余裕がない場合には、共有ライブラリの"プライベート・コピー"はアプリケーション・ヒープに(もし余裕があれば)置かれます。Code Fragment Managerは、この"プライベート・コピー" 用の領域として、最小使用サイズと実際のメモリパーティションサイズの差以上は使用しません。

コードフラグメントをメモリに読み込む際には、ファイルシステムのキャッシュをバイパスしています(Inside Macintosh:Filesの2-95に記載されているテクニックを使用しています)。また、BlockMoveDataをさまざまな部分で使用しています。この変更により、アプリケーションのローディングがより高速になりました。

デベロッパが混乱するであろう問題は、Code Fragment ManagerがSystem 7.5.5とSystem 7.5.3以前では異なるエラーコードを返す可能性があることです。これは特に、ウィークインポート(weak import)された(Inside Macintosh:PowerPC System Softwareではsoft importと記載されています)ライブラリが見つからない場合に発生します。返されるエラーコードは、GetSharedLibraryに渡されるオプションの値に依存します。特に、cfragNoLibraryErr (-2804)とcfragLibConnErr (-2817)は、非常に似通った理由で返されます。プログラマは、それらのエラーをそのどちらが返されても期待通りの処理ができるように(interchangable)扱う必要があります。ウィークインポートされた(weakly imported)シンボルがバインドされたかどうかをチェックする際には、GetSharedLibraryが返す特定のエラーコードに依存せずに、Inside Macintosh: PowerPC System Softwareの1-25のコードを使用してください。

これらの変更は、PowerPCを搭載したすべてのMacintoshに適用されます。このリリースに含まれる68K版Code Fragment Managerにはなんら変更はありません。

Modern Memory Manager
System 7.5.5以前では、メモリを確保する場合に小さな負数を指定すると、アプリケーションはタイプ11のエラーでクラッシュしました。Modern Memory Managerの内部では、あるローカル変数がsigned longからunsigned longに変更されており、また、大きな正数から小さな負数へのオーバーフローのチェックが行われています。この変更は、PowerPCを搭載したすべてのMacintoshに影響します。

Background-Only Application
System 7.5.5以前では、2つ(もしくはそれ以上)のBOAが起動されており、そのどちらもがMaxApplZoneを実行している場合、システムがハングアップしました。理由は、Process Managerがプロセス・ステートの保存とリストアを正しく行っていなかったためです(これは、Technote PS 2, "Background Only Applications."(訳注:実際にはTechnote 1070)に記載されているバグです)。このバグは、フェイスレス・バックグラウンド・アプリケーション(faceless background application)が登場したときから存在していました。System 7.5.5では、それぞれのアプリケーションのプロセス・ステートは正しく保存/リストアされます。これは、すべての機種に影響します。

フロッピーディスクの挿入と非同期I/Oに関するバグ
Macintosh 6100、7100および8100において、ファイルシステムに対して非同期のアクセスが行われている最中にフロッピーディスクが挿入されると、マシンはハングアップしました。これは、ファイルシステムの動作に関する実験が行われている間にROMが最終版となり、それにより内部ルーチンが正しく動作しなかったためです。System 7.5.5では、6100/7100/8100のROMをアップデートするために、パッチがあてられています。この修正は、それら3機種のすべてのクロックスピードのマシンに適用されます。

フロッピーディスクのフォーマッティング
高速な機種(180MHz以上で動作する604eを搭載)では、ヘッドが反対の面に移動するのをコードが待たなかったため、ときとしてフロッピーディスクのフォーマッティングに失敗しました。それにより、裏面がフォーマットされないままでした。System 7.5.5ではフロッピーディスクをフォーマッティングするルーチンのタイミングが変更されており、フロッピーディスクは正常にフォーマッティングされます。いくつかの機種に対して"PowerMac Format Patch"という機能拡張ファイルが提供されていますが、これはまったく同じ動作をするものです。System 7.5.5のインストーラは、その機能拡張ファイルを見つけるとそれを削除します(この機能拡張は、System 7.5.5以降ではそのコードをインストールしません)。

エミュレータのキャッシュフラッシュに関するバグ
存在しないメモリレンジをフラッシュする要求がエミュレータに対してなされた場合、エミュレータは無限ループに陥りました。System 7.5.5では、フラッシュすべきレンジをチェックし、もし不正なアドレスが指定された場合には何もしないように変更されています。この変更は、PowerBook 5300、2300そしてPCIバスを搭載したデスクトップ型Macintoshに対して行われています。

CalcCMask
CalcCMaskでカラー探索プロシージャ(search proc)が実行されるとその結果のビットマスクがランダムに左にシフトされ、エッジがぎざぎざに(jagged edge)なってしまいました。このシフト効果は、QuickDrawの内部マクロのロジックエラーによるものでした。このマクロは、転送先のピクセル深度が1ビットの場合に間違ったマスク値を(0 / 1であるべきところを0 / 0xFFを)CalcCMaskに対して返していました。

File Managerのメモリフラッシュに関するバグ
File Managerは存在しないメモリレンジのフラッシュ要求を行っていました。先に述べたとおり、エミュレータはキャッシュフラッシュのバグを有していたため、エミュレータは無限ループに陥っていました。System 7.5.5では、その問題をフィックスするために、_GetFPos_SetFPosそして_Readにパッチがあてられています。このフィックスはPowerBook 5300、2300そしてPCIバスを搭載したデスクトップ型Macintoshに対して行われています。

赤外線リモートコントロール
赤外線リモートコントロールには、問題が2点ほどありました。リモートコントローラによりCPUの電源が投入された場合、それ以降のリモートコントローラからの命令が無視されてしまいました。通常通りキーボードからCPUの電源が投入された場合、リモートコントローラからの命令は正常に処理されます。しかし、ボリューム・アップあるいはダウンのボタンがある時間以上押し続けられると(これは、赤外線リモートコントローラからのコマンドがリピート状態になる原因です)、赤外線コマンドは動作を停止してしまいました。これは、あるパッチがいくつかの状況でインストールされなかったことに起因します。このフィックスは、赤外線リモートコントロールをサポートしているすべての機種に対して適用されます。

LocalTalk DMA
System 7.5.5では、ある条件下のMacintosh 5400/120で発生しうるデータ損壊の可能性が修正されています。この問題は、Macintosh 5400/120のファイルサーバに複数のクライアントが接続されており、同時にそのマシンがApple Remote Accessサーバで、少なくとも1つのApple Remote Accessクライアントが接続されており、かつ、そのクライアントがApple Remote Access経由でログインしている場合に発生します。大量のトラフィックが発生すると、クライアントからMacintosh 5400/120のサーバに対しての、あるいは、サーバからのファイルコピーを行う際にデータの損壊が発生することがありました。また、LocalTalk DMA 1.0が適切なハードウェア構成ではないマシンにロードされてしまう問題も修正されています。

IR Talk
System 7.5.3 Revision 2では、IR Talk用コントロールパネルとドライバーがインストールされませんでした。それにより、System 7.5.3とともに出荷され、その状態から直接System 7.5.3 Revision 2にアップグレードされたマシンに含まれるIR Talkドライバー等は、System 7.5 Update 2.0、あるいは、System 7.5 Version 7.5.3がインストールされているマシンのものと異なります。

Macintosh5400/6400のEthernet
Macintosh 5400と6400には、Ethernetそれ自身を「busy Ethernet」と宣言してしまうバグがありました。それらの機種では、パケットの損失により通信速度が低下することがあったのです。これは、特定の種類のパケットに対してより高いプライオリティが与えられるという、内部的な設定に起因するものでした。System 7.5.5では、すべてのパケットは同じプライオリティとなっています。

SCSI Manager
Virtual Memoryの項で述べたLockMemoryForOutput()が追加され、そして使用されています。

System 7.5.5では、SCSI関連の完了ルーチンが実行される割り込みレベルがレベル2からレベル1に変更されています。SCSIの完了ルーチンが割り込みレベル2で実行されると、割り込みレベルが同じくレベル2の拡張カード(ビデオ・キャプチャー・カードやサウンドカード等)のパフォーマンスを低下させました。これは、ネイティブ版のSCSI Manager 4.3が動作しているPowerPC機種に影響します。

また、MESH SCSIコントローラのいくつかのエラーが修正されています(これらは、デスクトップ型のPowerPC Macintoshで見つかりました)。REQが発行される前にACKが発行されることがありました。また、旧タイプのテープドライブから読み込みをする際にディスコネクト/リコネクトが発生するというバグがありました。さらに、MESHチップからの割り込みを間違って解釈していました。

System 7.5.5では、FastSCSIを有するPCI Macintoshの内部SCSIバスに関連する2つのバグがフィックスされました。ひとつめは、まったく同一の再接続要求を、ときとしてバスに対する新しいコマンドと間違って処理してしまうというものでした。ふたつめはMESHコントローラのバグであり、ターゲットがREQを発行する前にコマンド終了の割り込みを発生させる原因となるものです。高速なマシンでは、REQがバス上にあるにも関わらず新しいコマンドが発行されるということがありました。コントローラはこれを新しいデータと解釈し、転送を2回行っていました。この現象は、メッセージ・イン・フェーズ、非同期的なデータ・イン・フェーズそしてステータス・フェーズというような非同期的な情報入力("asynchronous in")フェーズで発生します。このバグによる結果は、通常はシステムのハングアップです。現在のシステムでは、チップに対して新しいコマンドを発行する前にREQがデバイスにより除去されるのを待つようになっています。

プリンタの共有
共有設定の利用者名が空白の状態で共有プリンタを使用した場合、"Resource Not Found"エラーが発生しプリントに失敗することがありました。これは、System 7.5 Update 2.0が共有設定で使用されていたPascal形式の空白文字列(blank Pascal string)を削除したためでした。System 7.5.5では、もし利用者名が失われている場合、空白文字列をインストールし直すようにしました。この問題は、パフォーマのユーザや利用者名を設定したことのないユーザがSystem 7.5 Update 2.0にアップグレードした場合に影響します。

PCI起動時のハングアップ
180MHz以上で動作するPCI Macには、PCIブリッジチップの初期化にバグがありました。この問題により、システム起動時にPCIバスがアクセス不能になり、その結果、システムがハングアップしました。System 7.5.5では、PCIブリッジチップの初期化処理の信頼性がより高くなっています。

割り込みサービスルーチン
割り込みサービスルーチンからぬけ出るとき、もしサービスルーチンにはいったときよりも割り込みレベルが下がっていると、割り込みレベルが正しくクリアされず、その結果、最初のプライオリティかそれ以上の割り込みが発生するまでそれ以下のプライオリティの割り込みを処理することができません。これは、PCI Macと、PowerPCアップグレードカードがインストールされているMacintoshに影響します。デベロッパーのとりうる回避策は、割り込み処理ルーチンをぬけ出るときのプライオリティレベルを、サービスルーチンにはいるときと同じ値にすることです。System 7.5.5では、デスクトップ型MacintoshとPowerPCアップグレードカードでこの現象が発生していたSound Managerの割り込みサービスルーチンを修正しました。

コントロールパネルと共有ライブラリ
この現象はSystem 7.5.5をテストしている最中に発見されました。あるサードパーティ製コントロールパネルは、MathLibとリンクされていました(おそらく、CLibとリンクされているのが原因です)。MathLibはROMに組み込まれており、MathLibのグローバル変数領域が2回確保されてしまうのです。コントロールパネルはFinderのプロセス空間で実行されるので、MathLibのグローバル変数領域は、システムヒープではなくFinderのアプリケーションヒープに確保されます。

ほとんどのマシンでは、ROM中のMathLib用グローバル変数領域とリンクされたMathLib用グローバル変数領域の22Kの合計は、Finderのアプリケーションヒープに残っている未使用領域とパージ可能領域に収まる程度に充分小さなものです。しかし、PowerMac 7500/8500/9500では、ROM中のMathLib用グローバル変数領域も22Kであり、合計44KになるMathLib用グローバル変数領域はFinderのアプリケーションヒープの大半を使ってしまい、数バイトしか残しません。その結果として、Finder上で何らかの操作を行おうとすると、"Out Of Memory"という警告が頻繁に現れます。

将来のシステムソフトウェアのサポートについて

Macintosh Plus、SE、Classic、Portable、PowerBook 100、SE FDHD、SE/30、LC、II、IIxそしてIIcxに関しては、System 7.5.5アップデートがそれらに対する最後のシステム・ソフトウェア・リリースとなります。これらの機種は32ビットアドレッシングをサポートするようには設計されていません。今後のMac OSのリリースは32ビットアドレッシングを必要とします。32ビットアドレッシングは、上記以外の機種ではサポートされています。

7.5.4に何が起こったのか?

System 7.5.4は最終版として宣言され、シードサイトへの配布が始まりました。しかし、配布を中断して変更を行わなければならない問題が発見されたのです。私たちは、異なる2つの7.5.4と格闘し事態を混乱させることを避け、バージョン番号を7.5.5と変更する決定を行いました。

7.5.4と7.5.5の相違点は以下の通りです。

  • Macintosh 5400と6400ファミリーのIR Talkの変更
  • Macintosh 5400と6400ファミリーで、VMのプリファレンスとデスクトップパターンが保存されるように変更
  • 省エネルギーコントロールパネルの細部の変更

System 7.5.5の判別

システムソフトウェアの複数のバージョンを区別するために、'sysu' Gestaltセレクタが提供されました。これは、現在インストールされているシステムアップデートのバージョン番号を、'vers'リソースと同じバージョンナンバリング形式で返します(図1参照)。

図1
'sysu'セレクタに対するGestaltのレスポンスのフォーマット


Figure1

'sysu' Gestaltセレクタにより、アプリケーションプログラムは現在インストールされているシステム・ソフトウェア・バージョンがシステムアップデートによるものかどうかを知ることができます。'sysu' Gestaltセレクタは、現在のシステムバージョンをインストールするのにシステムアップデートが使用された場合のみ定義されます。つまり、'sysu' GestaltセレクタはSystem 7.5.3があらかじめインストールされ出荷されたマシンや7.5.3以前のシステム・ソフトウェア・バージョンでは定義されていません。

'sysv'と'sysu' Gestaltの使用
以下は、'sysv'と'sysu' Gestaltセレクタを使用してSystem 7.5.5に関する情報を取得する方法を示しています。

long response, updateversion;
OSErr err;
Boolean seven_five_five;
Boolean is_an_update;

seven_five_five = false; is_an_update = false;
err = Gestalt(gestaltSystemVersion, &response); if (err == noErr) { seven_five_five = (response == 0x00000755); if (seven_five_five) { err = Gestalt('sysu', &updateversion); is_an_update = (err == noErr); } } /* この時点で、もしsystem 7.5.5が現在のオペレーティングシステムならば、 seven_five_fiveはtrueになります。また、現在のシステムバージョンが アップデートによるものであれば、is_an_updateはtrueになります。 もし、is_an_updateがtrueならば、updateversionはSystem updateの バージョン番号(7.5.5の場合、0x02068000)となっているでしょう。*/

spacer image