Пример #1
0
/*!
* ミューテックスの初期化(動的型mutexの領域確保と初期化(freeリストを作成する))
* (返却値)E_NOMEM : メモリが取得できない
* (返却値)E_OK : 正常終了
*/
static ER dynamic_mtx_init(void)
{
	int mtxids, i;
	MTXCB *mcb;
	
	mg_mtx_info.freehead = mg_mtx_info.alochead = NULL;
	
	/* start_init_tsk()の時以外 */
	if (mg_mtx_info.power_count) {
		mtxids = MUTEX_ID_NUM << (mg_mtx_info.power_count - 1); /* 現在と同じ領域を確保する */
	}
	/* start_init_tsk()の時 */
	else {
		mtxids = MUTEX_ID_NUM << mg_mtx_info.power_count;
	}
	
	for (i = 0; i < mtxids; i++) {
		mcb = (MTXCB *)get_mpf_isr(sizeof(*mcb)); /* ノードのメモリ確保 */
		/*メモリが取得できない*/
  	if(mcb == NULL) {
  		return E_NOMEM;	 /* initタスクの時は,start_init_tsk()関数内でOSをスリープさせる */
  	}
		memset(mcb, -1, sizeof(*mcb)); /* 確保したノードを初期化 */
		/* freeキューの作成 */
		mcb->next = mg_mtx_info.freehead;
		mcb->prev = NULL;
		mg_mtx_info.freehead = mcb->next->prev = mcb;
	}
	
	return E_OK;
}
Пример #2
0
/*!
 * タスクの領域確保と初期化(タスクのfreeリストを作成する)
 * (返却値)E_NOMEM : メモリが取得できない
 * (返却値)E_OK : 正常終了
 */
static ER dynamic_tsk_init(void)
{
  int tskids, i;
  TCB *tcb;
	
  g_tsk_info.freehead = g_tsk_info.alochead = NULL;
	
  /* start_init_tsk()の時以外 */
  if (g_tsk_info.power_count) {
    tskids = TASK_ID_NUM << (g_tsk_info.power_count - 1); /* 現在と同じ領域を確保する */
  }
  /* start_init_tsk()の時 */
  else {
    tskids = g_tsk_info.tskid_num;
  }
	
  for (i = 0; i < tskids; i++) {
    tcb = (TCB *)get_mpf_isr(sizeof(*tcb)); /* ノードのメモリ確保 */
    /*メモリが取得できない*/
    if(tcb == NULL) {
      return E_NOMEM;	 /* initタスクの時は,start_init_tsk()関数内でOSをスリープさせる */
    }
    memset(tcb, -1, sizeof(*tcb)); /* 確保したノードを初期化 */
    /* freeキューの作成 */
    tcb->free_next = g_tsk_info.freehead;
    tcb->free_prev = NULL;
    /* NULLを経由するとCodeSourceryはエラー(データアボートを発行する) */
    if (tcb->free_next != NULL) {
      tcb->free_next->free_prev = tcb;
    }
    g_tsk_info.freehead = tcb;
  }
	
  return E_OK;
}
Пример #3
0
/*!
* ミューテックスの初期化(静的型mutexの領域確保と初期化(可変長配列として使用する))
* mtxids : 確保する可変長配列の個数
* (返却値)E_NOMEM : メモリが取得できない
* (返却値)E_OK : 正常終了
*/
static ER static_mtx_init(int mtxids)
{
	MTXCB *mcb;
	int size = sizeof(*mcb) * mtxids; /* 可変長配列のサイズ */
	
	mg_mtx_info.array = (MTXCB *)get_mpf_isr(size); /* 可変長配列確保 */
	if (mg_mtx_info.array == NULL) {
		return E_NOMEM; /* initタスクの時は,start_init_tsk()関数内でOSをスリープさせる */
	}
	/* 確保した可変長配列を初期化(可変長でも配列はメモリに連続しているのでこれでOK) */
	memset(mg_mtx_info.array, -1, size);
	
	return E_OK;
}
Пример #4
0
/*!
* ミューテックスの初期化(mutex ID変換テーブルの領域確保と初期化)
* -mutex IDが足らなくなった場合に呼ばれる
* (返却値)E_NOMEM : メモリが取得できない(この返却値は)
* (返却値)E_OK : 正常終了
*/
ER mtx_init(void)
{
	int mtxids, i;
	MTXCB *mcb;
	
	mtxids = MUTEX_ID_NUM << mg_mtx_info.power_count; /* 倍の領域を確保する(start_init_tsk()の時はデフォルト通り) */
	mg_mtx_info.id_table = (MTXCB **)get_mpf_isr(sizeof(mcb) * mtxids); /* 変換テーブルの動的メモリ確保 */
	/* mutexID変換テーブルの初期化(メモリにNULLを埋めるのにmemset()は使用できない) */
	for (i = 0; i < mtxids; i++) {
		mg_mtx_info.id_table[i] = NULL;
	}
	/* MTXCBの静的型配列の作成及び初期化とMTXCBの動的型freeリストの作成と初期化 */
	if ((E_NOMEM == static_mtx_init(mtxids)) || (E_NOMEM == dynamic_mtx_init())) {
		return E_NOMEM; /* initタスクの時は,start_init_tsk関数内でOSをスリープさせる */
	}
	
	return E_OK;
}
Пример #5
0
/*!
* 差分のキューのノードを作成
* 多少のすれ違い(タイマ割込みによるノード解放とシステムコールによるノード作成)の考慮
* flag : タイマの要求種類
* request_sec : 要求タイマ値
* rqobjp : ソフトタイマを要求したオブジェクトのポインタ(ソフトタイマで周期機能を使用したいケースのみ指定する.)
* func : タイマ満了時のコールバックルーチン
* *argv : コールバックルーチンに渡すパラメータ
* (返却値)E_NG : hard timerを差分のキュー管理しようとした場合
* (返却値)newtbf : 新規作成したタイマコントロールブロックへポインタ
*/
OBJP create_tmrcb_diffque(short flag, int request_sec, TMRRQ_OBJP rqobjp, TMR_CALLRTE func, void *argv)
{
	TMRCB *newtbf;

	newtbf = (TMRCB *)get_mpf_isr(sizeof(*newtbf)); /* 動的メモリ取得要求 */

	/* メモリが取得できない */
  if(newtbf == NULL) {
    down_system();
  }
  
	newtbf->next = newtbf->prev = NULL;
	newtbf->flag = flag;
	newtbf->msec = request_sec;
	newtbf->rqobjp = rqobjp; /* 周期機能を使用しない時は0が入る */
	newtbf->func = func;
	newtbf->argv = argv;
	
	insert_tmrcb_diffque(newtbf); /* タイマコントロールブロックの挿入 */
	
	return (OBJP)newtbf;
}
Пример #6
0
/*!
 * タスクの初期化(task ID変換テーブルの領域確保と初期化)
 * -この関数は,kernel_obj_init()で呼ばれる場合と,taskIDが足らなくなった場合に呼ばれる
 * (返却値)E_NOMEM : メモリが取得できない(この返却値は)
 * (返却値)E_OK : 正常終了
 */
ER tsk_init(void)
{
  int tskids, i;
  TCB *tcb;
	
  tskids = g_tsk_info.tskid_num; /* 倍の領域を確保する(start_init_tsk()の時はデフォルト通り) */
	
  g_tsk_info.id_table = (TCB **)get_mpf_isr(sizeof(tcb) * tskids); /* 変換テーブルの動的メモリ確保 */
	if (g_tsk_info.id_table == NULL) {
    return E_NOMEM; /* initタスクの時は,start_init_tsk()関数内でOSをスリープさせる */
  }
  /* taskID変換テーブルの初期化(メモリにNULLを埋めるのにmemset()は使用できない) */
  for (i = 0; i < tskids; i++) {
    g_tsk_info.id_table[i] = NULL;
  }
  /* TCBの静的型配列の作成及び初期化とTCBの動的型freeリストの作成と初期化 */
  if (E_NOMEM == dynamic_tsk_init()) {
    return E_NOMEM; /* initタスクの時は,start_init_tsk()関数内でOSをスリープさせる */
  }
	
  return E_OK;
}
Пример #7
0
/*!
 * レディーキューの初期化
 * typeはenumでやっているので,パラメータチェックはいらない
 * type : スケジューラのタイプ
 * (返却値)E_NOMEM : メモリ不足
 * (返却値)E_OK : 正常終了
 */
ER ready_init(void)
{
  RDYCB *rqcb;
  SCHDUL_TYPE type = mg_schdul_info.type;
  
  rqcb = (RDYCB *)get_mpf_isr(sizeof(*rqcb)); /* 動的メモリ取得 */
  if (rqcb == NULL) {
    return E_NOMEM;
  }
  memset(rqcb, 0, sizeof(*rqcb));
  
  mg_ready_info.entry = rqcb; /* レディー情報ブロックの設定 */
  
  /* First Come First Sarvedとラウンドロビンスケジューリングの時は単一のレディーキュー */
  if (type == FCFS_SCHEDULING || type == RR_SCHEDULING) {
    mg_ready_info.type = SINGLE_READY_QUEUE;
    /* キュー構造のレディーブロックのポインタ */
    rquecb_init(&mg_ready_info.entry->un.single.ready, 0);
    /* ビットマップの処理はない */
  }
  /* 簡易O(1)スケジューリング時はタイムアウトと優先度レベルごとのレディーキュー */
  else if (type == ODRONE_SCHEDULING) {
    mg_ready_info.type = TIMEOUT_PRIORITY_READYQUE;
    mg_ready_info.entry->un.tmout_pri.activ = &mg_ready_info.entry->un.tmout_pri.activ_ready;
    mg_ready_info.entry->un.tmout_pri.expired = &mg_ready_info.entry->un.tmout_pri.expired_ready;
    /* キュー構造のレディーブロックのポインタ */
    rquecb_init(mg_ready_info.entry->un.tmout_pri.activ_ready.que, PRIORITY_NUM);
    rquecb_init(mg_ready_info.entry->un.tmout_pri.expired_ready.que, PRIORITY_NUM);
    bitmap_init(); /*! ビットマップの初期化 */
  }
  /* Fair Schedulerは実行時間の2分探索木のレディー構造 */
  else if (type == FR_SCHEDULING) {
    mg_ready_info.type = BINARY_TREE;
    /* 2分木のレディーブロックの初期化(属性は実行時間) */
    btreercb_init(&mg_ready_info.entry->un.btree.ready, 0, EXECTION_TIME);
  }
  /* Priority Fair Schedulerは実行時間の優先度レベルの2分探索木のレディー構造 */
  else if (type == PFR_SCHEDULING) {
    mg_ready_info.type = PRIORITY_BINARY_TREE;
    btreercb_init(mg_ready_info.entry->un.pri_btree.ready, PRIORITY_NUM, EXECTION_TIME);
    bitmap_init(); /*! ビットマップの初期化 */
  }
  /* EDFスケジューリングはデッドライン2分探索木のレディー構造 */
  else if (type == EDF_SCHEDULING) {
    mg_ready_info.type = BINARY_TREE;
    /* 2分木のレディーブロックの初期化(属性はデッドライン時刻) */
    btreercb_init(&mg_ready_info.entry->un.btree.ready, 0, DEADLINE_TIME);
  }
  /* LLFスケジューリングフロートタイム2分探索木のレディー構造 */
  else if (type == LLF_SCHEDULING) {
    mg_ready_info.type = BINARY_TREE;
    /* 2分木のレディーブロックの初期化(属性は余裕時刻) */
    btreercb_init(&mg_ready_info.entry->un.btree.ready, 0, FLOAT_TIME);
  }
  /*
   * 優先度スケジューリングとラウンドロビン×優先度スケジューリング,Multilevel Feedback Queue,
   * Rate Monotonic,Deadline Monotonicは優先度レベルごとのレディーキュー
   */
  else {
    mg_ready_info.type = PRIORITY_READY_QUEUE;
    /* キュー構造のレディーブロックのポインタ */
    rquecb_init(mg_ready_info.entry->un.pri.ready.que, PRIORITY_NUM);
    bitmap_init(); /*! ビットマップの初期化 */
  }
  
  return E_OK;
}
Пример #8
0
/*!
* システムコール処理(acre_mtx():mutexコントロールブロックの作成(ID自動割付))
* type : 静的型か動的型か?
* atr : タスクをレディーへ戻すアルゴリズム(FIFO順か?優先度順か?)
* piver_mtx : 優先度逆転機構の選択
* maxlocks : 再帰ロックの上限値
* pcl_param : 優先度逆転プロトコル適用時のパラメータ(必要としない優先度逆転プロトコルもある)
* (返却値)E_PAR : システムコールの引数不正
* (返却値)E_NOID : 動的メモリが取得できない(割付可能なIDがない)
* (返却値)mcb : 正常終了(作成したmutexコントロールブロックへのポインタ)
*/
OBJP acre_mtx_isr(MTX_TYPE type, MTX_ATR atr, PIVER_TYPE piver_type, int maxlocks, int pcl_param)
{
  MTXCB *mcb, *vmcb;
  
  /* 静的型mutexの場合 */
  if (type == STATIC_MUTEX) {
  	mcb = &mg_mtx_info.array[mg_mtx_info.counter];
  }
  /* 動的型mutexの場合 */
  else {
  	mcb = mg_mtx_info.freehead; /* free headからノードを与える(抜き取るわけではない) */
  	mg_mtx_info.freehead = mcb->next; /* free headを一つ進める */
  	/* alocheadが空の場合 */
  	if (mg_mtx_info.alochead == NULL) {
  		mg_mtx_info.alochead = mcb;
  	}
  }
  mcb->mtxid = mg_mtx_info.counter; /* カウンタ(ID変換テーブル(可変長配列のインデックス)) */
	mcb->mtx_type = type; /* 静的か動的かを記録 */
	mcb->atr = atr; /* 属性 */
	mcb->piver_type = piver_type; /* 優先度逆転機構 */
  mcb->mtxvalue = 0; /* mutexの値,mutex作成時(初期値)は0 */
  mcb->locks = 0; /* 再帰ロックの回数,mutex作成時(初期値)は0 */
  mcb->maxlocks = maxlocks; /* 再帰ロックの上限値 */
  mcb->ownerid = -1; /* 作成時,オーナーシップは指定しない */
	mcb->pcl.pcl_next = mcb->pcl.pcl_prev = NULL;
  mcb->waithead = mcb->waittail = NULL;

		
	/* virtual priority inheritanceの場合,acre_mtx()の初回のみvirtual mtxを作成 */
	if (piver_type == TA_VINHERIT && mg_mtx_info.virtual_mtx == NULL) {
		/* virtual mutexの作成 */
		vmcb = (MTXCB *)get_mpf_isr(sizeof(*vmcb));
		/* メモリ取得できなかった場合 */
		if (vmcb == NULL) {
			down_system();
		}
		/* メモリ取得できた場合,virtual mutexを初期化 */
		else {
			/* mtxidは使用しない */
			/* mutex typeは指定しない */
			vmcb->atr = atr; /* 属性 */
			/* 優先度逆転機構は指定しない */
  		vmcb->mtxvalue = 0; /* mutexの値,mutex作成時(初期値)は0 */
  		vmcb->locks = 0; /* 再帰ロックの回数,mutex作成時(初期値)は0 */
  		/* 再帰ロックの上限値は指定しない */
  		vmcb->ownerid = -1; /* 作成時,オーナーシップは指定しない */
			/* 優先度逆転機構ポインタは使用しない */
  		vmcb->waithead = vmcb->waittail = NULL;

			mg_mtx_info.virtual_mtx = vmcb; /* グローバルエリアへ繋げておく */
		}
	}
	/* 優先度逆転機構エリアが必要ない場合 */
	else if (piver_type == TA_VOIDPCL || piver_type == TA_INHERIT || piver_type == TA_STACK) {
		mcb->pcl.pcl_param = -1;
	}
	/* 優先度逆転機構エリアが必要な場合 */
	else {
		mcb->pcl.pcl_param = pcl_param;
	}
	
 	DEBUG_OUTMSG("create mutexID for interrput handler\n");
  
  return (OBJP)mcb;
}