/* * inserts a wait for vline in the command stream */ void wait_vline_range(ScrnInfoPtr pScrn, drmBufPtr ib, int crtc, int start, int stop) { RHDPtr rhdPtr = RHDPTR(pScrn); struct rhdCrtc *rhdCrtc; if ((crtc < 0) || (crtc > 1)) return; rhdCrtc = rhdPtr->Crtc[crtc]; if(!rhdCrtc || !rhdCrtc->CurrentMode) return; start = max(start, 0); stop = min(stop, rhdCrtc->CurrentMode->VDisplay-1); #if 0 LOG("wait_vline_range: start %d stop %d\n", start, stop); #endif if (stop <= start) return; /* set the VLINE range */ if(crtc == 0) EREG(ib, D1MODE_VLINE_START_END, start | (stop << 16)); else EREG(ib, D2MODE_VLINE_START_END, start | (stop << 16)); /* tell the CP to poll the VLINE state register */ PACK3(ib, IT_WAIT_REG_MEM, 6); E32(ib, WAIT_REG | WAIT_EQ); if(crtc == 0) E32(ib, D1MODE_VLINE_STATUS >> 2); else
/* * coalesce * Boundary tag coalescing. Return ptr to coalesced block * delete or insert entry of free list. */ static void *coalesce(void *bp) { size_t prev_alloc = IS_PREV_ALLOC(HDRP(bp)); size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); if (prev_alloc && next_alloc) { /* Case 1 */ /* nop */ } else if (prev_alloc && !next_alloc) { /* Case 2 */ if (heap_tailp == NEXT_BLKP(bp)) { heap_tailp = bp; } delete_node(get_level(GET_SIZE(HDRP(NEXT_BLKP(bp)))), NEXT_BLKP(bp)); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK3(size, 2, 0)); PUT(FTRP(bp), PACK3(size, 2, 0)); } else if (!prev_alloc && next_alloc) { /* Case 3 */ int t = (bp == heap_tailp); delete_node(get_level(GET_SIZE(HDRP(PREV_BLKP(bp)))), PREV_BLKP(bp)); size += GET_SIZE(HDRP(PREV_BLKP(bp))); SET_SIZE(FTRP(bp), size); SET_SIZE(HDRP(PREV_BLKP(bp)), size); bp = PREV_BLKP(bp); if (t) { heap_tailp = bp; } } else { /* Case 4 */ int t = (NEXT_BLKP(bp) == heap_tailp); delete_node(get_level(GET_SIZE(HDRP(PREV_BLKP(bp)))), PREV_BLKP(bp)); delete_node(get_level(GET_SIZE(HDRP(NEXT_BLKP(bp)))), NEXT_BLKP(bp)); size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); SET_SIZE(HDRP(PREV_BLKP(bp)), size); SET_SIZE(FTRP(NEXT_BLKP(bp)), size); bp = PREV_BLKP(bp); if (t) { heap_tailp = bp; } } UNFLAG(HDRP(NEXT_BLKP(bp))); insert_node(get_level(GET_SIZE(HDRP(bp))), bp); return bp; }
void wait_3d_idle_clean(ScrnInfoPtr pScrn, drmBufPtr ib) { /* flush caches, don't generate timestamp */ PACK3(ib, IT_EVENT_WRITE, 1); E32(ib, CACHE_FLUSH_AND_INV_EVENT); /* wait for 3D idle clean */ EREG(ib, WAIT_UNTIL, (WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit)); }
/* * place - Place block of asize bytes at start of free block bp * and split if remainder would be at least minimum block size */ static void place(void *bp, size_t asize){ size_t csize = GET_SIZE(HDRP(bp)); if (IS_VALID(csize - asize)) { /* we want to make sure the new free block satisfy the minimum requirement */ int t = (bp == heap_tailp); delete_node(get_level(GET_SIZE(HDRP(bp))), bp); /* remove the record in the free block list */ SET_SIZE(HDRP(bp), asize); MARK_ALLOC(HDRP(bp)); bp = NEXT_BLKP(bp); PUT(HDRP(bp), PACK3(csize-asize, 2, 0)); PUT(FTRP(bp), PACK3(csize-asize, 2, 0)); insert_node(get_level(GET_SIZE(HDRP(bp))), bp); if (t) { heap_tailp = bp; } }else { delete_node(get_level(GET_SIZE(HDRP(bp))), bp); MARK_ALLOC(HDRP(bp)); FLAG(HDRP(NEXT_BLKP(bp))); } }
static void test_term_char_packing(void) { uint32_t seqs[][1024] = { { -1 }, { 0, -1 }, { 'A', '~', -1 }, { 'A', '~', 0, -1 }, { 'A', '~', 'a', -1 }, }; term_char_t res[] = { TERM_CHAR_NULL, PACK1(0), PACK2('A', '~'), PACK3('A', '~', 0), PACK3('A', '~', 'a'), }; uint32_t next; unsigned int i, j; term_char_t c = TERM_CHAR_NULL; /* * This creates term_char_t objects based on the data in @seqs and * compares the result to @res. Only basic packed types are tested, no * allocations are done. */ for (i = 0; i < ELEMENTSOF(seqs); ++i) { for (j = 0; j < ELEMENTSOF(seqs[i]); ++j) { next = seqs[i][j]; if (next == (uint32_t)-1) break; c = term_char_merge(c, next); } assert_se(!memcmp(&c, &res[i], sizeof(c))); c = term_char_free(c); } }
/* * extend_heap - Extend heap with free block and return its block pointer * * Return: * the new free block pointer */ static void *extend_heap(size_t words) { char *bp; size_t size; /* single-word alignment */ size = (words + 1) * WSIZE; if ((long)(bp = mem_sbrk(size)) == -1) return NULL; int prev_alloc = IS_PREV_ALLOC(HDRP(bp)); /* Initialize free block header/footer and the epilogue header */ PUT(HDRP(bp), PACK3(size, prev_alloc << 1, 0)); /* Free block header */ PUT(FTRP(bp), PACK3(size, prev_alloc << 1, 0)); /* Free block footer */ set_prev_free(bp, NULL); set_next_free(bp, NULL); PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ /* Coalesce if the previous block was free */ heap_tailp = coalesce(bp); return heap_tailp; }
int h2o_time_parse_rfc1123(const char *s, size_t len, struct tm *tm) { if (len != H2O_TIMESTR_RFC1123_LEN) return -1; /* 1 2 * 01234567890123456789012345678 * Fri, 19 Sep 2014 05:24:04 GMT */ #define FETCH(dst, pos, n) \ if ((dst = fetch_digits(s + pos, n)) == -1) \ return -1; FETCH(tm->tm_year, 12, 4); tm->tm_year -= 1900; /* month is parsed afterwards */ FETCH(tm->tm_mday, 5, 2); FETCH(tm->tm_hour, 17, 2); FETCH(tm->tm_min, 20, 2); FETCH(tm->tm_sec, 23, 2); #undef FETCH #define PACK3(a, b, c) (((a)&0xff) << 16 | ((b)&0xff) << 8 | ((c)&0xff)) #define MAP(c1, c2, c3, value) \ case PACK3(c1, c2, c3): \ tm->tm_mon = value; \ break switch (PACK3(s[8], s[9], s[10])) { MAP('J', 'a', 'n', 0); MAP('F', 'e', 'b', 1); MAP('M', 'a', 'r', 2); MAP('A', 'p', 'r', 3); MAP('M', 'a', 'y', 4); MAP('J', 'u', 'n', 5); MAP('J', 'u', 'l', 6); MAP('A', 'u', 'g', 7); MAP('S', 'e', 'p', 8); MAP('O', 'c', 't', 9); MAP('N', 'o', 'v', 10); MAP('D', 'e', 'c', 11); default: return -1; } #undef MAP #undef PACK3 return 0; }
static void test_term_char_allocating(void) { uint32_t seqs[][1024] = { { 0, -1 }, { 'A', '~', -1 }, { 'A', '~', 0, -1 }, { 'A', '~', 'a', -1 }, { 'A', '~', 'a', 'b', 'c', 'd', -1 }, { 'A', '~', 'a', 'b', 'c', 'd', 0, '^', -1 }, /* exceeding implementation-defined soft-limit of 64 */ { 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', -1 }, }; term_char_t res[] = { PACK1(0), PACK2('A', '~'), PACK3('A', '~', 0), PACK3('A', '~', 'a'), TERM_CHAR_NULL, /* allocated */ TERM_CHAR_NULL, /* allocated */ TERM_CHAR_NULL, /* allocated */ }; uint32_t str[][1024] = { { 0, -1 }, { 'A', '~', -1 }, { 'A', '~', 0, -1 }, { 'A', '~', 'a', -1 }, { 'A', '~', 'a', 'b', 'c', 'd', -1 }, { 'A', '~', 'a', 'b', 'c', 'd', 0, '^', -1 }, { 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', -1 }, }; size_t n; uint32_t next; unsigned int i, j; const uint32_t *t; /* * This builds term_char_t objects based on the data in @seqs. It * compares the result to @res for packed chars, otherwise it requires * them to be allocated. * After that, we resolve the UCS-4 string and compare it to the * expected strings in @str. */ for (i = 0; i < ELEMENTSOF(seqs); ++i) { _term_char_free_ term_char_t c = TERM_CHAR_NULL; for (j = 0; j < ELEMENTSOF(seqs[i]); ++j) { next = seqs[i][j]; if (next == (uint32_t)-1) break; c = term_char_merge(c, next); } /* we use TERM_CHAR_NULL as marker for allocated chars here */ if (term_char_is_null(res[i])) assert_se(term_char_is_allocated(c)); else assert_se(!memcmp(&c, &res[i], sizeof(c))); t = term_char_resolve(c, &n, NULL); for (j = 0; j < ELEMENTSOF(str[i]); ++j) { next = str[i][j]; if (next == (uint32_t)-1) break; assert_se(t[j] == next); } assert_se(n == j); } }