map immutable fields: count, capacity, allocator

This commit is contained in:
Ginger Bill
2017-02-06 22:53:48 +00:00
parent 8cfae17535
commit 5796c41357
4 changed files with 143 additions and 10 deletions
+7 -4
View File
@@ -142,10 +142,13 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
if info.params == nil {
buffer_write_string(buf, "()");
} else {
count := (cast(^Tuple)info.params).fields.count;
if count == 1 { buffer_write_string(buf, "("); }
buffer_write_type(buf, info.params);
if count == 1 { buffer_write_string(buf, ")"); }
fields := (cast(^Tuple)info.params).fields;
buffer_write_string(buf, "(");
for f, i in fields {
if i > 0 { buffer_write_string(buf, ", "); }
buffer_write_type(buf, f.type_info);
}
buffer_write_string(buf, ")");
}
if info.results != nil {
buffer_write_string(buf, " -> ");
+84 -2
View File
@@ -58,6 +58,7 @@ TODOS
- More date & time functions
VERSION HISTORY
0.27 - OSX fixes and Linux gbAffinity
0.26d - Minor changes to how gbFile works
0.26c - gb_str_to_f* fix
0.26b - Minor fixes
@@ -1008,7 +1009,12 @@ typedef struct gbAffinity {
} gbAffinity;
#elif defined(GB_SYSTEM_LINUX)
#error TODO(bill): Implement gbAffinity for linux
typedef struct gbAffinity {
b32 is_accurate;
isize core_count;
isize thread_count;
isize threads_per_core;
} gbAffinity;
#else
#error TODO(bill): Unknown system
#endif
@@ -4979,7 +4985,83 @@ isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) {
}
#elif defined(GB_SYSTEM_LINUX)
#error TODO(bill): Implement gbAffinity for linux
// IMPORTANT TODO(bill): This gbAffinity stuff for linux needs be improved a lot!
// NOTE(zangent): I have to read /proc/cpuinfo to get the number of threads per core.
#include <stdio.h>
void gb_affinity_init(gbAffinity *a) {
b32 accurate = true;
isize threads = 0;
a->thread_count = 1;
a->core_count = sysconf(_SC_NPROCESSORS_ONLN);
a->threads_per_core = 1;
if(a->core_count <= 0) {
a->core_count = 1;
accurate = false;
}
// Parsing /proc/cpuinfo to get the number of threads per core.
// NOTE(zangent): This calls the CPU's threads "cores", although the wording
// is kind of weird. This should be right, though.
if (fopen("/proc/cpuinfo", "r") != NULL) {
for (;;) {
// The 'temporary char'. Everything goes into this char,
// so that we can check against EOF at the end of this loop.
char c;
#define AF__CHECK(letter) ((c = getc(cpu_info)) == letter)
if (AF__CHECK('c') && AF__CHECK('p') && AF__CHECK('u') && AF__CHECK(' ') &&
AF__CHECK('c') && AF__CHECK('o') && AF__CHECK('r') && AF__CHECK('e') && AF__CHECK('s')) {
// We're on a CPU info line.
while (!AF__CHECK(EOF)) {
if (c == '\n') {
break;
} else if (c < '0' || '9' > c) {
continue;
}
threads = threads * 10 + (c - '0');
}
break;
} else {
while (!AF__CHECK('\n')) {
if (c==EOF) {
break;
}
}
}
if (c == EOF) {
break;
}
#undef AF__CHECK
}
}
if (threads == 0) {
threads = 1;
accurate = false;
}
a->threads_per_core = threads;
a->thread_count = a->threads_per_core * a->core_count;
a->is_accurate = accurate;
}
void gb_affinity_destroy(gbAffinity *a) {
gb_unused(a);
}
b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) {
return true;
}
isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) {
GB_ASSERT(0 <= core && core < a->core_count);
return a->threads_per_core;
}
#else
#error TODO(bill): Unknown system
#endif
+17 -3
View File
@@ -1495,7 +1495,7 @@ Type *ir_addr_type(irAddr addr) {
return type_deref(t);
}
irValue *ir_insert_map_key_and_value(irProcedure *proc, irValue *addr, Type *map_type,
irValue *ir_insert_dynamic_map_key_and_value(irProcedure *proc, irValue *addr, Type *map_type,
irValue *map_key, irValue *map_value) {
map_type = base_type(map_type);
@@ -1519,7 +1519,7 @@ irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
return NULL;
}
if (addr.kind == irAddr_Map) {
return ir_insert_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value);
return ir_insert_dynamic_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value);
}
irValue *v = ir_emit_conv(proc, value, ir_addr_type(addr));
@@ -1925,6 +1925,13 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, Type *type, irValue *e, Selec
e = ir_emit_array_epi(proc, e, index);
} else if (type->kind == Type_Array) {
e = ir_emit_array_epi(proc, e, index);
} else if (type->kind == Type_Map) {
e = ir_emit_struct_ep(proc, e, 1);
switch (index) {
case 0: e = ir_emit_struct_ep(proc, e, 1); break; // count
case 1: e = ir_emit_struct_ep(proc, e, 2); break; // capacity
case 2: e = ir_emit_struct_ep(proc, e, 3); break; // allocator
}
} else {
GB_PANIC("un-gep-able type");
}
@@ -1951,6 +1958,13 @@ irValue *ir_emit_deep_field_ev(irProcedure *proc, Type *type, irValue *e, Select
GB_PANIC("TODO(bill): IS THIS EVEN CORRECT?");
type = type->Record.fields[index]->type;
e = ir_emit_conv(proc, e, type);
} else if (type->kind == Type_Map) {
e = ir_emit_struct_ev(proc, e, 1);
switch (index) {
case 0: e = ir_emit_struct_ev(proc, e, 1); break; // count
case 1: e = ir_emit_struct_ev(proc, e, 2); break; // capacity
case 2: e = ir_emit_struct_ev(proc, e, 3); break; // allocator
}
} else {
e = ir_emit_struct_ev(proc, e, index);
}
@@ -4192,7 +4206,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
irValue *key = ir_build_expr(proc, fv->field);
irValue *value = ir_build_expr(proc, fv->value);
ir_insert_map_key_and_value(proc, v, type, key, value);
ir_insert_dynamic_map_key_and_value(proc, v, type, key, value);
}
} break;
+35 -1
View File
@@ -1073,6 +1073,10 @@ gb_global Entity *entity__dynamic_array_count = NULL;
gb_global Entity *entity__dynamic_array_capacity = NULL;
gb_global Entity *entity__dynamic_array_allocator = NULL;
gb_global Entity *entity__dynamic_map_count = NULL;
gb_global Entity *entity__dynamic_map_capacity = NULL;
gb_global Entity *entity__dynamic_map_allocator = NULL;
Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel);
Selection lookup_field(gbAllocator a, Type *type_, String field_name, bool is_type) {
@@ -1240,7 +1244,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__slice_count;
return sel;
}
} else if (type->kind == Type_DynamicArray) {
} else if (type->kind == Type_DynamicArray) {
String data_str = str_lit("data");
String count_str = str_lit("count");
String capacity_str = str_lit("capacity");
@@ -1273,6 +1277,36 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__dynamic_array_allocator;
return sel;
}
} else if (type->kind == Type_Map) {
String count_str = str_lit("count");
String capacity_str = str_lit("capacity");
String allocator_str = str_lit("allocator");
if (str_eq(field_name, count_str)) {
selection_add_index(&sel, 0);
if (entity__dynamic_map_count == NULL) {
entity__dynamic_map_count = make_entity_field(a, NULL, make_token_ident(count_str), t_int, false, 0);
entity__dynamic_map_count->Variable.is_immutable = true;
}
sel.entity = entity__dynamic_map_count;
return sel;
} else if (str_eq(field_name, capacity_str)) {
selection_add_index(&sel, 1);
if (entity__dynamic_map_capacity == NULL) {
entity__dynamic_map_capacity = make_entity_field(a, NULL, make_token_ident(capacity_str), t_int, false, 1);
entity__dynamic_map_capacity->Variable.is_immutable = true;
}
sel.entity = entity__dynamic_map_capacity;
return sel;
} else if (str_eq(field_name, allocator_str)) {
selection_add_index(&sel, 2);
if (entity__dynamic_map_allocator == NULL) {
entity__dynamic_map_allocator = make_entity_field(a, NULL, make_token_ident(allocator_str), t_allocator, false, 2);
entity__dynamic_map_allocator->Variable.is_immutable = true;
}
sel.entity = entity__dynamic_map_allocator;
return sel;
}
}
if (type->kind != Type_Record) {