/*************************************************************************** * Function: void flush_output() * * Description: * Use select() to determine which connections that have output pending * are capable of accepting output at the moment, and send as much data to * those connections as they will accept. **************************************************************************/ void flush_output() { conn_data *conn; fd_set fd_outset; struct timeval sel_timeout; iterator *conn_iter = create_iter(conn_list);; /* * Clear out the fd_set and add to it the fds of all connections with * output pending. */ FD_ZERO(&fd_outset); for (init_iter(conn_iter); (conn = peek_iter(conn_iter)); iterate_iter(conn_iter)) { if (length_list(conn->output) != 0) FD_SET(conn->fd, &fd_outset); } /* * Use select to determine which fds actually belong in the set. * (NOFILE is the maximum number of open files per process, as described * previously) */ bzero(&sel_timeout, sizeof(struct timeval)); if (select(NOFILE, NULL, &fd_outset, NULL, &sel_timeout) <0 ) { fprintf(stderr, "Error: Selection of ready file descriptors failed.\n"); perror(" flush_output(select)"); exit(ERROR); } /* * Process connections with pending output. Note that it is necessary to * iterate the iterator _before_ executing the loop in case the connection * we're currently working on gets disconnected. */ for (init_iter(conn_iter); (conn = peek_iter(conn_iter)); ) { iterate_iter(conn_iter); if (FD_ISSET(conn->fd, &fd_outset)) { if (send_text(conn) <= 0) { disconnect(conn); continue; } } } destroy_iter(conn_iter); }
bool parallel_sortTest(size_t n, Minimal * iter, Minimal * sorted_list, const MinimalCompare *compare) { bool passed = true; if (compare == NULL) return passed; init_iter(iter, sorted_list, n, *compare, true); do { REMARK("%s %s p=%llu n=%llu :",current_type.c_str(), test_type.c_str(), static_cast<unsigned long long>(current_p), static_cast<unsigned long long>(n)); tbb::parallel_sort(iter, iter + n, *compare ); if (!Validate(iter, sorted_list, n)) passed = false; REMARK("passed\n"); } while (init_iter(iter, sorted_list, n, *compare, false)); return passed; }
bool parallel_sortTest(size_t n, RandomAccessIterator iter, RandomAccessIterator sorted_list, const Compare *comp) { bool passed = true; Compare local_comp; init_iter(iter, sorted_list, n, local_comp, true); do { REMARK("%s %s p=%llu n=%llu :",current_type.c_str(), test_type.c_str(), static_cast<unsigned long long>(current_p), static_cast<unsigned long long>(n)); if (comp != NULL) { tbb::parallel_sort(iter, iter + n, local_comp ); } else { tbb::parallel_sort(iter, iter + n ); } if (!Validate(iter, sorted_list, n)) passed = false; REMARK("passed\n"); } while (init_iter(iter, sorted_list, n, local_comp, false)); return passed; }
size_t lst_index_of(t_lst *l, void *data) { t_lstiter it; init_iter(&it, l, increasing); while (lst_iterator_next(&it)) { if (it.data == data) return (it.pos); } return (LST_NOINDEX); }
static btSIter *setIterator(btSIter *iter, bt *btr, iter_single *itl, iter_single *itn) { btSIter *siter = iter; siter->dofree = 0; siter->missed = 0; siter->nim = 0; siter->empty = 1; siter->scan = 0; siter->ktype = btr->s.ktype; init_ai_obj(&siter->key); siter->be.key = &(siter->key); siter->be.val = NULL; init_iter(&siter->x, btr, itl, itn); return siter; }
t_material *get_material(const t_scene *scene, const char *name) { t_lstiter it; t_material *material; init_iter(&it, scene->materials, increasing); while (lst_iterator_next(&it)) { material = (t_material*)it.data; if (ft_strequ(material->name, name)) return (material); } return (NULL); }
static void raycast_light(t_hit *hit, unsigned depth) { t_lstiter it; t_ray ray; t_light *light; int raycast_result; t_vec3 lightness; t_hit sub_hit; if (depth == 0) return ; vec3_set(&lightness, 0, 0, 0); init_iter(&it, rt.scene->lights, increasing); while (lst_iterator_next(&it)) { light = (t_light*)it.data; vec3_copy(&ray.origin, &hit->position); vec3_copy(&ray.direction, &light->position); vec3_sub(&ray.direction, &hit->position); vec3_normalize(&ray.direction); ray.origin.x += ray.direction.x * RC_SHADOW_SHIFT; ray.origin.y += ray.direction.y * RC_SHADOW_SHIFT; ray.origin.z += ray.direction.z * RC_SHADOW_SHIFT; raycast_result = raycast(&ray, &sub_hit, depth - 1, NULL); if (sub_hit.object != NULL) { // ray bounce } else { vec3_add(&lightness, &light->color); } } vec3_div(&lightness, rt.scene->lights->size); vec3_add(&lightness, &rt.scene->ambient_light); color_clamp(&lightness); hit->color.x *= lightness.x; hit->color.y *= lightness.y; hit->color.z *= lightness.z; }
void *lst_remove_iterator_node(t_lstiter *it) { void *data; size_t pos; t_node *node; node = it->current; pos = it->pos; lst_iterator_next(it); it->flag = 2; data = lst_remove(it->lst, pos); if (node == it->end) init_iter(it, it->lst, it->dir); else it->pos = pos; return (data); }
int raycast(const t_ray *ray, t_hit *hit, unsigned depth, t_object *exclude) { t_lstiter it; int raycast_result; t_hit closest_hit; t_object *object; hit_reset(hit); if (depth == 0) return (0); hit_reset(&closest_hit); init_iter(&it, rt.scene->objects, increasing); while (lst_iterator_next(&it)) { object = (t_object*)it.data; if (object == exclude) continue ; raycast_result = raycast_to_object(hit, ray, object); if (raycast_result) { if (closest_hit.object == NULL || closest_hit.distance > hit->distance) hit_copy(&closest_hit, hit); } } hit_copy(hit, &closest_hit); if (closest_hit.object == NULL) { return (0); } else { raycast_light(hit, depth); return (1); } }
/*************************************************************************** * Function: void gather_input() * * Description: * Use select() to examine activity on all open sockets/file-descriptors. * This includes new connections on port sockets and input on connection * sockets (and, I suppose, exception states on either). After eliminating * any sockets in exception states, process all input on remaining sockets. **************************************************************************/ void gather_input() { int fd; port_data *port; conn_data *conn; fd_set fd_inset, fd_excset; struct timeval sel_timeout; iterator *conn_iter = create_iter(conn_list); iterator *port_iter = create_iter(port_list); /* * Initialize the input and exception fd_sets to the empty state, then add * all of the port and connection socket file descriptors. * */ FD_ZERO(&fd_inset); FD_ZERO(&fd_excset); for (init_iter(port_iter); (port = peek_iter(port_iter)); iterate_iter(port_iter)) { fd = port->fd; FD_SET(fd, &fd_inset); FD_SET(fd, &fd_excset); } for (init_iter(conn_iter); (conn = peek_iter(conn_iter)); iterate_iter(conn_iter)) { fd = conn->fd; FD_SET(fd, &fd_inset); FD_SET(fd, &fd_excset); } /* * Calling "select" will remove all sockets from each of the fd_sets to * which they don't actually belong. In other words, if there isn't any * input on a given connection (or no new connection on a port), it is * removed from the input set. Note that NOFILE is the maximum number of * open files per process, and, I suspect, is not a portable constant. If * it isn't defined anywhere on your system, you'll probably have to use the * "getrlimit" system call to find out what that number is. Also note that * select will sleep for the amount of time indicated in sel_timeout before * returning, which can be used to regulate how much time is consumed by * each game loop. For now, though, the timeout is set to 0, since we're * using "usleep" in the main loop. */ bzero(&sel_timeout, sizeof(struct timeval)); if (select(NOFILE, &fd_inset, NULL, &fd_excset, &sel_timeout) <0 ) { fprintf(stderr, "Error: Selection of ready file descriptors failed.\n"); perror(" gather_input(select)"); exit(ERROR); } /* * Process all port sockets, checking for new connections and exception states. * Since multiple connections may be pending on a single port, we keep calling * "get_connection" on each port in the input set until that function returns * FALSE, indicating that no more connections are pending on it. */ for (init_iter(port_iter); (port = peek_iter(port_iter)); iterate_iter(port_iter)) { fd = port->fd; if (FD_ISSET(fd, &fd_excset)) { fprintf(stderr, "Error: Exception state on port %d (fd %d).\n", port->portnum, fd); exit(ERROR); } else if (FD_ISSET(fd, &fd_inset)) while (get_connection(fd)); } /* * Process connection sockets, checking for new input and exception conditions. * Note that it is necessary to iterate the iterator _before_ executing the * loop in case the current connection gets disconnected. */ for (init_iter(conn_iter); (conn = peek_iter(conn_iter)); ) { iterate_iter(conn_iter); fd = conn->fd; /* * Check to see if this connection is in an exception state. If it is, * disconnect it. */ if (FD_ISSET(fd, &fd_excset)) { FD_CLR(fd, &fd_inset); disconnect(conn); continue; } /* * Check to see if this connection has pending input. If it does, attempt to * read it all in. If nothing can be read in, disconnect it. */ if (FD_ISSET(fd, &fd_inset)) { if (recv_text(conn) <= 0) { disconnect(conn); continue; } time(&(conn->input_time)); } } destroy_iter(port_iter); destroy_iter(conn_iter); }
iter* new_iter(FILE* f, char* buf, int buflen, char delim) { return init_iter(alloc_iter(),f,buf,buflen,delim); }