示例#1
0
文件: netif.c 项目: interwq/Composite
static int cos_net_create_net_acap(unsigned short int port, rb_meta_t *rbm)
{
	int acap;

	acap = cos_async_cap_cntl(COS_ACAP_CREATE, cos_spd_id(), cos_spd_id(), cos_get_thd_id());
	assert(acap);
	/* cli acap not used. The server acap will be triggered by
	 * network driver. */
	wildcard_acap_id = acap & 0xFFFF;
	assert(wildcard_acap_id > 0);

	if (sched_create_net_acap(cos_spd_id(), wildcard_acap_id, port)) return -1;
	if (cos_buff_mgmt(COS_BM_RECV_RING, rb1.packets, sizeof(rb1.packets), wildcard_acap_id)) {
		prints("net: could not setup recv ring.\n");
		return -1;
	}
	return 0;
}
示例#2
0
static int channel_init(int channel)
{
	char *addr, *start;
	unsigned long i, sz;
	int acap, srv_acap;
	int direction;

	direction = cos_trans_cntl(COS_TRANS_DIRECTION, channel, 0, 0);
	if (direction < 0) {
		channels[channel].exists = 0;
		return 0;
	}  
	channels[channel].exists = 1;
	channels[channel].direction = direction;

	sz = cos_trans_cntl(COS_TRANS_MAP_SZ, channel, 0, 0);
	assert(sz <= (4*1024*1024)); /* current 8MB max */
	start = valloc_alloc(cos_spd_id(), cos_spd_id(), sz/PAGE_SIZE);
	assert(start);
	for (i = 0, addr = start ; i < sz ; i += PAGE_SIZE, addr += PAGE_SIZE) {
		assert(!cos_trans_cntl(COS_TRANS_MAP, channel, (unsigned long)addr, i));
	}
	cringbuf_init(&channels[channel].rb, start, sz);

	if (direction == COS_TRANS_DIR_LTOC) {
		acap = cos_async_cap_cntl(COS_ACAP_CREATE, cos_spd_id(), cos_spd_id(), 
					  cos_get_thd_id() << 16 | cos_get_thd_id());
		assert(acap);
		/* cli acap not used. Linux thread will be triggering the
		 * acap. We set the cli acap owner to the current thread for
		 * access control only.*/
		srv_acap = acap & 0xFFFF;
		cos_trans_cntl(COS_TRANS_ACAP, channel, srv_acap, 0);

		while (1) {
			int ret;
			if (-1 == (ret = cos_ainv_wait(srv_acap))) BUG();
			assert(channels[channel].t);
			evt_trigger(cos_spd_id(), channels[channel].t->evtid);
		}
	}

	return 0;
}
示例#3
0
/* Return the acap (value) of the current thread (for the static cap_id) on
 * the client side. Major setup done in this function. */
int acap_cli_lookup(int spdid, int cap_id, int thd_init_idx) 
{
	int srv_thd_id, acap_id, acap_v, srv_acap, cspd, sspd, ret;
	struct srv_thd_info *srv_thd;
	struct cli_thd_info *cli_thd_info;
	struct comp_info *ci = &comp_info[spdid];
	int thd_id = cos_get_thd_id();

	if (unlikely(cap_id > ci->ncaps)) goto err_cap;
	assert(ci->cap);

	cspd = spdid;
	sspd = ci->cap[cap_id].srv_comp;

	cli_thd_info = ci->cli_thd_info[thd_id];

	if (cli_thd_info == NULL) {
		ci->cli_thd_info[thd_id] = malloc(sizeof(struct cli_thd_info));
		cli_thd_info = ci->cli_thd_info[thd_id];
		cli_thd_info->ncaps = ci->ncaps;
		cli_thd_info->cap_info = malloc(sizeof(struct per_cap_thd_info) * ci->ncaps);
	}
	if (unlikely(cli_thd_info == NULL || cli_thd_info->cap_info == NULL)) {
		printc("acap mgr %ld: cannot allocate memory for thd_info structure.\n", cos_spd_id());
		goto err;
	}

	if (cli_thd_info->cap_info[cap_id].acap > 0) //already exist?
		return cli_thd_info->cap_info[cap_id].acap;

	/* TODO: lookup some decision table (set by the policy) to
	 * decide whether create a acap for the current thread and the
	 * destination cpu */
	//also, if an acap can be used for multiple s_caps, reflect it here.
//	lookup(thd_id, spdid, cap_id);
// and if we want this thread use static cap, return 0
	int cpu = 1;

	/* create server thd. */
	srv_thd_id = create_thd_curr_prio(cpu, sspd, thd_init_idx);
	/* printc("Created handling thread %d on cpu %d\n", srv_thd_id, cpu); */
	srv_thd = &srv_thd_info[srv_thd_id];
	srv_thd->cli_spd_id = cspd;
	srv_thd->srv_spd_id = sspd;

	srv_thd->cli_thd = thd_id;
	srv_thd->cli_cap_id = cap_id;
	cli_thd_info->cap_info[cap_id].cap_srv_thd = srv_thd_id;

	/* create acap between cspd and sspd */

	ret = cos_async_cap_cntl(COS_ACAP_CREATE, cspd, sspd, srv_thd_id);
	acap_id = ret >> 16;
	srv_acap = ret & 0xFFFF;
	if (acap_id <= 0) { 
		printc("err: async cap creation failed.");
		goto err; 
	}
	acap_v = acap_id | COS_ASYNC_CAP_FLAG;
	cli_thd_info->cap_info[cap_id].acap = acap_v; /* client side acap */

	if (srv_acap <= 0) {
		printc("Server acap allocation failed for thread %d.\n", srv_thd_id);
		goto err;
	}
	srv_thd->srv_acap = srv_acap;

	ret = shared_page_setup(srv_thd_id);
	if (ret < 0) {
		printc("par_mgr: ring buffer allocation error!\n");
		goto err;
	}

	if (sched_wakeup(cos_spd_id(), srv_thd_id)) BUG();

	/* printc("par_mgr returning acap %d (%d), thd %d\n",  */
	/*        acap_v, acap_v & ~COS_ASYNC_CAP_FLAG, cos_get_thd_id()); */

	return acap_v;
err_cap:
	printc("par_mgr: thread %d calling lookup for non-existing cap %d in component %d.\n",
	       thd_id, cap_id, spdid);
err:
	return 0;
}