風邪が悪化orz orz
講義聴いてるだけなのに、
謎の全身筋肉痛w
でも、休むわけにはいかなんだ。
Eyebotは朝一で実験実にいき、
メニュー画面とかoption画面とか作成。
とりあえずはこれでプログラムは完成としよう。
さっさとレポートだ。
----- assignment -----
Operating System 2008/04/22
実践OS課題群
・プロセスのスケジューリングの中にある小さなプロセスにさらにスケジューリング機能を搭載?
・SH4aに移植(難易度:高)
・期限は最終講義日まで
・拡張機能も可
・スケジューリングのアルゴリズム変更(難易度:易)
・ある時間のときの設定を保存して、プログラムが動いたとき元に戻す。
→システムの復旧?
・メモリ内プロセスバック?
・使っていないprocessに対して、ある一定の時間がたったら勝手に圧縮するプログラム。
・終わったらレポート
----- note -----
システムコール = OSを呼び出すための関数
普通は、OSのデータ構造にはアクセスできない。
システムコールを介してのみ、アクセス可能。
Index
・カーネルの中身
・C言語の復習
-header, structについて
C言語とは
OSを作るのに適切な言語。
低水準programming
assembly言語はCPU毎にソースコードが違う
→移植するときは全部変更しなくてはいけない。
C言語の場合、大抵使いまわせる。
→移植するときの楽。
C言語には予約語が一杯ある。
→JAVAに似ているが、CLASSの概念はない。
C言語は分割しても一括してもどちらでも大丈夫。
→どの関数をどのファイルに置くかを考える必要がある。
Structure
-宣言部
-main関数
-そのほかの関数
C言語を使うときは、型のbyte数を把握する必要がある。
JAVAの"NEW"に近いallocateをするためには、
sizeof(型)をやって自分でbyte数を確保する必要がある。
・auto(自動変数)
関数内部の変数とか。
関数から出たら、解放する。
・static(静的変数)
呼び出すかどうかに関わらず、いつでも存在する。
EX:staticで大きい配列はダメ
・Register(レジスタ変数)
register上に置くので、早くなるかもしれない。
現在は、compilerが勝手にやってくれるので、
使っても無視されることがしばしばある。
・exterm(外部参照変数)
プログラムの外に変数を書く。
グローバル変数 = static変数
main()内はauto変数
関数内の変数をstaticにすると、以前使ったときの
結果が残っている。
int foo(void)
int main()
引数の数は自分で数える。
GNU gccは良いが、他のコンパイラには
引数をカウントしないものもある。
→clashしてdownする可能性がある。
・prototype宣言
int foo(int);
compilerがcheckしてくれる。
Ex:型のミス
void foo(void);
int x = foo;
---------------------------------
・C言語のsequence
C sourve(*.c)
↓
↓ preprocessor
↓
preprocessor後のsource(*.i)
↓
↓ C compiler
↓
Object file
↓ linker
↓←←←←←←library
↓
実行ファイル
・header
#include "queue.h"
↓
preprocessorがlibraryの中にある"queue.h"を
ソースファイル内に展開する。
・マクロ展開
#define MAX 10
MAXを10に置き換える
#define putchar(x) fputc(x, stdout)
xは引数としてマクロ展開する。
用途:何行も使うものをまとめるときに使う。
「何故methodにしないのか」
methodの呼び出しのために、サイクルカウント値を消費してしまい、
動作が遅くなるから。
OSでは、致命的。C言語では重要な部分。
→overflowはなるべく少なくする。
・他の記号
#include"hoge.h"
#if DEBUG == TRUE
print("value = %d\n", val);
→hoge.hが
#define DEBUG TRUEならば
print文がマクロ展開される。
→#include"hoge.h"の文があるかどうかで
実行の有無がわかる。
↓
debugに便利!
・gcc -DTEST ~~~
オプションの-DTESTがあれば
#ifdef TEST以下の文が展開
そうでなければ
#else以下の文が展開される。
用途:
#ifdef LINUX #else WINDOWS
Linux用とwindows用にわけてマクロ展開させることが可能。
・#incledeファイルの場所
→/usr/include/
or
/usr/include/sys/
and
/usr/include/linux/
・include fileのpathを指定したいとき
gcc -I/usr/local/hoge.h
・ifdef~else~endif
#ifdef MAIN
/* MAIN が #define してあったらここの部分がコンパイルされる。#define されていなかったらここの部分は無視される */
#else
/* MAIN が #define されていなかったらここの部分がコンパイルされる。#define してあったらここの部分は無視される */
#endif
・Compilerとlink
実行ファイルの中身
hm -g a.out | grep't'
00001c64 T __darmin_~~~
00001d44 T _main
0000166c T start
プログラムが実行させるときは、まず最初にstartを探す!
startの位置をprogram counterに設定する。
※start -> _mainまでに
色々と初期化している。
mainかんすを呼ぶためにlibraryの中で、
色々と初期化されている。
・動的リンク
必要になったときにlibraryを呼ぶ
複数のプログラムから同じlibraryを使う場合、
共有ライブラリにする
*.so (shared object)
・コンパイラの最適化
program -> binaryにする場合
defaultで -O2 optionが入る。
→-O3以上にしても、あまり結果は変わらない。
・library
-lnew 自分が定義したもの?
-L/usr/local/mylibs
↑このdirectoryの中から優先的に探しだしてlinkする。
・libraryを作る場合
gcc -c newlib.c
ar rcs libnew.a newlib.o
で"new"ライブラリにnewlibを追加
nm/usr/lib/libc
・静的リンク
全部取り込む
→programが大きくなりやすい!注意!
・構造体
データ構造のみを定義。
struct tag名{
type member1;
type member2;
};
struct log{
char time[10];
long ch0;
long ch1;
};
↑この場合
1 structure = 10B+4B+4B = 18B
struct log logger1, logger2;
typedef struct{
~~
~~
~~
}LOG;
↓
LOG logger1;
LOG logger2;
→structを宣言しないで済む。
typedefが主流。
・Pointer
※2000番地に10が入っているものとする。
int a;
int *p;
p=2000;
p=&a;
int *p;
int c = *p;
→integer型のpointerに10が入る。
func(&val);
→OSがCで書かれている理由の一つ
→pointer
予断:javaの場合classはcall-by-referenceになる
☆文字列の最後は必ず'0'が入っている。
"abcd"
↓
'a'+'b'+'c'+'d'+'0'
while(*str) str++;
→文字列を読み終わったら0が入る
→偽になる→while文終了
予断:NULL = 0
・配列とポインタ
&array[0] と arrayは同じ意味
++arrayとすると
array[1]から読み込まれる。
↓
データ構造の文だけincrementされるから。
→箱のサイズは気にしなくてもよい。
・character型の場合
char str[] ⇔ char *str
同じ
一般的に、*pには乗算や除算は使わない
structureをコピーするかpointerで指定するかで、
作業効率が大幅に変わってくる。
struct hm_time{
int hour;
int minute;
};
アクセスするには2つの方法がある。
①time.hour or time.minute
②void addtime(struct hm_time *t1, struct hm_time *t2){
t1->hour += t2->hour; ←メンバーアクセスと呼ぶ
t1->minute += t2->minute;
}
・command line
javaとはちょっと違う。
main(int argc, char argc[]){~~~
argc = コマンド(1)+引数の数
argv[] = コマンド及び引数へのポインタ
・pointerの危険性
異常終了or迷子のポインタ
エラーのとき
int *p;
int c = *p;
malloc <- 動的に領域を割り当てる。
malloc(10) = 10byte確保する
↑うまく確保できない場合は0を返すので
if文を使ってエラー処理することも可能!
☆確保したものはfree()で解放すること!
解放し忘れると、メモリがドンドン減ってくる!
0 件のコメント:
コメントを投稿