CFIndex CFArrayBSearchValues(CFArrayRef array, CFRange range, const void *value, CFComparatorFunction comparator, void *context) { FAULT_CALLBACK((void **)&(comparator)); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CFAssert1(NULL != comparator, __kCFLogAssertion, "%s(): pointer to comparator function may not be NULL", __PRETTY_FUNCTION__); // implemented abstractly, careful! if (range.length <= 0) return range.location; const void *item = CFArrayGetValueAtIndex(array, range.location + range.length - 1); if ((CFComparisonResult)(INVOKE_CALLBACK3(comparator, item, value, context)) < 0) { return range.location + range.length; } item = CFArrayGetValueAtIndex(array, range.location); if ((CFComparisonResult)(INVOKE_CALLBACK3(comparator, value, item, context)) < 0) { return range.location; } SInt32 lg = flsl(range.length) - 1; // lg2(range.length) item = CFArrayGetValueAtIndex(array, range.location + -1 + (1 << lg)); // idx will be the current probe index into the range CFIndex idx = (comparator(item, value, context) < 0) ? range.length - (1 << lg) : -1; while (lg--) { item = CFArrayGetValueAtIndex(array, range.location + idx + (1 << lg)); if (comparator(item, value, context) < 0) { idx += (1 << lg); } } idx++; return idx + range.location; }
CF_INLINE CFIndex __CFDataRoundUpCapacity(CFIndex capacity) { if (capacity < 16) { return 16; } else if (capacity < LOW_THRESHOLD) { /* Up to 4x */ long idx = flsl(capacity); return (1L << (long)(idx + ((idx % 2 == 0) ? 0 : 1))); } else if (capacity < HIGH_THRESHOLD) { /* Up to 2x */ return (1L << (long)flsl(capacity)); } else { /* Round up to next multiple of CHUNK_SIZE */ unsigned long newCapacity = CHUNK_SIZE * (1+(capacity >> ((long)flsl(CHUNK_SIZE)-1))); return __CFMin(newCapacity, CFDATA_MAX_SIZE); } }
CFIndex CFCalendarGetOrdinalityOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) { CFIndex result = kCFNotFound; if (!__validUnits(smallerUnit, biggerUnit)) return result; CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFIndex, calendar, "_ordinalityOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at); __CFGenericValidateType(calendar, CFCalendarGetTypeID()); if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { UErrorCode status = U_ZERO_ERROR; ucal_clear(calendar->_cal); if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitYear == biggerUnit) { UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); ucal_setMillis(calendar->_cal, udate, &status); int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status); return val; } else if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitMonth == biggerUnit) { UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); ucal_setMillis(calendar->_cal, udate, &status); int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_MONTH, &status); return val; } UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit); // Set calendar to first instant of big unit __CFCalendarSetToFirstInstant(calendar, biggerUnit, at); UDate curr = ucal_getMillis(calendar->_cal, &status); UDate goal = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); result = 1; const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14}; int multiple = (1 << multiple_table[flsl(smallerUnit) - 1]); Boolean divide = false, alwaysDivide = false; while (curr < goal) { ucal_add(calendar->_cal, smallField, multiple, &status); UDate newcurr = ucal_getMillis(calendar->_cal, &status); if (curr < newcurr && newcurr <= goal) { result += multiple; curr = newcurr; } else { // Either newcurr is going backwards, or not making // progress, or has overshot the goal; reset date // and try smaller multiples. ucal_setMillis(calendar->_cal, curr, &status); divide = true; // once we start overshooting the goal, the add at // smaller multiples will succeed at most once for // each multiple, so we reduce it every time through // the loop. if (goal < newcurr) alwaysDivide = true; } if (divide) { multiple = multiple / 2; if (0 == multiple) break; divide = alwaysDivide; } } } return result; }
f8 unint_to_f8 (unint x) { if (x < (INT_ADD << 1)) return x; unint b = flsl(x) - 1; unint i = x >> (b - INT_SHIFT) & INT_MASK; unint e = b - INT_SHIFT + 1; printf("e=%lu i=%lu ", e, i); return (e << INT_SHIFT) | i; }
void tstFindHighBit (unsigned long x) { unsigned a; unsigned b; a = simpleFindHighBit(x); b = flsl(x); if (a != b) { fatal("%lx %d %d", x, a, b); } }
void eventHistogram (Histogram_s *histogram, unint event) { histogram->currentCount = event; histogram->eventSum += event; ++histogram->totalCount; ++histogram->bucket[flsl(event)]; if (event > histogram->highWaterMark) { histogram->highWaterMark = event; } }
void incHistogram (Histogram_s *histogram) { unint level = ++histogram->currentCount; ++histogram->totalCount; ++histogram->bucket[flsl(level)]; if (level > histogram->highWaterMark) { histogram->highWaterMark = level; } }
Boolean _CFCalendarGetComponentDifferenceV(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, int **vector, int count) { if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { UErrorCode status = U_ZERO_ERROR; ucal_clear(calendar->_cal); UDate curr = floor((startingAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0); UDate goal = floor((resultAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0); ucal_setMillis(calendar->_cal, curr, &status); int direction = (startingAT <= resultAT) ? 1 : -1; char ch = *componentDesc; while (ch) { UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14}; int multiple = direction * (1 << multiple_table[flsl(__CFCalendarGetCalendarUnitFromChar(ch)) - 1]); Boolean divide = false, alwaysDivide = false; int result = 0; while ((direction > 0 && curr < goal) || (direction < 0 && goal < curr)) { ucal_add(calendar->_cal, field, multiple, &status); UDate newcurr = ucal_getMillis(calendar->_cal, &status); if ((direction > 0 && curr < newcurr && newcurr <= goal) || (direction < 0 && newcurr < curr && goal <= newcurr)) { result += multiple; curr = newcurr; } else { // Either newcurr is going backwards, or not making // progress, or has overshot the goal; reset date // and try smaller multiples. ucal_setMillis(calendar->_cal, curr, &status); divide = true; // once we start overshooting the goal, the add at // smaller multiples will succeed at most once for // each multiple, so we reduce it every time through // the loop. if ((direction > 0 && goal < newcurr) || (direction < 0 && newcurr < goal)) alwaysDivide = true; } if (divide) { multiple = multiple / 2; if (0 == multiple) break; divide = alwaysDivide; } } *(*vector) = result; vector++; componentDesc++; ch = *componentDesc; } return U_SUCCESS(status) ? true : false; } return false; }
static void test_fls(void *p) { /* fls */ int_check(fls(0), 0); int_check(fls(1), 1); int_check(fls(3), 2); int_check(fls((int)-1), 32); /* flsl */ int_check(flsl(0), 0); int_check(flsl(1), 1); int_check(flsl(3), 2); if (sizeof(long) == 4) int_check(flsl((long)-1), 32); else int_check(flsl((long)-1), 64); /* flsll */ int_check(flsll(0), 0); int_check(flsll(1), 1); int_check(flsll(3), 2); int_check(flsll((long long)-1), 64); end:; }
static int isns_req_getspace(struct isns_req *req, uint32_t len) { void *newbuf; int newlen; if (req->ir_usedlen + len <= req->ir_buflen) return (0); newlen = 1 << flsl(req->ir_usedlen + len); newbuf = realloc(req->ir_buf, newlen); if (newbuf == NULL) { log_err(1, "realloc"); return (1); } req->ir_buf = newbuf; req->ir_buflen = newlen; return (0); }
static int round_freq(struct eventtimer *et, int freq) { uint64_t div; if (et->et_frequency != 0) { div = lmax((et->et_frequency + freq / 2) / freq, 1); if (et->et_flags & ET_FLAGS_POW2DIV) div = 1 << (flsl(div + div / 2) - 1); freq = (et->et_frequency + div / 2) / div; } if (et->et_min_period.sec > 0) freq = 0; else if (et->et_min_period.frac != 0) freq = min(freq, BT2FREQ(&et->et_min_period)); if (et->et_max_period.sec == 0 && et->et_max_period.frac != 0) freq = max(freq, BT2FREQ(&et->et_max_period)); return (freq); }
CF_INLINE CFIndex __CFBinaryHeapRoundUpCapacity(CFIndex capacity) { if (capacity < 4) return 4; return (1 << flsl(capacity)); }
int pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx, uint64_t hostbase, enum pcibar_type type, uint64_t size) { int error; uint64_t *baseptr, limit, addr, mask, lobits, bar; assert(idx >= 0 && idx <= PCI_BARMAX); if ((size & (size - 1)) != 0) size = 1UL << flsl(size); /* round up to a power of 2 */ /* Enforce minimum BAR sizes required by the PCI standard */ if (type == PCIBAR_IO) { if (size < 4) size = 4; } else { if (size < 16) size = 16; } switch (type) { case PCIBAR_NONE: baseptr = NULL; addr = mask = lobits = 0; break; case PCIBAR_IO: baseptr = &pci_emul_iobase; limit = PCI_EMUL_IOLIMIT; mask = PCIM_BAR_IO_BASE; lobits = PCIM_BAR_IO_SPACE; break; case PCIBAR_MEM64: /* * XXX * Some drivers do not work well if the 64-bit BAR is allocated * above 4GB. Allow for this by allocating small requests under * 4GB unless then allocation size is larger than some arbitrary * number (32MB currently). */ if (size > 32 * 1024 * 1024) { /* * XXX special case for device requiring peer-peer DMA */ if (size == 0x100000000UL) baseptr = &hostbase; else baseptr = &pci_emul_membase64; limit = PCI_EMUL_MEMLIMIT64; mask = PCIM_BAR_MEM_BASE; lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | PCIM_BAR_MEM_PREFETCH; break; } else { baseptr = &pci_emul_membase32; limit = PCI_EMUL_MEMLIMIT32; mask = PCIM_BAR_MEM_BASE; lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64; } break; case PCIBAR_MEM32: baseptr = &pci_emul_membase32; limit = PCI_EMUL_MEMLIMIT32; mask = PCIM_BAR_MEM_BASE; lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; break; default: printf("pci_emul_alloc_base: invalid bar type %d\n", type); assert(0); } if (baseptr != NULL) { error = pci_emul_alloc_resource(baseptr, limit, size, &addr); if (error != 0) return (error); } pdi->pi_bar[idx].type = type; pdi->pi_bar[idx].addr = addr; pdi->pi_bar[idx].size = size; /* Initialize the BAR register in config space */ bar = (addr & mask) | lobits; pci_set_cfgdata32(pdi, PCIR_BAR(idx), bar); if (type == PCIBAR_MEM64) { assert(idx + 1 <= PCI_BARMAX); pdi->pi_bar[idx + 1].type = PCIBAR_MEMHI64; pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32); }
static CFRange __CFCalendarGetRangeOfUnit1(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) { CFRange range = {kCFNotFound, kCFNotFound}; if (!__validUnits(smallerUnit, biggerUnit)) return range; CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFRange, calendar, "_rangeOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at); __CFGenericValidateType(calendar, CFCalendarGetTypeID()); if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { int32_t dow = -1; ucal_clear(calendar->_cal); UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit); UCalendarDateFields bigField = __CFCalendarGetICUFieldCode(biggerUnit); if (kCFCalendarUnitWeekdayOrdinal == smallerUnit) { UErrorCode status = U_ZERO_ERROR; UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); ucal_setMillis(calendar->_cal, udate, &status); dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status); } // Set calendar to first instant of big unit __CFCalendarSetToFirstInstant(calendar, biggerUnit, at); UErrorCode status = U_ZERO_ERROR; UDate start = ucal_getMillis(calendar->_cal, &status); if (kCFCalendarUnitWeek == biggerUnit) { range.location = ucal_get(calendar->_cal, smallField, &status); if (kCFCalendarUnitMonth == smallerUnit) range.location++; } else { range.location = (kCFCalendarUnitHour == smallerUnit || kCFCalendarUnitMinute == smallerUnit || kCFCalendarUnitSecond == smallerUnit) ? 0 : 1; } // Set calendar to first instant of next value of big unit if (UCAL_ERA == bigField) { // ICU refuses to do the addition, probably because we are // at the limit of UCAL_ERA. Use alternate strategy. CFIndex limit = ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_MAXIMUM, &status); if (100000 < limit) limit = 100000; ucal_add(calendar->_cal, UCAL_YEAR, limit, &status); } else { ucal_add(calendar->_cal, bigField, 1, &status); } if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitYear == biggerUnit) { ucal_add(calendar->_cal, UCAL_SECOND, -1, &status); range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status); while (1 == range.length) { ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, -1, &status); range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status); } range.location = 1; return range; } else if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitMonth == biggerUnit) { ucal_add(calendar->_cal, UCAL_SECOND, -1, &status); range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status); range.location = 1; return range; } UDate goal = ucal_getMillis(calendar->_cal, &status); // Set calendar back to first instant of big unit ucal_setMillis(calendar->_cal, start, &status); if (kCFCalendarUnitWeekdayOrdinal == smallerUnit) { // roll day forward to first 'dow' while (ucal_get(calendar->_cal, (kCFCalendarUnitMonth == biggerUnit) ? UCAL_WEEK_OF_MONTH : UCAL_WEEK_OF_YEAR, &status) != 1) { ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status); } while (ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != dow) { ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status); } start = ucal_getMillis(calendar->_cal, &status); goal -= 1000; range.location = 1; // constant here works around ICU -- see 3948293 } UDate curr = start; range.length = (kCFCalendarUnitWeekdayOrdinal == smallerUnit) ? 1 : 0; const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14}; int multiple = (1 << multiple_table[flsl(smallerUnit) - 1]); Boolean divide = false, alwaysDivide = false; while (curr < goal) { ucal_add(calendar->_cal, smallField, multiple, &status); UDate newcurr = ucal_getMillis(calendar->_cal, &status); if (curr < newcurr && newcurr <= goal) { range.length += multiple; curr = newcurr; } else { // Either newcurr is going backwards, or not making // progress, or has overshot the goal; reset date // and try smaller multiples. ucal_setMillis(calendar->_cal, curr, &status); divide = true; // once we start overshooting the goal, the add at // smaller multiples will succeed at most once for // each multiple, so we reduce it every time through // the loop. if (goal < newcurr) alwaysDivide = true; } if (divide) { multiple = multiple / 2; if (0 == multiple) break; divide = alwaysDivide; } } } return range; }
CF_INLINE CFIndex __CFArrayDequeRoundUpCapacity(CFIndex capacity) { if (capacity < 4) return 4; return __CFMin((1 << flsl(capacity)), __CF_MAX_BUCKETS_PER_DEQUE); }