object_t objectmap_reserve( objectmap_t* map ) { uint64_t idx, next, id; FOUNDATION_ASSERT( map ); /*lint -esym(613,pool) */ //Reserve spot in array //TODO: Look into double-ended implementation with allocation from tail and free push to head do { idx = atomic_load64( &map->free ); if( idx >= map->size ) { log_error( 0, ERROR_OUT_OF_MEMORY, "Pool full, unable to reserve id" ); return 0; } next = ((uintptr_t)map->map[idx]) >> 1; } while( !atomic_cas64( &map->free, next, idx ) ); //Sanity check that slot isn't taken FOUNDATION_ASSERT_MSG( (intptr_t)(map->map[idx]) & 1, "Map failed sanity check, slot taken after reserve" ); map->map[idx] = 0; //Allocate ID id = 0; do { id = atomic_incr64( &map->id ) & map->id_max; //Wrap-around handled by masking } while( !id ); //Make sure id stays within correct bits (if fails, check objectmap allocation and the mask setup there) FOUNDATION_ASSERT( ( ( id << map->size_bits ) & map->mask_id ) == ( id << map->size_bits ) ); return ( id << map->size_bits ) | idx; /*lint +esym(613,pool) */ }
static void* inc_thread(void* arg) { int loop = 0; int icount = 0; FOUNDATION_UNUSED(arg); while (!thread_try_wait(0) && (loop < 65535)) { for (icount = 0; icount < 256; ++icount) { atomic_incr32(&val_32); atomic_incr64(&val_64); } ++loop; thread_yield(); } return 0; }
void* inc_thread( object_t thread, void* arg ) { int loop = 0; int icount = 0; while( !thread_should_terminate( thread ) && ( loop < 65535 ) ) { for( icount = 0; icount < 256; ++icount ) { atomic_incr32( &val_32 ); atomic_incr64( &val_64 ); } ++loop; thread_yield(); } return 0; }