int main() { node* nodes[5]; int i; for(i=0;i<5;++i) { nodes[i]=create_node(); if(i!=0) { nodes[i-1]->next=nodes[i]; } } nodes[4]->next=nodes[2]; for(i=0;i<5;++i) { printf("node %d,self:%p,next:%p\n",i,nodes[i],nodes[i]->next); } if(has_cycle(nodes[0])) { printf("has cycle!\n"); } else { printf("not has cycle!\n"); } return 0; }
struct path *find_shortest_ (int **weights, struct path **cache, struct node **graph, int id1, int id2) { printf ("id1: %d, id2: %d\n", id1, id2); if (id1 == id2) { struct path *stub = new_path (id1); cache[id1] = stub; return stub; } // If the path passed to us is a cycl //struct node *start = get_node (graph, id1); struct node *end = get_node (graph, id2); // Get all of the shortest paths for the predecessors // Also, the shortest path to us is us plus the shortest of the paths to our // predecessors int i; int min = 65535; int minpath = 0; for (i = 0; i < end->num_back; i++) { struct path *cur = cache[end->back[i]]; // Only do work if we have to if (cur == NULL) { cur = find_shortest_ (weights, cache, graph, id1, end->back[i]); } // Now we definitely have a value if (cur->numelems > 0 && cur->length + weights[end->back[i]][id2] < min) { min = cur->length + weights[end->back[i]][id2]; minpath = end->back[i]; } } // If there's no path, return that // We also get here if there's nobody behind us if (min == 65535) return no_path (); // Add us to the cache and return struct path *our_shortest = add_stop (weights, cache[minpath], minpath, id2); // If we've cycled (only happens if there's a negative cycle) then print out // that we have a negative cycle and the path that has it // Might not terminate if we do... Hmm... if (has_cycle (our_shortest)) { printf ("======== We have a cycle =======\n"); print_path (our_shortest); printf("================\n"); } // Add us to the cache cache[id2] = our_shortest; return our_shortest; }
void enlist_conn(conn *c, conn **list) { LIBEVENT_THREAD *thr = c->thread; assert(list == &thr->pending_io); if ((c->list_state & LIST_STATE_PROCESSING) == 0) { assert(!list_contains(thr->pending_io, c)); assert(c->next == NULL); c->next = *list; *list = c; assert(list_contains(*list, c)); assert(!has_cycle(*list)); } else { c->list_state |= LIST_STATE_REQ_PENDING_IO; } }
int main() { list *head = create(); int i, y; for (i = 0; i < 8; i++) { put(head, i); } show(head); head->next = reverse(head); show(head); while (!is_empty(head)) { y = get(head); printf("y=%d\n", y); } cycle_create(head); printf("has cycle: %d\n", has_cycle(head)); }
void test_has_cycle(void) { int i; node nodes[25]; //enough to run our tests for(i=0; i < sizeof(nodes)/sizeof(node); i++) { nodes[i].next = 0; nodes[i].value = 0; } nodes[0].next = &nodes[1]; nodes[1].next = &nodes[2]; nodes[2].next = &nodes[3]; printf("Checking first list for cycles. There should be none, has_cycle says it has %s cycle\n", has_cycle(&nodes[0])?"a":"no"); nodes[4].next = &nodes[5]; nodes[5].next = &nodes[6]; nodes[6].next = &nodes[7]; nodes[7].next = &nodes[8]; nodes[8].next = &nodes[9]; nodes[9].next = &nodes[10]; nodes[10].next = &nodes[4]; printf("Checking second list for cycles. There should be a cycle, has_cycle says it has %s cycle\n", has_cycle(&nodes[4])?"a":"no"); nodes[11].next = &nodes[12]; nodes[12].next = &nodes[13]; nodes[13].next = &nodes[14]; nodes[14].next = &nodes[15]; nodes[15].next = &nodes[16]; nodes[16].next = &nodes[17]; nodes[17].next = &nodes[14]; printf("Checking third list for cycles. There should be a cycle, has_cycle says it has %s cycle\n", has_cycle(&nodes[11])?"a":"no"); nodes[18].next = &nodes[18]; printf("Checking fourth list for cycles. There should be a cycle, has_cycle says it has %s cycle\n", has_cycle(&nodes[18])?"a":"no"); nodes[19].next = &nodes[20]; nodes[20].next = &nodes[21]; nodes[21].next = &nodes[22]; nodes[22].next = &nodes[23]; printf("Checking fifth list for cycles. There should be none, has_cycle says it has %s cycle\n", has_cycle(&nodes[19])?"a":"no"); printf("Checking length-zero list for cycles. There should be none, has_cycle says it has %s cycle\n", has_cycle(NULL)?"a":"no"); }
static void libevent_tap_process(int fd, short which, void *arg) { LIBEVENT_THREAD *me = arg; assert(me->type == TAP); if (recv(fd, devnull, sizeof(devnull), 0) == -1) { if (settings.verbose > 0) { settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL, "Can't read from libevent pipe: %s\n", strerror(errno)); } } if (memcached_shutdown) { event_base_loopbreak(me->base); return ; } // Do we have pending closes? const size_t max_items = 256; LOCK_THREAD(me); conn *pending_close[max_items]; size_t n_pending_close = 0; if (me->pending_close && me->last_checked != current_time) { assert(!has_cycle(me->pending_close)); me->last_checked = current_time; n_pending_close = list_to_array(pending_close, max_items, &me->pending_close); } // Now copy the pending IO buffer and run them... conn *pending_io[max_items]; size_t n_items = list_to_array(pending_io, max_items, &me->pending_io); UNLOCK_THREAD(me); for (size_t i = 0; i < n_items; ++i) { conn *c = pending_io[i]; assert(c->thread == me); LOCK_THREAD(c->thread); assert(me == c->thread); settings.extensions.logger->log(EXTENSION_LOG_DEBUG, NULL, "Processing tap pending_io for %d\n", c->sfd); UNLOCK_THREAD(me); if (!c->registered_in_libevent) { register_event(c, NULL); } /* * We don't want the thread to keep on serving all of the data * from the context of the notification pipe, so just let it * run one time to set up the correct mask in libevent */ c->nevents = 1; c->which = EV_WRITE; while (c->state(c)) { /* do task */ } } /* Close any connections pending close */ for (size_t i = 0; i < n_pending_close; ++i) { conn *ce = pending_close[i]; if (ce->refcount == 1) { settings.extensions.logger->log(EXTENSION_LOG_DEBUG, NULL, "OK, time to nuke: %p\n", (void*)ce); assert(ce->next == NULL); conn_close(ce); pending_close[i] = NULL; } else { LOCK_THREAD(me); enlist_conn(ce, &me->pending_close); UNLOCK_THREAD(me); } } LOCK_THREAD(me); finalize_list(pending_io, n_items); finalize_list(pending_close, n_pending_close); UNLOCK_THREAD(me); }