2024-06-28 03:28:23 +02:00
2024-07-03 00:41:52 +02:00
///
/// Most of these are generated by gpt so there might be some goofyness
///
2024-06-28 18:50:30 +02:00
void log_heap ( ) {
os_spinlock_lock ( heap_lock ) ;
2024-07-02 15:27:33 +02:00
print ( " \n HEAP: \n " ) ;
2024-06-28 18:50:30 +02:00
Heap_Block * block = heap_head ;
while ( block ! = 0 ) {
2024-07-02 15:27:33 +02:00
print ( " \t BLOCK @ 0x%I64x, %llu bytes \n " , ( u64 ) block , block - > size ) ;
2024-06-28 18:50:30 +02:00
Heap_Free_Node * node = block - > free_head ;
u64 total_free = 0 ;
while ( node ! = 0 ) {
2024-07-02 15:27:33 +02:00
print ( " \t \t FREE NODE @ 0x%I64x, %llu bytes \n " , ( u64 ) node , node - > size ) ;
2024-06-28 18:50:30 +02:00
total_free + = node - > size ;
node = node - > next ;
}
2024-07-02 15:27:33 +02:00
print ( " \t TOTAL FREE: %llu \n \n " , total_free ) ;
2024-06-28 18:50:30 +02:00
block = block - > next ;
}
os_spinlock_unlock ( heap_lock ) ;
}
2024-06-28 03:28:23 +02:00
void test_allocator ( bool do_log_heap ) {
2024-07-01 13:10:06 +02:00
Allocator heap = get_heap_allocator ( ) ;
2024-06-28 03:28:23 +02:00
// Basic allocation and free
2024-07-01 13:10:06 +02:00
int * a = ( int * ) alloc ( heap , sizeof ( int ) ) ;
int * b = ( int * ) alloc ( heap , sizeof ( int ) ) ;
int * c = ( int * ) alloc ( heap , sizeof ( int ) ) ;
2024-06-28 03:28:23 +02:00
* a = 69 ;
* b = 420 ;
* c = 1337 ;
assert ( * a = = 69 , " Test failed: Memory corrupted " ) ;
assert ( * b = = 420 , " Test failed: Memory corrupted " ) ;
assert ( * c = = 1337 , " Test failed: Memory corrupted " ) ;
// Test growing memory
2024-07-02 19:12:31 +02:00
//os_grow_program_memory(1024 * 1024 * 1000);
2024-06-28 03:28:23 +02:00
assert ( * a = = 69 , " Test failed: Memory corrupted " ) ;
assert ( * b = = 420 , " Test failed: Memory corrupted " ) ;
assert ( * c = = 1337 , " Test failed: Memory corrupted " ) ;
2024-07-02 19:12:31 +02:00
u8 check_bytes [ 1024 ] ;
for ( u64 i = 0 ; i < 1024 ; i + = 4 ) {
* ( ( int * ) & check_bytes [ i ] ) = ( int ) get_random ( ) ;
}
u8 * check_bytes_copy = ( u8 * ) alloc ( heap , 1024 ) ;
memcpy ( check_bytes_copy , check_bytes , 1024 ) ;
2024-06-28 03:28:23 +02:00
// Allocate and free large block
2024-07-02 19:12:31 +02:00
//void* large_block = alloc(heap, 1024 * 1024 * 100);
//dealloc(heap, large_block);
2024-06-28 03:28:23 +02:00
// Allocate multiple small blocks
void * blocks [ 100 ] ;
for ( int i = 0 ; i < 100 ; + + i ) {
2024-07-01 13:10:06 +02:00
blocks [ i ] = alloc ( heap , 128 ) ;
2024-06-28 03:28:23 +02:00
assert ( blocks [ i ] ! = NULL , " Failed to allocate small block " ) ;
}
for ( int i = 0 ; i < 100 ; + + i ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
// Stress test with various sizes
for ( int i = 1 ; i < = 1000 ; + + i ) {
2024-07-01 13:10:06 +02:00
void * p = alloc ( heap , i * 64 ) ;
2024-06-28 03:28:23 +02:00
assert ( p ! = NULL , " Failed to allocate varying size block " ) ;
2024-07-01 13:10:06 +02:00
dealloc ( heap , p ) ;
2024-06-28 03:28:23 +02:00
}
2024-07-02 19:12:31 +02:00
2024-06-28 03:28:23 +02:00
// Free in reverse order
for ( int i = 0 ; i < 100 ; + + i ) {
2024-07-01 13:10:06 +02:00
blocks [ i ] = alloc ( heap , 128 ) ;
2024-06-28 03:28:23 +02:00
assert ( blocks [ i ] ! = NULL , " Failed to allocate small block " ) ;
}
for ( int i = 99 ; i > = 0 ; - - i ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
// Test memory integrity with various allocation patterns
int * nums [ 10 ] ;
for ( int i = 0 ; i < 10 ; + + i ) {
2024-07-01 13:10:06 +02:00
nums [ i ] = ( int * ) alloc ( heap , sizeof ( int ) * 10 ) ;
2024-06-28 03:28:23 +02:00
for ( int j = 0 ; j < 10 ; + + j ) {
nums [ i ] [ j ] = i * 10 + j ;
}
}
2024-07-02 19:12:31 +02:00
2024-06-28 03:28:23 +02:00
for ( int i = 0 ; i < 10 ; + + i ) {
for ( int j = 0 ; j < 10 ; + + j ) {
assert ( nums [ i ] [ j ] = = i * 10 + j , " Memory corruption detected " ) ;
}
2024-07-01 13:10:06 +02:00
dealloc ( heap , nums [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
2024-07-02 19:12:31 +02:00
2024-06-28 18:50:30 +02:00
reset_temporary_storage ( ) ;
2024-06-28 03:28:23 +02:00
2024-07-02 19:12:31 +02:00
2024-07-01 13:10:06 +02:00
int * foo = ( int * ) alloc ( temp , 72 ) ;
2024-06-28 03:28:23 +02:00
* foo = 1337 ;
2024-07-01 13:10:06 +02:00
void * bar = alloc ( temp , 69 ) ;
2024-06-28 19:10:29 +02:00
( void ) bar ;
2024-07-01 13:10:06 +02:00
void * baz = alloc ( temp , 420 ) ;
2024-06-28 19:10:29 +02:00
( void ) baz ;
2024-06-28 03:28:23 +02:00
assert ( * foo = = 1337 , " Temp memory corruptada " ) ;
int * old_foo = foo ;
reset_temporary_storage ( ) ;
2024-07-01 13:10:06 +02:00
foo = ( int * ) alloc ( temp , 72 ) ;
2024-06-28 03:28:23 +02:00
assert ( old_foo = = foo , " Temp allocator goof " ) ;
// Repeated Allocation and Free
for ( int i = 0 ; i < 10000 ; + + i ) {
2024-07-01 13:10:06 +02:00
void * temp = alloc ( heap , 128 ) ;
2024-06-28 03:28:23 +02:00
assert ( temp ! = NULL & & " Repeated allocation failed " ) ;
2024-07-01 13:10:06 +02:00
dealloc ( heap , temp ) ;
2024-06-28 03:28:23 +02:00
}
// Mixed Size Allocations
void * mixed_blocks [ 200 ] ;
for ( int i = 0 ; i < 200 ; + + i ) {
if ( i % 2 = = 0 ) {
2024-07-01 13:10:06 +02:00
mixed_blocks [ i ] = alloc ( heap , 128 ) ;
2024-06-28 03:28:23 +02:00
} else {
2024-07-01 13:10:06 +02:00
mixed_blocks [ i ] = alloc ( heap , 1024 * 1024 ) ; // 1MB blocks
2024-06-28 03:28:23 +02:00
}
assert ( mixed_blocks [ i ] ! = NULL & & " Mixed size allocation failed " ) ;
}
for ( int i = 0 ; i < 200 ; + + i ) {
if ( i % 2 = = 0 ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , mixed_blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
}
for ( int i = 0 ; i < 200 ; + + i ) {
if ( i % 2 ! = 0 ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , mixed_blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
}
// Fragmentation Stress Test
for ( int i = 0 ; i < 50 ; + + i ) {
2024-07-01 13:10:06 +02:00
blocks [ i ] = alloc ( heap , 256 ) ;
2024-06-28 03:28:23 +02:00
assert ( blocks [ i ] ! = NULL & & " Failed to allocate small block for fragmentation test " ) ;
}
for ( int i = 0 ; i < 50 ; i + = 2 ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
for ( int i = 50 ; i < 100 ; + + i ) {
2024-07-01 13:10:06 +02:00
blocks [ i ] = alloc ( heap , 128 ) ;
2024-06-28 03:28:23 +02:00
assert ( blocks [ i ] ! = NULL & & " Failed to allocate small block in fragmented heap " ) ;
}
for ( int i = 50 ; i < 100 ; + + i ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
for ( int i = 1 ; i < 50 ; i + = 2 ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
2024-07-02 19:12:31 +02:00
assert ( bytes_match ( check_bytes , check_bytes_copy , 1024 ) , " Memory corrupt " ) ;
2024-06-28 03:28:23 +02:00
if ( do_log_heap ) log_heap ( ) ;
}
void test_thread_proc1 ( Thread * t ) {
os_sleep ( 5 ) ;
2024-07-02 15:27:33 +02:00
print ( " Hello from thread %llu \n " , t - > id ) ;
2024-06-28 03:28:23 +02:00
os_sleep ( 5 ) ;
2024-07-02 15:27:33 +02:00
print ( " Hello from thread %llu \n " , t - > id ) ;
2024-06-28 03:28:23 +02:00
os_sleep ( 5 ) ;
2024-07-02 15:27:33 +02:00
print ( " Hello from thread %llu \n " , t - > id ) ;
2024-06-28 03:28:23 +02:00
os_sleep ( 5 ) ;
2024-07-02 15:27:33 +02:00
print ( " Hello from thread %llu \n " , t - > id ) ;
2024-06-28 03:28:23 +02:00
os_sleep ( 5 ) ;
2024-07-02 15:27:33 +02:00
print ( " Hello from thread %llu \n " , t - > id ) ;
2024-06-28 03:28:23 +02:00
}
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
2024-06-28 03:28:23 +02:00
void test_threads ( ) {
2024-07-01 13:10:06 +02:00
Thread * t = os_make_thread ( test_thread_proc1 , get_heap_allocator ( ) ) ;
2024-06-28 03:28:23 +02:00
os_start_thread ( t ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
os_sleep ( 20 ) ;
2024-07-02 15:27:33 +02:00
print ( " This should be printed in middle of thread execution \n " ) ;
2024-06-28 03:28:23 +02:00
os_join_thread ( t ) ;
2024-07-02 15:27:33 +02:00
print ( " Thread is joined \n " ) ;
2024-06-28 03:28:23 +02:00
Mutex_Handle m = os_make_mutex ( ) ;
os_lock_mutex ( m ) ;
os_unlock_mutex ( m ) ;
}
void test_allocator_threaded ( Thread * t ) {
2024-07-01 13:10:06 +02:00
Allocator heap = get_heap_allocator ( ) ;
2024-06-28 03:28:23 +02:00
for ( int i = 0 ; i < 1000 ; + + i ) {
2024-07-01 13:10:06 +02:00
void * temp = alloc ( heap , 128 ) ;
2024-06-28 03:28:23 +02:00
assert ( temp ! = NULL & & " Repeated allocation failed " ) ;
2024-07-01 13:10:06 +02:00
dealloc ( heap , temp ) ;
2024-06-28 03:28:23 +02:00
}
void * mixed_blocks [ 40 ] ;
for ( int i = 0 ; i < 40 ; + + i ) {
if ( i % 2 = = 0 ) {
2024-07-01 13:10:06 +02:00
mixed_blocks [ i ] = alloc ( heap , 128 ) ;
2024-06-28 03:28:23 +02:00
} else {
2024-07-01 13:10:06 +02:00
mixed_blocks [ i ] = alloc ( heap , 1024 * 1024 ) ; // 1MB blocks
2024-06-28 03:28:23 +02:00
}
assert ( mixed_blocks [ i ] ! = NULL & & " Mixed size allocation failed " ) ;
}
for ( int i = 0 ; i < 40 ; + + i ) {
if ( i % 2 = = 0 ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , mixed_blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
}
for ( int i = 0 ; i < 40 ; + + i ) {
if ( i % 2 ! = 0 ) {
2024-07-01 13:10:06 +02:00
dealloc ( heap , mixed_blocks [ i ] ) ;
2024-06-28 03:28:23 +02:00
}
}
}
2024-06-28 12:07:02 +02:00
void test_strings ( ) {
2024-07-01 13:10:06 +02:00
Allocator heap = get_heap_allocator ( ) ;
2024-07-02 15:27:33 +02:00
{
// Test length_of_null_terminated_string
assert ( length_of_null_terminated_string ( " Test " ) = = 4 , " Failed: length_of_null_terminated_string " ) ;
assert ( length_of_null_terminated_string ( " " ) = = 0 , " Failed: length_of_null_terminated_string " ) ;
// Test alloc_string and dealloc_string
string alloc_str = alloc_string ( heap , 10 ) ;
assert ( alloc_str . data ! = NULL , " Failed: alloc_string " ) ;
assert ( alloc_str . count = = 10 , " Failed: alloc_string " ) ;
dealloc_string ( heap , alloc_str ) ;
// Test string_concat
string str1 = STR ( " Hello, " ) ;
string str2 = STR ( " World! " ) ;
string concat_str = string_concat ( str1 , str2 , heap ) ;
assert ( concat_str . count = = str1 . count + str2 . count , " Failed: string_concat " ) ;
assert ( memcmp ( concat_str . data , " Hello, World! " , concat_str . count ) = = 0 , " Failed: string_concat " ) ;
dealloc_string ( heap , concat_str ) ;
// Test convert_to_null_terminated_string
char * cstr = convert_to_null_terminated_string ( str1 , heap ) ;
assert ( strcmp ( cstr , " Hello, " ) = = 0 , " Failed: convert_to_null_terminated_string " ) ;
dealloc ( heap , cstr ) ;
// Test temp_convert_to_null_terminated_string
cstr = temp_convert_to_null_terminated_string ( str2 ) ;
assert ( strcmp ( cstr , " World! " ) = = 0 , " Failed: temp_convert_to_null_terminated_string " ) ;
// Test sprint
string format_str = STR ( " Number: %d " ) ;
string formatted_str = sprint ( heap , format_str , 42 ) ;
char * formatted_cstr = convert_to_null_terminated_string ( formatted_str , heap ) ;
assert ( strcmp ( formatted_cstr , " Number: 42 " ) = = 0 , " Failed: sprint " ) ;
dealloc ( heap , formatted_str . data ) ;
dealloc ( heap , formatted_cstr ) ;
// Test tprint
string temp_formatted_str = tprint ( format_str , 100 ) ;
formatted_cstr = temp_convert_to_null_terminated_string ( temp_formatted_str ) ;
assert ( strcmp ( formatted_cstr , " Number: 100 " ) = = 0 , " Failed: tprint " ) ;
// Test print and printf (visual inspection)
print ( " Expected output: Hello, World! \n " ) ;
print ( " Hello, %s! \n " , STR ( " World " ) ) ;
print ( " Expected output: Number: 1234 \n " ) ;
print ( " Number: %d \n " , 1234 ) ;
print ( " Expected output: Number: 1234 \n " ) ;
print ( " Number: %d \n " , 1234 ) ;
print ( " Expected output: Mixed values: 42 and 3.14 \n " ) ;
print ( " Mixed values: %d and %.2f \n " , 42 , 3.14 ) ;
// This should fail assert and print descriptive error
//print("Expected output (printf): Hello, World!\n");
//print("Hello, %cs!\n", 5);
// This should fail assert and print descriptive error
// print("Expected output (printf): Hello, World!\n");
// print("Hello, %s!\n", "World");
print ( " Expected output (printf): Hello, World! \n " ) ;
print ( " Hello, %s! \n " , STR ( " World " ) ) ;
print ( " Expected output (printf): Number: 5678 \n " ) ;
print ( " Number: %d \n " , 5678 ) ;
print ( " Expected output (printf): Mixed values: 99 and 2.71 \n " ) ;
print ( " Mixed values: %d and %.2f \n " , 99 , 2.71 ) ;
// Test handling of empty strings
string empty_str = STR ( " " ) ;
string concat_empty_str = string_concat ( empty_str , empty_str , heap ) ;
assert ( concat_empty_str . count = = 0 , " Failed: string_concat with empty strings " ) ;
dealloc_string ( heap , concat_empty_str ) ;
// Test very large strings (performance test)
string large_str1 = alloc_string ( heap , 1024 * 1024 ) ;
string large_str2 = alloc_string ( heap , 1024 * 1024 ) ;
string large_concat_str = string_concat ( large_str1 , large_str2 , heap ) ;
assert ( large_concat_str . count = = 2 * 1024 * 1024 , " Failed: large string_concat " ) ;
dealloc_string ( heap , large_str1 ) ;
dealloc_string ( heap , large_str2 ) ;
dealloc_string ( heap , large_concat_str ) ;
// Test string with special characters
string special_char_str = STR ( " Special chars: \n \t \r " ) ;
cstr = convert_to_null_terminated_string ( special_char_str , heap ) ;
assert ( strcmp ( cstr , " Special chars: \n \t \r " ) = = 0 , " Failed: special character string " ) ;
dealloc ( heap , cstr ) ;
string a = tprint ( " Hello, %cs! \n " , " balls " ) ;
string balls1 = string_view ( a , 7 , 5 ) ;
string balls2 = STR ( " balls " ) ;
assert ( strings_match ( balls1 , balls2 ) , " String match failed " ) ;
assert ( ! strings_match ( balls1 , a ) , " String match failed " ) ;
}
// Test string_builder_init
String_Builder builder ;
string_builder_init ( & builder , heap ) ;
assert ( builder . buffer ! = NULL , " Failed: string_builder_init " ) ;
assert ( builder . buffer_capacity > = 128 , " Failed: string_builder_init " ) ;
assert ( builder . count = = 0 , " Failed: string_builder_init " ) ;
// Test string_builder_reserve
string_builder_reserve ( & builder , 256 ) ;
assert ( builder . buffer_capacity > = 256 , " Failed: string_builder_reserve " ) ;
// Test string_builder_append
string str1 = STR ( " Hello, " ) ;
string_builder_append ( & builder , str1 ) ;
assert ( builder . count = = str1 . count , " Failed: string_builder_append " ) ;
assert ( memcmp ( builder . buffer , str1 . data , str1 . count ) = = 0 , " Failed: string_builder_append " ) ;
string str2 = STR ( " World! " ) ;
string_builder_append ( & builder , str2 ) ;
assert ( builder . count = = str1 . count + str2 . count , " Failed: string_builder_append " ) ;
assert ( memcmp ( builder . buffer , " Hello, World! " , builder . count ) = = 0 , " Failed: string_builder_append " ) ;
// Test string_builder_prints
string format_str = STR ( " Number: %d " ) ;
string_builder_prints ( & builder , format_str , 42 ) ;
char * expected_result = " Hello, World! Number: 42 " ;
assert ( builder . count = = strlen ( expected_result ) , " Failed: string_builder_prints " ) ;
assert ( memcmp ( builder . buffer , expected_result , builder . count ) = = 0 , " Failed: string_builder_prints " ) ;
// Test string_builder_printf
string_builder_printf ( & builder , " And a float: %.2f " , 3.14 ) ;
expected_result = " Hello, World! Number: 42 And a float: 3.14 " ;
assert ( builder . count = = strlen ( expected_result ) , " Failed: string_builder_printf " ) ;
assert ( memcmp ( builder . buffer , expected_result , builder . count ) = = 0 , " Failed: string_builder_printf " ) ;
// Test string_builder_get_string
string result_str = string_builder_get_string ( & builder ) ;
assert ( result_str . count = = builder . count , " Failed: string_builder_get_string " ) ;
assert ( memcmp ( result_str . data , builder . buffer , result_str . count ) = = 0 , " Failed: string_builder_get_string " ) ;
// Cleanup
dealloc ( heap , builder . buffer ) ;
2024-06-28 18:50:30 +02:00
2024-07-02 15:27:33 +02:00
// Test handling of empty builder
String_Builder empty_builder ;
string_builder_init ( & empty_builder , heap ) ;
result_str = string_builder_get_string ( & empty_builder ) ;
assert ( result_str . count = = 0 , " Failed: empty builder handling " ) ;
dealloc ( heap , empty_builder . buffer ) ;
2024-06-28 18:50:30 +02:00
2024-07-02 15:27:33 +02:00
// Test appending large strings (performance test)
String_Builder large_builder ;
string_builder_init ( & large_builder , heap ) ;
string large_str = alloc_string ( heap , 1024 * 1024 ) ;
memset ( large_str . data , ' A ' , 1024 * 1024 ) ;
string_builder_append ( & large_builder , large_str ) ;
assert ( large_builder . count = = 1024 * 1024 , " Failed: large string_builder_append " ) ;
dealloc_string ( heap , large_str ) ;
dealloc ( heap , large_builder . buffer ) ;
2024-06-28 18:50:30 +02:00
2024-07-02 15:27:33 +02:00
// Test appending special characters
String_Builder special_char_builder ;
string_builder_init ( & special_char_builder , heap ) ;
string special_char_str = STR ( " Special chars: \n \t \r " ) ;
string_builder_append ( & special_char_builder , special_char_str ) ;
assert ( special_char_builder . count = = special_char_str . count , " Failed: special character append " ) ;
assert ( memcmp ( special_char_builder . buffer , special_char_str . data , special_char_str . count ) = = 0 , " Failed: special character append " ) ;
dealloc ( heap , special_char_builder . buffer ) ;
2024-06-28 18:50:30 +02:00
2024-07-02 15:27:33 +02:00
// Test multiple appends
String_Builder multi_append_builder ;
string_builder_init ( & multi_append_builder , heap ) ;
string str_a = STR ( " First part " ) ;
string str_b = STR ( " and second part " ) ;
string str_c = STR ( " and third part. " ) ;
string_builder_append ( & multi_append_builder , str_a ) ;
string_builder_append ( & multi_append_builder , str_b ) ;
string_builder_append ( & multi_append_builder , str_c ) ;
expected_result = " First part and second part and third part. " ;
assert ( multi_append_builder . count = = strlen ( expected_result ) , " Failed: multiple appends " ) ;
assert ( memcmp ( multi_append_builder . buffer , expected_result , multi_append_builder . count ) = = 0 , " Failed: multiple appends " ) ;
dealloc ( heap , multi_append_builder . buffer ) ;
2024-06-28 12:07:02 +02:00
}
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
void test_file_io ( ) {
# if TARGET_OS == WINDOWS
// Test win32_fixed_utf8_to_null_terminated_wide
2024-07-02 15:27:33 +02:00
string utf8_str = STR ( " Test " ) ;
2024-07-01 13:10:06 +02:00
u16 * wide_str = win32_fixed_utf8_to_null_terminated_wide ( utf8_str , get_heap_allocator ( ) ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( wide_str ! = NULL , " Failed: win32_fixed_utf8_to_null_terminated_wide " ) ;
assert ( wide_str [ 4 ] = = 0 , " Failed: win32_fixed_utf8_to_null_terminated_wide " ) ;
2024-07-01 13:10:06 +02:00
dealloc ( get_heap_allocator ( ) , wide_str ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
// Test temp_win32_fixed_utf8_to_null_terminated_wide
wide_str = temp_win32_fixed_utf8_to_null_terminated_wide ( utf8_str ) ;
assert ( wide_str ! = NULL , " Failed: temp_win32_fixed_utf8_to_null_terminated_wide " ) ;
assert ( wide_str [ 4 ] = = 0 , " Failed: temp_win32_fixed_utf8_to_null_terminated_wide " ) ;
# endif
2024-06-28 18:50:30 +02:00
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
File file = OS_INVALID_FILE ;
os_file_close ( file ) ;
// Test os_file_open and os_file_close
2024-07-02 15:27:33 +02:00
file = os_file_open ( " test.txt " , O_WRITE | O_CREATE ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( file ! = OS_INVALID_FILE , " Failed: os_file_open (write/create) " ) ;
os_file_close ( file ) ;
// Test os_file_write_string and os_file_read
2024-07-02 15:27:33 +02:00
string hello_world_write = STR ( " Hello, World! " ) ;
file = os_file_open ( " test.txt " , O_WRITE | O_CREATE ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( file ! = OS_INVALID_FILE , " Failed: os_file_open (write/create) " ) ;
bool write_result = os_file_write_string ( file , hello_world_write ) ;
assert ( write_result , " Failed: os_file_write_string " ) ;
os_file_close ( file ) ;
2024-07-02 15:27:33 +02:00
file = os_file_open ( " test.txt " , O_READ ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( file ! = OS_INVALID_FILE , " Failed: os_file_open (read) " ) ;
string hello_world_read = talloc_string ( hello_world_write . count ) ;
bool read_result = os_file_read ( file , hello_world_read . data , hello_world_read . count , & hello_world_read . count ) ;
assert ( read_result , " Failed: os_file_read %d " , GetLastError ( ) ) ;
assert ( strings_match ( hello_world_read , hello_world_write ) , " Failed: os_file_read write/read mismatch " ) ;
os_file_close ( file ) ;
// Test os_file_write_bytes
2024-07-02 15:27:33 +02:00
file = os_file_open ( " test_bytes.txt " , O_WRITE | O_CREATE ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( file ! = OS_INVALID_FILE , " Failed: os_file_open (write/create) " ) ;
int int_data = 42 ;
write_result = os_file_write_bytes ( file , & int_data , sizeof ( int ) ) ;
assert ( write_result , " Failed: os_file_write_bytes " ) ;
os_file_close ( file ) ;
// Test os_read_entire_file and os_write_entire_file
2024-07-02 15:27:33 +02:00
string write_data = STR ( " Entire file test " ) ;
bool write_entire_result = os_write_entire_file ( " entire_test.txt " , write_data ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( write_entire_result , " Failed: os_write_entire_file " ) ;
2024-07-01 13:10:06 +02:00
Allocator heap = get_heap_allocator ( ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
string read_data ;
2024-07-02 15:27:33 +02:00
bool read_entire_result = os_read_entire_file ( " entire_test.txt " , & read_data , heap ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( read_entire_result , " Failed: os_read_entire_file " ) ;
assert ( strings_match ( read_data , write_data ) , " Failed: os_read_entire_file write/read mismatch " ) ;
assert ( memcmp ( read_data . data , write_data . data , write_data . count ) = = 0 , " Failed: os_read_entire_file (content mismatch) " ) ;
2024-07-01 13:10:06 +02:00
dealloc ( heap , read_data . data ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
// Test fprint
2024-07-02 15:27:33 +02:00
File balls = os_file_open ( " balls.txt " , O_WRITE | O_CREATE ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( balls ! = OS_INVALID_FILE , " Failed: Could not create balls.txt " ) ;
fprint ( balls , " Hello, %cs! " , " Balls " ) ;
os_file_close ( balls ) ;
string hello_balls ;
2024-07-02 15:27:33 +02:00
read_entire_result = os_read_entire_file ( " balls.txt " , & hello_balls , heap ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( read_entire_result , " Failed: could not read balls.txt " ) ;
2024-07-02 15:27:33 +02:00
assert ( strings_match ( hello_balls , STR ( " Hello, Balls! " ) ) , " Failed: balls read/write mismatch. Expected 'Hello, Balls!', got '%s' " , hello_balls ) ;
2024-07-01 02:14:08 +02:00
u64 integers [ 4096 ] ;
for ( u64 i = 0 ; i < 4096 ; i + + ) {
integers [ i ] = get_random ( ) ;
}
string integers_data ;
integers_data . data = ( u8 * ) integers ;
integers_data . count = 4096 * sizeof ( u64 ) ;
2024-07-02 15:27:33 +02:00
bool ok = os_write_entire_file ( " integers " , integers_data ) ;
2024-07-01 02:14:08 +02:00
assert ( ok , " write integers fail " ) ;
string integers_read ;
2024-07-02 15:27:33 +02:00
ok = os_read_entire_file ( " integers " , & integers_read , heap ) ;
2024-07-01 02:14:08 +02:00
assert ( ok , " read integers fail " ) ;
u64 * new_integers = ( u64 * ) integers_data . data ;
assert ( integers_read . count = = integers_data . count , " Failed: big file read/write mismatch. Read was %d and written was %d " , integers_read . count , integers_data . count ) ;
assert ( strings_match ( integers_data , integers_read ) , " Failed: big file read/write mismatch " ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
2024-07-03 23:01:46 +02:00
assert ( os_is_file ( " test.txt " ) , " Failed: test.txt not recognized as file " ) ;
assert ( os_is_file ( " test_bytes.txt " ) , " Failed: test_bytes.txt not recognized as file " ) ;
assert ( os_is_file ( " entire_test.txt " ) , " Failed: entire_test.txt not recognized as file " ) ;
assert ( os_is_file ( " balls.txt " ) , " Failed: balls.txt not recognized as file " ) ;
assert ( os_is_file ( " integers " ) , " Failed: integers not recognized as file " ) ;
bool dir_ok = os_make_directory ( " test_dir " , false ) ;
assert ( dir_ok , " Failed: os_make_directory " ) ;
assert ( os_is_directory ( " test_dir " ) , " Failed: os_is_directory " ) ;
string dir_abs ;
bool abs_ok = os_get_absolute_path ( STR ( " test_dir " ) , & dir_abs , heap ) ;
assert ( abs_ok , " Failed: os_get_absolute_path " ) ;
assert ( os_is_path_absolute ( dir_abs ) , " Failed: os_is_path_absolute " ) ;
assert ( ! os_is_path_absolute ( STR ( " test_dir " ) ) , " Failed: os_is_path_absolute " ) ;
string dir_rel ;
bool rel_ok = os_get_relative_path ( STR ( " . " ) , dir_abs , & dir_rel , heap ) ;
assert ( rel_ok , " Failed: os_get_relative_path " ) ;
assert ( os_do_paths_match ( dir_rel , STR ( " test_dir " ) ) , " Failed: Resolved relative path does not match. Expected '. \t est_dir', got %s. " , dir_rel ) ;
dir_ok = os_make_directory ( " test_dir1/test_dir2/test_dir3 " , true ) ;
assert ( dir_ok , " Failed: os_make_directory " ) ;
dir_ok = os_make_directory ( " test_dir1/test_dir2/test_dir4 " , true ) ;
assert ( dir_ok , " Failed: os_make_directory " ) ;
assert ( os_is_directory ( " test_dir1 " ) , " Failed: os_is_directory " ) ;
assert ( os_is_directory ( " test_dir1/test_dir2 " ) , " Failed: os_is_directory " ) ;
assert ( os_is_directory ( " test_dir1/test_dir2//test_dir3 " ) , " Failed: os_is_directory " ) ;
assert ( os_is_directory ( " test_dir1/test_dir2//test_dir4 " ) , " Failed: os_is_directory " ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
// Clean up test files
bool delete_ok = false ;
2024-07-02 15:27:33 +02:00
delete_ok = os_file_delete ( " test.txt " ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( delete_ok , " Failed: could not delete test.txt " ) ;
2024-07-02 15:27:33 +02:00
delete_ok = os_file_delete ( " test_bytes.txt " ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( delete_ok , " Failed: could not delete test_bytes.txt " ) ;
2024-07-02 15:27:33 +02:00
delete_ok = os_file_delete ( " entire_test.txt " ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( delete_ok , " Failed: could not delete entire_test.txt " ) ;
2024-07-02 15:27:33 +02:00
delete_ok = os_file_delete ( " balls.txt " ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
assert ( delete_ok , " Failed: could not delete balls.txt " ) ;
2024-07-02 15:27:33 +02:00
delete_ok = os_file_delete ( " integers " ) ;
assert ( delete_ok , " Failed: could not delete integers " ) ;
2024-07-03 23:01:46 +02:00
delete_ok = os_delete_directory ( " test_dir " , false ) ;
assert ( delete_ok , " Failed: could not delete test_dir " ) ;
delete_ok = os_delete_directory ( " test_dir1 " , true ) ;
assert ( delete_ok , " Failed: could not delete test_dir1 (recursive) " ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
}
2024-07-03 17:55:25 +02:00
bool floats_roughly_match ( float a , float b ) {
return fabs ( a - b ) < 0.01 ;
}
2024-07-03 00:01:11 +02:00
void test_simd ( ) {
2024-06-28 18:50:30 +02:00
2024-07-03 17:55:25 +02:00
2024-07-03 00:01:11 +02:00
2024-07-03 17:55:25 +02:00
f32 * a_f32 = alloc ( get_heap_allocator ( ) , 128 * sizeof ( f32 ) ) ;
f32 * b_f32 = alloc ( get_heap_allocator ( ) , 128 * sizeof ( f32 ) ) ;
f32 * result_f32 = alloc ( get_heap_allocator ( ) , 128 * sizeof ( f32 ) ) ;
s32 * a_i32 = alloc ( get_heap_allocator ( ) , 128 * sizeof ( f32 ) ) ;
s32 * b_i32 = alloc ( get_heap_allocator ( ) , 128 * sizeof ( f32 ) ) ;
s32 * result_i32 = alloc ( get_heap_allocator ( ) , 128 * sizeof ( f32 ) ) ;
( * ( u64 * ) & a_f32 ) = ( ( * ( u64 * ) & a_f32 ) + 64 ) & ~ ( 63 ) ;
( * ( u64 * ) & b_f32 ) = ( ( * ( u64 * ) & b_f32 ) + 64 ) & ~ ( 63 ) ;
( * ( u64 * ) & result_f32 ) = ( ( * ( u64 * ) & result_f32 ) + 64 ) & ~ ( 63 ) ;
( * ( u64 * ) & a_i32 ) = ( ( * ( u64 * ) & a_i32 ) + 64 ) & ~ ( 63 ) ;
( * ( u64 * ) & b_i32 ) = ( ( * ( u64 * ) & b_i32 ) + 64 ) & ~ ( 63 ) ;
( * ( u64 * ) & result_i32 ) = ( ( * ( u64 * ) & result_i32 ) + 64 ) & ~ ( 63 ) ;
assert ( ( u64 ) a_f32 % 16 = = 0 ) ;
assert ( ( u64 ) b_f32 % 16 = = 0 ) ;
assert ( ( u64 ) result_f32 % 16 = = 0 ) ;
assert ( ( u64 ) a_i32 % 16 = = 0 ) ;
assert ( ( u64 ) b_i32 % 16 = = 0 ) ;
assert ( ( u64 ) result_i32 % 16 = = 0 ) ;
assert ( ( u64 ) a_f32 % 32 = = 0 ) ;
assert ( ( u64 ) b_f32 % 32 = = 0 ) ;
assert ( ( u64 ) result_f32 % 32 = = 0 ) ;
assert ( ( u64 ) a_i32 % 32 = = 0 ) ;
assert ( ( u64 ) b_i32 % 32 = = 0 ) ;
assert ( ( u64 ) result_i32 % 32 = = 0 ) ;
assert ( ( u64 ) a_f32 % 64 = = 0 ) ;
assert ( ( u64 ) b_f32 % 64 = = 0 ) ;
assert ( ( u64 ) result_f32 % 64 = = 0 ) ;
assert ( ( u64 ) a_i32 % 64 = = 0 ) ;
assert ( ( u64 ) b_i32 % 64 = = 0 ) ;
assert ( ( u64 ) result_i32 % 64 = = 0 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 16 ; + + i ) {
a_f32 [ i ] = i * 1.0f ;
b_f32 [ i ] = ( i + 1 ) * 2.0f ;
a_i32 [ i ] = i ;
b_i32 [ i ] = i + 1 ;
}
// Test function pointers setup
query_cpu_capabilities ( ) ;
// Test float32 add
simd_add_float32_64 ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ 0 ] , a_f32 [ 0 ] + b_f32 [ 0 ] ) , " SIMD add float32 64 failed " ) ;
2024-07-03 00:01:11 +02:00
2024-07-04 12:18:16 +02:00
simd_add_float32_128_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 4 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] + b_f32 [ i ] ) , " SIMD add float32 128 failed " ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
simd_add_float32_256_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 8 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] + b_f32 [ i ] ) , " SIMD add float32 256 failed " ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
simd_add_float32_512_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 16 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] + b_f32 [ i ] ) , " SIMD add float32 512 failed " ) ;
2024-07-03 00:01:11 +02:00
}
// Test float32 subtract
simd_sub_float32_64 ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ 0 ] , a_f32 [ 0 ] - b_f32 [ 0 ] ) , " SIMD sub float32 64 failed " ) ;
2024-07-03 00:01:11 +02:00
2024-07-04 12:18:16 +02:00
simd_sub_float32_128_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 4 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] - b_f32 [ i ] ) , " SIMD sub float32 128 failed " ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
simd_sub_float32_256_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 8 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] - b_f32 [ i ] ) , " SIMD sub float32 256 failed " ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
simd_sub_float32_512_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 16 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] - b_f32 [ i ] ) , " SIMD sub float32 512 failed " ) ;
2024-07-03 00:01:11 +02:00
}
// Test float32 multiply
simd_mul_float32_64 ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ 0 ] , a_f32 [ 0 ] * b_f32 [ 0 ] ) , " SIMD mul float32 64 failed " ) ;
2024-07-03 00:01:11 +02:00
2024-07-04 12:18:16 +02:00
simd_mul_float32_128_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 4 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] * b_f32 [ i ] ) , " SIMD mul float32 128 failed " ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
simd_mul_float32_256_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 8 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] * b_f32 [ i ] ) , " SIMD mul float32 256 failed " ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
simd_mul_float32_512_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 16 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] * b_f32 [ i ] ) , " SIMD mul float32 512 failed " ) ;
2024-07-03 00:01:11 +02:00
}
// Test float32 divide
simd_div_float32_64 ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ 0 ] , a_f32 [ 0 ] / b_f32 [ 0 ] ) , " SIMD div float32 64 failed " ) ;
2024-07-03 00:01:11 +02:00
2024-07-04 12:18:16 +02:00
simd_div_float32_128_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 4 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] / b_f32 [ i ] ) , " SIMD div float32 128 failed " ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
simd_div_float32_256_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 8 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] / b_f32 [ i ] ) , " SIMD div float32 256 failed, %.5f, %.5f, %.5f " , result_f32 [ i ] , a_f32 [ i ] , a_f32 [ i ] / b_f32 [ i ] ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
simd_div_float32_512_aligned ( a_f32 , b_f32 , result_f32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 16 ; + + i ) {
2024-07-03 17:55:25 +02:00
assert ( floats_roughly_match ( result_f32 [ i ] , a_f32 [ i ] / b_f32 [ i ] ) , " SIMD div float32 512 failed " ) ;
2024-07-03 00:01:11 +02:00
}
// Test int32 add
2024-07-04 12:18:16 +02:00
simd_add_int32_128_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 4 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] + b_i32 [ i ] , " SIMD add int32 128 failed " ) ;
}
2024-07-04 12:18:16 +02:00
simd_add_int32_256_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 8 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] + b_i32 [ i ] , " SIMD add int32 256 failed " ) ;
}
2024-07-04 12:18:16 +02:00
simd_add_int32_512_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 16 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] + b_i32 [ i ] , " SIMD add int32 512 failed " ) ;
}
// Test int32 subtract
2024-07-04 12:18:16 +02:00
simd_sub_int32_128_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 4 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] - b_i32 [ i ] , " SIMD sub int32 128 failed " ) ;
}
2024-07-04 12:18:16 +02:00
simd_sub_int32_256_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 8 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] - b_i32 [ i ] , " SIMD sub int32 256 failed " ) ;
}
2024-07-04 12:18:16 +02:00
simd_sub_int32_512_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 16 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] - b_i32 [ i ] , " SIMD sub int32 512 failed " ) ;
}
// Test int32 multiply
2024-07-04 12:18:16 +02:00
simd_mul_int32_128_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 4 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] * b_i32 [ i ] , " SIMD mul int32 128 failed " ) ;
}
2024-07-04 12:18:16 +02:00
simd_mul_int32_256_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 8 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] * b_i32 [ i ] , " SIMD mul int32 256 failed " ) ;
}
2024-07-04 12:18:16 +02:00
simd_mul_int32_512_aligned ( a_i32 , b_i32 , result_i32 ) ;
2024-07-03 00:01:11 +02:00
for ( int i = 0 ; i < 16 ; + + i ) {
assert ( result_i32 [ i ] = = a_i32 [ i ] * b_i32 [ i ] , " SIMD mul int32 512 failed " ) ;
}
2024-07-03 17:55:25 +02:00
# define _TEST_NUM_SAMPLES ((100000 + 64) & ~(63))
assert ( _TEST_NUM_SAMPLES % 16 = = 0 ) ;
2024-07-04 12:18:16 +02:00
float * samples_a = alloc ( get_heap_allocator ( ) , _TEST_NUM_SAMPLES * sizeof ( float ) + 512 ) ;
float * samples_b = alloc ( get_heap_allocator ( ) , _TEST_NUM_SAMPLES * sizeof ( float ) + 512 ) ;
samples_a = ( float * ) ( ( ( u64 ) samples_a + 64 ) & ~ ( 63 ) ) ;
samples_b = ( float * ) ( ( ( u64 ) samples_b + 64 ) & ~ ( 63 ) ) ;
2024-07-03 17:55:25 +02:00
memset ( samples_a , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
memset ( samples_b , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
u64 start = os_get_current_cycle_count ( ) ;
for ( u64 i = 0 ; i < _TEST_NUM_SAMPLES ; i + = 16 ) {
2024-07-04 12:18:16 +02:00
simd_mul_float32_512_aligned ( & samples_a [ i ] , & samples_b [ i ] , & samples_a [ i ] ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-03 17:55:25 +02:00
u64 end = os_get_current_cycle_count ( ) ;
u64 cycles = end - start ;
print ( " simd 512 float32 mul took %llu cycles \n " , cycles ) ;
memset ( samples_a , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
memset ( samples_b , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
start = os_get_current_cycle_count ( ) ;
for ( u64 i = 0 ; i < _TEST_NUM_SAMPLES ; i + = 8 ) {
2024-07-04 12:18:16 +02:00
simd_mul_float32_256_aligned ( & samples_a [ i ] , & samples_b [ i ] , & samples_a [ i ] ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-03 17:55:25 +02:00
end = os_get_current_cycle_count ( ) ;
cycles = end - start ;
print ( " simd 256 float32 mul took %llu cycles \n " , cycles ) ;
memset ( samples_a , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
memset ( samples_b , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
start = os_get_current_cycle_count ( ) ;
for ( u64 i = 0 ; i < _TEST_NUM_SAMPLES ; i + = 4 ) {
2024-07-04 12:18:16 +02:00
simd_mul_float32_128_aligned ( & samples_a [ i ] , & samples_b [ i ] , & samples_a [ i ] ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-03 17:55:25 +02:00
end = os_get_current_cycle_count ( ) ;
cycles = end - start ;
print ( " simd 128 float32 mul took %llu cycles \n " , cycles ) ;
memset ( samples_a , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
memset ( samples_b , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
start = os_get_current_cycle_count ( ) ;
for ( u64 i = 0 ; i < _TEST_NUM_SAMPLES ; i + = 2 ) {
simd_mul_float32_64 ( & samples_a [ i ] , & samples_b [ i ] , & samples_a [ i ] ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-03 17:55:25 +02:00
end = os_get_current_cycle_count ( ) ;
cycles = end - start ;
print ( " simd 64 float32 mul took %llu cycles \n " , cycles ) ;
2024-07-03 00:01:11 +02:00
2024-07-03 17:55:25 +02:00
memset ( samples_a , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
memset ( samples_b , 2 , _TEST_NUM_SAMPLES * sizeof ( float ) ) ;
2024-07-03 00:01:11 +02:00
2024-07-03 17:55:25 +02:00
start = os_get_current_cycle_count ( ) ;
for ( u64 i = 0 ; i < _TEST_NUM_SAMPLES ; i + = 1 ) {
samples_a [ i ] = samples_a [ i ] + samples_b [ i ] ;
}
end = os_get_current_cycle_count ( ) ;
cycles = end - start ;
print ( " NO SIMD float32 mul took %llu cycles \n " , cycles ) ;
2024-07-03 00:01:11 +02:00
}
2024-07-04 12:18:16 +02:00
// Indirect testing of some simd stuff
void test_linmath ( ) {
2024-07-03 00:41:52 +02:00
// Test vector creation and access
Vector2 v2_test = v2 ( 1.0f , 2.0f ) ;
assert ( v2_test . x = = 1.0f & & v2_test . y = = 2.0f , " v2 creation incorrect " ) ;
Vector3 v3_test = v3 ( 1.0f , 2.0f , 3.0f ) ;
assert ( v3_test . x = = 1.0f & & v3_test . y = = 2.0f & & v3_test . z = = 3.0f , " v3 creation incorrect " ) ;
Vector4 v4_test = v4 ( 1.0f , 2.0f , 3.0f , 4.0f ) ;
assert ( v4_test . x = = 1.0f & & v4_test . y = = 2.0f & & v4_test . z = = 3.0f & & v4_test . w = = 4.0f , " v4 creation incorrect " ) ;
// Test vector operations
Vector2 v2_a = v2 ( 3.0f , 4.0f ) ;
Vector2 v2_b = v2 ( 1.0f , 2.0f ) ;
Vector2 v2_result = v2_add ( v2_a , v2_b ) ;
assert ( v2_result . x = = 4.0f & & v2_result . y = = 6.0f , " v2_add incorrect. %.3f, %.3f " , v2_result . x , v2_result . y ) ;
v2_result = v2_sub ( v2_a , v2_b ) ;
assert ( v2_result . x = = 2.0f & & v2_result . y = = 2.0f , " v2_sub incorrect " ) ;
v2_result = v2_mul ( v2_a , v2_b ) ;
assert ( v2_result . x = = 3.0f & & v2_result . y = = 8.0f , " v2_mul incorrect " ) ;
v2_result = v2_div ( v2_a , v2_b ) ;
assert ( v2_result . x = = 3.0f & & v2_result . y = = 2.0f , " v2_div incorrect " ) ;
v2_result = v2_mulf ( v2_a , 2.0f ) ;
assert ( v2_result . x = = 6.0f & & v2_result . y = = 8.0f , " v2_mulf incorrect " ) ;
v2_result = v2_divf ( v2_a , 2.0f ) ;
assert ( v2_result . x = = 1.5f & & v2_result . y = = 2.0f , " v2_divf incorrect " ) ;
// Test matrix operations
Matrix4 m1 = m4_scalar ( 2.0f ) ;
assert ( m1 . data [ 0 ] = = 2.0f & & m1 . data [ 5 ] = = 2.0f & & m1 . data [ 10 ] = = 2.0f & & m1 . data [ 15 ] = = 2.0f , " m4_scalar incorrect " ) ;
Vector3 translation = v3 ( 1.0f , 2.0f , 3.0f ) ;
Matrix4 m2 = m4_make_translation ( translation ) ;
assert ( m2 . m [ 0 ] [ 3 ] = = 1.0f & & m2 . m [ 1 ] [ 3 ] = = 2.0f & & m2 . m [ 2 ] [ 3 ] = = 3.0f , " m4_make_translation incorrect " ) ;
Vector3 scale = v3 ( 2.0f , 3.0f , 4.0f ) ;
Matrix4 m4 = m4_make_scale ( scale ) ;
assert ( m4 . m [ 0 ] [ 0 ] = = 2.0f & & m4 . m [ 1 ] [ 1 ] = = 3.0f & & m4 . m [ 2 ] [ 2 ] = = 4.0f , " m4_make_scale incorrect " ) ;
// Test orthographic projection matrix
Matrix4 ortho = m4_make_orthographic_projection ( - 1.0f , 1.0f , - 1.0f , 1.0f , 1.0f , - 1.0f ) ;
assert ( ortho . m [ 0 ] [ 0 ] = = 1.0f & & ortho . m [ 1 ] [ 1 ] = = 1.0f & & ortho . m [ 2 ] [ 2 ] = = 1.0f , " m4_make_orthographic_projection incorrect " ) ;
// Test matrix multiplication
Matrix4 m5 = m4_scalar ( 1.0f ) ;
m5 . m [ 0 ] [ 3 ] = 1.0f ; m5 . m [ 1 ] [ 3 ] = 2.0f ; m5 . m [ 2 ] [ 3 ] = 3.0f ;
Matrix4 result_matrix = m4_multiply ( m2 , m5 ) ;
assert ( result_matrix . m [ 0 ] [ 3 ] = = 2.0f & & result_matrix . m [ 1 ] [ 3 ] = = 4.0f & & result_matrix . m [ 2 ] [ 3 ] = = 6.0f , " m4_multiply incorrect " ) ;
// Test matrix inverse
Matrix4 identity = m4_scalar ( 1.0f ) ;
Matrix4 inverse_matrix = m4_inverse ( identity ) ;
for ( int i = 0 ; i < 4 ; + + i ) {
for ( int j = 0 ; j < 4 ; + + j ) {
assert ( inverse_matrix . m [ i ] [ j ] = = identity . m [ i ] [ j ] , " m4_inverse incorrect for identity matrix " ) ;
}
}
// Test Vector2 creation
Vector2 v2_test1 = v2 ( 1.0f , 2.0f ) ;
assert ( v2_test1 . x = = 1.0f & & v2_test1 . y = = 2.0f , " Vector2 creation failed " ) ;
Vector2 v2_test2 = v2 ( 3.0f , 4.0f ) ;
assert ( v2_test2 . x = = 3.0f & & v2_test2 . y = = 4.0f , " Vector2 creation failed " ) ;
// Test Vector2 addition
Vector2 v2_add_result = v2_add ( v2_test1 , v2_test2 ) ;
assert ( v2_add_result . x = = 4.0f & & v2_add_result . y = = 6.0f , " Vector2 addition failed " ) ;
// Test Vector2 subtraction
Vector2 v2_sub_result = v2_sub ( v2_test2 , v2_test1 ) ;
assert ( v2_sub_result . x = = 2.0f & & v2_sub_result . y = = 2.0f , " Vector2 subtraction failed " ) ;
// Test Vector2 multiplication
Vector2 v2_mul_result = v2_mul ( v2_test1 , v2_test2 ) ;
assert ( v2_mul_result . x = = 3.0f & & v2_mul_result . y = = 8.0f , " Vector2 multiplication failed " ) ;
// Test Vector2 scalar multiplication
Vector2 v2_mulf_result = v2_mulf ( v2_test1 , 2.0f ) ;
assert ( v2_mulf_result . x = = 2.0f & & v2_mulf_result . y = = 4.0f , " Vector2 scalar multiplication failed " ) ;
// Test Vector2 division
Vector2 v2_div_result = v2_div ( v2_test2 , v2_test1 ) ;
assert ( v2_div_result . x = = 3.0f & & v2_div_result . y = = 2.0f , " Vector2 division failed " ) ;
// Test Vector2 scalar division
Vector2 v2_divf_result = v2_divf ( v2_test2 , 2.0f ) ;
assert ( v2_divf_result . x = = 1.5f & & v2_divf_result . y = = 2.0f , " Vector2 scalar division failed " ) ;
// Test Vector2 normalization
Vector2 v2_norm_result = v2_normalize ( v2 ( 3.0f , 4.0f ) ) ;
assert ( fabs ( v2_norm_result . x - 0.6f ) < 1e-6 & & fabs ( v2_norm_result . y - 0.8f ) < 1e-6 , " Vector2 normalization failed " ) ;
// Test Vector2 rotation
Vector2 pivot = v2 ( 0.0f , 0.0f ) ;
Vector2 point = v2 ( 1.0f , 0.0f ) ;
Vector2 v2_rot_result = v2_rotate_point_around_pivot ( point , pivot , PI32 / 2.0f ) ;
assert ( fabs ( v2_rot_result . x ) < 1e-6 & & fabs ( v2_rot_result . y - 1.0f ) < 1e-6 , " Vector2 rotation around pivot failed " ) ;
// Test Vector3 creation
Vector3 v3_test1 = v3 ( 1.0f , 2.0f , 3.0f ) ;
assert ( v3_test1 . x = = 1.0f & & v3_test1 . y = = 2.0f & & v3_test1 . z = = 3.0f , " Vector3 creation failed " ) ;
Vector3 v3_test2 = v3 ( 4.0f , 5.0f , 6.0f ) ;
assert ( v3_test2 . x = = 4.0f & & v3_test2 . y = = 5.0f & & v3_test2 . z = = 6.0f , " Vector3 creation failed " ) ;
// Test Vector3 addition
Vector3 v3_add_result = v3_add ( v3_test1 , v3_test2 ) ;
assert ( v3_add_result . x = = 5.0f & & v3_add_result . y = = 7.0f & & v3_add_result . z = = 9.0f , " Vector3 addition failed " ) ;
// Test Vector3 subtraction
Vector3 v3_sub_result = v3_sub ( v3_test2 , v3_test1 ) ;
assert ( v3_sub_result . x = = 3.0f & & v3_sub_result . y = = 3.0f & & v3_sub_result . z = = 3.0f , " Vector3 subtraction failed " ) ;
// Test Vector3 multiplication
Vector3 v3_mul_result = v3_mul ( v3_test1 , v3_test2 ) ;
assert ( v3_mul_result . x = = 4.0f & & v3_mul_result . y = = 10.0f & & v3_mul_result . z = = 18.0f , " Vector3 multiplication failed " ) ;
// Test Vector3 scalar multiplication
Vector3 v3_mulf_result = v3_mulf ( v3_test1 , 2.0f ) ;
assert ( v3_mulf_result . x = = 2.0f & & v3_mulf_result . y = = 4.0f & & v3_mulf_result . z = = 6.0f , " Vector3 scalar multiplication failed " ) ;
// Test Vector3 division
Vector3 v3_div_result = v3_div ( v3_test2 , v3_test1 ) ;
assert ( v3_div_result . x = = 4.0f & & v3_div_result . y = = 2.5f & & v3_div_result . z = = 2.0f , " Vector3 division failed " ) ;
// Test Vector3 scalar division
Vector3 v3_divf_result = v3_divf ( v3_test2 , 2.0f ) ;
assert ( v3_divf_result . x = = 2.0f & & v3_divf_result . y = = 2.5f & & v3_divf_result . z = = 3.0f , " Vector3 scalar division failed " ) ;
// Test Vector4 creation
Vector4 v4_test1 = v4 ( 1.0f , 2.0f , 3.0f , 4.0f ) ;
assert ( v4_test1 . x = = 1.0f & & v4_test1 . y = = 2.0f & & v4_test1 . z = = 3.0f & & v4_test1 . w = = 4.0f , " Vector4 creation failed " ) ;
Vector4 v4_test2 = v4 ( 5.0f , 6.0f , 7.0f , 8.0f ) ;
assert ( v4_test2 . x = = 5.0f & & v4_test2 . y = = 6.0f & & v4_test2 . z = = 7.0f & & v4_test2 . w = = 8.0f , " Vector4 creation failed " ) ;
// Test Vector4 addition
Vector4 v4_add_result = v4_add ( v4_test1 , v4_test2 ) ;
assert ( v4_add_result . x = = 6.0f & & v4_add_result . y = = 8.0f & & v4_add_result . z = = 10.0f & & v4_add_result . w = = 12.0f , " Vector4 addition failed " ) ;
// Test Vector4 subtraction
Vector4 v4_sub_result = v4_sub ( v4_test2 , v4_test1 ) ;
assert ( v4_sub_result . x = = 4.0f & & v4_sub_result . y = = 4.0f & & v4_sub_result . z = = 4.0f & & v4_sub_result . w = = 4.0f , " Vector4 subtraction failed " ) ;
// Test Vector4 multiplication
Vector4 v4_mul_result = v4_mul ( v4_test1 , v4_test2 ) ;
assert ( v4_mul_result . x = = 5.0f & & v4_mul_result . y = = 12.0f & & v4_mul_result . z = = 21.0f & & v4_mul_result . w = = 32.0f , " Vector4 multiplication failed " ) ;
// Test Vector4 scalar multiplication
Vector4 v4_mulf_result = v4_mulf ( v4_test1 , 2.0f ) ;
assert ( v4_mulf_result . x = = 2.0f & & v4_mulf_result . y = = 4.0f & & v4_mulf_result . z = = 6.0f & & v4_mulf_result . w = = 8.0f , " Vector4 scalar multiplication failed " ) ;
// Test Vector4 division
Vector4 v4_div_result = v4_div ( v4_test2 , v4_test1 ) ;
assert ( v4_div_result . x = = 5.0f & & v4_div_result . y = = 3.0f & & v4_div_result . w = = 2.0f , " Vector4 division failed " ) ;
// Test Vector4 scalar division
Vector4 v4_divf_result = v4_divf ( v4_test2 , 2.0f ) ;
assert ( v4_divf_result . x = = 2.5f & & v4_divf_result . y = = 3.0f & & v4_divf_result . z = = 3.5f & & v4_divf_result . w = = 4.0f , " Vector4 scalar division failed " ) ;
// Test mixed vector and scalar operations
Vector2 mixed_v2 = v2 ( 2.0f , 4.0f ) ;
Vector2 mixed_v2_result = v2_mulf ( mixed_v2 , 0.5f ) ;
assert ( mixed_v2_result . x = = 1.0f & & mixed_v2_result . y = = 2.0f , " Mixed Vector2 scalar multiplication failed " ) ;
Vector3 mixed_v3 = v3 ( 3.0f , 6.0f , 9.0f ) ;
Vector3 mixed_v3_result = v3_divf ( mixed_v3 , 3.0f ) ;
assert ( mixed_v3_result . x = = 1.0f & & mixed_v3_result . y = = 2.0f & & mixed_v3_result . z = = 3.0f , " Mixed Vector3 scalar division failed " ) ;
Vector4 mixed_v4 = v4 ( 4.0f , 8.0f , 12.0f , 16.0f ) ;
Vector4 mixed_v4_result = v4_mulf ( mixed_v4 , 0.25f ) ;
assert ( mixed_v4_result . x = = 1.0f & & mixed_v4_result . y = = 2.0f & & mixed_v4_result . z = = 3.0f & & mixed_v4_result . w = = 4.0f , " Mixed Vector4 scalar multiplication failed " ) ;
2024-07-04 12:18:16 +02:00
float v2_dot = v2_dot_product ( v2 ( 2 , 7 ) , v2 ( 3 , 2 ) ) ;
float v3_dot = v3_dot_product ( v3 ( 2 , 7 , 2 ) , v3 ( 3 , 2 , 9 ) ) ;
float v4_dot = v4_dot_product ( v4 ( 2 , 7 , 6 , 1 ) , v4 ( 3 , 2 , 1 , 4 ) ) ;
assert ( floats_roughly_match ( v2_dot , 20 ) , " Failed: v2_dot_product " ) ;
assert ( floats_roughly_match ( v3_dot , 38 ) , " Failed: v3_dot_product " ) ;
assert ( floats_roughly_match ( v4_dot , 30 ) , " Failed: v4_dot_product " ) ;
2024-07-03 00:41:52 +02:00
}
2024-06-28 03:28:23 +02:00
void oogabooga_run_tests ( ) {
2024-07-03 17:55:25 +02:00
2024-07-03 00:01:11 +02:00
2024-07-02 15:27:33 +02:00
print ( " Testing allocator... " ) ;
2024-06-28 03:28:23 +02:00
test_allocator ( true ) ;
2024-07-02 15:27:33 +02:00
print ( " OK! \n " ) ;
2024-06-28 03:28:23 +02:00
2024-07-02 15:27:33 +02:00
print ( " Testing threads... " ) ;
2024-06-28 03:28:23 +02:00
test_threads ( ) ;
2024-07-02 15:27:33 +02:00
print ( " OK! \n " ) ;
2024-06-28 12:07:02 +02:00
2024-07-02 15:27:33 +02:00
print ( " Testing strings... " ) ;
2024-06-28 12:07:02 +02:00
test_strings ( ) ;
2024-07-02 15:27:33 +02:00
print ( " OK! \n " ) ;
2024-06-28 03:28:23 +02:00
2024-07-03 00:01:11 +02:00
2024-07-04 12:18:16 +02:00
//print("Thread bombing allocator... ");
//Thread* threads[100];
//for (int i = 0; i < 100; i++) {
// threads[i] = os_make_thread(test_allocator_threaded, get_heap_allocator());
// os_start_thread(threads[i]);
//}
//for (int i = 0; i < 100; i++) {
// os_join_thread(threads[i]);
//}
//print("OK!\n");
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
2024-07-02 15:27:33 +02:00
print ( " Testing file IO... " ) ;
- File IO
- os_file_open(string path, Os_Io_Open_Flags flags)
- os_file_close(File f)
- os_file_delete(string path)
- os_file_write_string(File f, string s)
- os_file_write_bytes(File f, void *buffer, u64 size_in_bytes)
- os_file_read(File f, void* buffer, u64 bytes_to_read, u64 *actual_read_bytes)
- os_write_entire_file_handle(File f, string data)
- os_write_entire_file(string path, string data)
- os_read_entire_file_handle(File f, string *result)
- os_read_entire_file(string path, string *result)
- fprint(File, string/char*, ...)
- Buncha tests
- os_high_precision_sleep
- talloc_string
- Program memory is touched on VirtualAlloc so it actually allocates physical memory (and we can tell when an address is untouched)
2024-06-29 20:55:43 +02:00
test_file_io ( ) ;
2024-07-02 15:27:33 +02:00
print ( " OK! \n " ) ;
2024-07-03 00:01:11 +02:00
2024-07-04 12:18:16 +02:00
print ( " Testing linmath... " ) ;
test_linmath ( ) ;
2024-07-03 00:41:52 +02:00
print ( " OK! \n " ) ;
2024-07-03 17:55:25 +02:00
print ( " Testing simd... " ) ;
test_simd ( ) ;
print ( " OK! \n " ) ;
2024-06-28 03:28:23 +02:00
}