メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

# dkcTaskEngine.h

いわいるタスク処理 [詳細]

`#include <stdio.h>`
`#include <string.h>`
`#include "dkcOSIndependent.h"`

dkcTaskEngine.hのインクルード依存関係図

このグラフは、どのファイルから直接、間接的にインクルードされているかを示しています。

ソースコードを見る。

## 構成
struct | dkc_TaskEngine
| タスクマネージャー [詳細]
struct | dkc_Task
| タスク本体 [詳細]
## マクロ定義
#define | dkcdTASK_NUM 256
| タスクの数
## 型定義
typedef BYTE | TASK_COUNT_T
| カウント変数のタイプ
typedef dkc_TaskEngine | DKC_TASK_ENGINE
| タスクマネージャー
typedef dkc_Task | DKC_TASK
| タスク本体
typedef void(* | DKC_TASK_PROC )(DKC_TASK_ENGINE *, DKC_TASK *)
## 関数
DKC_EXTERN DKC_TASK_ENGINE * | dkcAllocTaskEngine (size_t taskworksize)
DKC_EXTERN int | dkcFreeTaskEngine (DKC_TASK_ENGINE **)
DKC_EXTERN void | dkcTaskEngineInit (DKC_TASK_ENGINE *p, DKC_TASK *TaskPool[dkcdTASK_NUM], BYTE *TaskWorkPool[dkcdTASK_NUM])
| 自分で確保したメモリ領域を割り当てて初期化する場合。
DKC_EXTERN int | dkcTaskEngineSet (DKC_TASK_ENGINE *p, TASK_COUNT_T prio, DKC_TASK_PROC proc)
| タスクを設定します。使用済みのプライオリティーの場合等で設定できなかった場合はedk_FAILEDを返します。
DKC_EXTERN int | dkcTaskEngineKill (DKC_TASK_ENGINE *p, TASK_COUNT_T prio)
| タスクを削除します。
DKC_EXTERN int | dkcTaskEngineIteration (DKC_TASK_ENGINE *p)
| タスクエンジンに登録されているタスクをイテレーションします。
DKC_EXTERN BOOL | dkcTaskEngineEmpty (DKC_TASK_ENGINE *p, TASK_COUNT_T prio)
| prioのタスクは空いているかどうか≠ﾈら空いている

## 説明

いわいるタスク処理

作者:
  d金魚

から:
  2004/08/22

覚え書き:

  ### タスク処理に関する持論

タスクマネージャー（タスクの生成、削除を管理するもの）（このソースではDKC_TASK_ENGINE構造体） タスク（一つの処理）（このソースではDKC_TASK構造体）

タスクマネージャーがタスクを操作する形。

ここで、今までのタスク処理に関して多少不満があった。

- タスク処理は沢山タスクを一つのタスクマネージャーに登録するとデバッグしにくい。(例１）
- タスク処理は連結リストを使うのでイテレーションが遅いほうだ。
- 連結リストなのでシリアライズ、デシリアライズの実装が非常に面倒。

と言う事で、これらの解決案としては

- 一つのタスクマネージャーはタスクを管理できるのは255-256個にする。 \ また、一連のプロセスの流れに対してタスクマネージャーを一個割り当てるようにする。 \ これらのタスクマネージャーを断層構造にして処理をする方が分かりやすいと考える。
- 連結リストではなく配列でアクセスを行う。
- 連結リストではなくなったのでシリアライズ、デシリアライズの実装が容易。

また、タスク処理はメモリ使用量を少なく済ませる事が美徳と考える私は メモリ使用量をかなり少なめにする事にした。 メモリ使用量を少なくするには空き領域情報とかを無くせば良いと思うが、 その情報が無くなるといちいち線形探索である。 ここらへん、どーすれば良いかが良くわからない･･･。 ARRAY_ONEBYONEとか？

妄想メモ

- 通称、順序無しリスト（stdvectorのようなもの？）を使おうか？。\ http://www.aya.or.jp/%7Esanami/peace/memorial/code41-50.html#CODE44</s>
- タスクワークのプールを外部にする事で、コピーのオーバーヘッドを抑える事が出来るのでは？

と、言う事で、考えてみた結果･･･。

決定事項

- 関数へのポインタが何もしない関数（ Return() )の時のタスク領域は使用可能

以上。このような思想の元にタスクエンジンをくみ上げる事にした。

例１： 例えばシューティングで弾を沢山出したい時、 弾ひとつをタスクとすると沢山のタスクがタスクマネージャーに登録される。 これにより、主要処理をしているタスクの状態遷移が見にくくなり、デバッグしにくくなる。

なので、この場合はタスクの中にもう一つ、弾用タスクエンジンを使って、 または専用の弾の「生成」「消滅」マネージャーを作ってしまうのが良いと思われる。

タスク処理については以下のページが詳しい http://homepage3.nifty.com/moha/ http://www.hh.iij4u.or.jp/~peto/Games/games_top.html

dkcTaskEngine.h で定義されています。

## マクロ定義

#define dkcdTASK_NUM 256

| タスクの数 dkcTaskEngine.h の 74 行で定義されています。 参照元 dkcAllocTaskEngine(), と dkcTaskEngineIteration().

## 型定義

typedef struct dkc_Task DKC_TASK

| タスク本体

typedef struct dkc_TaskEngine DKC_TASK_ENGINE

| タスクマネージャー

typedef void(* DKC_TASK_PROC)(DKC_TASK_ENGINE *, DKC_TASK *)

| dkcTaskEngine.h の 105 行で定義されています。

typedef BYTE TASK_COUNT_T

| カウント変数のタイプ 事実上ULONGLONとかの64bit整数は無理なので指定しないで下さい。 多分USHORTあたりまでがいいところだと思う。 また、unsigned な変数型にしてください。 dkcTaskEngine.h の 81 行で定義されています。

## 関数

DKC_EXTERN DKC_TASK_ENGINE* dkcAllocTaskEngine | ( | size_t | taskworksize | ) |

| dkcTaskEngine.c の 11 行で定義されています。 参照先 BYTE, dkcAllocate(), dkcdTASK_NUM, dkcFree(), dkcTaskEngineInit(), と NULL.
    00011                                                         {
    00012     BYTE *temp = NULL;
    00013
    00014     DKC_TASK_ENGINE *p = NULL;
    00015     DKC_TASK *tp = NULL;
    00016
    00017     if(0==taskworksize){
    00018         return NULL;
    00019     }
    00020
    00021
    00022
    00023     p = dkcAllocate(sizeof(DKC_TASK_ENGINE));
    00024     if(NULL==p){
    00025         return NULL;
    00026     }
    00027
    00028     temp = dkcAllocate(taskworksize * dkcdTASK_NUM);
    00029     if(NULL==temp){
    00030         goto Error;
    00031     }
    00032     tp = dkcAllocate(sizeof(DKC_TASK) * dkcdTASK_NUM);
    00033     if(NULL==tp){
    00034         goto Error;
    00035     }
    00036
    00037
    00038
    00039     dkcTaskEngineInit(p,&tp,&temp);
    00040
    00041     return p;
    00042
    00043
    00044 Error:
    00045     //dkcFree((void **)&tp);
    00046     dkcFree((void **)&temp);
    00047     dkcFree((void **)&p);
    00048
    00049     return NULL;
    00050 }

DKC_EXTERN int dkcFreeTaskEngine | ( | DKC_TASK_ENGINE ** |  | ) |

| dkcTaskEngine.c の 52 行で定義されています。 参照先 dkcFree().
    00052                                            {
    00053     dkcFree((void **) (*pp)->mTaskPool );//&[0]
    00054     dkcFree((void **) (*pp)->mTaskWorkPool );//&[0]
    00055     return dkcFree((void **) pp );
    00056 }

DKC_EXTERN BOOL dkcTaskEngineEmpty | ( | DKC_TASK_ENGINE * | p,
|  | TASK_COUNT_T | prio
| ) |

| prioのタスクは空いているかどうか≠ﾈら空いている dkcTaskEngine.c の 125 行で定義されています。 参照先 dkc_TaskEngine::mTaskPool, dkc_Task::proc, と Return().
    00125                                                              {
    00126     DKC_TASK_PROC tp = Return;
    00127     DKC_TASK *task_p = (DKC_TASK *)p->mTaskPool[prio];
    00128
    00129     return (task_p->proc==tp);
    00130 }

DKC_EXTERN void dkcTaskEngineInit | ( | DKC_TASK_ENGINE * | p,
|  | DKC_TASK * | TaskPool[dkcdTASK_NUM],
|  | BYTE * | TaskWorkPool[dkcdTASK_NUM]
| ) |

  | 自分で確保したメモリ領域を割り当てて初期化する場合。 引数:
  | TaskPool[in] | タスクdkcdTASK_NUM個分のメモリ空間へのアドレス
  | TaskWorkPool[in] | タスクワークdkcdTASK_NUM個分のメモリ空間へのアドレス
覚え書き: 内部でmallocを使わない版 なぜこんなのを用意したかと言うと、タスク処理は組み込み系でも使われそうと思うので･･･？ かなり速度等にシビアなものだと考えているからだ･･･。 dkcTaskEngine.c の 63 行で定義されています。 参照先 BYTE, dkc_TaskEngine::mNowPriority, dkc_TaskEngine::mTaskPool, dkc_TaskEngine::mTaskWorkPool, dkc_TaskEngine::mTaskWorkSize, と Return(). 参照元 dkcAllocTaskEngine().
    00063                                                                                                             {
    00064     int i;
    00065     size_t taskworksize = p->mTaskWorkSize;
    00066     p->mNowPriority = 0;
    00067
    00068     for(i=0;i<dkcdTASK_NUM;i++){
    00069         p->mTaskWorkPool[i] = TaskWorkPool[i * taskworksize];
    00070
    00071         TaskPool[i]->proc = Return;
    00072         TaskPool[i]->work = p->mTaskWorkPool[i];
    00073
    00074         p->mTaskPool[i] = (BYTE *)TaskPool[i];
    00075     }
    00076 }

DKC_EXTERN int dkcTaskEngineIteration | ( | DKC_TASK_ENGINE * | p | ) |

| タスクエンジンに登録されているタスクをイテレーションします。 dkcTaskEngine.c の 104 行で定義されています。 参照先 dkcdTASK_NUM, dkc_TaskEngine::mNowPriority, dkc_TaskEngine::mTaskPool, と dkc_Task::proc.
    00104                                               {
    00105     unsigned int i;
    00106     //一時変数
    00107     DKC_TASK_PROC proc;
    00108     DKC_TASK *task_p;
    00109
    00110     for(i=0;i<dkcdTASK_NUM;i++){
    00111         task_p = (DKC_TASK *)(p->mTaskPool[i]);
    00112         proc = task_p->proc;
    00113         p->mNowPriority = (TASK_COUNT_T)i;
    00114
    00115         //呼び出す。
    00116         proc(p,task_p);
    00117
    00118     }
    00119     return edk_SUCCEEDED;
    00120
    00121 }

DKC_EXTERN int dkcTaskEngineKill | ( | DKC_TASK_ENGINE * | p,
|  | TASK_COUNT_T | prio
| ) |

| タスクを削除します。 dkcTaskEngine.c の 95 行で定義されています。 参照先 dkc_TaskEngine::mTaskPool, dkc_Task::proc, と Return().
    00096 {
    00097     DKC_TASK *pt = (DKC_TASK *)p->mTaskPool[prio];
    00098
    00099     pt->proc  = Return;
    00100     return edk_SUCCEEDED;
    00101 }

DKC_EXTERN int dkcTaskEngineSet | ( | DKC_TASK_ENGINE * | p,
|  | TASK_COUNT_T | prio,
|  | DKC_TASK_PROC | proc
| ) |

| タスクを設定します。使用済みのプライオリティーの場合等で設定できなかった場合はedk_FAILEDを返します。 dkcTaskEngine.c の 79 行で定義されています。 参照先 dkc_TaskEngine::mTaskPool, dkc_Task::proc, と Return().
    00079                                                                              {
    00080     DKC_TASK_PROC sentinel = Return;
    00081     DKC_TASK *pt = (DKC_TASK *)p->mTaskPool[prio];
    00082
    00083     if(pt->proc != sentinel)
    00084     {   //使用している。
    00085         return edk_FAILED;
    00086     }
    00087
    00088     //使用していないなら登録
    00089     pt->proc = proc;
    00090
    00091     return edk_SUCCEEDED;
    00092 }