Example #1
0
/***
 * この時点で子スレッドは存在しないものと仮定する.
 * 通常のアプリであれば numは128くらいあれば十分であろう.
 * この値の指定に上限はない(単にListのメモリサイズに影響するのみで
 * 大きな値を指定してもたかが知れている).
 * 実際に使用する数よりもやや多めに指定した方がよい.
 * ぎりぎりくらいに設定するとissue処理の際、探索に時間が
 * かかる可能性が高くなってしまう.
 */
void
ZnkThreadList_initiate( size_t num )
{
	ZnkBfr thlist;
	ZnkMutex* mtxp = znThreadList_theMutex();
	if( *mtxp == NULL ){
		*mtxp = ZnkMutex_create();
	}
	thlist = znThreadList_theList();
	ZnkBfr_resize( thlist, num * sizeof( struct znThreadListElem ) );
	allocInternal( thlist, 0, num );
}
Example #2
0
/***
 * この関数は、lockは掛かっている状態で呼ばれることを前提とする.
 */
static ZnkThreadInfo
issueInfoInteranal( size_t* thno )
{
	static size_t begin = 0;
	ZnkBfr thlist = znThreadList_theList();
	const size_t num = znThreadList_getListNum( thlist );
	struct znThreadListElem* elemp = NULL;
	size_t idx;
	struct znThreadListElem* data = (struct znThreadListElem*)ZnkBfr_data( thlist );

	/***
	 * beginの位置はサイクリックに移動させる.
	 */
	if( begin >= num ){ begin = num; }
	for( idx=begin; idx<num; ++idx ){
		elemp = data + idx;
		if( !elemp->used_ ){
			/* 現在未使用 */
			begin = idx; /* 次回検索を高速化するためのヒューリスティック */
			*thno = idx;
			elemp->used_ = true; /* 使用中に切り替える */
			return elemp->info_;
		}
	}
	for( idx=0; idx<begin; ++idx ){
		elemp = data + idx;
		if( !elemp->used_ ){
			/* 現在未使用 */
			begin = idx; /* 次回検索を高速化するためのヒューリスティック */
			*thno = idx;
			elemp->used_ = true; /* 使用中に切り替える */
			return elemp->info_;
		}
	}

	/***
	 * 用意していたThreadの定員数がオーバーした.
	 * この状態はかなりイレギュラーである.
	 * 本来ならばこのような状況が発生しないようにinit時に与えるnumを十分に用意すべきである.
	 * ここでは、num をそれまでの 2 倍に増やす.
	 */
	ZnkBfr_resize( thlist, 2 * num * sizeof(struct znThreadListElem) );
	allocInternal( thlist, num, num );
	data = (struct znThreadListElem*)ZnkBfr_data( thlist );
	*thno = num;
	elemp = data + num;
	elemp->used_ = true; /* 使用中に切り替える */
	return elemp->info_;
}
 ExecutablePool::Allocation alloc(size_t size)
 {
     return ExecutablePool::Allocation(allocInternal(size), size);
 }