// ------------------------------------------------------------------------------------------------ static void ehci_remove_qh(EHCI_QH* qh) { EHCI_QH* prev = link_data(qh->qh_link.prev, EHCI_QH, qh_link); prev->qhlp = qh->qhlp; link_remove(&qh->qh_link); }
int main(void) { // link_head_init(&link_head); int a[5] = {1,2,3,4,5}; int i; node_t *tmp = NULL; for (i = 0; i < 5; i++) link_head = link_insert_e(link_head, a[i]); link_print(link_head); //tmp = link_search(link_head, 4); //printf("%d\n", tmp->val); tmp = link_remove(link_head, 3); link_node_free(tmp); link_print(link_head); link_destroy(link_head); return 0; }
static void processEvent_Apple_Network(struct kern_event_msg *ev_msg) { const char * eventName = NULL; int dataLen = (ev_msg->total_size - KEV_MSG_HEADER_SIZE); void * event_data = &ev_msg->event_data[0]; Boolean handled = TRUE; char ifr_name[IFNAMSIZ]; switch (ev_msg->kev_subclass) { case KEV_INET_SUBCLASS : { eventName = inetEventNameString(ev_msg->event_code); switch (ev_msg->event_code) { case KEV_INET_NEW_ADDR : case KEV_INET_CHANGED_ADDR : case KEV_INET_ADDR_DELETED : case KEV_INET_SIFDSTADDR : case KEV_INET_SIFBRDADDR : case KEV_INET_SIFNETMASK : { struct kev_in_data * ev; ev = (struct kev_in_data *)event_data; if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name)); interface_update_ipv4(NULL, ifr_name); break; } case KEV_INET_ARPCOLLISION : { struct kev_in_collision * ev; ev = (struct kev_in_collision *)event_data; if ((dataLen < sizeof(*ev)) || (dataLen < (sizeof(*ev) + ev->hw_len))) { handled = FALSE; break; } copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name)); interface_collision_ipv4(ifr_name, ev->ia_ipaddr, ev->hw_len, ev->hw_addr); break; } #if !TARGET_OS_IPHONE case KEV_INET_PORTINUSE : { struct kev_in_portinuse * ev; ev = (struct kev_in_portinuse *)event_data; if (dataLen < sizeof(*ev)) { handled = FALSE; break; } port_in_use_ipv4(ev->port, ev->req_pid); break; } #endif /* !TARGET_OS_IPHONE */ default : handled = FALSE; break; } break; } case KEV_INET6_SUBCLASS : { struct kev_in6_data * ev; eventName = inet6EventNameString(ev_msg->event_code); ev = (struct kev_in6_data *)event_data; switch (ev_msg->event_code) { case KEV_INET6_NEW_USER_ADDR : case KEV_INET6_CHANGED_ADDR : case KEV_INET6_ADDR_DELETED : case KEV_INET6_NEW_LL_ADDR : case KEV_INET6_NEW_RTADV_ADDR : case KEV_INET6_DEFROUTER : if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name)); interface_update_ipv6(NULL, ifr_name); break; default : handled = FALSE; break; } break; } case KEV_DL_SUBCLASS : { struct net_event_data * ev; eventName = dlEventNameString(ev_msg->event_code); ev = (struct net_event_data *)event_data; switch (ev_msg->event_code) { case KEV_DL_IF_ATTACHED : /* * new interface added */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); link_add(ifr_name); break; case KEV_DL_IF_DETACHED : /* * interface removed */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); link_remove(ifr_name); break; case KEV_DL_IF_DETACHING : /* * interface detaching */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); interface_detaching(ifr_name); break; case KEV_DL_PROTO_ATTACHED : case KEV_DL_PROTO_DETACHED : { struct kev_dl_proto_data * protoEvent; protoEvent = (struct kev_dl_proto_data *)event_data; if (dataLen < sizeof(*protoEvent)) { handled = FALSE; break; } copy_if_name(&protoEvent->link_data, ifr_name, sizeof(ifr_name)); if (protoEvent->proto_remaining_count == 0) { mark_if_down(ifr_name); } else { mark_if_up(ifr_name); } break; } #ifdef KEV_DL_IF_IDLE_ROUTE_REFCNT case KEV_DL_IF_IDLE_ROUTE_REFCNT: { /* * interface route refcnt idle */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); interface_update_idle_state(ifr_name); break; } #endif // KEV_DL_IF_IDLE_ROUTE_REFCNT case KEV_DL_LINK_OFF : case KEV_DL_LINK_ON : /* * update the link status in the store */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); link_update_status(ifr_name, FALSE); break; #ifdef KEV_DL_LINK_QUALITY_METRIC_CHANGED case KEV_DL_LINK_QUALITY_METRIC_CHANGED: { struct kev_dl_link_quality_metric_data * lqm_data; lqm_data = (struct kev_dl_link_quality_metric_data *) event_data; if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); interface_update_quality_metric(ifr_name, lqm_data->link_quality_metric); break; } #endif // KEV_DL_LINK_QUALITY_METRIC_CHANGED #ifdef KEV_DL_ISSUES case KEV_DL_ISSUES: { struct kev_dl_issues *issues; issues = (struct kev_dl_issues *)event_data; if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); interface_update_link_issues(ifr_name, issues->timestamp, issues->modid, DLIL_MODIDLEN, issues->info, (bcmp(issues->info, info_zero, DLIL_MODIDLEN) != 0) ?DLIL_MODARGLEN :0); break; } #endif // KEV_DL_ISSUES case KEV_DL_SIFFLAGS : case KEV_DL_SIFMETRICS : case KEV_DL_SIFMTU : case KEV_DL_SIFPHYS : case KEV_DL_SIFMEDIA : case KEV_DL_SIFGENERIC : case KEV_DL_ADDMULTI : case KEV_DL_DELMULTI : case KEV_DL_LINK_ADDRESS_CHANGED : case KEV_DL_WAKEFLAGS_CHANGED : #ifdef KEV_DL_IFCAP_CHANGED case KEV_DL_IFCAP_CHANGED : #endif // KEV_DL_IFCAP_CHANGED break; default : handled = FALSE; break; } break; } #ifdef KEV_ND6_SUBCLASS case KEV_ND6_SUBCLASS : { eventName = nd6EventNameString(ev_msg->event_code); switch (ev_msg->event_code) { case KEV_KEV_ND6_RA : break; default : handled = FALSE; break; } break; } #endif // KEV_ND6_SUBCLASS case KEV_LOG_SUBCLASS : { break; } default : handled = FALSE; break; } if (handled == FALSE) { CFStringRef evStr; evStr = CFStringCreateWithCString(NULL, (eventName != NULL) ? eventName : "New Apple network subclass", kCFStringEncodingASCII); logEvent(evStr, ev_msg); CFRelease(evStr); } return; }
static void processEvent_Apple_Network(struct kern_event_msg *ev_msg) { const char * eventName = NULL; int dataLen = (ev_msg->total_size - KEV_MSG_HEADER_SIZE); void * event_data = &ev_msg->event_data[0]; Boolean handled = TRUE; char ifr_name[IFNAMSIZ+1]; switch (ev_msg->kev_subclass) { case KEV_INET_SUBCLASS : { eventName = inetEventNameString(ev_msg->event_code); switch (ev_msg->event_code) { case KEV_INET_NEW_ADDR : case KEV_INET_CHANGED_ADDR : case KEV_INET_ADDR_DELETED : case KEV_INET_SIFDSTADDR : case KEV_INET_SIFBRDADDR : case KEV_INET_SIFNETMASK : { struct kev_in_data * ev; ev = (struct kev_in_data *)event_data; if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name)); interface_update_ipv4(NULL, ifr_name); break; } case KEV_INET_ARPCOLLISION : { struct kev_in_collision * ev; ev = (struct kev_in_collision *)event_data; if ((dataLen < sizeof(*ev)) || (dataLen < (sizeof(*ev) + ev->hw_len))) { handled = FALSE; break; } copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name)); interface_collision_ipv4(ifr_name, ev->ia_ipaddr, ev->hw_len, ev->hw_addr); break; } default : handled = FALSE; break; } break; } case KEV_INET6_SUBCLASS : { struct kev_in6_data * ev; eventName = inet6EventNameString(ev_msg->event_code); ev = (struct kev_in6_data *)event_data; switch (ev_msg->event_code) { case KEV_INET6_NEW_USER_ADDR : case KEV_INET6_CHANGED_ADDR : case KEV_INET6_ADDR_DELETED : case KEV_INET6_NEW_LL_ADDR : case KEV_INET6_NEW_RTADV_ADDR : case KEV_INET6_DEFROUTER : if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name)); interface_update_ipv6(NULL, ifr_name); break; default : handled = FALSE; break; } break; } case KEV_DL_SUBCLASS : { struct net_event_data * ev; eventName = dlEventNameString(ev_msg->event_code); ev = (struct net_event_data *)event_data; switch (ev_msg->event_code) { case KEV_DL_IF_ATTACHED : /* * new interface added */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); link_add(ifr_name); break; case KEV_DL_IF_DETACHED : /* * interface removed */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); link_remove(ifr_name); break; case KEV_DL_IF_DETACHING : /* * interface detaching */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); interface_detaching(ifr_name); break; case KEV_DL_SIFFLAGS : case KEV_DL_SIFMETRICS : case KEV_DL_SIFMTU : case KEV_DL_SIFPHYS : case KEV_DL_SIFMEDIA : case KEV_DL_SIFGENERIC : case KEV_DL_ADDMULTI : case KEV_DL_DELMULTI : handled = FALSE; break; case KEV_DL_PROTO_ATTACHED : case KEV_DL_PROTO_DETACHED : { struct kev_dl_proto_data * protoEvent; protoEvent = (struct kev_dl_proto_data *)event_data; if (dataLen < sizeof(*protoEvent)) { handled = FALSE; break; } copy_if_name(&protoEvent->link_data, ifr_name, sizeof(ifr_name)); if (protoEvent->proto_remaining_count == 0) { mark_if_down(ifr_name); } else { mark_if_up(ifr_name); } break; } case KEV_DL_LINK_OFF : case KEV_DL_LINK_ON : /* * update the link status in the store */ if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(ev, ifr_name, sizeof(ifr_name)); link_update_status(ifr_name, FALSE); break; default : handled = FALSE; break; } break; } case KEV_ATALK_SUBCLASS: { struct kev_atalk_data * ev; eventName = atalkEventNameString(ev_msg->event_code); ev = (struct kev_atalk_data *)event_data; if (dataLen < sizeof(*ev)) { handled = FALSE; break; } copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name)); switch (ev_msg->event_code) { case KEV_ATALK_ENABLED: interface_update_atalk_address(ev, ifr_name); break; case KEV_ATALK_DISABLED: interface_update_shutdown_atalk(); break; case KEV_ATALK_ZONEUPDATED: interface_update_atalk_zone(ev, ifr_name); break; case KEV_ATALK_ROUTERUP: case KEV_ATALK_ROUTERUP_INVALID: case KEV_ATALK_ROUTERDOWN: interface_update_appletalk(NULL, ifr_name); break; case KEV_ATALK_ZONELISTCHANGED: break; default : handled = FALSE; break; } break; } default : handled = FALSE; break; } if (handled == FALSE) { CFStringRef evStr; evStr = CFStringCreateWithCString(NULL, (eventName != NULL) ? eventName : "New Apple network subclass", kCFStringEncodingASCII); logEvent(evStr, ev_msg); CFRelease(evStr); } return; }
/* * Burn CPU at a steady rate in this worker. */ void* cpuworker(void *opts) { int rc; int cpu_index; int32_t target_epochs; int64_t next_deadline; int64_t target_cpuwork; int64_t link_waittime; double curr_epochs; double epochs_per_link; cpu_opts *cpu; cpu_burn_opts cbopts; gamut_opts *gopts; struct timeval start; struct timeval finish; struct timeval finish_time; if(!opts) return NULL; gopts = (gamut_opts *)opts; cpu_index = worker_register(gopts, CLS_CPU); if(cpu_index < 0) { return NULL; } else { cpu = &gopts->cpu[cpu_index]; } /* * See if we need to wait for another linked worker * to set us off. */ rc = link_start_wait(gopts, CLS_CPU, cpu_index); if(rc < 0) { return NULL; } (void)gettimeofday(&cpu->shopts.start_time, NULL); cpu->total_work = 0; cpu->shopts.missed_deadlines = 0; cpu->shopts.missed_usecs = 0; cpu->shopts.total_deadlines = 0; link_waittime = 0; restart: (void)gettimeofday(&cpu->shopts.mod_time, NULL); cpu->shopts.dirty = 0; target_cpuwork = 0; epochs_per_link = 0.0; curr_epochs = 0.0; target_epochs = 0; rc = validate_worker_opts(opts, CLS_CPU, cpu_index); if(rc <= 0) { s_log(G_WARNING, "%s has invalid settings.\n", cpu->shopts.label); goto clean_out; } /* * We set the timer and deadline first so any delays in starting our * work are absorbed; we'll catch up if necessary. */ { struct timeval tv; (void)gettimeofday(&tv, NULL); if(cpu->shopts.exec_time) { finish_time.tv_sec = tv.tv_sec + cpu->shopts.exec_time; finish_time.tv_usec = tv.tv_usec; } else { finish_time.tv_sec = 0; finish_time.tv_usec = 0; } next_deadline = tv.tv_usec; next_deadline += tv.tv_sec * US_SEC; } memset(&cbopts, 0, sizeof(cbopts)); cbopts.count64 = (uint64_t)(second_count * cpu->percent_cpu) / (100 * WORKER_EPOCHS_PER_SEC); s_log(G_INFO, "%s will do %lld CPU work per epoch.\n", cpu->shopts.label, cbopts.count64); if(cpu->shopts.max_work) { target_cpuwork = cpu->shopts.max_work / cbopts.count64; /* * If the target work is 0, it's less than an epoch's worth. * Do one iteration anyway. */ if(!target_cpuwork) target_cpuwork = 1; } else { target_cpuwork = -1; } /* * Make sure that if we've been asked to be part of a link, * that we've got enough information to be sure that the * link will actually work. */ if(cpu->shopts.link_work && cpu->shopts.next_worker) { shared_opts *link_shopts; epochs_per_link = (double)cpu->shopts.link_work / cbopts.count64; curr_epochs = epochs_per_link; target_epochs = (int32_t)curr_epochs; link_shopts = (shared_opts *)cpu->shopts.next_worker; s_log(G_DEBUG, "Will do %.2f epochs per link, handing off to %s.\n", epochs_per_link, link_shopts->label); } else { target_epochs = -1; } /* * Each time through, perform these operations in this order: * 1. Calculate the next deadline * 2. Perform the CPU work * 3. If we're linked with another worker, see if it's handoff time * 4. See if it's time to exit * 5. Sleep, if there's enough time */ (void)gettimeofday(&start, NULL); while(!cpu->shopts.exiting) { struct timeval now; /* Steps 1, 2 & 3 */ if(target_epochs < 0) { /* * Just step 1 & 2 (burn CPU) since there are no links here. */ next_deadline += US_PER_WORKER_EPOCH; cpu->cbfunc(cpu, &cbopts); } else /* (target_epochs >= 0) */ { if(target_epochs > 0) { next_deadline += US_PER_WORKER_EPOCH; cpu->cbfunc(cpu, &cbopts); target_epochs--; } /* * If we do have to wait, make sure we don't over-work * when it's our turn. Move the next_deadline backward * by as much time as we spend waiting. */ if(!target_epochs) { int64_t timediff; struct timeval b_link; (void)gettimeofday(&b_link, NULL); rc = link_next_wait(gopts, CLS_CPU, cpu_index, epochs_per_link, &curr_epochs, &target_epochs); if(rc < 0) { s_log(G_WARNING, "Error in link_next_wait.\n"); } else if(!rc) { s_log(G_DEBUG, "We need to exit (link_wait says so).\n"); break; } else { struct timeval f_link; (void)gettimeofday(&f_link, NULL); s_log(G_DEBUG, "EL %.2f CE %.2f TE %d\n", epochs_per_link, curr_epochs, target_epochs); timediff = calculate_timediff(&b_link, &f_link); next_deadline += timediff; link_waittime += timediff; s_log(G_DEBUG, "Moved next deadline backward by %lld usec.\n", timediff); } } } /* Step 4 */ if(target_cpuwork > 0) { target_cpuwork--; if(!target_cpuwork) { cpu->shopts.exiting = 1; break; } } /* Step 5 */ (void)gettimeofday(&now, NULL); if(!finish_time.tv_sec || (finish_time.tv_sec > now.tv_sec) || ((finish_time.tv_sec == now.tv_sec) && (finish_time.tv_usec > now.tv_usec) ) ) { /* * Either there isn't a deadline * or there is one, but we're a few seconds short * or we're spot-on with the seconds * and the usecs are short. */ int64_t time_diff; int64_t current_time; current_time = now.tv_usec; current_time += now.tv_sec * US_SEC; time_diff = next_deadline - current_time; s_log(G_DLOOP, "TD %lld\n", time_diff); if(current_time < next_deadline) { if(time_diff > MIN_SLEEP_US) { struct timeval sleeptv; sleeptv.tv_sec = time_diff / US_SEC; sleeptv.tv_usec = time_diff - (sleeptv.tv_sec * US_SEC); s_log(G_DLOOP, "%s sleep.\n", cpu->shopts.label); (void)select(0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &sleeptv); s_log(G_DLOOP, "%s woke.\n", cpu->shopts.label); } } else { cpu->shopts.missed_deadlines++; cpu->shopts.missed_usecs += (current_time - next_deadline); } cpu->shopts.total_deadlines++; } else { cpu->shopts.exiting = 1; break; } if(cpu->shopts.dirty) { s_log(G_INFO, "%s reloading values.\n", cpu->shopts.label); goto restart; } } (void)gettimeofday(&finish, NULL); rc = lock_stats(gopts); if(rc < 0) { goto clean_out; } gopts->wstats.workers_exiting++; (void)unlock_stats(gopts); clean_out: if(cpu->total_work) { int64_t cpu_usec; int64_t total_usec; uint64_t avg_miss_time; double cputime; double totaltime; total_usec = calculate_timediff(&start, &finish); cpu_usec = total_usec - link_waittime; totaltime = (double)total_usec / US_SEC; cputime = (double)cpu_usec / US_SEC; if(cpu->shopts.missed_deadlines) { avg_miss_time = cpu->shopts.missed_usecs / cpu->shopts.missed_deadlines; } else { avg_miss_time = 0; } s_log(G_NOTICE, "%s did %llu CPU work in %.3f sec (total).\n", cpu->shopts.label, cpu->total_work, totaltime); /* * Only print this out if we spent any time waiting on a link. */ if(link_waittime) { s_log(G_NOTICE, "%s did %llu CPU work in %.3f sec (working).\n", cpu->shopts.label, cpu->total_work, cputime); } s_log(G_INFO, "%s missed %llu of %llu deadlines by %llu usecs (avg).\n", cpu->shopts.label, cpu->shopts.missed_deadlines, cpu->shopts.total_deadlines, avg_miss_time); } /* * Remove ourselves from any link. */ rc = link_remove(gopts, CLS_CPU, cpu_index); if(rc < 0) { s_log(G_WARNING, "Error removing %s from any link.\n", cpu->shopts.label); } /* * Something has come along and decided we need to go. * Clean up state behind us. */ (void)worker_unregister(gopts, CLS_CPU); return NULL; }