示例#1
0
method(MCUnitTestCase, void, runTests, voida)
{
	runtime_log("%s\n", "MCUnitTestCase runTests");
	unsigned i;
	unsigned bye_key = hash("bye");
	unsigned setUp_key = hash("setUp");
	unsigned tearDown_key = hash("tearDown");

	if(obj==null || cast(MCObject*, obj)->isa==null)
		return;

	runtime_log("%s\n", "MCUnitTestCase runTests before for loop");
    mc_hashitem* amethod;
	for (i = 0; i < get_tablesize(cast(MCObject*, obj)->isa->table->level); i++)
	{
		//runtime_log("MCUnitTestCase runTests in for loop index:[%d]\n", i);
		amethod = cast(MCObject*, obj)->isa->table->items[i];
		if(amethod->value.mcvoidptr!=null
		&& i!=bye_key
		&& i!=setUp_key
		&& i!=tearDown_key){
			runtime_log("%s\n", "MCUnitTestCase runTests hit a matched method");
			if(obj==null){
				error_log("MCUnitTestCase runTests this pointer is null\n");
			}
			runMethodByPointer(obj, amethod);
		}
	}
}
示例#2
0
文件: Messaging.c 项目: LinkinW/monkc
mc_message _self_response_to_h(const mo obj, const char* methodname, unsigned hashval)
{
	//we will return a struct
	mc_hashitem* res;
	mc_message tmpmsg = {nil, nil};

	if(obj == nil){
		error_log("_self_response_to(obj) obj is nil. return {nil, nil}\n");
		return tmpmsg;
	}
	if(obj->isa == nil){
		error_log("_self_response_to(obj) obj->isa is nil. return {nil, nil}\n");
		return tmpmsg;
	}

	if((res=get_item_byhash(&(obj->isa->table), hashval, methodname)) != nil){
		tmpmsg.object = obj;
		tmpmsg.addr = res->value;
		runtime_log("return a message[%s/%s]\n", nameof(tmpmsg.object), methodname);
		return tmpmsg;
	}else{
		runtime_log("self_response_to class[%s] can not response to method[%s]\n", nameof(obj), methodname);
		return tmpmsg;
	}
}
示例#3
0
mc_message _self_response_to_h(const mo obj, const char* methodname, MCHash hashval)
{
	//we will return a struct
	mc_hashitem* res = mull;
	mc_message tmpmsg = {mull, mull};

	if(obj == mull){
		//no need to warning user
		return tmpmsg;
	}
	if(obj->isa == mull){
		error_log("_self_response_to(obj, '%s') obj->isa is mull. return {mull, mull}\n", methodname);
		return tmpmsg;
	}

	if((res=get_item_byhash(obj->isa->table, hashval, methodname)) != mull){
		tmpmsg.object = obj;
		tmpmsg.address = res->value.mcfuncptr;
		runtime_log("return a message[%s/%s]\n", nameof(obj), methodname);
		return tmpmsg;
	}else{
        if (obj->nextResponder != mull) {
            return _self_response_to_h(obj->nextResponder, methodname, hashval);
        }else{
            runtime_log("self_response_to class[%s] can not response to method[%s]\n", nameof(obj), methodname);
            if (MC_STRICT_MODE == 1) {
                exit(-1);
            }else{
                return tmpmsg;
            }
        }
	}
}
示例#4
0
int _runtime() {
	MPI_Status probe_status;
	int probe_flag = 0;
	MPI_Status rcv_status;
	int i = 0;
	int *message_buffer;
	int message_buffer_size = 2;
	int message_size = 0;

	message_buffer = malloc(sizeof(MPI_INT ) * message_buffer_size);
	if (message_buffer == NULL ) {
		sprintf(log_buffer, "RUNTIME ERROR: Cannot allocate initial message_buffer.");
		runtime_log(ERROR_RUNTIME);
		return -1;
	}

	/* Barrier synch to check that all subsystems have been initialized */
	MPI_Barrier(comm);

	while (!close_application) {
		probe_flag = 0;
		MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &probe_flag, &probe_status);
		if (probe_flag) {
			if (!probe_status.MPI_ERROR) {
				MPI_Get_count(&probe_status, MPI_INT, &message_size);

				if (message_size > message_buffer_size) {
					free(message_buffer);
					message_buffer = malloc(sizeof(MPI_INT ) * message_size);
					if (message_buffer == NULL ) {
						sprintf(log_buffer, "RUNTIME ERROR: Cannot allocate resized message_buffer.");
						runtime_log(ERROR_RUNTIME);
						return -1;
					}
					message_buffer_size = message_size;
				}

				MPI_Recv(message_buffer, message_size, MPI_INT, probe_status.MPI_SOURCE, probe_status.MPI_TAG, comm,
						&rcv_status);
				perform_receive_callback(message_buffer, message_size, probe_status.MPI_SOURCE, probe_status.MPI_TAG);
			}
		}
		perform_request_callback();
		perform_timely_callbacks();
		_perform_event();
		i++;
		if (!probe_flag) {
			nanosleep(&tim, &tim2);
		}

	}
	free(message_buffer);
	_runtime_cleanup();
	return 0;
}
示例#5
0
/*
 * Utility function to unregister a callback given it's handle
 */
int _consensus_based_tob_unregister_callback(int handle) {
	if ((callback[handle] == consensus_based_tob_dummy_callback) || (handle >= callback_num)) {
		sprintf(log_buffer,
				"CONSENSUS BASED TOB ERROR: Cannot unregister callback, handle does not correspond to any registered callback");
		runtime_log(ERROR_TOB);
		return -1;
	}

	callback[handle] = consensus_based_tob_dummy_callback;
	sprintf(log_buffer, "CONSENSUS BASED TOB INFO: Callback %d unregistered", handle);
	runtime_log(DEBUG_TOB);
	return 0;
}
示例#6
0
/*
 * Utility function to register a callback and getting the related handle
 */
int _consensus_based_tob_register_callback(int (*callback_func)(int*, int, int), int* handle) {
	int i = 0;
	for (i = 0; i < MAX_CALLBACK_NUM; i++) {
		if (callback[i] == consensus_based_tob_dummy_callback) {
			callback[i] = callback_func;
			*handle = i;
			callback_num++;
			sprintf(log_buffer, "CONSENSUS BASED TOB INFO: Callback %d registered", i);
			runtime_log(DEBUG_TOB);
			return 0;
		}
	}
	sprintf(log_buffer, "CONSENSUS BASED TOB ERROR: Cannot register callback, no slot available");
	runtime_log(ERROR_TOB);
	return -1;
}
示例#7
0
/*
 * Utility function to register a timely callbacks and getting the related handle
 */
int _runtime_register_timely_callback(int (*callback_func)(void), int* handle) {
	int i = 0;
	for (i = 0; i < MAX_CALLBACK_NUM; i++) {
		if (timely_callback[i] == NULL ) {
			timely_callback[i] = callback_func;
			*handle = i;
			timely_callback_num++;
			sprintf(log_buffer, "RUNTIME INFO: Timely callback %d registered", i);
			runtime_log(DEBUG_RUNTIME);
			return 0;
		}
	}
	sprintf(log_buffer, "RUNTIME ERROR: Cannot register timely callback, no slot available");
	runtime_log(ERROR_RUNTIME);
	return -1;
}
示例#8
0
void test_cut_objdsc()
{
	test_bp_init();

	pushToTail(pool, b1);
	pushToTail(pool, b2);
	pushToTail(pool, b3);
	pushToTail(pool, b4);
	pushToTail(pool, b5);
	pushToTail(pool, b6);


	runtime_log("pool count should be 6:%d\n", count(pool));
	cut(pool, deref(o6).block, &tb);
	runtime_log("pool count should be 5:%d\n", count(pool));
	cut(pool, deref(o5).block, &tb);
	runtime_log("pool count should be 4:%d\n", count(pool));	
	cut(pool, deref(o4).block, &tb);
	runtime_log("pool count should be 3:%d\n", count(pool));
	cut(pool, deref(o3).block, &tb);
	runtime_log("pool count should be 2:%d\n", count(pool));
	cut(pool, deref(o2).block, &tb);
	runtime_log("pool count should be 1:%d\n", count(pool));
	cut(pool, deref(o1).block, &tb);
	runtime_log("pool count should be 0:%d\n", count(pool));


	test_bp_end();

}
示例#9
0
void test_cut_asc()
{
	test_bp_init();

	pushToTail(pool, b1);
	pushToTail(pool, b2);
	pushToTail(pool, b3);
	pushToTail(pool, b4);
	pushToTail(pool, b5);
	pushToTail(pool, b6);

	runtime_log("pool count should be 6:%d\n", count(pool));
	cut(pool, b1, &tb);
	runtime_log("pool count should be 5:%d\n", count(pool));
	cut(pool, b2, &tb);
	runtime_log("pool count should be 4:%d\n", count(pool));	
	cut(pool, b3, &tb);
	runtime_log("pool count should be 3:%d\n", count(pool));
	cut(pool, b4, &tb);
	runtime_log("pool count should be 2:%d\n", count(pool));
	cut(pool, b5, &tb);
	runtime_log("pool count should be 1:%d\n", count(pool));
	cut(pool, b6, &tb);
	runtime_log("pool count should be 0:%d\n", count(pool));

	test_bp_end();
}
示例#10
0
int _consensus_based_tob_rb_deliver(int *data, int count) {

	int* message = (int*) data;

	if (count < 3) {
		sprintf(log_buffer, "CONSENSUS BASED TOB ERROR: Message bad format");
		runtime_log(ERROR_TOB);
		return -1;
	}

	int handle = message[0];
	int id = message[1];
	int real_sender = message[2];
	int message_size = count - 3;
	if (handle < 0 || handle > callback_num) {
		sprintf(log_buffer, "CONSENSUS BASED TOB ERROR: Handle out of range: %d", handle);
		runtime_log(ERROR_TOB);
		return -1;
	}

	if (real_sender < 0 || real_sender >= num_procs) {
		sprintf(log_buffer, "CONSENSUS BASED TOB ERROR: Message sent by unkown sender.");
		runtime_log(ERROR_TOB);
		return -1;
	}

	sprintf(log_buffer, "CONSENSUS BASED TOB INFO: Received message \"%d\" of size %d with handle %d from process %d",
			message[1], count, handle, real_sender);
	runtime_log(DEBUG_TOB);

	print_data("CONSENSUS BASED TOB Received Message", "value", data, count, DEBUG_LOG_LEVEL);

	if (is_in_delivered(id, real_sender) == -1)
		return -1;

	add_to_unordered(id, real_sender, &message[3], message_size, handle);

	fflush(stdout);
	free(data);

	_consensus_based_tob_new_consensus_istance();

	return 0;
}
示例#11
0
void test_getFromHead()
{
	test_bp_init();
	
	pushToTail(pool, b1);
	pushToTail(pool, b2);
	pushToTail(pool, b3);
	pushToTail(pool, b4);

	runtime_log("pool count should be 4:%d\n", count(pool));
	getFromHead(pool);
	runtime_log("pool count should be 3:%d\n", count(pool));
	getFromHead(pool);
	runtime_log("pool count should be 2:%d\n", count(pool));	
	getFromHead(pool);
	runtime_log("pool count should be 1:%d\n", count(pool));
	getFromHead(pool);
	runtime_log("pool count should be 0:%d\n", count(pool));

	test_bp_end();
}
示例#12
0
文件: monkc.c 项目: sunpaq/monkc
mc_class* _load(const char* name, size_t objsize, MCLoaderPointer loader)
{
	mc_class* aclass = findclass(name);
	//try lock spin lock
	trylock_global_classtable();
	if (aclass == null) {
		//new a item
		aclass = alloc_mc_class(objsize);
		mc_hashitem* item = new_item(name, MCGenericVp(null), hash(name));//nil first
		package_by_item(item, aclass);
		(*loader)(aclass);
		//set item
		//MCBool isOverride, MCBool isFreeValue
		set_item(&mc_global_classtable, item, false, name);
		runtime_log("load a class[%s]\n", name);
	}
	else {
		runtime_log("find a class[%s]\n", name);
	}
	//unlock
	unlock_global_classtable();
	return aclass;
}
示例#13
0
/*
 * upon event <rbBroadcast | m>
 *
 * Given a pointer to the message array, the number of elements in the array and handle,
 * it packs the message, self id and the handle into a new buffer. The message is sent to the other
 * processes through Best Effort BroadCast
 */
int _consensus_based_tob_send(int *message, int count, int handle) {
	sprintf(log_buffer, "CONSENSUS BASED TOB INFO: Registering message \"%d\" with handle %d", message[0], handle);
	runtime_log(DEBUG_TOB);

	// Copying the message, adding CONSENSUS BASED TOB callback.
	int * buffer = (int*) malloc(sizeof(int) * (count + 3));
	buffer[0] = handle;
	buffer[1] = serial_number++;
	buffer[2] = my_rank;
	copy_to_array(&buffer[3], message, count);
	_eager_reliable_broadcast_send(buffer, count + 3, eager_reliable_broadcast_handle);
	free(buffer);
	return 0;
}
示例#14
0
文件: monkc.c 项目: sunpaq/monkc
MCInline mc_class* findclass(const char* name)
{
	//create a class hashtable
	if (mc_global_classtable == null)
		mc_global_classtable = new_table(MCHashTableLevel1);

	//cache
	//    mc_hashitem* cache = mc_global_classtable->cache;
	//    if (cache && cache->key == name) {
	//        return (mc_class*)(cache->value.mcvoidptr);
	//    }

	mc_hashitem* item = get_item_byhash(mc_global_classtable, hash(name), name);
	if (item == null)
		return null;
	else
		runtime_log("findClass item key:%s, value:%p\n", item->key, item->value.mcvoidptr);
	return (mc_class*)(item->value.mcvoidptr);
}
示例#15
0
static void runMethodByPointer(MCUnitTestCase* obj, mc_hashitem* amethod)
{
	ff(obj, setUp, null);
	runtime_log("%s\n", "runMethodByPointer start");

	try{
		_push_jump(response_to(cast(MCObject*, obj), amethod->key), null);
		//if exception generated, this line will never be reached
	}
	catch(MCAssertYESException){
		error_log("MCAssertNOException\n");
	}
	catch(MCAssertNOException){
		error_log("MCAssertNOException\n");
	}
	catch(MCAssertnullException){
		error_log("MCAssertnullException\n");
	}
	catch(MCAssertNotnullException){
		error_log("MCAssertNotnullException\n");
	}
	catch(MCAssertSameException){
		error_log("MCAssertSameException\n");
	}
	catch(MCAssertNotSameException){
		error_log("MCAssertNotSameException\n");
	}
	catch(MCAssertEqualsException){
		error_log("MCAssertEqualsException\n");
	}
	finally{
		error_log("testcase: %s at method: [%s]\n", cast(MCObject*, obj)->isa->item->key, amethod->key);
	}

	ff(obj, tearDown, null);
}
示例#16
0
文件: monkc.c 项目: sunpaq/monkc
static int ref_count_down(MCObject* const obj)
{
	for (;;) {
		if (obj == null) {
			error_log("recycle/release(null) do nothing.\n");
			return REFCOUNT_ERR;
		}
		if (obj->ref_count == 0)
		{
			runtime_log("recycle/release(%s) count=0 return\n", nameof(obj));
			return REFCOUNT_ERR;
		}
		if (obj->ref_count == REFCOUNT_NO_MM) {
			debug_log("ref_count is REFCOUNT_NO_MM manage by runtime. do nothing\n");
			return REFCOUNT_NO_MM;
		}
		if (obj->isa == null) {
			error_log("recycle/release(obj) obj have no class linked. do nothing.\n");
			return REFCOUNT_ERR;
		}
#ifdef NO_ATOMIC
		obj->ref_count--; break;
#else
		int oldcount, newcount;
		int *addr;
		addr = &(this->ref_count);
		oldcount = mc_atomic_get_integer(addr);
		newcount = oldcount;
		if (newcount > 0)
			newcount--;
		if (!mc_atomic_set_integer(addr, oldcount, newcount))
			break;
#endif
	}
	return obj->ref_count;
}
示例#17
0
int _runtime_init(int argc, char **argv, unsigned int flags) {
	if (initialized)
		return -1;
	int i = 0;

	tim.tv_sec = 0;
	tim.tv_nsec = 1000000L;

	/* start up MPI if necessary */
	MPI_Initialized(&initialized);
	if (!initialized) {
		MPI_Init(&argc, &argv);
	}

	comm = MPI_COMM_WORLD;

	/* find out process rank */
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	/* find out number of processes */
	MPI_Comm_size(MPI_COMM_WORLD, &num_procs);

	logger_init();

	cleanup_callback_num = 0;
	cleanup_callback = (int (**)(void)) malloc(sizeof(int (*)(void)) * MAX_CALLBACK_NUM);
	if (cleanup_callback == NULL ) {
		sprintf(log_buffer, "RUNTIME ERROR:Cannot allocate cleanup callback vector");
		runtime_log(ERROR_RUNTIME);
	}
	for (i = 0; i < MAX_CALLBACK_NUM; i++)
		cleanup_callback[i] = NULL;

	receive_callback_num = 0;
	receive_callback = (int (**)(int*, int, int)) malloc(sizeof(int (*)(int*, int, int)) * MAX_CALLBACK_NUM);
	if (receive_callback == NULL ) {
		sprintf(log_buffer, "RUNTIME ERROR:Cannot allocate receive callback vector");
		runtime_log(ERROR_RUNTIME);
	}
	for (i = 0; i < MAX_CALLBACK_NUM; i++)
		receive_callback[i] = NULL;

	request_callback_num = 0;
	request_callback = (int (**)(void)) malloc(sizeof(int (*)(void)) * MAX_CALLBACK_NUM);
	if (request_callback == NULL ) {
		sprintf(log_buffer, "RUNTIME ERROR:Cannot allocate request callback vector");
		runtime_log(ERROR_RUNTIME);
	}
	for (i = 0; i < MAX_CALLBACK_NUM; i++)
		request_callback[i] = NULL;

	timely_callback_num = 0;
	timely_callback = (int (**)(void)) malloc(sizeof(int (*)(void)) * MAX_CALLBACK_NUM);
	if (timely_callback == NULL ) {
		sprintf(log_buffer, "RUNTIME ERROR:Cannot allocate timely callback vector");
		runtime_log(ERROR_RUNTIME);
	}
	for (i = 0; i < MAX_CALLBACK_NUM; i++)
		timely_callback[i] = NULL;

	_event_queue_init();

	_runtime_register_request_callback(_runtime_request_callback, &runtime_receive_handle);
	_get_application_layer_message_id(&application_layer_message_id);
	_send_id_to_application(application_layer_message_id);

	initialized = 1;

	return 0;
}
示例#18
0
/*
 * Initialization function
 * Allocates the callback and unordered datastructures
 */
int _consensus_based_tob_init(unsigned int flags) {
	if (initialized)
		return -1;

	sprintf(log_buffer, "CONSENSUS BASED TOB INFO: Initializing Total Order Broadcast");
	runtime_log(INFO_TOB);

	_eager_reliable_broadcast_init(flags);
	_flooding_consensus_init(flags);

	callback_num = 0;

	callback = (int (**)(int*, int, int)) malloc(sizeof(int (*)(int*, int, int)) * MAX_CALLBACK_NUM);

	if (callback == NULL ) {
		sprintf(log_buffer, "CONSENSUS BASED TOB ERROR:Cannot allocate callback vector");
		runtime_log(ERROR_TOB);
	}

	int i = 0;
	for (i = 0; i < MAX_CALLBACK_NUM; i++)
		callback[i] = consensus_based_tob_dummy_callback;

	proc_data_set = (proc_data**) malloc(sizeof(proc_data*) * num_procs);
	for (i = 0; i < num_procs; i++) {
		proc_data_set[i] = (proc_data*) malloc(sizeof(proc_data));
		proc_data_set[i]->gc_threshold = (serialNumber*) malloc(sizeof(serialNumber));
		initializeSerialNumber(proc_data_set[i]->gc_threshold);
		proc_data_set[i]->delivered_set = (delivered*) malloc(sizeof(delivered));
		proc_data_set[i]->delivered_set->id = -1;
		proc_data_set[i]->delivered_set->next = NULL;
	}

	serial_number = 0;

	unordered_set = (unordered *) malloc(sizeof(unordered));
	unordered_set->id = -1;
	unordered_set->callback_id = -1;
	unordered_set->size = 0;
	unordered_set->message = NULL;
	unordered_set->next = NULL;

	consensus_set = (consensus *) malloc(sizeof(consensus));
	consensus_set->round = -1;
	consensus_set->decided_set_size = 0;
	consensus_set->decided_set = NULL;
	consensus_set->next = NULL;

	current_consensus_round = 0;
	next_deciding_consensus_round = 0;

	if (flags & USING_CONSENSUS_BASED_TOTAL_ORDER_BROADCAST) {
		_consensus_based_tob_register_callback(_consensus_based_tob_deliver_to_application_callback,
				&application_layer_handle);
		_runtime_register_request_callback(_consensus_based_tob_request_callback, &runtime_request_handle);

		_get_application_layer_message_id(&application_layer_message_id);
		_send_id_to_application(application_layer_message_id);
	}
	_eager_reliable_broadcast_register_callback(consensus_based_tob_rb_deliver_callback,
			&eager_reliable_broadcast_handle);
	_flooding_consensus_register_callback(consensus_based_tob_decided_callback, &flooding_consensus_handle);

	initialized = 1;
	return 0;
}
示例#19
0
void test_bp_end()
{
	empty(pool);
	runtime_log("test_bp_end pool count should be 0:%d\n", count(pool));
}
示例#20
0
method(MCUnitTestCase, void, tearDown, voida)
{
	//tear down fixture
	runtime_log("----MCUnitTestCase tearDown\n");
}
示例#21
0
method(MCUnitTestCase, void, setUp, voida)
{
	//set up fixture
	runtime_log("----MCUnitTestCase setUp\n");
}
示例#22
0
/*
 * Place holder for the callback vector, should not be invoked
 */
int consensus_based_tob_dummy_callback(int* message, int count, int sender) {
	sprintf(log_buffer, "CONSENSUS BASED TOB ERROR: Referenced callback is not registered");
	runtime_log(ERROR_TOB);
	return -1;
}
示例#23
0
文件: Messaging.c 项目: LinkinW/monkc
mc_message _response_to_h(const mo obj, const char* methodname, unsigned hashval, int strict)
{
	mc_object* obj_iterator = obj;
	mc_object* obj_first_hit = nil;
	mc_hashitem* met_first_hit = nil;
	mc_hashitem* met_item = nil;
	int hit_count = 0;
	int iter_count = 0;
	//int max_iter = get_tablesize(5);
	int max_iter = 10000;

	mc_message tmpmsg = {nil, nil};
	if(obj == nil || obj->isa == nil){
		error_log("_response_to(obj) obj is nil or obj->isa is nil. return {nil, nil}\n");
		return tmpmsg;
	}

	for(obj_iterator = obj;
		obj_iterator!= nil;
		obj_iterator = obj_iterator->super){
		if(iter_count++ > max_iter){
			error_log("iter_count>max but class still can not response to method\n");
			break;
		}
		if((met_item=get_item_byhash(&(obj_iterator->isa->table), hashval, methodname)) != nil) {
			runtime_log("hit a method [%s/%d] to match [%s]\n", 
				met_item->key, met_item->index, methodname);
			hit_count++;
			tmpmsg.object = obj_iterator;
			tmpmsg.addr = met_item->value;
			if(obj_first_hit==nil)obj_first_hit = obj_iterator;
			if(met_first_hit==nil)met_first_hit = met_item;
			//for the method key have conflicted with some super class in inherit tree
			if(hit_count>1){
				if(hit_count==2){
					//to support the "overide" feature of oop
					if(mc_compare_key(met_first_hit->key, methodname) == 0){
						tmpmsg.object = obj_first_hit;
                        tmpmsg.addr = met_first_hit->value;
						runtime_log("[first hit]return a message[%s/%s(%p/%p)]\n", 
                                                            tmpmsg.object->isa->item->key, 
                                                            methodname,
                                                            tmpmsg.object,
                                                            tmpmsg.addr);
						return tmpmsg;}
				}
				if(mc_compare_key(met_item->key, methodname) == 0){
					tmpmsg.object = obj_iterator;
					runtime_log("[string equal]return a message[%s/%s]\n", tmpmsg.object->isa->item->key, methodname);
					return tmpmsg;}
			}
		}
	}
	if(hit_count==1)
		runtime_log("return a message[%s/%s]\n", nameof(tmpmsg.object), methodname);
	else if(hit_count==0)
    {
        if (strict!=2) error_log("class[%s] can not response to method[%s]\n", nameof(obj), methodname);
        if (strict==1) exit(1);
    }
	else
    {
        if (strict!=2) error_log("hit_count>1 but class still can not response to method\n");
        if (strict==1) exit(1);
    }
	return tmpmsg;
}