organizing windows file handling, removed profile junk from past
parent
866fcf988c
commit
179cbd7404
|
@ -12,7 +12,7 @@
|
|||
#if !defined(FRED_OS_COMP_CRACKING_H)
|
||||
#define FRED_OS_COMP_CRACKING_H
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_MSC_VER) /* COMPILER */
|
||||
|
||||
# define IS_CL
|
||||
|
||||
|
@ -21,20 +21,30 @@
|
|||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
# if defined(_WIN32)
|
||||
# if defined(_WIN32) /* OS */
|
||||
# define IS_WINDOWS
|
||||
# pragma comment(lib, "Kernel32.lib")
|
||||
# else
|
||||
# error This compiler/platform combo is not supported yet
|
||||
# endif
|
||||
|
||||
# if defined(_M_AMD64) /* Arch */
|
||||
# define CALL_CONVENTION
|
||||
# define BUILD_X64
|
||||
# elif defined(_M_IX86)
|
||||
# define CALL_CONVENTION __stdcall
|
||||
# define BUILD_X86
|
||||
# else
|
||||
# error architecture not supported yet
|
||||
# endif
|
||||
|
||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||
|
||||
# define IS_GCC
|
||||
# define IS_GCC /* COMPILER */
|
||||
|
||||
# if defined(__gnu_linux__)
|
||||
# if defined(__gnu_linux__) /* OS */
|
||||
# define IS_LINUX
|
||||
# elif defined(__APPLE__) && defined(__MACH__)
|
||||
# elif defined(__APPLE__) && defined(__MACH__) /* OS */
|
||||
# define IS_MAC
|
||||
#else
|
||||
# error This compiler/platform combo is not supported yet
|
||||
|
@ -44,7 +54,6 @@
|
|||
#error This compiler is not supported yet
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
|
217
4ed_profile.cpp
217
4ed_profile.cpp
|
@ -1,217 +0,0 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 29.03.2017
|
||||
*
|
||||
* Really basic profiling primitives. (not meant to stay for long)
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#define FRED_INTERNAL 1
|
||||
|
||||
#include "4tech_defines.h"
|
||||
#include "4ed_profile.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
global f32 frame_target = 58000000.f;
|
||||
|
||||
internal void
|
||||
usage(){
|
||||
fprintf(stderr, "No! Like this, you moron:\n"
|
||||
"\t<PROFILE-EXE> <PROFILE-DATA> [min-time-filter]\n");
|
||||
}
|
||||
|
||||
internal u32
|
||||
parse_frame_count(u8 *ptr, u8 *end){
|
||||
u32 count = 0;
|
||||
|
||||
for (;ptr < end;){
|
||||
u8 *frame_base = *(u8**)ptr;
|
||||
ptr += 8;
|
||||
|
||||
u8 *frame_end = *(u8**)ptr;
|
||||
ptr += 8;
|
||||
|
||||
umem skip_size = frame_end - frame_base;
|
||||
ptr += skip_size;
|
||||
++count;
|
||||
}
|
||||
|
||||
if (ptr != end){
|
||||
count = 0;
|
||||
}
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
struct Parse_Frame_Result{
|
||||
u8 *next_read_ptr;
|
||||
u8 *output_chunk;
|
||||
b32 still_looping;
|
||||
b32 bad_parse;
|
||||
f32 frame_time;
|
||||
};
|
||||
|
||||
internal Parse_Frame_Result
|
||||
parse_frame(u8 *ptr, u8 *end_ptr){
|
||||
Parse_Frame_Result result = {0};
|
||||
|
||||
u8 *frame_base = *(u8**)ptr;
|
||||
ptr += 8;
|
||||
|
||||
u8 *frame_end = *(u8**)ptr;
|
||||
ptr += 8;
|
||||
|
||||
umem frame_size = frame_end - frame_base;
|
||||
u8 *frame_start_ptr = ptr;
|
||||
u8 *frame_end_ptr = ptr + frame_size;
|
||||
|
||||
u8 *out_chunk = (u8*)malloc(frame_size*2);
|
||||
u8 *out_ptr = out_chunk;
|
||||
|
||||
Profile_Group *group = (Profile_Group*)frame_start_ptr;
|
||||
Profile_Group *group_end = (Profile_Group*)frame_end_ptr;
|
||||
|
||||
Profile_Group *stack[64];
|
||||
u32 top = 0;
|
||||
|
||||
stack[top++] = group;
|
||||
|
||||
result.frame_time = group->cycle_count / frame_target;
|
||||
|
||||
for (;group < group_end;){
|
||||
for (u32 i = 1; i < top; ++i){
|
||||
*out_ptr++ = ' ';
|
||||
}
|
||||
|
||||
char *name = group->name;
|
||||
for (u32 i = 0; name[i]; ++i){
|
||||
*out_ptr++ = name[i];
|
||||
}
|
||||
|
||||
*out_ptr++ = ':';
|
||||
*out_ptr++ = ' ';
|
||||
|
||||
char str[64];
|
||||
sprintf(str, "%f", group->cycle_count / frame_target);
|
||||
for (u32 i = 0; str[i]; ++i){
|
||||
*out_ptr++ = str[i];
|
||||
}
|
||||
*out_ptr++ = '\n';
|
||||
|
||||
++group;
|
||||
|
||||
for(;top > 0;){
|
||||
Profile_Group *group_top = stack[top-1];
|
||||
umem end_offset = (u8*)group_top->end - frame_base;
|
||||
u8 *this_group_end_ptr = frame_start_ptr + end_offset;
|
||||
Profile_Group *this_group_end = (Profile_Group*)this_group_end_ptr;
|
||||
|
||||
if (group == this_group_end){
|
||||
--top;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stack[top++] = group;
|
||||
}
|
||||
|
||||
if (top != 1){
|
||||
result.bad_parse = true;
|
||||
}
|
||||
else{
|
||||
*out_ptr++ = 0;
|
||||
result.next_read_ptr = frame_end_ptr;
|
||||
result.output_chunk = out_chunk;
|
||||
if (frame_end_ptr != end_ptr){
|
||||
result.still_looping = true;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
print_profile(char *filename, f32 min_filter){
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if (!file){
|
||||
fprintf(stderr, "There ain't no file sittin' around called %s.\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
u32 size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
u8 *buffer = (u8*)malloc(size);
|
||||
|
||||
fread(buffer, 1, size, file);
|
||||
fclose(file);
|
||||
|
||||
u8 *read_ptr = buffer;
|
||||
u8 *end_ptr = buffer + size;
|
||||
|
||||
// Frame Count Parse
|
||||
u32 frame_count = parse_frame_count(read_ptr, end_ptr);
|
||||
|
||||
if (frame_count == 0){
|
||||
fprintf(stderr, "There's some fricken problem. I didn't get a good frame count!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Full Parse
|
||||
u8 **output_chunks = (u8**)malloc(frame_count*sizeof(u8*));
|
||||
u32 chunk_i = 0;
|
||||
|
||||
Parse_Frame_Result result = {0};
|
||||
do{
|
||||
if (chunk_i >= frame_count){
|
||||
fprintf(stderr, "The parse ain't lined up! You're fired!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
result = parse_frame(read_ptr, end_ptr);
|
||||
|
||||
if (result.bad_parse){
|
||||
fprintf(stderr, "You've pickled the data nimwit!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
read_ptr = result.next_read_ptr;
|
||||
if (result.frame_time >= min_filter){
|
||||
output_chunks[chunk_i++] = result.output_chunk;
|
||||
}
|
||||
}while(result.still_looping);
|
||||
|
||||
// Print
|
||||
fprintf(stdout, "Frames: %u (%u)\n", chunk_i, frame_count);
|
||||
for (u32 i = 0; i < chunk_i; ++i){
|
||||
fprintf(stdout, "%s", output_chunks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
if (argc < 2){
|
||||
usage();
|
||||
}
|
||||
else{
|
||||
f32 min_filter = 0.f;
|
||||
if (argc == 3){
|
||||
min_filter = (f32)atof(argv[2]);
|
||||
}
|
||||
|
||||
print_profile(argv[1], min_filter);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
||||
|
162
4ed_profile.h
162
4ed_profile.h
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 29.03.2017
|
||||
*
|
||||
* Really basic profiling primitives. (not meant to stay for long)
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FRED_PROFILE_H)
|
||||
#define FRED_PROFILE_H
|
||||
|
||||
#if FRED_INTERNAL && IS_MSVC
|
||||
|
||||
#include <intrin.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct Profile_Group{
|
||||
char name[104];
|
||||
u64 cycle_start;
|
||||
u64 cycle_count;
|
||||
void *end;
|
||||
};
|
||||
|
||||
struct Profile{
|
||||
u8 *buffer;
|
||||
u32 pos, max;
|
||||
|
||||
Profile_Group *stack[64];
|
||||
u32 stack_top;
|
||||
};
|
||||
global Profile global_profile = {0};
|
||||
|
||||
internal Profile_Group*
|
||||
push_group(char *name){
|
||||
Profile_Group *result = 0;
|
||||
if (global_profile.pos + sizeof(Profile_Group) <= global_profile.max){
|
||||
result = (Profile_Group*)(global_profile.buffer + global_profile.pos);
|
||||
global_profile.pos += sizeof(Profile_Group);
|
||||
u32 i = 0;
|
||||
for (; name[i] && i < sizeof(result->name)-1; ++i){
|
||||
result->name[i] = name[i];
|
||||
}
|
||||
result->name[i] = 0;
|
||||
result->cycle_start = __rdtsc();
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_init(void *mem, u32 max){
|
||||
global_profile.buffer = (u8*)mem;
|
||||
global_profile.max = max;
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_begin_group(char *name){
|
||||
u32 stack_pos = global_profile.stack_top;
|
||||
if (stack_pos < ArrayCount(global_profile.stack)){
|
||||
global_profile.stack[stack_pos] = push_group(name);
|
||||
Assert(global_profile.stack[stack_pos] != 0);
|
||||
++global_profile.stack_top;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_end_group(){
|
||||
Assert(global_profile.stack_top > 0);
|
||||
u32 stack_pos = --global_profile.stack_top;
|
||||
if (stack_pos < ArrayCount(global_profile.stack)){
|
||||
Profile_Group *group = global_profile.stack[stack_pos];
|
||||
Assert(group != 0);
|
||||
group->cycle_count = __rdtsc() - group->cycle_start;
|
||||
group->end = global_profile.buffer + global_profile.pos;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_begin_frame(){
|
||||
global_profile.pos = 0;
|
||||
global_profile.stack_top = 0;
|
||||
profile_begin_group("*frame*");
|
||||
}
|
||||
|
||||
internal void
|
||||
profile_end_frame(char *filename){
|
||||
profile_end_group();
|
||||
Assert(global_profile.stack_top == 0);
|
||||
|
||||
FILE *file = fopen(filename, "ab");
|
||||
Assert(file != 0);
|
||||
fwrite(&global_profile.buffer, 8, 1, file);
|
||||
|
||||
Profile_Group *first_group = (Profile_Group*)global_profile.buffer;
|
||||
fwrite(&first_group->end, 8, 1, file);
|
||||
|
||||
fwrite(global_profile.buffer, 1, global_profile.pos, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
internal Profile_Group*
|
||||
profile_begin_resumable(char *name){
|
||||
Profile_Group *result = push_group(name);
|
||||
Assert(result != 0);
|
||||
result->cycle_count = 0;
|
||||
result->end = result + 1;
|
||||
return(result);
|
||||
}
|
||||
|
||||
struct profile_scope{
|
||||
profile_scope(char *name){
|
||||
profile_begin_group(name);
|
||||
}
|
||||
|
||||
~profile_scope(){
|
||||
profile_end_group();
|
||||
}
|
||||
};
|
||||
|
||||
#define PRFL_INIT(m,s) profile_init(m,s)
|
||||
|
||||
#define PRFL_BEGIN_FRAME() profile_begin_frame()
|
||||
#define PRFL_END_FRAME(n) profile_end_frame(n)
|
||||
|
||||
#define PRFL_BEGIN_GROUP(n) profile_begin_group(#n)
|
||||
#define PRFL_END_GROUP() profile_end_group()
|
||||
#define PRFL_SCOPE_GROUP(n) profile_scope SCOPE_##n(#n)
|
||||
|
||||
#define PRFL_FUNC_GROUP() profile_scope SCOPE_FUNC(__FUNCTION__)
|
||||
|
||||
#define PRFL_BEGIN_RESUMABLE(n) Profile_Group *PRFLGRP_##n = profile_begin_resumable(#n)
|
||||
#define PRFL_START_RESUMABLE(n) PRFLGRP_##n->cycle_start = __rdtsc()
|
||||
#define PRFL_STOP_RESUMABLE(n) PRFLGRP_##n->cycle_count += __rdtsc() - PRFLGRP_##n->cycle_start
|
||||
#define PRFL_END_RESUMABLE(n)
|
||||
|
||||
#else
|
||||
|
||||
#define PRFL_INIT(m,s)
|
||||
|
||||
#define PRFL_BEGIN_FRAME()
|
||||
#define PRFL_END_FRAME(n)
|
||||
|
||||
#define PRFL_BEGIN_GROUP(n)
|
||||
#define PRFL_END_GROUP()
|
||||
#define PRFL_SCOPE_GROUP(n)
|
||||
|
||||
#define PRFL_FUNC_GROUP()
|
||||
|
||||
#define PRFL_BEGIN_RESUMABLE(n)
|
||||
#define PRFL_START_RESUMABLE(n)
|
||||
#define PRFL_STOP_RESUMABLE(n)
|
||||
#define PRFL_END_RESUMABLE(n)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ link_system_code(System_Functions *system){
|
|||
SYSLINK(send_exit_signal);
|
||||
|
||||
SYSLINK(log);
|
||||
#if FRED_INTERNAL
|
||||
#if defined(FRED_INTERNAL)
|
||||
SYSLINK(internal_get_thread_states);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 18.07.2017
|
||||
*
|
||||
* Cross platform logic for work queues.
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
internal u32
|
||||
directory_cd(char *dir, i32 *len, i32 cap, char *rel_path, i32 rel_len, char slash){
|
||||
String directory = make_string_cap(dir, *len, cap);
|
||||
b32 result = false;
|
||||
|
||||
if (rel_path[0] != 0){
|
||||
if (rel_path[0] == '.' && rel_path[1] == 0){
|
||||
result = true;
|
||||
}
|
||||
else if (rel_path[0] == '.' && rel_path[1] == '.' && rel_path[2] == 0){
|
||||
result = remove_last_folder(&directory);
|
||||
terminate_with_null(&directory);
|
||||
}
|
||||
else{
|
||||
if (directory.size + rel_len + 1 > directory.memory_size){
|
||||
i32 old_size = directory.size;
|
||||
append_partial_sc(&directory, rel_path);
|
||||
append_s_char(&directory, slash);
|
||||
terminate_with_null(&directory);
|
||||
|
||||
if (system_directory_exists(directory.str)){
|
||||
result = true;
|
||||
}
|
||||
else{
|
||||
directory.size = old_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*len = directory.size;
|
||||
LOGF("%.*s: %d\n", directory.size, directory.str, result);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 17.07.2017
|
||||
* 18.07.2017
|
||||
*
|
||||
* Cross platform threading constants
|
||||
*
|
||||
|
|
|
@ -596,7 +596,7 @@ ctxErrorHandler( Display *dpy, XErrorEvent *ev )
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if FRED_INTERNAL
|
||||
#if defined(FRED_INTERNAL)
|
||||
|
||||
static void LinuxGLDebugCallback(
|
||||
GLenum source,
|
||||
|
@ -646,7 +646,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
|
|||
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||
#if FRED_INTERNAL
|
||||
#if defined(FRED_INTERNAL)
|
||||
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_DEBUG_BIT_ARB,
|
||||
#endif
|
||||
None
|
||||
|
@ -775,7 +775,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
|
|||
LOG("VSync enabled? nope, no suitable extension\n");
|
||||
}
|
||||
|
||||
#if FRED_INTERNAL
|
||||
#if defined(FRED_INTERNAL)
|
||||
typedef PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackProc;
|
||||
|
||||
GLXLOAD(glDebugMessageCallback);
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 17.07.2017
|
||||
* 18.07.2017
|
||||
*
|
||||
* Linux threading wrapper
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO(allen): Can this just be placed in UNIX? If so do that.
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(LINUX_THREADING_WRAPPER)
|
||||
|
|
|
@ -304,7 +304,7 @@ Sys_Get_Canonical_Sig(system_get_canonical){
|
|||
write_p = path;
|
||||
}
|
||||
|
||||
#if FRED_INTERNAL
|
||||
#if defined(FRED_INTERNAL)
|
||||
if(len != (write_p - path) || memcmp(filename, path, len) != 0){
|
||||
LOGF("[%.*s] -> [%.*s]\n", len, filename, (int)(write_p - path), path);
|
||||
}
|
||||
|
@ -320,14 +320,15 @@ Sys_Load_Handle_Sig(system_load_handle){
|
|||
b32 result = false;
|
||||
|
||||
i32 fd = open(filename, O_RDONLY);
|
||||
if(fd == -1){
|
||||
if (fd == -1){
|
||||
LOG("error: open\n");
|
||||
} else {
|
||||
}
|
||||
else{
|
||||
*(int*)handle_out = fd;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
|
@ -431,6 +432,13 @@ Sys_File_Exists_Sig(system_file_exists){
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
system_directory_exists(char *path){
|
||||
struct stat st;
|
||||
b32 result = (stat(directory.str, &st) == 0 && S_ISDIR(st.st_mode));
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Directory_CD_Sig(system_directory_cd){
|
||||
String directory = make_string_cap(dir, *len, cap);
|
||||
|
@ -451,8 +459,7 @@ Sys_Directory_CD_Sig(system_directory_cd){
|
|||
append_s_char(&directory, '/');
|
||||
terminate_with_null(&directory);
|
||||
|
||||
struct stat st;
|
||||
if (stat(directory.str, &st) == 0 && S_ISDIR(st.st_mode)){
|
||||
if (system_directory_exists(directory.str)){
|
||||
result = true;
|
||||
}
|
||||
else{
|
||||
|
|
|
@ -11,19 +11,7 @@
|
|||
|
||||
#define IS_PLAT_LAYER
|
||||
|
||||
//
|
||||
// Architecture cracking
|
||||
//
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
# define CALL_CONVENTION
|
||||
# define BUILD_X64
|
||||
#elif defined(_M_IX86)
|
||||
# define CALL_CONVENTION __stdcall
|
||||
# define BUILD_X86
|
||||
#else
|
||||
# error architecture not supported yet
|
||||
#endif
|
||||
#include "4ed_os_comp_cracking.h"
|
||||
|
||||
|
||||
//
|
||||
|
@ -197,6 +185,8 @@ system_schedule_step(){
|
|||
PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
//
|
||||
// 4ed path
|
||||
//
|
||||
|
@ -240,6 +230,21 @@ Sys_Log_Sig(system_log){
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Shared system functions (system_shared.h)
|
||||
//
|
||||
|
||||
internal
|
||||
Sys_File_Can_Be_Made_Sig(system_file_can_be_made){
|
||||
HANDLE file = CreateFile_utf8(filename, FILE_APPEND_DATA, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
b32 result = false;
|
||||
if (file != 0 && file != INVALID_HANDLE_VALUE){
|
||||
CloseHandle(file);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
//
|
||||
// Memory
|
||||
//
|
||||
|
@ -276,122 +281,10 @@ Sys_Memory_Free_Sig(system_memory_free){
|
|||
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
//
|
||||
// Threads
|
||||
//
|
||||
|
||||
#include "4ed_work_queues.cpp"
|
||||
|
||||
//
|
||||
// Coroutines
|
||||
//
|
||||
|
||||
internal Win32_Coroutine*
|
||||
Win32AllocCoroutine(){
|
||||
Win32_Coroutine *result = win32vars.coroutine_free;
|
||||
Assert(result != 0);
|
||||
win32vars.coroutine_free = result->next;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
Win32FreeCoroutine(Win32_Coroutine *data){
|
||||
data->next = win32vars.coroutine_free;
|
||||
win32vars.coroutine_free = data;
|
||||
}
|
||||
|
||||
internal void CALL_CONVENTION
|
||||
Win32CoroutineMain(void *arg_){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)arg_;
|
||||
c->coroutine.func(&c->coroutine);
|
||||
c->done = 1;
|
||||
Win32FreeCoroutine(c);
|
||||
SwitchToFiber(c->coroutine.yield_handle);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Create_Coroutine_Sig(system_create_coroutine){
|
||||
Win32_Coroutine *c;
|
||||
Coroutine *coroutine;
|
||||
void *fiber;
|
||||
|
||||
c = Win32AllocCoroutine();
|
||||
c->done = 0;
|
||||
|
||||
coroutine = &c->coroutine;
|
||||
|
||||
fiber = CreateFiber(0, Win32CoroutineMain, coroutine);
|
||||
|
||||
coroutine->plat_handle = handle_type(fiber);
|
||||
coroutine->func = func;
|
||||
|
||||
return(coroutine);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)coroutine;
|
||||
void *fiber;
|
||||
|
||||
fiber = handle_type(coroutine->plat_handle);
|
||||
coroutine->yield_handle = GetCurrentFiber();
|
||||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
|
||||
SwitchToFiber(fiber);
|
||||
|
||||
if (c->done){
|
||||
DeleteFiber(fiber);
|
||||
Win32FreeCoroutine(c);
|
||||
coroutine = 0;
|
||||
}
|
||||
|
||||
return(coroutine);
|
||||
}
|
||||
|
||||
Sys_Resume_Coroutine_Sig(system_resume_coroutine){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)coroutine;
|
||||
void *fiber;
|
||||
|
||||
Assert(c->done == 0);
|
||||
|
||||
coroutine->yield_handle = GetCurrentFiber();
|
||||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
|
||||
fiber = handle_type(coroutine->plat_handle);
|
||||
|
||||
SwitchToFiber(fiber);
|
||||
|
||||
if (c->done){
|
||||
DeleteFiber(fiber);
|
||||
Win32FreeCoroutine(c);
|
||||
coroutine = 0;
|
||||
}
|
||||
|
||||
return(coroutine);
|
||||
}
|
||||
|
||||
Sys_Yield_Coroutine_Sig(system_yield_coroutine){
|
||||
SwitchToFiber(coroutine->yield_handle);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Files
|
||||
//
|
||||
|
||||
internal
|
||||
Sys_File_Can_Be_Made_Sig(system_file_can_be_made){
|
||||
HANDLE file = CreateFile_utf8(filename, FILE_APPEND_DATA, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
b32 result = false;
|
||||
if (file != 0 && file != INVALID_HANDLE_VALUE){
|
||||
CloseHandle(file);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Set_File_List_Sig(system_set_file_list){
|
||||
b32 clear_list = true;
|
||||
|
@ -521,34 +414,34 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
|||
}
|
||||
}
|
||||
|
||||
internal u32
|
||||
win32_canonical_ascii_name(char *src, u32 len, char *dst, u32 max){
|
||||
internal
|
||||
Sys_Get_Canonical_Sig(system_get_canonical){
|
||||
u32 result = 0;
|
||||
|
||||
char src_space[MAX_PATH + 32];
|
||||
if (len < sizeof(src_space) && len >= 2 && ((src[0] >= 'a' && src[0] <= 'z') || (src[0] >= 'A' && src[0] <= 'Z')) && src[1] == ':'){
|
||||
memcpy(src_space, src, len);
|
||||
if (len < sizeof(src_space) && len >= 2 && ((filename[0] >= 'a' && filename[0] <= 'z') || (filename[0] >= 'A' && filename[0] <= 'Z')) && filename[1] == ':'){
|
||||
memcpy(src_space, filename, len);
|
||||
src_space[len] = 0;
|
||||
|
||||
HANDLE file = CreateFile_utf8((u8*)src_space, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
if (file != INVALID_HANDLE_VALUE){
|
||||
DWORD final_length = GetFinalPathNameByHandle_utf8(file, (u8*)dst, max, 0);
|
||||
DWORD final_length = GetFinalPathNameByHandle_utf8(file, (u8*)buffer, max, 0);
|
||||
|
||||
if (final_length < max && final_length >= 4){
|
||||
if (dst[final_length-1] == 0){
|
||||
if (buffer[final_length-1] == 0){
|
||||
--final_length;
|
||||
}
|
||||
final_length -= 4;
|
||||
memmove(dst, dst+4, final_length);
|
||||
dst[final_length] = 0;
|
||||
memmove(buffer, buffer+4, final_length);
|
||||
buffer[final_length] = 0;
|
||||
result = final_length;
|
||||
}
|
||||
|
||||
CloseHandle(file);
|
||||
}
|
||||
else{
|
||||
String src_str = make_string(src, len);
|
||||
String src_str = make_string(filename, len);
|
||||
String path_str = path_of_directory(src_str);
|
||||
String front_str = front_of_directory(src_str);
|
||||
|
||||
|
@ -558,18 +451,18 @@ win32_canonical_ascii_name(char *src, u32 len, char *dst, u32 max){
|
|||
HANDLE dir = CreateFile_utf8((u8*)src_space, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0);
|
||||
|
||||
if (dir != INVALID_HANDLE_VALUE){
|
||||
DWORD final_length = GetFinalPathNameByHandle_utf8(dir, (u8*)dst, max, 0);
|
||||
DWORD final_length = GetFinalPathNameByHandle_utf8(dir, (u8*)buffer, max, 0);
|
||||
|
||||
if (final_length < max && final_length >= 4){
|
||||
if (dst[final_length-1] == 0){
|
||||
if (buffer[final_length-1] == 0){
|
||||
--final_length;
|
||||
}
|
||||
final_length -= 4;
|
||||
memmove(dst, dst+4, final_length);
|
||||
dst[final_length++] = '\\';
|
||||
memcpy(dst + final_length, front_str.str, front_str.size);
|
||||
memmove(buffer, buffer+4, final_length);
|
||||
buffer[final_length++] = '\\';
|
||||
memcpy(buffer + final_length, front_str.str, front_str.size);
|
||||
final_length += front_str.size;
|
||||
dst[final_length] = 0;
|
||||
buffer[final_length] = 0;
|
||||
result = final_length;
|
||||
}
|
||||
|
||||
|
@ -581,12 +474,6 @@ win32_canonical_ascii_name(char *src, u32 len, char *dst, u32 max){
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Get_Canonical_Sig(system_get_canonical){
|
||||
u32 result = win32_canonical_ascii_name(filename, len, buffer, max);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Load_Handle_Sig(system_load_handle){
|
||||
b32 result = false;
|
||||
|
@ -666,17 +553,9 @@ Sys_Save_File_Sig(system_save_file){
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Now_Time_Sig(system_now_time){
|
||||
u64 result = __rdtsc();
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
Win32DirectoryExists(char *path){
|
||||
DWORD attrib = GetFileAttributes_utf8((u8*)path);
|
||||
return(attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
//
|
||||
// File System
|
||||
//
|
||||
|
||||
internal
|
||||
Sys_File_Exists_Sig(system_file_exists){
|
||||
|
@ -701,45 +580,137 @@ Sys_File_Exists_Sig(system_file_exists){
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
system_directory_exists(char *path){
|
||||
DWORD attrib = GetFileAttributes_utf8((u8*)path);
|
||||
return(attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
#include "4ed_shared_file_handling.cpp"
|
||||
|
||||
internal
|
||||
Sys_Directory_CD_Sig(system_directory_cd){
|
||||
String directory = make_string_cap(dir, *len, cap);
|
||||
b32 result = 0;
|
||||
i32 old_size;
|
||||
|
||||
char rel_path_space[1024];
|
||||
String rel_path_string = make_fixed_width_string(rel_path_space);
|
||||
copy_ss(&rel_path_string, make_string(rel_path, rel_len));
|
||||
terminate_with_null(&rel_path_string);
|
||||
|
||||
if (rel_path[0] != 0){
|
||||
if (rel_path[0] == '.' && rel_path[1] == 0){
|
||||
result = 1;
|
||||
}
|
||||
else if (rel_path[0] == '.' && rel_path[1] == '.' && rel_path[2] == 0){
|
||||
result = remove_last_folder(&directory);
|
||||
terminate_with_null(&directory);
|
||||
}
|
||||
else{
|
||||
if (directory.size + rel_len + 1 > directory.memory_size){
|
||||
old_size = directory.size;
|
||||
append_partial_sc(&directory, rel_path);
|
||||
append_s_char(&directory, '\\');
|
||||
if (Win32DirectoryExists(directory.str)){
|
||||
result = 1;
|
||||
}
|
||||
else{
|
||||
directory.size = old_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*len = directory.size;
|
||||
|
||||
u32 result = directory_cd(dir, len, cap, rel_path, rel_len, '\\');
|
||||
return(result);
|
||||
}
|
||||
|
||||
//
|
||||
// Time
|
||||
//
|
||||
|
||||
internal
|
||||
Sys_Now_Time_Sig(system_now_time){
|
||||
u64 result = __rdtsc();
|
||||
return(result);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
//
|
||||
// Threads
|
||||
//
|
||||
|
||||
#include "4ed_work_queues.cpp"
|
||||
|
||||
//
|
||||
// Coroutines
|
||||
//
|
||||
|
||||
internal Win32_Coroutine*
|
||||
Win32AllocCoroutine(){
|
||||
Win32_Coroutine *result = win32vars.coroutine_free;
|
||||
Assert(result != 0);
|
||||
win32vars.coroutine_free = result->next;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
Win32FreeCoroutine(Win32_Coroutine *data){
|
||||
data->next = win32vars.coroutine_free;
|
||||
win32vars.coroutine_free = data;
|
||||
}
|
||||
|
||||
internal void CALL_CONVENTION
|
||||
Win32CoroutineMain(void *arg_){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)arg_;
|
||||
c->coroutine.func(&c->coroutine);
|
||||
c->done = 1;
|
||||
Win32FreeCoroutine(c);
|
||||
SwitchToFiber(c->coroutine.yield_handle);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Create_Coroutine_Sig(system_create_coroutine){
|
||||
Win32_Coroutine *c;
|
||||
Coroutine *coroutine;
|
||||
void *fiber;
|
||||
|
||||
c = Win32AllocCoroutine();
|
||||
c->done = 0;
|
||||
|
||||
coroutine = &c->coroutine;
|
||||
|
||||
fiber = CreateFiber(0, Win32CoroutineMain, coroutine);
|
||||
|
||||
coroutine->plat_handle = handle_type(fiber);
|
||||
coroutine->func = func;
|
||||
|
||||
return(coroutine);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)coroutine;
|
||||
void *fiber;
|
||||
|
||||
fiber = handle_type(coroutine->plat_handle);
|
||||
coroutine->yield_handle = GetCurrentFiber();
|
||||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
|
||||
SwitchToFiber(fiber);
|
||||
|
||||
if (c->done){
|
||||
DeleteFiber(fiber);
|
||||
Win32FreeCoroutine(c);
|
||||
coroutine = 0;
|
||||
}
|
||||
|
||||
return(coroutine);
|
||||
}
|
||||
|
||||
Sys_Resume_Coroutine_Sig(system_resume_coroutine){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)coroutine;
|
||||
void *fiber;
|
||||
|
||||
Assert(c->done == 0);
|
||||
|
||||
coroutine->yield_handle = GetCurrentFiber();
|
||||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
|
||||
fiber = handle_type(coroutine->plat_handle);
|
||||
|
||||
SwitchToFiber(fiber);
|
||||
|
||||
if (c->done){
|
||||
DeleteFiber(fiber);
|
||||
Win32FreeCoroutine(c);
|
||||
coroutine = 0;
|
||||
}
|
||||
|
||||
return(coroutine);
|
||||
}
|
||||
|
||||
Sys_Yield_Coroutine_Sig(system_yield_coroutine){
|
||||
SwitchToFiber(coroutine->yield_handle);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Files
|
||||
//
|
||||
|
||||
/*
|
||||
NOTE(casey): This follows Raymond Chen's prescription
|
||||
for fullscreen toggling, see:
|
||||
|
@ -1236,7 +1207,7 @@ Win32InitGL(){
|
|||
}
|
||||
|
||||
#if (defined(BUILD_X64) && 1) || (defined(BUILD_X86) && 0)
|
||||
#if FRED_INTERNAL
|
||||
#if defined(FRED_INTERNAL)
|
||||
// NOTE(casey): This slows down GL but puts error messages to
|
||||
// the debug console immediately whenever you do something wrong
|
||||
glDebugMessageCallback_type *glDebugMessageCallback =
|
||||
|
@ -1572,7 +1543,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
//
|
||||
|
||||
LPVOID base;
|
||||
#if FRED_INTERNAL
|
||||
#if defined(FRED_INTERNAL)
|
||||
#if defined(BUILD_X64)
|
||||
base = (LPVOID)TB(1);
|
||||
#elif defined(BUILD_X86)
|
||||
|
@ -1585,7 +1556,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
memory_vars.vars_memory_size = MB(2);
|
||||
memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
#if FRED_INTERNAL
|
||||
#if defined(FRED_INTERNAL)
|
||||
#if defined(BUILD_X64)
|
||||
base = (LPVOID)TB(2);
|
||||
#elif defined(BUILD_X86)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 17.07.2017
|
||||
* 18.07.2017
|
||||
*
|
||||
* Win32 threading wrapper
|
||||
*
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
@echo off
|
||||
|
||||
SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX
|
||||
SET OPTS=%OPTS% /GR- /EHa- /nologo /FC
|
||||
|
||||
pushd ..\build
|
||||
cl %OPTS% ..\code\4ed_profile.cpp /Zi /Feprofile
|
||||
popd
|
||||
|
||||
pushd ..\data\test
|
||||
..\..\build\profile profile.data 0.4
|
||||
popd
|
Loading…
Reference in New Issue