objectmap_t* objectmap_allocate( unsigned int size ) { uint64_t bits; unsigned int ip; uintptr_t next_indexshift; objectmap_t* map; void** slot; FOUNDATION_ASSERT_MSG( size > 2, "Invalid objectmap size" ); if( size <= 2 ) size = 2; bits = math_round( math_log2( (real)size ) ); //Number of bits needed FOUNDATION_ASSERT_MSGFORMAT( bits < 50, "Invalid objectmap size %d", size ); //Top two bits unused for Lua compatibility map = memory_allocate_zero( sizeof( objectmap_t ) + ( sizeof( void* ) * size ), 16, MEMORY_PERSISTENT ); map->size_bits = bits; map->id_max = ((1ULL<<(62ULL-bits))-1); map->size = size; map->mask_index = ((1ULL<<bits)-1ULL); map->mask_id = ( 0x3FFFFFFFFFFFFFFFULL & ~map->mask_index ); atomic_store64( &map->free, 0 ); atomic_store64( &map->id, 1 ); slot = map->map; for( ip = 0, next_indexshift = 3; ip < ( size - 1 ); ++ip, next_indexshift += 2, ++slot ) *slot = (void*)next_indexshift; *slot = (void*)((uintptr_t)-1); return map; }
DECLARE_TEST( math, exponentials ) { EXPECT_REALONE( math_exp( REAL_ZERO ) ); EXPECT_REALEQ( math_exp( REAL_ONE ), REAL_E ); EXPECT_REALONE( math_pow( REAL_ONE, REAL_ONE ) ); EXPECT_REALONE( math_pow( REAL_ONE, REAL_ZERO ) ); EXPECT_REALONE( math_pow( REAL_THREE, REAL_ZERO ) ); EXPECT_REALEQ( math_pow( REAL_SQRT2, REAL_TWO ), REAL_TWO ); EXPECT_REALEQ( math_logn( REAL_TWO ), REAL_LOGN2 ); EXPECT_REALEQ( math_logn( REAL_C( 10.0 ) ), REAL_LOGN10 ); EXPECT_REALONE( math_log2( REAL_TWO ) ); EXPECT_REALEQ( math_log2( REAL_TWO * REAL_TWO ), REAL_TWO ); EXPECT_REALEQ( math_log2( REAL_TWO * REAL_TWO * REAL_TWO * REAL_TWO ), REAL_C( 4.0 ) ); return 0; }