//push消息并执行同步操作 static inline void msgque_sync_push(ptq_t ptq) { assert(ptq->mode == MSGQ_WRITE); if(ptq->mode != MSGQ_WRITE) return; msgque_t que = ptq->que; mutex_lock(que->mtx); uint8_t empty = llist_is_empty(&que->share_que); llist_swap(&que->share_que,&ptq->local_que); if(empty){ struct dnode *l = dlist_pop(&que->blocks); if(l){ //if there is a block per_thread_struct wake it up ptq_t block_ptq = (ptq_t)l; mutex_unlock(que->mtx); condition_signal(block_ptq->cond); } } //对所有在can_interrupt中的元素调用回调 while(!dlist_empty(&que->can_interrupt)) { ptq_t ptq = (ptq_t)dlist_pop(&que->can_interrupt); ptq->read_que.notify_function(ptq->read_que.ud); } mutex_unlock(que->mtx); }
void destroy_heap(heap* const h) throw() { dlist_pop(this, h); std::free(h); --m_depth; DBG_PRINTF(("(%p/%d/%d) Dynamic Region Shrink\n", (void*)h, m_depth, m_max_depth)); }
inline void* allocate(std::size_t sz) throw(std::bad_alloc) { sz = ALIGN_SIZE(sz, std::size_t, sizeof(aligner)); if (sz <= T_depth) { heap* h = m_head; while (h) { void* const ptr = h->allocate(sz); if (ptr) { if (h != m_head) { dlist_pop(this, h); dlist_push_head(this, h); DBG_PRINTF(("(%p/%d/%d) Dynamic Region Heap Adjust\n", (void*)h, m_depth, m_max_depth)); } return ptr; } h = h->m_next; } void* const ptr = create_heap()->allocate(sz); if (ptr) { return ptr; } } void* const ptr = std::malloc(sz); if(! ptr) { throw std::bad_alloc(); } return ptr; }
line_t *line_list_pop(line_list_t *list) { dlink_t *link; line_t *line; assert(list); link = dlist_pop((dlist_t *)list); line = (line_t *)link->object; line_dec_ref(line); dlink_destroy(link); return line; }
point_t *point_list_pop(point_list_t *list) { dlink_t *link; point_t *p; assert(list); link = dlist_pop((dlist_t *)list); p = (point_t *)link->object; point_dec_ref(p); dlink_destroy(link); return p; }
void point_list_destroy(point_list_t *list) { dlink_t *link; assert(list); if (point_list_get_ref(list) <= 0) { while (point_list_get_count(list) > 0) { link = dlist_pop((dlist_t *)list); point_destroy((point_t *)link->object); dlink_destroy(link); } dlist_destroy((dlist_t *)list); } else { list->reference--; } }
/* void line_list_delete(line_list_t *list) { dlink_t *link; line_t *line; assert(list); for (link = list->tail->next; link != list->head; link = link->next) { line = (line_t *)link->object; line_(line); } } */ void line_list_destroy(line_list_t *list) { dlink_t *link; assert(list); if (line_list_get_ref(list) <= 0) { while (line_list_get_count(list) > 0) { link = dlist_pop((dlist_t *)list); line_destroy((line_t *)link->object); dlink_destroy(link); } dlist_destroy((dlist_t *)list); } else { line_list_dec_ref(list); } }
int32_t epoll_loop(poller_t n,int32_t ms) { assert(n); if(ms < 0)ms = 0; uint64_t sleep_ms; uint64_t timeout = GetSystemMs64() + (uint64_t)ms; uint64_t current_tick; uint32_t read_event = EV_IN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; int32_t notify = 0; do{ if(!dlist_empty(&n->connecting)) { //check timeout connecting uint64_t l_now = GetSystemMs64(); dlist_check_remove(&n->connecting,check_connect_timeout,(void*)&l_now); } if(!is_active_empty(n)) { struct dlist *actived = get_active_list(n); n->actived_index = (n->actived_index+1)%2; socket_t s; while((s = (socket_t)dlist_pop(actived)) != NULL) { if(Process(s)) putin_active(n,(struct dnode*)s); } } current_tick = GetSystemMs64(); if(is_active_empty(n)) sleep_ms = timeout > current_tick ? timeout - current_tick:0; else sleep_ms = 0; notify = 0; int32_t nfds = _epoll_wait(n->poller_fd,n->events,MAX_SOCKET,(uint32_t)sleep_ms); if(nfds < 0) return -1; int32_t i; for(i = 0 ; i < nfds ; ++i) { if(n->events[i].data.fd == n->pipe_reader) { char buf[1]; read(n->pipe_reader,buf,1); notify = 1; }else{ socket_t sock = (socket_t)n->events[i].data.ptr; if(sock) { if(sock->socket_type == CONNECT){ process_connect(sock); } else if(sock->socket_type == LISTEN){ process_accept(sock); } else{ if(n->events[i].events & read_event) on_read_active(sock); if(n->events[i].events & EPOLLOUT) on_write_active(sock); } } } } current_tick = GetSystemMs64(); }while(notify == 0 && timeout > current_tick); return 0; }
static int quickhull(polygon_t *chull, point_list_t *points) { real_t ymin, ymax, yval; point_t *p, *v1, *v2, *v3; dlink_t *ax, *bx, *x, *y, *next; dlist_t *right_group, *left_group; assert(chull); assert(points); // Allocate the structure element of convex hull for (x = points->tail->next; x != points->head; x = x->next) { p = (point_t *)x->object; point_inc_ref(p); y = dlink_new(); y->object = (void *)p; dlist_insert(y, chull); } // find the extreme points along y-axis ax = NULL; bx = NULL; for (x = chull->tail->next; x != chull->head; x = x->next) { yval = point_get_y((point_t *)(x->object)); if (ax == NULL || yval < ymin) { ax = x; ymin = yval; } if (bx == NULL || yval > ymax) { bx = x; ymax = yval; } } dlink_cutoff(ax); dlist_dec_count(chull); dlink_cutoff(bx); dlist_dec_count(chull); //point_dump((point_t *)ax->object); //point_dump((point_t *)bx->object); v1 = point_new(); v2 = point_new(); v3 = point_new(); //printf("for right section\n"); right_group= dlist_new(); dlist_insert(ax, right_group); point_subtract(v2, (point_t *)bx->object, (point_t *)ax->object); for (x = chull->tail->next; x != chull->head;) { //point_dump((point_t *)x->object); point_subtract(v1, (point_t *)x->object, (point_t *)ax->object); point_xproduct(v3, v1, v2); if (point_get_z(v3) > 0) { next = x->next; dlink_cutoff(x); dlist_dec_count(chull); dlist_insert(x, right_group); //printf(" "); //point_dump((point_t *)x->object); x = next; } else x = x->next; } dlist_insert(bx, right_group); quickhull_grouping(right_group); //printf("for left section\n"); ax = dlist_pop(right_group); bx = dlist_extract(right_group); //point_dump((point_t *)ax->object); //point_dump((point_t *)bx->object); left_group = dlist_new(); dlist_insert(bx, left_group); point_subtract(v2, (point_t *)ax->object, (point_t *)bx->object); for (x = chull->tail->next; x != chull->head; ) { point_subtract(v1, (point_t *)x->object, (point_t *)bx->object); point_xproduct(v3, v1, v2); if (point_get_z(v3) > 0) { next = x->next; dlink_cutoff(x); dlist_dec_count(chull); dlist_insert(x, left_group); //point_dump((point_t *)x->object); x = next; } else { next = x->next; dlink_cutoff(x); dlist_dec_count(chull); point_destroy((point_t *)x->object); dlink_destroy(x); x = next; } } dlist_insert(ax, left_group); quickhull_grouping(left_group); ax = dlist_extract(left_group); bx = dlist_pop(left_group); dlist_insert(ax, chull); while (dlist_get_count(right_group) > 0) { x = dlist_pop(right_group); dlist_insert(x, chull); } dlist_insert(bx, chull); while (dlist_get_count(left_group) > 0) { x = dlist_pop(left_group); dlist_insert(x, chull); } dlist_destroy(left_group); dlist_destroy(right_group); point_destroy(v3); point_destroy(v2); point_destroy(v1); return dlist_get_count(chull); }
/* * Quick-Hull * Here's an algorithm that deserves its name. * It's a fast way to compute the convex hull of a set of points on the plane. * It shares a few similarities with its namesake, quick-sort: * - it is recursive. * - each recursive step partitions data into several groups. * * The partitioning step does all the work. The basic idea is as follows: * 1. We are given a some points, * and line segment AB which we know is a chord of the convex hull. * 2. Among the given points, find the one which is farthest from AB. * Let's call this point C. * 3. The points inside the triangle ABC cannot be on the hull. * Put them in set s0. * 4. Put the points which lie outside edge AC in set s1, * and points outside edge BC in set s2. * * Once the partitioning is done, we recursively invoke quick-hull on sets s1 and s2. * The algorithm works fast on random sets of points * because step 3 of the partition typically discards a large fraction of the points. */ static int quickhull_grouping(dlist_t *group) { dlink_t *x, *ax, *bx, *cx, *next; dlist_t *s1, *s2; point_t *v1, *v2, *v3; real_t area; assert(group); if (dlist_get_count(group) <= 2) return dlist_get_count(group); v1 = point_new(); v2 = point_new(); v3 = point_new(); // Find the point with maximum parallelogram's area ax = dlist_pop(group); bx = dlist_extract(group); cx = NULL; point_subtract(v2, (point_t *)(bx->object), (point_t *)(ax->object)); for (x = group->tail->next; x != group->head; x = x->next) { point_subtract(v1, (point_t *)(x->object), (point_t *)(ax->object)); point_xproduct(v3, v1, v2); if (cx == NULL || point_get_z(v3) > area) { cx = x; area = point_get_z(v3); } } dlink_cutoff(cx); dlist_dec_count(group); // S1 grouping s1 = dlist_new(); dlist_insert(ax, s1); point_subtract(v2, (point_t *)(cx->object), (point_t *)(ax->object)); for (x = group->tail->next; x != group->head; ) { point_subtract(v1, (point_t *)(x->object), (point_t *)(ax->object)); point_xproduct(v3, v1, v2); if (point_get_z(v3) > 0) { next = x->next; dlink_cutoff(x); dlist_dec_count(group); dlist_insert(x, s1); x = next; } else x = x->next; } dlist_insert(cx, s1); quickhull_grouping(s1); assert(cx == s1->head->prev); // S2 grouping and pop out others cx = dlist_extract(s1); s2 = dlist_new(); dlist_insert(cx, s2); point_subtract(v2, (point_t *)bx->object, (point_t *)cx->object); for (x = group->tail->next; x != group->head;) { point_subtract(v1, (point_t *)x->object, (point_t *)cx->object); point_xproduct(v3, v1, v2); if (point_get_z(v3) > 0) { next = x->next; dlink_cutoff(x); dlist_dec_count(group); dlist_insert(x, s2); x = next; } else { next = x->next; dlink_cutoff(x); dlist_dec_count(group); point_destroy((point_t *)x->object); dlink_destroy(x); x = next; } } dlist_insert(bx, s2); quickhull_grouping(s2); assert(bx == s2->head->prev); assert(dlist_get_count(group) == 0); //assert(group->count == 0); // Merge s1 and s2 into group while (dlist_get_count(s1) > 0) { x = dlist_pop(s1); dlist_insert(x, group); } while (dlist_get_count(s2) > 0) { x = dlist_pop(s2); dlist_insert(x, group); } dlist_destroy(s2); dlist_destroy(s1); point_destroy(v3); point_destroy(v2); point_destroy(v1); return dlist_get_count(group); }