예제 #1
0
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);
    }
}
예제 #3
0
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;
}
예제 #4
0
파일: count.c 프로젝트: taysom/tau
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;
}
예제 #5
0
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);
	}
}
예제 #6
0
파일: histogram.c 프로젝트: taysom/tau
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;
	}
}
예제 #7
0
파일: histogram.c 프로젝트: taysom/tau
void incHistogram (Histogram_s *histogram)
{
	unint	level = ++histogram->currentCount;

	++histogram->totalCount;
	++histogram->bucket[flsl(level)];

	if (level > histogram->highWaterMark)
	{
		histogram->highWaterMark = level;
	}
}
예제 #8
0
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;
}
예제 #9
0
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:;
}
예제 #10
0
파일: isns.c 프로젝트: mr-justin/freebsd
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);
}
예제 #11
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);
}
예제 #12
0
CF_INLINE CFIndex __CFBinaryHeapRoundUpCapacity(CFIndex capacity) {
    if (capacity < 4) return 4;
    return (1 << flsl(capacity));
}
예제 #13
0
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);
	}
예제 #14
0
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;
}
예제 #15
0
CF_INLINE CFIndex __CFArrayDequeRoundUpCapacity(CFIndex capacity) {
    if (capacity < 4) return 4;
    return __CFMin((1 << flsl(capacity)), __CF_MAX_BUCKETS_PER_DEQUE);
}