Пример #1
0
str* client_new(client_info_t* ci,b2b_notify_t b2b_cback,
		b2b_add_dlginfo_t add_dlginfo, str* param)
{
	int result;
	b2b_dlg_t* dlg;
	unsigned int hash_index;
	str* callid = NULL;
	int size;
	str ehdr = {0, 0};
	str* b2b_key_shm = NULL;
	dlg_t td;
	str from_tag;
	str random_info = {0, 0};

	if(ci == NULL || b2b_cback == NULL || param== NULL)
	{
		LM_ERR("Wrong parameters.\n");
		return NULL;
	}
	if(param && param->len > B2BL_MAX_KEY_LEN)
	{
		LM_ERR("parameter too long, received [%d], maximum [%d]\n",
				param->len, B2BL_MAX_KEY_LEN);
		return 0;
	}

	hash_index = core_hash(&ci->from_uri, &ci->to_uri, client_hsize);

	if(ci->from_tag)
		from_tag = *ci->from_tag;
	else
		generate_tag(&from_tag, &ci->from_uri, ci->extra_headers);

	/* create a dummy b2b dialog structure to be inserted in the hash table*/
	size = sizeof(b2b_dlg_t) + ci->to_uri.len + ci->from_uri.len
		+ ci->from_dname.len + ci->to_dname.len +
		from_tag.len + ci->local_contact.len + B2B_MAX_KEY_SIZE + B2BL_MAX_KEY_LEN;

	/* create record in hash table */
	dlg = (b2b_dlg_t*)shm_malloc(size);
	if(dlg == NULL)
	{
		LM_ERR("No more shared memory\n");
		return 0;
	}
	memset(dlg, 0, size);
	size = sizeof(b2b_dlg_t);

	CONT_COPY(dlg, dlg->from_uri, ci->from_uri);
	CONT_COPY(dlg, dlg->to_uri, ci->to_uri);
	if(ci->to_dname.s)
		CONT_COPY(dlg, dlg->to_dname, ci->to_dname);
	if(ci->from_dname.s)
		CONT_COPY(dlg, dlg->from_dname, ci->from_dname);
	CONT_COPY(dlg, dlg->tag[CALLER_LEG], from_tag);
	CONT_COPY(dlg, dlg->contact[CALLER_LEG], ci->local_contact);

	if(param && param->s)
	{
		dlg->param.s = (char*)dlg + size;
		memcpy(dlg->param.s, param->s, param->len);
		dlg->param.len = param->len;
		size+= B2BL_MAX_KEY_LEN;
	}
	dlg->b2b_cback = b2b_cback;
	dlg->add_dlginfo = add_dlginfo;
	if(parse_method(ci->method.s, ci->method.s+ci->method.len, &dlg->last_method)< 0)
	{
		LM_ERR("wrong method %.*s\n", ci->method.len, ci->method.s);
		shm_free(dlg);
		goto error;
	}
	dlg->state = B2B_NEW;
	dlg->cseq[CALLER_LEG] =(ci->cseq?ci->cseq:1);
	dlg->send_sock = ci->send_sock;

	/* if the callid should be the same in more instances running at the same time (replication)*/
	if(!replication_mode)
	{
		srand(get_uticks());
		random_info.s = int2str(rand(), &random_info.len);
	}

	dlg->send_sock = ci->send_sock;
	dlg->id = core_hash(&from_tag, random_info.s?&random_info:0, HASH_SIZE);

	/* callid must have the special format */
	dlg->db_flag = NO_UPDATEDB_FLAG;
	callid = b2b_htable_insert(client_htable, dlg, hash_index, B2B_CLIENT, 0);
	if(callid == NULL)
	{
		LM_ERR("Inserting new record in hash table failed\n");
		shm_free(dlg);
		goto error;
	}

	if(b2breq_complete_ehdr(ci->extra_headers, &ehdr, ci->body,
				&ci->local_contact)< 0)
	{
		LM_ERR("Failed to complete extra headers\n");
		goto error;
	}

	/* copy the key in shared memory to transmit it as a parameter to the tm callback */
	b2b_key_shm = b2b_key_copy_shm(callid);
	if(b2b_key_shm== NULL)
	{
		LM_ERR("no more shared memory\n");
		goto error;
	}
	CONT_COPY(dlg, dlg->callid, (*callid));

	/* create the tm dialog structure with the a costum callid */
	memset(&td, 0, sizeof(dlg_t));
	td.loc_seq.value = dlg->cseq[CALLER_LEG];
	dlg->last_invite_cseq = dlg->cseq[CALLER_LEG];
	td.loc_seq.is_set = 1;

	td.id.call_id = *callid;
	td.id.loc_tag = from_tag;
	td.id.rem_tag.s = 0;
	td.id.rem_tag.len = 0;

	td.rem_uri = ci->to_uri;
	if(ci->req_uri.s)
		td.rem_target    = ci->req_uri;
	else
		td.rem_target    = ci->to_uri;
	if(td.rem_target.s[0] == '<')
	{
		td.rem_target.s++;
		td.rem_target.len-=2;
	}

	td.rem_dname  = ci->to_dname;

	td.loc_uri    = ci->from_uri;
	td.loc_dname  = ci->from_dname;

	td.state= DLG_CONFIRMED;
	td.T_flags=T_NO_AUTOACK_FLAG|T_PASS_PROVISIONAL_FLAG ;

	td.send_sock = ci->send_sock;

	if(ci->dst_uri.len)
		td.obp = ci->dst_uri;

	td.avps = ci->avps;

	tmb.setlocalTholder(&dlg->uac_tran);

	/* send request */
	result= tmb.t_request_within
		(&ci->method,          /* method*/
		&ehdr,                 /* extra headers*/
		ci->body,              /* body*/
		&td,                   /* dialog structure*/
		b2b_client_tm_cback,   /* callback function*/
		b2b_key_shm,
		shm_free_param);       /* function to release the parameter*/

	if(td.route_set)
		pkg_free(td.route_set);
	if(result< 0)
	{
		LM_ERR("while sending request with t_request\n");
		pkg_free(callid);
		shm_free(b2b_key_shm);
		return NULL;
	}
	tmb.setlocalTholder(NULL);

	LM_DBG("new client entity [%p] callid=[%.*s] tag=[%.*s] param=[%.*s]"
			" last method=[%d] dlg->uac_tran=[%p]\n",
			dlg, callid->len, callid->s,
			dlg->tag[CALLER_LEG].len, dlg->tag[CALLER_LEG].s,
			dlg->param.len, dlg->param.s, dlg->last_method, dlg->uac_tran);

	return callid;

error:
	if(callid)
		pkg_free(callid);
	return NULL;
}
int Simulator::dispatch() {
	bool dispatch = true;
	int num_dispatch = 0;
	while (dispatch_buffer.size() > 0 && dispatch && num_dispatch < n_width) {
		dispatch = false;
		if (dispatch_buffer.front().opcode <= 2) {
			if (RS[0].size() < rs_width) {
				dispatch = true;
			}
		}
		else if (dispatch_buffer.front().opcode <= 4) {
			if (RS[1].size() < rs_width) {
				dispatch = true;
			}
		}
		else if (dispatch_buffer.front().opcode <= 6) {
			if (RS[2].size() < rs_width) {
				dispatch = true;
			}
		}
		else {
			dispatch = true;
		}

		if (dispatch) {
			rs_entry rs;
			rob_entry r;
			pipeline_instr p = dispatch_buffer.front();
			int id = generate_id();
			int tag = generate_tag();
			p.id = id;

			r.id = id;
			rs.id = id;
			r.busy = true;

			if (p.opcode <= 2) {
				if (arf_flags[p.op2].valid) {
					p.A = register_file[p.op2];
					rs_f e1;
					e1.valid = true;
					rs.operand.push_back(e1);
				}
				else {
					rs_f e1;
					e1.valid = false;
					e1.tag = arf_flags[p.op2].tag;
					rs.operand.push_back(e1);
				}
				if (p.immediate) {
					p.imm_field = p.op3;
					rs_f e1;
					e1.valid = true;
					rs.operand.push_back(e1);
				}
				else {	
					if (arf_flags[p.op3].valid) {
						p.B = register_file[p.op3];
						rs_f e1;
						e1.valid = true;
						rs.operand.push_back(e1);
					}
					else {
						rs_f e1;
						e1.valid = false;
						e1.tag = arf_flags[p.op3].tag;
						rs.operand.push_back(e1);
					}
				}
				arf_flags[p.op1].valid = false;
				arf_flags[p.op1].tag = tag;
				p.rs_tag = tag;
				rs.instr = p;
				r.instr = p;
				RS[0].push_back(rs);
				rob.push_back(r);
			}
			else if (p.opcode == 3) {
				if (arf_flags[p.op2].valid) {
					p.A = register_file[p.op2];
					rs_f e1;
					e1.valid = true;
					rs.operand.push_back(e1);
				}
				else {
					rs_f e1;
					e1.valid = false;
					e1.tag = arf_flags[p.op2].tag;
					rs.operand.push_back(e1);
				}
				arf_flags[p.op1].valid = false;
				arf_flags[p.op1].tag = tag;
				p.rs_tag = tag;
				rs.instr = p;
				r.instr = p;
				RS[1].push_back(rs);
				rob.push_back(r);
			}
			else if (p.opcode == 4) {
				if (arf_flags[p.op2].valid) {
					p.B = register_file[p.op2];
					rs_f e1;
					e1.valid = true;
					rs.operand.push_back(e1);
				}
				else {
					rs_f e1;
					e1.valid = false;
					e1.tag = arf_flags[p.op2].tag;
					rs.operand.push_back(e1);
				}
				if (arf_flags[p.op1].valid) {
					p.A = register_file[p.op1];
					rs_f e1;
					e1.valid = true;
					rs.operand.push_back(e1);
				}
				else {
					rs_f e1;
					e1.valid = false;
					e1.tag = arf_flags[p.op1].tag;
					rs.operand.push_back(e1);
				}
				p.rs_tag = tag;
				rs.instr = p;
				r.instr = p;
				RS[1].push_back(rs);
				rob.push_back(r);
			}
			else if (p.opcode == 5) {
				p.imm_field = p.op1;
				p.rs_tag = tag;
				rs.instr = p;
				r.instr = p;
				RS[2].push_back(rs);
				rob.push_back(r);
			}
			else if (p.opcode == 6) {
				p.imm_field = p.op2;
				if (arf_flags[p.op1].valid) {
					p.A = register_file[p.op1];
					rs_f e1;
					e1.valid = true;
					rs.operand.push_back(e1);
				}
				else {
					rs_f e1;
					e1.valid = false;
					e1.tag = arf_flags[p.op1].tag;
					rs.operand.push_back(e1);
				}
				p.rs_tag = tag;
				rs.instr = p;
				r.instr = p;
				RS[2].push_back(rs);
				rob.push_back(r);
			}
			else {
				r.finished = true;
				r.instr = p;
				rob.push_back(r);
			}

		    cout<<"Dispatch: "<<p.IR<<endl;	
			num_dispatch++;
			dispatch_buffer.pop();
		}

	}
	return 1;
}