Skip to content

Commit cc8a6da

Browse files
committed
optimize ecs_get_ptr_t when locks are not active
1 parent d0c5ffa commit cc8a6da

7 files changed

Lines changed: 140 additions & 104 deletions

File tree

distr/flecs.c

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2786,19 +2786,36 @@ void flecs_enqueue(
27862786
#ifdef FLECS_MUT_ALIAS_LOCKS
27872787
#define FLECS_LOCK_TARGET_INIT(cr_, table_, col_) \
27882788
.lock_target = (ecs_lock_target_t){ .cr = (cr_), .table = (table_), .column_index = (int16_t)(col_) },
2789+
2790+
/* Construct ecs_get_ptr_t with lock target info */
2791+
#define ECS_GET_PTR(ptr_, cr_, table_, col_) \
2792+
(ecs_get_ptr_t){ \
2793+
.ptr = (ptr_), \
2794+
.lock_target = (ecs_lock_target_t){ .cr = (cr_), .table = (table_), .column_index = (int16_t)(col_) } \
2795+
}
2796+
2797+
/* Construct null ecs_get_ptr_t */
2798+
#define ECS_GET_PTR_NULL (ecs_get_ptr_t){0}
2799+
2800+
/* Extract the pointer from ecs_get_ptr_t */
2801+
#define ECS_GET_PTR_PTR(get_ptr_) ((get_ptr_).ptr)
27892802
#else
27902803
#define FLECS_LOCK_TARGET_INIT(cr_, table_, col_) /* nothing */
2804+
2805+
/* When FLECS_MUT_ALIAS_LOCKS is not defined, ecs_get_ptr_t is just void* */
2806+
#define ECS_GET_PTR(ptr_, cr_, table_, col_) ((ecs_get_ptr_t)(ptr_))
2807+
#define ECS_GET_PTR_NULL ((ecs_get_ptr_t)NULL)
2808+
#define ECS_GET_PTR_PTR(get_ptr_) (get_ptr_)
27912809
#endif
27922810

27932811
#define ecs_get_low_id(table, r, id)\
27942812
ecs_assert(table->component_map != NULL, ECS_INTERNAL_ERROR, NULL);\
27952813
int16_t column_index = table->component_map[id];\
27962814
if (column_index > 0) {\
27972815
ecs_column_t *column = &table->data.columns[--column_index];\
2798-
return (ecs_get_ptr_t){\
2799-
.ptr = ECS_ELEM(column->data, column->ti->size, ECS_RECORD_TO_ROW(r->row)),\
2800-
FLECS_LOCK_TARGET_INIT(NULL, table, column_index)\
2801-
};\
2816+
return ECS_GET_PTR(\
2817+
ECS_ELEM(column->data, column->ti->size, ECS_RECORD_TO_ROW(r->row)),\
2818+
NULL, table, column_index);\
28022819
}
28032820

28042821
typedef struct {
@@ -5687,7 +5704,7 @@ void* flecs_defer_ensure(
56875704
void *base = NULL;
56885705
if (table && (table->flags & EcsTableHasIsA)) {
56895706
ecs_component_record_t *cr = flecs_components_get(world, id);
5690-
base = flecs_get_base_component(world, table, id, cr, 0).ptr;
5707+
base = ECS_GET_PTR_PTR(flecs_get_base_component(world, table, id, cr, 0));
56915708
}
56925709

56935710
if (!base) {
@@ -7527,16 +7544,16 @@ ecs_get_ptr_t flecs_get_base_component(
75277544

75287545
/* Table (and thus entity) does not have component, look for base */
75297546
if (!(table->flags & EcsTableHasIsA)) {
7530-
return (ecs_get_ptr_t){0};
7547+
return ECS_GET_PTR_NULL;
75317548
}
75327549

75337550
if (!(cr->flags & EcsIdOnInstantiateInherit)) {
7534-
return (ecs_get_ptr_t){0};
7551+
return ECS_GET_PTR_NULL;
75357552
}
75367553

75377554
/* Exclude Name */
75387555
if (component == ecs_pair(ecs_id(EcsIdentifier), EcsName)) {
7539-
return (ecs_get_ptr_t){0};
7556+
return ECS_GET_PTR_NULL;
75407557
}
75417558

75427559
/* Table should always be in the table index for (IsA, *), otherwise the
@@ -7548,7 +7565,7 @@ ecs_get_ptr_t flecs_get_base_component(
75487565
ecs_type_t type = table->type;
75497566
ecs_id_t *ids = type.array;
75507567
int32_t i = tr_isa->index, end = tr_isa->count + tr_isa->index;
7551-
ecs_get_ptr_t ptr = {0};
7568+
ecs_get_ptr_t ptr = ECS_GET_PTR_NULL;
75527569

75537570
do {
75547571
ecs_id_t pair = ids[i ++];
@@ -7563,36 +7580,33 @@ ecs_get_ptr_t flecs_get_base_component(
75637580
const ecs_table_record_t *tr = flecs_component_get_table(cr, table);
75647581
if (!tr) {
75657582
if (cr->flags & EcsIdDontFragment) {
7566-
ptr = (ecs_get_ptr_t){
7567-
.ptr = flecs_component_sparse_get(world, cr, table, base),
7568-
FLECS_LOCK_TARGET_INIT(cr, NULL, -1)
7569-
};
7583+
ptr = ECS_GET_PTR(
7584+
flecs_component_sparse_get(world, cr, table, base),
7585+
cr, NULL, -1);
75707586
}
75717587

7572-
if (!ptr.ptr) {
7588+
if (!ECS_GET_PTR_PTR(ptr)) {
75737589
ptr = flecs_get_base_component(world, table, component, cr,
75747590
recur_depth + 1);
75757591
}
75767592
} else {
75777593
if (cr->flags & EcsIdSparse) {
7578-
return (ecs_get_ptr_t){
7579-
.ptr = flecs_component_sparse_get(world, cr, table, base),
7580-
FLECS_LOCK_TARGET_INIT(cr, NULL, -1)
7581-
};
7594+
return ECS_GET_PTR(
7595+
flecs_component_sparse_get(world, cr, table, base),
7596+
cr, NULL, -1);
75827597
} else {
75837598
int32_t row = ECS_RECORD_TO_ROW(r->row);
75847599
int16_t column = tr->column;
7585-
return (ecs_get_ptr_t){
7586-
.ptr = flecs_table_get_component(table, column, row).ptr,
7587-
FLECS_LOCK_TARGET_INIT(NULL, table, column)
7588-
};
7600+
return ECS_GET_PTR(
7601+
flecs_table_get_component(table, column, row).ptr,
7602+
NULL, table, column);
75897603
}
75907604
}
7591-
} while (!ptr.ptr && (i < end));
7605+
} while (!ECS_GET_PTR_PTR(ptr) && (i < end));
75927606

75937607
return ptr;
75947608
error:
7595-
return (ecs_get_ptr_t){0};
7609+
return ECS_GET_PTR_NULL;
75967610
}
75977611

75987612
ecs_entity_t flecs_new_id(
@@ -9377,22 +9391,19 @@ ecs_get_ptr_t flecs_record_get_id(
93779391
if (component < FLECS_HI_COMPONENT_ID) {
93789392
if (!world->non_trivial_lookup[component]) {
93799393
ecs_get_low_id(table, r, component);
9380-
return (ecs_get_ptr_t){0};
9394+
return ECS_GET_PTR_NULL;
93819395
}
93829396
}
93839397

93849398
ecs_component_record_t *cr = flecs_components_get(world, component);
93859399
if (!cr) {
9386-
return (ecs_get_ptr_t){0};
9400+
return ECS_GET_PTR_NULL;
93879401
}
93889402

93899403
if (cr->flags & EcsIdDontFragment) {
93909404
void *ptr = flecs_component_sparse_get(world, cr, table, entity);
93919405
if (ptr) {
9392-
return (ecs_get_ptr_t){
9393-
.ptr = ptr,
9394-
FLECS_LOCK_TARGET_INIT(cr, NULL, -1)
9395-
};
9406+
return ECS_GET_PTR(ptr, cr, NULL, -1);
93969407
}
93979408
}
93989409

@@ -9401,10 +9412,9 @@ ecs_get_ptr_t flecs_record_get_id(
94019412
return flecs_get_base_component(world, table, component, cr, 0);
94029413
} else {
94039414
if (cr->flags & EcsIdSparse) {
9404-
return (ecs_get_ptr_t){
9405-
.ptr = flecs_component_sparse_get(world, cr, table, entity),
9406-
FLECS_LOCK_TARGET_INIT(cr, NULL, -1)
9407-
};
9415+
return ECS_GET_PTR(
9416+
flecs_component_sparse_get(world, cr, table, entity),
9417+
cr, NULL, -1);
94089418
}
94099419
ecs_check(tr->column != -1, ECS_INVALID_PARAMETER,
94109420
"component '%s' passed to get() is a tag/zero sized",
@@ -9413,12 +9423,11 @@ ecs_get_ptr_t flecs_record_get_id(
94139423

94149424
int32_t row = ECS_RECORD_TO_ROW(r->row);
94159425
int32_t column_index = tr->column;
9416-
return (ecs_get_ptr_t){
9417-
.ptr = flecs_table_get_component(table, column_index, row).ptr,
9418-
FLECS_LOCK_TARGET_INIT(NULL, table, column_index)
9419-
};
9426+
return ECS_GET_PTR(
9427+
flecs_table_get_component(table, column_index, row).ptr,
9428+
NULL, table, column_index);
94209429
error:
9421-
return (ecs_get_ptr_t){0};
9430+
return ECS_GET_PTR_NULL;
94229431
}
94239432

94249433
const void* ecs_get_id(
@@ -9432,7 +9441,7 @@ const void* ecs_get_id(
94329441

94339442
ecs_record_t *r = flecs_entities_get(world, entity);
94349443

9435-
return flecs_record_get_id(world, entity, r, component).ptr;
9444+
return ECS_GET_PTR_PTR(flecs_record_get_id(world, entity, r, component));
94369445
error:
94379446
return NULL;
94389447
}
@@ -9473,21 +9482,23 @@ ecs_get_ptr_t flecs_record_get_mut_id(
94739482
if (component < FLECS_HI_COMPONENT_ID) {
94749483
if (!world->non_trivial_lookup[component]) {
94759484
ecs_get_low_id(r->table, r, component);
9476-
return (ecs_get_ptr_t){0};
9485+
return ECS_GET_PTR_NULL;
94779486
}
94789487
}
94799488

94809489
ecs_component_record_t *cr = flecs_components_get(world, component);
94819490
int32_t row = ECS_RECORD_TO_ROW(r->row);
94829491
flecs_component_ptr_t component_ptr = flecs_get_component_ptr(world, r->table, row, cr);
9492+
#ifdef FLECS_MUT_ALIAS_LOCKS
94839493
return (ecs_get_ptr_t) {
9484-
.ptr = component_ptr.ptr
9485-
#ifdef FLECS_MUT_ALIAS_LOCKS
9486-
, .lock_target = component_ptr.lock_target
9487-
#endif
9494+
.ptr = component_ptr.ptr,
9495+
.lock_target = component_ptr.lock_target
94889496
};
9497+
#else
9498+
return (ecs_get_ptr_t)component_ptr.ptr;
9499+
#endif
94899500
error:
9490-
return (ecs_get_ptr_t){0};
9501+
return ECS_GET_PTR_NULL;
94919502
}
94929503

94939504
void* ecs_get_mut_id(
@@ -9503,7 +9514,7 @@ void* ecs_get_mut_id(
95039514

95049515
ecs_record_t *r = flecs_entities_get(world, entity);
95059516

9506-
return flecs_record_get_mut_id(world, r, component).ptr;
9517+
return ECS_GET_PTR_PTR(flecs_record_get_mut_id(world, r, component));
95079518

95089519
error:
95099520
return NULL;
@@ -10099,8 +10110,8 @@ bool ecs_has_id(
1009910110
if (flecs_component_sparse_has(cr, entity)) {
1010010111
return true;
1010110112
} else {
10102-
return flecs_get_base_component(
10103-
world, table, component, cr, 0).ptr != NULL;
10113+
return ECS_GET_PTR_PTR(flecs_get_base_component(
10114+
world, table, component, cr, 0)) != NULL;
1010410115
}
1010510116
}
1010610117

distr/flecs.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,7 +1270,9 @@ typedef struct ecs_record_t ecs_record_t;
12701270
typedef struct ecs_component_record_t ecs_component_record_t;
12711271

12721272
/** the void* returned from flecs_record_get_id fns which optionally returns origin of the ptr when FLECS_MUT_ALIAS_LOCKS is defined` */
1273+
#ifdef FLECS_MUT_ALIAS_LOCKS
12731274
typedef struct ecs_get_ptr_t ecs_get_ptr_t;
1275+
#endif
12741276

12751277
/** A poly object.
12761278
* A poly (short for polymorph) object is an object that has a variable list of
@@ -4481,18 +4483,23 @@ typedef struct ecs_lock_target_t{
44814483
ecs_table_t *table;
44824484
int16_t column_index;
44834485
} ecs_lock_target_t;
4484-
#endif
44854486

44864487
/* a wrapper around a void* which represents a component pointer.
44874488
* When FLECS_MUT_ALIAS_LOCKS is defined, then this also provides additional safety information about the pointer.
44884489
*/
44894490
struct ecs_get_ptr_t{
44904491
void *ptr;
4491-
#ifdef FLECS_MUT_ALIAS_LOCKS
44924492
ecs_lock_target_t lock_target;
4493-
#endif
44944493
};
44954494

4495+
#else
4496+
4497+
/* When FLECS_MUT_ALIAS_LOCKS is not defined, ecs_get_ptr_t is just a void*
4498+
* for zero-overhead abstraction */
4499+
typedef void* ecs_get_ptr_t;
4500+
4501+
#endif
4502+
44964503

44974504

44984505
/** Find record for entity.

include/flecs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,9 @@ typedef struct ecs_record_t ecs_record_t;
473473
typedef struct ecs_component_record_t ecs_component_record_t;
474474

475475
/** the void* returned from flecs_record_get_id fns which optionally returns origin of the ptr when FLECS_MUT_ALIAS_LOCKS is defined` */
476+
#ifdef FLECS_MUT_ALIAS_LOCKS
476477
typedef struct ecs_get_ptr_t ecs_get_ptr_t;
478+
#endif
477479

478480
/** A poly object.
479481
* A poly (short for polymorph) object is an object that has a variable list of

include/flecs/private/api_internals.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,23 @@ typedef struct ecs_lock_target_t{
5959
ecs_table_t *table;
6060
int16_t column_index;
6161
} ecs_lock_target_t;
62-
#endif
6362

6463
/* a wrapper around a void* which represents a component pointer.
6564
* When FLECS_MUT_ALIAS_LOCKS is defined, then this also provides additional safety information about the pointer.
6665
*/
6766
struct ecs_get_ptr_t{
6867
void *ptr;
69-
#ifdef FLECS_MUT_ALIAS_LOCKS
7068
ecs_lock_target_t lock_target;
71-
#endif
7269
};
7370

71+
#else
72+
73+
/* When FLECS_MUT_ALIAS_LOCKS is not defined, ecs_get_ptr_t is just a void*
74+
* for zero-overhead abstraction */
75+
typedef void* ecs_get_ptr_t;
76+
77+
#endif
78+
7479

7580

7681
/** Find record for entity.

src/commands.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ void* flecs_defer_ensure(
392392
void *base = NULL;
393393
if (table && (table->flags & EcsTableHasIsA)) {
394394
ecs_component_record_t *cr = flecs_components_get(world, id);
395-
base = flecs_get_base_component(world, table, id, cr, 0).ptr;
395+
base = ECS_GET_PTR_PTR(flecs_get_base_component(world, table, id, cr, 0));
396396
}
397397

398398
if (!base) {

0 commit comments

Comments
 (0)