Skip to content

Commit

Permalink
ring: improve looping over links
Browse files Browse the repository at this point in the history
Signed-off-by: Federico Simoncelli <federico.simoncelli@gmail.com>
  • Loading branch information
simon3z committed Dec 3, 2010
1 parent 10a377f commit c06be3a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 30 deletions.
57 changes: 36 additions & 21 deletions ring.c
Expand Up @@ -151,28 +151,34 @@ int knet_host_release(knet_handle_t knet_h)
return pthread_rwlock_unlock(&knet_h->list_rwlock);
}

int knet_link_foreach(knet_handle_t knet_h, knet_link_fn_t linkfn, void *data)
int knet_link_foreach(struct knet_link_search *data, knet_link_fn_t linkfn)
{
int lockstatus, i;
struct knet_host *host;
int lockstatus, i, ret;

lockstatus = pthread_rwlock_tryrdlock(&knet_h->list_rwlock);
lockstatus = pthread_rwlock_rdlock(&data->knet_h->list_rwlock);

if ((lockstatus != 0) && (lockstatus != EDEADLK)) {
return -EBUSY;
}

for (host = knet_h->host_head; host != NULL; host = host->next) {
data->host = data->knet_h->host_head;

for (; data->host != NULL; data->host = data->host->next) {
for (i = 0; i < KNET_MAX_LINK; i++) {
if (host->link[i].ready != 1) continue;
if (linkfn(knet_h, host, &host->link[i], data) == 1)
if (data->host->link[i].ready != 1) continue;

ret = linkfn(data, &data->host->link[i]);

if (ret == KNET_LINK_FOREACH_SKIP)
break;
else if (ret == KNET_LINK_FOREACH_FOUND)
goto exit_unlock;
}
}

exit_unlock:
if (lockstatus == 0)
pthread_rwlock_unlock(&knet_h->list_rwlock);
pthread_rwlock_unlock(&data->knet_h->list_rwlock);

return 0;
}
Expand Down Expand Up @@ -314,26 +320,33 @@ int knet_listener_add(knet_handle_t knet_h, struct knet_listener *listener)
return -1;
}

static int check_listener_sock(struct knet_link_search *data, struct knet_link *j)
{
if (j->sock == data->param1) {
data->retval = -EBUSY;
return KNET_LINK_FOREACH_FOUND;
}

return KNET_LINK_FOREACH_NEXT;
}

int knet_listener_remove(knet_handle_t knet_h, struct knet_listener *listener)
{
int ret, j;
struct epoll_event ev; /* kernel < 2.6.9 bug (see epoll_ctl man) */
struct knet_listener *lp;
struct knet_host *i;
struct knet_link_search check_search;

if (pthread_rwlock_wrlock(&knet_h->list_rwlock) != 0)
return -1;
return -EINVAL;

ret = 0;
check_search.knet_h = knet_h;
check_search.retval = 0;
check_search.param1 = listener->sock;

for (i = knet_h->host_head; i != NULL; i = i->next) {
for (j = 0; j < KNET_MAX_LINK; j++) {
if (i->link[j].sock == listener->sock) {
errno = ret = EBUSY;
goto exit_fail1;
}
}
}
knet_link_foreach(&check_search, check_listener_sock);

if (check_search.retval != 0)
goto exit_fail1;

/* TODO: use a doubly-linked list? */
if (listener == knet_h->listener_head) {
Expand All @@ -353,7 +366,9 @@ int knet_listener_remove(knet_handle_t knet_h, struct knet_listener *listener)
exit_fail1:
pthread_rwlock_unlock(&knet_h->list_rwlock);

return (ret > 0) ? -ret : ret;
if (check_search.retval != 0) errno = check_search.retval;

return check_search.retval;
}

void knet_link_timeout(struct knet_link *lnk,
Expand Down
16 changes: 14 additions & 2 deletions ring.h
Expand Up @@ -89,8 +89,20 @@ int knet_host_remove(knet_handle_t khandle, struct knet_host *host);

void knet_link_timeout(struct knet_link *lnk, time_t interval, time_t timeout, int precision);

typedef int (*knet_link_fn_t)(knet_handle_t knet_h, struct knet_host *host, struct knet_link *link, void *data);
int knet_link_foreach(knet_handle_t knet_h, knet_link_fn_t linkfn, void *data);
#define KNET_LINK_FOREACH_NEXT 0 /* next link */
#define KNET_LINK_FOREACH_SKIP 1 /* skip to next host */
#define KNET_LINK_FOREACH_FOUND 2 /* loop stop */

struct knet_link_search {
knet_handle_t knet_h;
struct knet_host *host;
int param1;
int retval;
void *data;
};

typedef int (*knet_link_fn_t)(struct knet_link_search *data, struct knet_link *link);
int knet_link_foreach(struct knet_link_search *data, knet_link_fn_t linkfn);

int knet_listener_acquire(knet_handle_t knet_h, struct knet_listener **head, int writelock);
int knet_listener_release(knet_handle_t knet_h);
Expand Down
17 changes: 10 additions & 7 deletions tests/ping_test.c
Expand Up @@ -113,11 +113,12 @@ static void argv_to_hosts(int argc, char *argv[])
* # tc -d qdisc show dev lo
* # tc qdisc del dev lo root
*/
static int print_link(knet_handle_t handle, struct knet_host *i, struct knet_link *j, void *data)
static int print_link(struct knet_link_search *data, struct knet_link *j)
{
printf("link %p latency is %llums, status: %s\n",
j, j->latency, (j->enabled == 0) ? "disabled" : "enabled");
return 0;
printf("host %p, link %p latency is %llums, status: %s\n",
data->host, j, j->latency, (j->enabled == 0) ? "disabled" : "enabled");

return KNET_LINK_FOREACH_NEXT;
}

static void sigint_handler(int signum)
Expand All @@ -144,6 +145,7 @@ int main(int argc, char *argv[])
size_t len;
fd_set rfds;
struct timeval tv;
struct knet_link_search print_search;

if (argc < 3) {
print_usage(argv[0]);
Expand All @@ -167,12 +169,13 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}

print_search.knet_h = knet_h;

argv_to_hosts(argc, argv);

knet_handle_setfwd(knet_h, 1);
knet_handle_setfwd(knet_h, 1);

while (1) {
knet_link_foreach(knet_h, print_link, NULL);
knet_link_foreach(&print_search, print_link);

log_info("Sending 'Hello World!' frame");
write(knet_sock[1], "Hello World!", 13);
Expand Down

0 comments on commit c06be3a

Please sign in to comment.