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; }
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; }
/* 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; }