Exemplo n.º 1
0
TEST(BytesTest, Arithmetic)
{
  EXPECT_EQ(Terabytes(1), Gigabytes(512) + Gigabytes(512));
  EXPECT_EQ(Terabytes(1), Terabytes(2) - Terabytes(1));

  EXPECT_EQ(Terabytes(1), Gigabytes(1) * 1024);

  EXPECT_EQ(Gigabytes(1), Terabytes(1) / 1024);
}
Exemplo n.º 2
0
TEST(BytesTest, Comparison)
{
  EXPECT_GT(Terabytes(1), Gigabytes(1));
  EXPECT_GT(Gigabytes(1), Megabytes(1));
  EXPECT_GT(Megabytes(1), Kilobytes(1));
  EXPECT_GT(Kilobytes(1), Bytes(1));

  EXPECT_EQ(Bytes(1024), Kilobytes(1));
  EXPECT_LT(Bytes(1023), Kilobytes(1));
  EXPECT_GT(Bytes(1025), Kilobytes(1));
}
Exemplo n.º 3
0
TEST(BytesTest, Stringify)
{
  EXPECT_NE(Megabytes(1023), Gigabytes(1));

  EXPECT_EQ("0B", stringify(Bytes()));

  EXPECT_EQ("1KB", stringify(Kilobytes(1)));
  EXPECT_EQ("1MB", stringify(Megabytes(1)));
  EXPECT_EQ("1GB", stringify(Gigabytes(1)));
  EXPECT_EQ("1TB", stringify(Terabytes(1)));

  EXPECT_EQ("1023B", stringify(Bytes(1023)));
  EXPECT_EQ("1023KB", stringify(Kilobytes(1023)));
  EXPECT_EQ("1023MB", stringify(Megabytes(1023)));
  EXPECT_EQ("1023GB", stringify(Gigabytes(1023)));
}
Exemplo n.º 4
0
namespace slave {

const Duration EXECUTOR_REGISTRATION_TIMEOUT = Minutes(1);
const Duration EXECUTOR_SHUTDOWN_GRACE_PERIOD = Seconds(5);
const Duration EXECUTOR_REREGISTER_TIMEOUT = Seconds(2);
const Duration EXECUTOR_SIGNAL_ESCALATION_TIMEOUT = Seconds(3);
const Duration STATUS_UPDATE_RETRY_INTERVAL_MIN = Seconds(10);
const Duration STATUS_UPDATE_RETRY_INTERVAL_MAX = Minutes(10);
const Duration REGISTRATION_BACKOFF_FACTOR = Seconds(1);
const Duration REGISTER_RETRY_INTERVAL_MAX = Minutes(1);
const Duration GC_DELAY = Weeks(1);
const double GC_DISK_HEADROOM = 0.1;
const Duration DISK_WATCH_INTERVAL = Minutes(1);
const Duration RECOVERY_TIMEOUT = Minutes(15);
const Duration RESOURCE_MONITORING_INTERVAL = Seconds(1);
const uint32_t MAX_COMPLETED_FRAMEWORKS = 50;
const uint32_t MAX_COMPLETED_EXECUTORS_PER_FRAMEWORK = 150;
const uint32_t MAX_COMPLETED_TASKS_PER_EXECUTOR = 200;
const double DEFAULT_CPUS = 1;
const Bytes DEFAULT_MEM = Gigabytes(1);
const Bytes DEFAULT_DISK = Gigabytes(10);
const std::string DEFAULT_PORTS = "[31000-32000]";
#ifdef WITH_NETWORK_ISOLATOR
const uint16_t DEFAULT_EPHEMERAL_PORTS_PER_CONTAINER = 1024;
#endif
const Duration DOCKER_REMOVE_DELAY = Hours(6);
const Duration DOCKER_INSPECT_DELAY = Seconds(1);
// TODO(tnachen): Make this a flag.
const Duration DOCKER_VERSION_WAIT_TIMEOUT = Seconds(5);
const std::string DEFAULT_AUTHENTICATEE = "crammd5";

Duration DEFAULT_MASTER_PING_TIMEOUT()
{
  return master::DEFAULT_SLAVE_PING_TIMEOUT *
    master::DEFAULT_MAX_SLAVE_PING_TIMEOUTS;
}

} // namespace slave {
Exemplo n.º 5
0
TEST(BytesTest, Parse)
{
  EXPECT_SOME_EQ(Terabytes(1), Bytes::parse("1TB"));
  EXPECT_SOME_EQ(Gigabytes(1), Bytes::parse("1GB"));
  EXPECT_SOME_EQ(Megabytes(1), Bytes::parse("1MB"));
  EXPECT_SOME_EQ(Kilobytes(1), Bytes::parse("1KB"));
  EXPECT_SOME_EQ(Bytes(1), Bytes::parse("1B"));

  // Cannot have fractional bytes.
  EXPECT_ERROR(Bytes::parse("1.5B"));

  // Parsing fractions is unsupported.
  EXPECT_ERROR(Bytes::parse("1.5GB"));

  // Unknown unit.
  EXPECT_ERROR(Bytes::parse("1PB"));
}
int
main(int argc, char *argv[])
{
    memory_arena Arena = {};
    InitializeArena(&Arena, (size_t)Gigabytes(1));

    // freopen("err.log", "w", stderr);
    
    if(argc == 1)
    {
        int32 day = ArrayCount(DayList)-1;
        DayList[day](&Arena, true);
    }
    else if (argc == 2)
    {
        int32 day = (int32) strtol(argv[1], &argv[1], 0);
        if(day && day <ArrayCount(DayList))
        {
            DayList[day](&Arena, true);
        }
        else if (day == 0)
        {
            printf("Running All Days.\n");
            for (int32 i = 1; i < ArrayCount(DayList); ++i)
            {
                printf("---- Day %d ----\n", i);
                DayList[i](&Arena, false);
                ResetArena(&Arena);
                printf("\n");
            }
        }
        else
        {
            PrintHelp();
        }
    }
    else
    {
        PrintHelp();
    }

    FreeArena(&Arena);
}
Exemplo n.º 7
0
int main(int argc, char *argv[]) {
    sdl_state SDLState = {};

    platform_work_queue HighPriorityQueue = {};
    SDLMakeQueue(&HighPriorityQueue, 6);

    platform_work_queue LowPriorityQueue = {};
    SDLMakeQueue(&LowPriorityQueue, 2);


    GlobalPerfCountFrequency = SDL_GetPerformanceFrequency();

    SDLGetEXEFileName(&SDLState);

    char SourceGameCodeDLLFullpath[SDL_STATE_FILE_NAME_COUNT];
    SDLBuildEXEPathFileName(&SDLState, "handmade.dylib",
                            sizeof(SourceGameCodeDLLFullpath), SourceGameCodeDLLFullpath);

    char TempGameCodeDLLFullpath[SDL_STATE_FILE_NAME_COUNT];
    SDLBuildEXEPathFileName(&SDLState, "handmade_temp.dylib",
                            sizeof(TempGameCodeDLLFullpath), TempGameCodeDLLFullpath);

    char GameCodeLockFullpath[SDL_STATE_FILE_NAME_COUNT];
    SDLBuildEXEPathFileName(&SDLState, "lock.tmp",
                            sizeof(GameCodeLockFullpath), GameCodeLockFullpath);

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0) {
        printf("Failed to initialize SDL: %s\n", SDL_GetError());
        return -1;
    }

    SDL_Window *Window = SDL_CreateWindow("Handmade Hero",
                                          SDL_WINDOWPOS_CENTERED,
                                          SDL_WINDOWPOS_CENTERED,
                                          960, 540,
                                          SDL_WINDOW_OPENGL);
    if (!Window) {
        printf("Failed to create window: %s\n", SDL_GetError());
        return -1;
    }

    SDLResizeDIBSection(Window, &GlobalBackBuffer, 960, 540);

    // TODO: Set GameUpdateHz by monitor refresh HZ
    real32 GameUpdateHz = 60.0f;
    real32 TargetSecondsPerFrame = 1.0f / GameUpdateHz;

    sdl_sound_output SoundOutput = {};
    SoundOutput.SamplesPerSecond = 48000;
    SoundOutput.BytesPerSample = sizeof(int16) * 2;
    SoundOutput.BufferSize = SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample;

    SDL_AudioDeviceID Audio = SDLInitSound(SoundOutput.SamplesPerSecond);

    u32 MaxPossibleOverrun = 2 * 4 * sizeof(u16);
    int16 *Samples = (int16 *)mmap(0, (size_t)(SoundOutput.BufferSize + MaxPossibleOverrun),
                                   PROT_READ | PROT_WRITE,
                                   MAP_PRIVATE | MAP_ANON, -1, 0);

    GlobalRunning = true;

#if HANDMADE_INTERNAL
    void *BaseAddress = (void *)Terabytes(2);
#else
    void *BaseAddress = 0;
#endif

    game_memory GameMemory = {};
    GameMemory.PermanentStorageSize = Megabytes(64);
    GameMemory.TransientStorageSize = Gigabytes(256);
    GameMemory.HighPriorityQueue = &HighPriorityQueue;
    GameMemory.LowPriorityQueue = &LowPriorityQueue;

    GameMemory.PlatformAPI.AddEntry = SDLAddEntry;
    GameMemory.PlatformAPI.CompleteAllWork = SDLCompleteAllWork;

    GameMemory.PlatformAPI.GetAllFilesOfTypeBegin = SDLGetAllFilesOfTypeBegin;
    GameMemory.PlatformAPI.GetAllFilesOfTypeEnd = SDLGetAllFilesOfTypeEnd;
    GameMemory.PlatformAPI.OpenNextFile = SDLOpenNextFile;
    GameMemory.PlatformAPI.ReadDataFromFile = SDLReadDataFromFile;
    GameMemory.PlatformAPI.FileError = SDLFileError;

    GameMemory.PlatformAPI.AllocateMemory = SDLAllocateMemory;
    GameMemory.PlatformAPI.DeallocateMemory = SDLDeallocateMemory;

    GameMemory.PlatformAPI.DEBUGFreeFileMemory = DEBUGPlatformFreeFileMemory;
    GameMemory.PlatformAPI.DEBUGReadEntireFile = DEBUGPlatformReadEntireFile;
    GameMemory.PlatformAPI.DEBUGWriteEntireFile = DEBUGPlatformWriteEntireFile;

    SDLState.TotalSize = GameMemory.PermanentStorageSize + GameMemory.TransientStorageSize;

    SDLState.GameMemoryBlock = mmap(BaseAddress,
                                    (size_t) SDLState.TotalSize,
                                    PROT_READ | PROT_WRITE,
                                    MAP_PRIVATE | MAP_ANON, -1, 0);
    GameMemory.PermanentStorage = SDLState.GameMemoryBlock;
    GameMemory.TransientStorage = ((uint8 *) GameMemory.PermanentStorage + GameMemory.PermanentStorageSize);

    if (!(GameMemory.PermanentStorage && GameMemory.TransientStorage)) {
        printf("Failed to allocate game memory\n");
        return -1;
    }

    // TODO: Add game replay support here

    game_input Input[2] = {};
    game_input *NewInput = &Input[0];
    game_input *OldInput = &Input[1];

    uint64 LastCounter = SDL_GetPerformanceCounter();
    uint64 FlipWallClock = SDL_GetPerformanceCounter();

    sdl_game_code Game = SDLLoadGameCode(SourceGameCodeDLLFullpath,
                                         TempGameCodeDLLFullpath,
                                         GameCodeLockFullpath);

    uint64 LastCycleCount = _rdtsc();

    while (GlobalRunning) {
        NewInput->dtForFrame = TargetSecondsPerFrame;

        NewInput->ExecutableReloaded = false;
        time_t NewDLLWriteTime = SDLGetLastWriteTime(SourceGameCodeDLLFullpath);
        if (difftime(NewDLLWriteTime, Game.DLLLastWriteTime) > 0) {
            SDLCompleteAllWork(&HighPriorityQueue);
            SDLCompleteAllWork(&LowPriorityQueue);

            SDLUnloadGameCode(&Game);
            Game = SDLLoadGameCode(SourceGameCodeDLLFullpath,
                                   TempGameCodeDLLFullpath,
                                   GameCodeLockFullpath);
            NewInput->ExecutableReloaded = true;
        }

        game_controller_input *OldKeyboardController = GetController(OldInput, 0);
        game_controller_input *NewKeyboardController = GetController(NewInput, 0);
        *NewKeyboardController = {};
        NewKeyboardController->IsConnected = true;
        for (size_t ButtonIndex = 0; ButtonIndex < ArrayCount(NewKeyboardController->Buttons); ++ButtonIndex) {
            NewKeyboardController->Buttons[ButtonIndex].EndedDown = OldKeyboardController->Buttons[ButtonIndex].EndedDown;
        }

        SDLProcessPendingMessage(&SDLState, NewKeyboardController);

        if (!GlobalPause) {
            Uint32 MouseButtons = SDL_GetMouseState(&NewInput->MouseX, &NewInput->MouseY);
            NewInput->MouseZ = 0;
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[0],
                                      SDL_BUTTON(SDL_BUTTON_LEFT));
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[1],
                                      SDL_BUTTON(SDL_BUTTON_MIDDLE));
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[2],
                                      SDL_BUTTON(SDL_BUTTON_RIGHT));
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[3],
                                      SDL_BUTTON(SDL_BUTTON_X1));
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[4],
                                      SDL_BUTTON(SDL_BUTTON_X2));

            // TODO: Handle Mouse button here

            // TODO: Game controller support here

            game_offscreen_buffer Buffer = {};
            Buffer.Memory = GlobalBackBuffer.Memory;
            Buffer.Width = GlobalBackBuffer.Width;
            Buffer.Height = GlobalBackBuffer.Height;
            Buffer.Pitch = GlobalBackBuffer.Pitch;

            if (Game.UpdateAndRender) {
                Game.UpdateAndRender(&GameMemory, NewInput, &Buffer);
                HandleDebugCycleCounters(&GameMemory);
            }

            // TODO: Game audio support here
            game_sound_output_buffer SoundBuffer = {};
            SoundBuffer.SamplesPerSecond = SoundOutput.SamplesPerSecond;
            SoundBuffer.SampleCount = Align8((u32)(SoundOutput.SamplesPerSecond * TargetSecondsPerFrame));
            SoundBuffer.Samples = Samples;
            if (Game.GetSoundSamples) {
                Game.GetSoundSamples(&GameMemory, &SoundBuffer);
                SDL_QueueAudio(Audio, SoundBuffer.Samples, SoundBuffer.SampleCount * SoundOutput.BytesPerSample);
            }

            SDLDisplayBufferInWindow(&GlobalBackBuffer);

            game_input *Temp = NewInput;
            NewInput = OldInput;
            OldInput = Temp;
        }
    }

    return 0;
}
Exemplo n.º 8
0
int
main(void) {
    uint64 PerfCountFrequency = SDL_GetPerformanceFrequency();
    SDL_Event Event;
    SDL_Window *Window;
    SDL_Renderer *Renderer;

    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) != 0) {
        fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError());
        return -1;
    }

    atexit(SDL_Quit);

    int WindowWidth = 1300;
    int WindowHeight = 870;
    int BytesPerPixel = 4;

    Window = SDL_CreateWindow("Echelon",
                              0, 0,
                              WindowWidth, WindowHeight,
                              SDL_WINDOW_RESIZABLE);
    
    if(Window) {
        Renderer = SDL_CreateRenderer(Window, -1, 0);

        if(Renderer) {
            GlobalRunning = true;
            window_dimensions Dimensions = SDLGetWindowDimensions(Window);
            SDLCreateNewTexture(&GlobalBuffer,
                                Renderer,
                                Dimensions.Width, Dimensions.Height,
                                BytesPerPixel);

            uint64 LastCounter = SDL_GetPerformanceCounter();
            uint64 LastCycleCount = _rdtsc();

            real64 DebugTimer = 0;
            real64 FPSTimer = 0;
            real64 UpdateTimer = 0;

            uint32 FPS = 0;
            uint32 UPS = 0;
            
            keyboard_input KeyboardInput = {};
            gamepad_input GamePadInput = {};

            game_code Game = LoadGameCode();

            game_memory GameMemory = {};
            GameMemory.IsInitialized = false;
            GameMemory.PlayRumble = SDLPlayRumble;
            GameMemory.WindowDimensions = SDLGetWindowDimensions(Window);
            GameMemory.PlatformDrawRenderQueue = DrawRenderQueueStub;
            GameMemory.PermanentStorageSize = Megabytes(100);
            GameMemory.PermanentStorage = mmap(0,
                                               GameMemory.PermanentStorageSize,
                                               PROT_READ | PROT_WRITE,
                                               MAP_PRIVATE | MAP_ANONYMOUS,
                                               -1, 0);
            
            GameMemory.TransientStorageSize = Gigabytes(2);
            GameMemory.TransientStorage = mmap(0,
                                               GameMemory.TransientStorageSize,
                                               PROT_READ | PROT_WRITE,
                                               MAP_PRIVATE | MAP_ANONYMOUS,
                                               -1, 0);

            Game.GameInit(&GameMemory);
            
            while(GlobalRunning) {
                // NOTE(Redab): This needs to while loop because we need
                // to handle events as long as they are available.
                while(SDL_PollEvent(&Event)) {
                    SDLHandleEvent(&Event, &Dimensions);
                    SDLHandleUserInput(&Event, &Game, &GameMemory, &KeyboardInput, &GamePadInput);
                }

                uint64 EndCycleCount = _rdtsc();
                uint64 EndCounter = SDL_GetPerformanceCounter();
                uint64 CounterElapsed = EndCounter - LastCounter;
                uint64 CyclesElapsed = EndCycleCount - LastCycleCount;

                // NOTE(Redab): CounterElapsed Contains the number of
                // clock cycles since last check. So we need to divide
                // this by the number of cycles per second which we
                // have in PerCountFrequency. Multiplied by 1000 to
                // get milliseconds.

                real64 SecondsPerFrame = ((real64)CounterElapsed / (real64)PerfCountFrequency);
                real64 MSPerFrame = SecondsPerFrame * 1000.0f;
                
                real64 KCPF = ((real64)CyclesElapsed / (1000.0f));

                FPSTimer += MSPerFrame;
                UpdateTimer += MSPerFrame;
                DebugTimer += MSPerFrame;

                if(UpdateTimer >= (1000.0f / 60.0f)) {
                    GameMemory.WindowDimensions = Dimensions;                        
                    Game.GameUpdate(&GameMemory, &KeyboardInput, &GamePadInput, UpdateTimer / 1000.0f);

                    UPS++;
                    UpdateTimer = 0;
                }

                if(FPSTimer >= (1000.0f / 60.0f)) {
                    SDLGameRender(&GlobalBuffer, &Game, &GameMemory);
                    SDLBlitFrameToWindow(&GlobalBuffer, Renderer);
                    
                    FPS++;
                    FPSTimer = 0;
                }
                
                if(DebugTimer >= 1000.0f) {
                    printf("%.05fms/f, FPS: %d, UPS: %d, %.02fKc/f, Timer: %.02f\n",
                           MSPerFrame, FPS, UPS, KCPF, DebugTimer);

                    FPS = 0;
                    UPS = 0;
                    DebugTimer = 0;
                }

                LastCycleCount = EndCycleCount;
                LastCounter = EndCounter;
            }
        } else {
            printf("Failed to create SDL_Renderer: %s\n", SDL_GetError());
        }
    } else {
        printf("Failed to create SDL_Window: %s\n", SDL_GetError());
    }

    SDL_CloseAudio();
    SDL_Quit();
    return 0;
}
Exemplo n.º 9
0
TEST_F(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get());
  ASSERT_SOME(slave);

  MockScheduler sched1;
  MesosSchedulerDriver driver1(
      &sched1, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched1, registered(&driver1, _, _));

  Future<vector<Offer>> offers;
  EXPECT_CALL(sched1, resourceOffers(&driver1, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver1.start();

  AWAIT_READY(offers);
  ASSERT_FALSE(offers->empty());

  TaskInfo task;
  task.set_name("");
  task.mutable_task_id()->set_value("1");
  task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id());
  task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO);

  Resource* cpus = task.add_resources();
  cpus->set_name("cpus");
  cpus->set_type(Value::SCALAR);
  cpus->mutable_scalar()->set_value(-1);

  Resource* mem = task.add_resources();
  mem->set_name("mem");
  mem->set_type(Value::SCALAR);
  mem->mutable_scalar()->set_value(static_cast<double>(Gigabytes(1).bytes()));

  vector<TaskInfo> tasks;
  tasks.push_back(task);

  Future<TaskStatus> status;
  EXPECT_CALL(sched1, statusUpdate(&driver1, _))
    .WillOnce(FutureArg<1>(&status));

  driver1.launchTasks(offers.get()[0].id(), tasks);

  AWAIT_READY(status);
  EXPECT_EQ(task.task_id(), status->task_id());
  EXPECT_EQ(TASK_ERROR, status->state());
  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status->reason());
  EXPECT_TRUE(status->has_message());
  EXPECT_TRUE(strings::contains(status->message(), "Invalid scalar resource"))
    << status->message();

  MockScheduler sched2;
  MesosSchedulerDriver driver2(
      &sched2, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched2, registered(&driver2, _, _));

  EXPECT_CALL(sched2, resourceOffers(&driver2, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver2.start();

  AWAIT_READY(offers);

  driver1.stop();
  driver1.join();

  driver2.stop();
  driver2.join();
}
Exemplo n.º 10
0
//Program entry point
int main(int argc, char *argv[])
{
	UNUSED(argc);
	UNUSED(argv);

	//paths required by platform code
	platform::app_code.app_dll_path = "App.dll";
	platform::app_state.record_file = "input.smi";

	//Load the application dll
	platform_load_app_code(&platform::app_code);

	//initialize sdl
	if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
	{
		std::cerr << ERROR_LINE << "SDL Error: Unable to initialize SDL" << std::endl;
	}
	else
	{
		std::cout << "SDL initialized"<<std::endl;
	}

	//SDL version
	{
		SDL_version ver;
		SDL_VERSION(&ver);
		std::cout << "SDL version " << (int)ver.major << "." << (int)ver.minor << "." << (int)ver.patch << std::endl;
		SDL_GetVersion(&ver);
		std::cout << "Linked version " << (int)ver.major << "." << (int)ver.minor << "." << (int)ver.patch << std::endl;
	}

	//init time
	platform_update_time(platform::app_time);

	//call app config to get settings
	platform::app_code.config(&platform::services.config);

	//Set Opengl attributes
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, PLATFORM_GL_VERSION_MAJOR);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, PLATFORM_GL_VERSION_MINOR);

	//Set buffer attributes
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, PLATFORM_GL_DOUBLEBUFFER);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, PLATFORM_GL_DEPTHBUFFER);


	//Create a window
	platform_create_window();

	if (!platform::services.config.sdl_window)
	{
		std::cerr << ERROR_LINE << "Error: Unable to create window" << std::endl;
		return -1;
	}
	else
	{
		platform::services.config.quit = false;
		std::cout << "SDL window " << platform::services.config.width << "x" << platform::services.config.height << " opened" << std::endl;
	}

	//set OpenGL context
	auto sdl_context = SDL_GL_CreateContext(platform::services.config.sdl_window);

	// Initialise GLEW
	glewExperimental = GL_TRUE;
	GLenum glewError = glewInit();

	if (glewError != GLEW_OK)
	{
		std::cerr << ERROR_LINE << "GLEW Error: Unable to initialise glew";
		return -1;
	}
	else
	{
		std::cout<<"GLEW "<<glewGetString(GLEW_VERSION)<<" Initialised";
	}

	//Allocate memory for the app
	auto base_address = Gigabytes(1);
	platform::services.memory = {};
	platform::services.memory.permanent_memory_size = Megabytes(8);
	platform::services.memory.permanent_memory = platform::os::get_memory(base_address,platform::services.memory.permanent_memory_size);

	if (!platform::services.memory.permanent_memory)
	{
		std::cerr << "\nUnable to allocate enough memory";
		return -1;
	}

	//link memory to app state
	platform::app_state.memory = &platform::services.memory;

	//call the application startup
	platform::app_code.startup(&platform::services);

	//run application
	#ifdef __EMSCRIPTEN__
	emscripten_set_main_loop(platform_update, 0, true);
	#else
	//run as long as quit is not set to true
	while(!platform::services.config.quit)
	{
		platform_update();
	}
	#endif

	//free resources
	SDL_GL_DeleteContext(sdl_context);
	SDL_DestroyWindow(platform::services.config.sdl_window);

	//exit
	return 0;
}
Exemplo n.º 11
0
int CALLBACK WinMain(HINSTANCE Instance, HINSTANCE PrevInstance, LPSTR CommandLine, int ShowCode) {
	win32_state Win32State = {};

	LARGE_INTEGER PerfCounterFrequencyResult;
	QueryPerformanceFrequency(&PerfCounterFrequencyResult);
	GlobalPerfCounterFrequency = PerfCounterFrequencyResult.QuadPart;

	Win32GetEXEFileName(&Win32State);
	char SourceGameCodeDLLFullPath[WIN32_STATE_FILE_NAME_COUNT];
	Win32BuildEXEPathFileName(&Win32State, "handmade.dll", sizeof(SourceGameCodeDLLFullPath), SourceGameCodeDLLFullPath);
	char TempGameCodeDLLFullPath[WIN32_STATE_FILE_NAME_COUNT];
	Win32BuildEXEPathFileName(&Win32State, "handmade_temp.dll", sizeof(TempGameCodeDLLFullPath), TempGameCodeDLLFullPath);
	char GameCodeLockFullPath[WIN32_STATE_FILE_NAME_COUNT];
	Win32BuildEXEPathFileName(&Win32State, "lock.tmp", sizeof(GameCodeLockFullPath), GameCodeLockFullPath);

	// NOTE: setting windows scheduler granularity for our sleep() call
	UINT DesiredSchedulerMS = 1;
	bool32 SleepIsGranular = (timeBeginPeriod(DesiredSchedulerMS) == TIMERR_NOERROR);

	Win32LoadXInput();
	Win32ResizeDIBSection(&GlobalBackbuffer, 960, 540);

#if HANDMADE_INTERNAL
	DEBUGGlobalShowCursor = true;
#endif

	WNDCLASSEXA WindowClass = {};
	WindowClass.style = CS_VREDRAW | CS_HREDRAW;
	WindowClass.cbSize = sizeof(WNDCLASSEXA);
	WindowClass.lpfnWndProc = Win32MainWindowCallback;
	WindowClass.hInstance = Instance;
	WindowClass.hCursor = LoadCursor(0, IDC_ARROW);
	// WindowClass.hIcon;
	WindowClass.lpszClassName = "HandmadeHeroWindowClass";

	if (RegisterClassExA(&WindowClass)) {
		// WS_EX_TOPMOST|WS_EX_LAYERED
		HWND Window = CreateWindowExA(0, WindowClass.lpszClassName, "Handmade Hero", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 996, 600, 0, 0, Instance, 0);

		if (Window) {
			// TODO: reliably query this from windows
			int MonitorRefreshHz = 60;
			HDC RefreshDC = GetDC(Window);
			int Win32RefreshRate = GetDeviceCaps(RefreshDC, VREFRESH);
			ReleaseDC(Window, RefreshDC);
			if (Win32RefreshRate > 1) {
				MonitorRefreshHz = Win32RefreshRate;

				if (MonitorRefreshHz == 59) {
					MonitorRefreshHz = 60;
				}
			}
			real32 GameUpdateHz = MonitorRefreshHz / 2.0f;
			real32 TargetSecondsPerFrame = 1.0f / GameUpdateHz;

			// NOTE: sound test
			win32_sound_output SoundOutput = {};
			SoundOutput.SamplesPerSecond = 48000;
			SoundOutput.BytesPerSample = sizeof(int16) * 2;
			SoundOutput.SecondaryBufferSize = SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample;
			// TODO: compute this variance and see what the lowest reasonable value is
			SoundOutput.SafetyBytes = (int)((real32)SoundOutput.SamplesPerSecond * (real32)SoundOutput.BytesPerSample / GameUpdateHz / 3.0f);

			Win32InitDSound(Window, SoundOutput.SamplesPerSecond, SoundOutput.SecondaryBufferSize);
			Win32ClearSoundBuffer(&SoundOutput);
			GlobalSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING);

			GlobalRunning = true;

			// TODO: pool with bitmap virtualalloc
			int16 *Samples = (int16 *)VirtualAlloc(0, SoundOutput.SecondaryBufferSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

#if HANDMADE_INTERNAL
			LPVOID BaseAddress = (LPVOID)Terabytes(2);
#else
			LPVOID BaseAddress = 0;
#endif

			game_memory GameMemory = {};
			GameMemory.PermanentStorageSize = Megabytes(64);
			GameMemory.TransientStorageSize = Gigabytes(1);
			GameMemory.DEBUGPlatformFreeFileMemory = DEBUGPlatformFreeFileMemory;
			GameMemory.DEBUGPlatformReadEntireFile = DEBUGPlatformReadEntireFile;
			GameMemory.DEBUGPlatformWriteEntireFile = DEBUGPlatformWriteEntireFile;

			// TODO: handle various memory footprints using system metrics
			// TODO: use MEM_LARGE_PAGES
			Win32State.TotalSize = GameMemory.PermanentStorageSize + GameMemory.TransientStorageSize;
			Win32State.GameMemoryBlock = VirtualAlloc(BaseAddress, (size_t)Win32State.TotalSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
			GameMemory.PermanentStorage = Win32State.GameMemoryBlock;
			GameMemory.TransientStorage = (uint8 *)GameMemory.PermanentStorage + GameMemory.PermanentStorageSize;

			for (int ReplayIndex = 1; ReplayIndex < ArrayCount(Win32State.ReplayBuffers); ++ReplayIndex) {
				// TODO: recording system still takes too long on record start
				win32_replay_buffer *ReplayBuffer = &Win32State.ReplayBuffers[ReplayIndex];

				Win32GetInputFileLocation(&Win32State, false, ReplayIndex, sizeof(ReplayBuffer->FileName), ReplayBuffer->FileName);
				ReplayBuffer->FileHandle = CreateFileA(ReplayBuffer->FileName, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);

				LARGE_INTEGER MaxSize;
				MaxSize.QuadPart = Win32State.TotalSize;
				ReplayBuffer->MemoryMap = CreateFileMapping(ReplayBuffer->FileHandle, 0, PAGE_READWRITE, MaxSize.HighPart, MaxSize.LowPart, 0);
				ReplayBuffer->MemoryBlock = MapViewOfFile(ReplayBuffer->MemoryMap, FILE_MAP_ALL_ACCESS, 0, 0, (size_t)Win32State.TotalSize);

				if (!ReplayBuffer->MemoryBlock) {
					// TODO: diagnostic
				}
			}

			if (Samples && GameMemory.PermanentStorage && GameMemory.TransientStorage) {
				game_input Input[2] = {};
				game_input *NewInput = &Input[0];
				game_input *OldInput = &Input[1];

				LARGE_INTEGER LastCounter = Win32GetWallClock();
				LARGE_INTEGER FlipWallClock = Win32GetWallClock();

				int DebugTimeMarkerIndex = 0;
				win32_debug_time_marker DebugTimeMarkers[30] = { 0 };

				// TODO: handle startup specially
				bool32 SoundIsValid = false;
				DWORD AudioLatencyBytes = 0;
				real32 AudioLatencySeconds = 0;

				win32_game_code Game = Win32LoadGameCode(SourceGameCodeDLLFullPath, TempGameCodeDLLFullPath, GameCodeLockFullPath);

				uint64 LastCycleCount = __rdtsc();

				while (GlobalRunning) {
					NewInput->FrameTimeDelta = TargetSecondsPerFrame;

					FILETIME NewDLLWriteTime = Win32GetLastWriteTime(SourceGameCodeDLLFullPath);
					if (CompareFileTime(&NewDLLWriteTime, &Game.DLLLastWriteTime) != 0) {
						Win32UnloadGameCode(&Game);
						Game = Win32LoadGameCode(SourceGameCodeDLLFullPath, TempGameCodeDLLFullPath, GameCodeLockFullPath);
					}

					// TODO: zeroing macro
					// TODO: we cant zero everything as the up/down state will be wrong
					game_controller_input *OldKeyboardController = GetController(OldInput, 0);
					game_controller_input *NewKeyboardController = GetController(NewInput, 0);
					*NewKeyboardController = {};
					NewKeyboardController->IsConnected = true;

					for (int ButtonIndex = 0; ButtonIndex < ArrayCount(NewKeyboardController->Buttons); ++ButtonIndex) {
						NewKeyboardController->Buttons[ButtonIndex].EndedDown = OldKeyboardController->Buttons[ButtonIndex].EndedDown;
					}

					Win32ProcessPendingMessages(&Win32State, NewKeyboardController);

					if (!GlobalPause) {
						POINT MousePoint;
						GetCursorPos(&MousePoint);
						ScreenToClient(Window, &MousePoint);
						NewInput->MouseX = MousePoint.x;
						NewInput->MouseY = MousePoint.y;
						NewInput->MouseZ = 0; // TODO: support mousewheel?
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[0], GetKeyState(VK_LBUTTON) & (1 << 15));
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[1], GetKeyState(VK_MBUTTON) & (1 << 15));
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[2], GetKeyState(VK_RBUTTON) & (1 << 15));
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[3], GetKeyState(VK_XBUTTON1) & (1 << 15));
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[4], GetKeyState(VK_XBUTTON2) & (1 << 15));

						// TODO: should we poll this more frequently
						// TODO: dont poll disconnected controllers to prevent xinput frame rate impact
						DWORD MaxControllerCount = XUSER_MAX_COUNT;
						if (MaxControllerCount > (ArrayCount(NewInput->Controllers) - 1)) {
							MaxControllerCount = (ArrayCount(NewInput->Controllers) - 1);
						}

						for (DWORD ControllerIndex = 0; ControllerIndex < MaxControllerCount; ++ControllerIndex) {
							DWORD OurControllerIndex = ControllerIndex + 1;
							game_controller_input *OldController = GetController(OldInput, OurControllerIndex);
							game_controller_input *NewController = GetController(NewInput, OurControllerIndex);

							XINPUT_STATE ControllerState;

							if (XInputGetState(ControllerIndex, &ControllerState) == ERROR_SUCCESS) {
								NewController->IsConnected = true;
								NewController->IsAnalog = OldController->IsAnalog;
								// TODO: See if ControllerState.dwPacketNumber increments too rapidly
								XINPUT_GAMEPAD *Pad = &ControllerState.Gamepad;

								// TODO: currently handling a square deadzone, check if it is circular
								NewController->StickAverageX = Win32ProcessXInputStickValue(Pad->sThumbLX, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
								NewController->StickAverageY = Win32ProcessXInputStickValue(Pad->sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);

								if ((NewController->StickAverageX != 0.0f) || (NewController->StickAverageY != 0.0f)) {
									NewController->IsAnalog = true;
								}

								if (Pad->wButtons & XINPUT_GAMEPAD_DPAD_UP) {
									NewController->StickAverageY = 1.0f;
									NewController->IsAnalog = false;
								}

								if (Pad->wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
									NewController->StickAverageY = -1.0f;
									NewController->IsAnalog = false;
								}

								if (Pad->wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
									NewController->StickAverageX = -1.0f;
									NewController->IsAnalog = false;
								}

								if (Pad->wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
									NewController->StickAverageX = 1.0f;
									NewController->IsAnalog = false;
								}

								real32 Threshold = 0.5f;
								Win32ProcessXInputDigitalButton((NewController->StickAverageX < -Threshold) ? 1 : 0, &OldController->MoveLeft, 1, &NewController->MoveLeft);
								Win32ProcessXInputDigitalButton((NewController->StickAverageX > Threshold) ? 1 : 0, &OldController->MoveRight, 1, &NewController->MoveRight);
								Win32ProcessXInputDigitalButton((NewController->StickAverageY < -Threshold) ? 1 : 0, &OldController->MoveDown, 1, &NewController->MoveDown);
								Win32ProcessXInputDigitalButton((NewController->StickAverageY > Threshold) ? 1 : 0, &OldController->MoveUp, 1, &NewController->MoveUp);

								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->ActionDown, XINPUT_GAMEPAD_A, &NewController->ActionDown);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->ActionRight, XINPUT_GAMEPAD_B, &NewController->ActionRight);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->ActionLeft, XINPUT_GAMEPAD_X, &NewController->ActionLeft);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->ActionUp, XINPUT_GAMEPAD_Y, &NewController->ActionUp);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->LeftShoulder, XINPUT_GAMEPAD_LEFT_SHOULDER, &NewController->LeftShoulder);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->RightShoulder, XINPUT_GAMEPAD_RIGHT_SHOULDER, &NewController->RightShoulder);

								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->Start, XINPUT_GAMEPAD_START, &NewController->Start);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->Back, XINPUT_GAMEPAD_BACK, &NewController->Back);
							}
							else {
								// NOTE: the controller is not available
								NewController->IsConnected = false;
							}
						}

						thread_context Thread = {};

						game_offscreen_buffer Buffer = {};
						Buffer.Memory = GlobalBackbuffer.Memory;
						Buffer.Width = GlobalBackbuffer.Width;
						Buffer.Height = GlobalBackbuffer.Height;
						Buffer.Pitch = GlobalBackbuffer.Pitch;
						Buffer.BytesPerPixel = GlobalBackbuffer.BytesPerPixel;

						if (Win32State.InputRecordingIndex) {
							Win32RecordInput(&Win32State, NewInput);
						}

						if (Win32State.InputPlaybackIndex) {
							Win32PlaybackInput(&Win32State, NewInput);
						}

						if (Game.UpdateAndRender) {
							Game.UpdateAndRender(&Thread, &GameMemory, NewInput, &Buffer);
						}

						LARGE_INTEGER AudioWallClock = Win32GetWallClock();
						real32 FromBeginToAudioSeconds = Win32GetSecondsElapsed(FlipWallClock, AudioWallClock);

						DWORD PlayCursor;
						DWORD WriteCursor;

						if (GlobalSecondaryBuffer->GetCurrentPosition(&PlayCursor, &WriteCursor) == DS_OK) {
							/* NOTE: Sound output explanation

							We define a safety value that is the number of samples we think our game update loop can vary by.
							When we wake up to write audio we look at the play cursor position and forecast where we think it will be on the next frame boundary.
							If the write cursor is before that by at least our safety value, the target fill position is the frame boundary plus one frame. This gives us perfect audio sync if the audio latency is low enough.
							If the write cursor is after that safety value then we assume we can't sync the audio so we write one frames worth of audio plus the safety values worth of samples.

							*/

							if (!SoundIsValid) {
								SoundOutput.RunningSampleIndex = WriteCursor / SoundOutput.BytesPerSample;
								SoundIsValid = true;
							}

							DWORD ByteToLock = (SoundOutput.RunningSampleIndex * SoundOutput.BytesPerSample) % SoundOutput.SecondaryBufferSize;
							DWORD ExpectedSoundBytesPerFrame = (int)((real32)(SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample) / GameUpdateHz);
							real32 SecondsLeftUntilFlip = TargetSecondsPerFrame - FromBeginToAudioSeconds;
							DWORD ExpectedBytesUntilFlip = (DWORD)((SecondsLeftUntilFlip / TargetSecondsPerFrame) * (real32)ExpectedSoundBytesPerFrame);
							DWORD ExpectedFrameBoundaryByte = PlayCursor + ExpectedBytesUntilFlip;
							DWORD SafeWriteCursor = WriteCursor;

							if (SafeWriteCursor < PlayCursor) {
								SafeWriteCursor += SoundOutput.SecondaryBufferSize;
							}

							Assert(SafeWriteCursor >= PlayCursor);
							SafeWriteCursor += SoundOutput.SafetyBytes;
							bool32 AudioCardIsLowLatency = (SafeWriteCursor < ExpectedFrameBoundaryByte);
							DWORD TargetCursor = 0;

							if (AudioCardIsLowLatency) {
								TargetCursor = ExpectedFrameBoundaryByte + ExpectedSoundBytesPerFrame;
							}
							else {
								TargetCursor = WriteCursor + ExpectedSoundBytesPerFrame + SoundOutput.SafetyBytes;
							}

							TargetCursor = TargetCursor % SoundOutput.SecondaryBufferSize;
							DWORD BytesToWrite = 0;

							if (ByteToLock > TargetCursor) {
								BytesToWrite = SoundOutput.SecondaryBufferSize - ByteToLock;
								BytesToWrite += TargetCursor;
							}
							else {
								BytesToWrite = TargetCursor - ByteToLock;
							}

							game_sound_output_buffer SoundBuffer = {};
							SoundBuffer.SamplesPerSecond = SoundOutput.SamplesPerSecond;
							SoundBuffer.SampleCount = BytesToWrite / SoundOutput.BytesPerSample;
							SoundBuffer.Samples = Samples;
							if (Game.GetSoundSamples) {
								Game.GetSoundSamples(&Thread, &GameMemory, &SoundBuffer);
							}

#if HANDMADE_INTERNAL
							win32_debug_time_marker *Marker = &DebugTimeMarkers[DebugTimeMarkerIndex];
							Marker->OutputPlayCursor = PlayCursor;
							Marker->OutputWriteCursor = WriteCursor;
							Marker->OutputLocation = ByteToLock;
							Marker->OutputByteCount = BytesToWrite;
							Marker->ExpectedFlipPlayCursor = ExpectedFrameBoundaryByte;
							DWORD UnwrappedWriteCursor = WriteCursor;

							if (UnwrappedWriteCursor < PlayCursor) {
								UnwrappedWriteCursor += SoundOutput.SecondaryBufferSize;
							}

							AudioLatencyBytes = UnwrappedWriteCursor - PlayCursor;
							AudioLatencySeconds = ((real32)AudioLatencyBytes / (real32)SoundOutput.BytesPerSample) / (real32)SoundOutput.SamplesPerSecond;

#if 0
							char DebugSoundBuffer[256];
							sprintf_s(DebugSoundBuffer, "BTL:%u TC:%u BTW:%u - PC:%u WC:%u DELTA:%u (%fs)\n", ByteToLock, TargetCursor, BytesToWrite, PlayCursor, WriteCursor, AudioLatencyBytes, AudioLatencySeconds);
							OutputDebugStringA(DebugSoundBuffer);
#endif
#endif
							Win32FillSoundBuffer(&SoundOutput, ByteToLock, BytesToWrite, &SoundBuffer);
						}
						else {
							SoundIsValid = false;
						}

						LARGE_INTEGER WorkCounter = Win32GetWallClock();
						real32 WorkSecondsElapsed = Win32GetSecondsElapsed(LastCounter, WorkCounter);
						// TODO: not tested yet!
						real32 SecondsElapsedForFrame = WorkSecondsElapsed;

						if (SecondsElapsedForFrame < TargetSecondsPerFrame) {
							if (SleepIsGranular) {
								DWORD SleepMS = (DWORD)(1000.0f * (TargetSecondsPerFrame - SecondsElapsedForFrame));
								if (SleepMS > 0) {
									Sleep(SleepMS);
								}
							}

							real32 TestSecondsElapsedForFrame = Win32GetSecondsElapsed(LastCounter, Win32GetWallClock());

							if (TestSecondsElapsedForFrame < TargetSecondsPerFrame) {
								// TODO: log missed sleep here
							}

							while (SecondsElapsedForFrame < TargetSecondsPerFrame) {
								SecondsElapsedForFrame = Win32GetSecondsElapsed(LastCounter, Win32GetWallClock());
							}
						}
						else {
							// TODO: missed frame rate
							// TODO: logging
						}

						LARGE_INTEGER EndCounter = Win32GetWallClock();
						real32 MSPerFrame = 1000.0f * Win32GetSecondsElapsed(LastCounter, EndCounter);
						LastCounter = EndCounter;

						win32_window_dimension Dimension = Win32GetWindowDimension(Window);
						HDC BufferDC = GetDC(Window);
						Win32DisplayBufferInWindow(&GlobalBackbuffer, BufferDC, Dimension.Width, Dimension.Height);
						ReleaseDC(Window, BufferDC);

						FlipWallClock = Win32GetWallClock();

#if HANDMADE_INTERNAL
						DWORD DebugPlayCursor;
						DWORD DebugWriteCursor;
						if (GlobalSecondaryBuffer->GetCurrentPosition(&DebugPlayCursor, &DebugWriteCursor) == DS_OK) {
							Assert(DebugTimeMarkerIndex < ArrayCount(DebugTimeMarkers));
							win32_debug_time_marker *Marker = &DebugTimeMarkers[DebugTimeMarkerIndex];
							Marker->FlipPlayCursor = DebugPlayCursor;
							Marker->FlipWriteCursor = DebugWriteCursor;
						}
#endif

						game_input *Temp = NewInput;
						NewInput = OldInput;
						OldInput = Temp;
						// TODO: should these be cleared?

#if 0
						uint64 EndCycleCount = __rdtsc();
						uint64 CyclesElapsed = EndCycleCount - LastCycleCount;
						LastCycleCount = EndCycleCount;

						// real32 FPS = (real32)GlobalPerfCounterFrequency / (real32)CounterElapsed;
						real32 FPS = 0.0f;
						real32 MCPF = (real32)CyclesElapsed / (1000.0f * 1000.0f);

						char DebugPerformanceBuffer[256];
						sprintf_s(DebugPerformanceBuffer, "%0.02fmspf, %0.02ffps, %0.02fmcpf\n", MSPerFrame, FPS, MCPF);
						OutputDebugStringA(DebugPerformanceBuffer);
#endif

#if HANDMADE_INTERNAL
						++DebugTimeMarkerIndex;
						if (DebugTimeMarkerIndex == ArrayCount(DebugTimeMarkers)) {
							DebugTimeMarkerIndex = 0;
						}
#endif
					}
				}
			}
			else {
				// TODO: logging
			}
		}
		else {
			// TODO: logging
		}
	}
	else {
		// TODO: logging
	}

	return(0);
}
Exemplo n.º 12
0
TEST_F(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
{
  Try<PID<Master>> master = StartMaster();
  ASSERT_SOME(master);

  Try<PID<Slave>> slave = StartSlave();
  ASSERT_SOME(slave);

  MockScheduler sched1;
  MesosSchedulerDriver driver1(
      &sched1, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched1, registered(&driver1, _, _))
    .Times(1);

  Future<vector<Offer>> offers;
  EXPECT_CALL(sched1, resourceOffers(&driver1, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver1.start();

  AWAIT_READY(offers);
  EXPECT_NE(0u, offers.get().size());

  TaskInfo task;
  task.set_name("");
  task.mutable_task_id()->set_value("1");
  task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id());
  task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO);

  Resource* cpus = task.add_resources();
  cpus->set_name("cpus");
  cpus->set_type(Value::SCALAR);
  cpus->mutable_scalar()->set_value(-1);

  Resource* mem = task.add_resources();
  mem->set_name("mem");
  mem->set_type(Value::SCALAR);
  mem->mutable_scalar()->set_value(Gigabytes(1).bytes());

  vector<TaskInfo> tasks;
  tasks.push_back(task);

  Future<TaskStatus> status;
  EXPECT_CALL(sched1, statusUpdate(&driver1, _))
    .WillOnce(FutureArg<1>(&status));

  driver1.launchTasks(offers.get()[0].id(), tasks);

  AWAIT_READY(status);
  EXPECT_EQ(task.task_id(), status.get().task_id());
  EXPECT_EQ(TASK_ERROR, status.get().state());
  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status.get().reason());
  EXPECT_TRUE(status.get().has_message());
  EXPECT_TRUE(strings::startsWith(
        status.get().message(), "Task uses invalid resources"));

  MockScheduler sched2;
  MesosSchedulerDriver driver2(
      &sched2, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched2, registered(&driver2, _, _))
    .Times(1);

  EXPECT_CALL(sched2, resourceOffers(&driver2, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver2.start();

  AWAIT_READY(offers);

  driver1.stop();
  driver1.join();

  driver2.stop();
  driver2.join();

  Shutdown();
}
Exemplo n.º 13
0
namespace slave {

// TODO(jieyu): Use static functions for all the constants. See more
// details in MESOS-1023.

constexpr Duration EXECUTOR_REGISTRATION_TIMEOUT = Minutes(1);
constexpr Duration EXECUTOR_REREGISTRATION_TIMEOUT = Seconds(2);

// The maximum timeout within which an executor can re-register.
// Note that this value has to be << 'MIN_AGENT_REREGISTER_TIMEOUT'
// declared in 'master/constants.hpp'; since agent recovery will only
// complete after this timeout has elapsed, this ensures that the
// agent can re-register with the master before it is marked
// unreachable and its tasks are transitioned to TASK_UNREACHABLE or
// TASK_LOST.
constexpr Duration MAX_EXECUTOR_REREGISTRATION_TIMEOUT = Seconds(15);

// The default amount of time to wait for the executor to
// shut down before destroying the container.
constexpr Duration DEFAULT_EXECUTOR_SHUTDOWN_GRACE_PERIOD = Seconds(5);

constexpr Duration RECOVERY_TIMEOUT = Minutes(15);

// TODO(gkleiman): Move this to a different file once `TaskStatusUpdateManager`
// uses `StatusUpdateManagerProcess`. See MESOS-8296.
constexpr Duration STATUS_UPDATE_RETRY_INTERVAL_MIN = Seconds(10);
constexpr Duration STATUS_UPDATE_RETRY_INTERVAL_MAX = Minutes(10);

// Default backoff interval used by the slave to wait before registration.
constexpr Duration DEFAULT_REGISTRATION_BACKOFF_FACTOR = Seconds(1);

// The maximum interval the slave waits before retrying registration.
// Note that this value has to be << 'MIN_SLAVE_REREGISTER_TIMEOUT'
// declared in 'master/constants.hpp'. This helps the slave to retry
// (re-)registration multiple times between when the master finishes
// recovery and when it times out slave re-registration.
constexpr Duration REGISTER_RETRY_INTERVAL_MAX = Minutes(1);

// The maximum interval the slave waits before retrying authentication.
constexpr Duration AUTHENTICATION_RETRY_INTERVAL_MAX = Minutes(1);

// Default backoff interval used by the slave to wait after failed
// authentication.
constexpr Duration DEFAULT_AUTHENTICATION_BACKOFF_FACTOR = Seconds(1);

constexpr Duration GC_DELAY = Weeks(1);
constexpr Duration DISK_WATCH_INTERVAL = Minutes(1);

// Minimum free disk capacity enforced by the garbage collector.
constexpr double GC_DISK_HEADROOM = 0.1;

// Maximum number of completed frameworks to store in memory.
constexpr size_t MAX_COMPLETED_FRAMEWORKS = 50;

// Default maximum number of completed executors per framework
// to store in memory.
constexpr size_t DEFAULT_MAX_COMPLETED_EXECUTORS_PER_FRAMEWORK = 150;

// Maximum number of completed tasks per executor to store in memory.
//
// NOTE: This should be greater than zero because the agent looks
// for completed tasks to determine (with false positives) whether
// an executor ever received tasks. See MESOS-8411.
//
// TODO(mzhu): Remove this note once we can determine whether an
// executor ever received tasks without looking through the
// completed tasks.
constexpr size_t MAX_COMPLETED_TASKS_PER_EXECUTOR = 200;

// Default cpus offered by the slave.
constexpr double DEFAULT_CPUS = 1;

// Default memory offered by the slave.
constexpr Bytes DEFAULT_MEM = Gigabytes(1);

// Default disk space offered by the slave.
constexpr Bytes DEFAULT_DISK = Gigabytes(10);

// Default ports range offered by the slave.
constexpr char DEFAULT_PORTS[] = "[31000-32000]";

// Default cpu resource given to a command executor.
constexpr double DEFAULT_EXECUTOR_CPUS = 0.1;

// Default memory resource given to a command executor.
constexpr Bytes DEFAULT_EXECUTOR_MEM = Megabytes(32);

#ifdef ENABLE_PORT_MAPPING_ISOLATOR
// Default number of ephemeral ports allocated to a container by the
// network isolator.
constexpr uint16_t DEFAULT_EPHEMERAL_PORTS_PER_CONTAINER = 1024;
#endif

// Default UNIX socket (Linux) or Named Pipe (Windows) resource that provides
// CLI access to the Docker daemon.
#ifdef __WINDOWS__
constexpr char DEFAULT_DOCKER_HOST_RESOURCE[] = "//./pipe/docker_engine";
#else
constexpr char DEFAULT_DOCKER_HOST_RESOURCE[] = "/var/run/docker.sock";
#endif // __WINDOWS__

// Default duration that docker containers will be removed after exit.
constexpr Duration DOCKER_REMOVE_DELAY = Hours(6);

// Default duration to wait before retry inspecting a docker
// container.
constexpr Duration DOCKER_INSPECT_DELAY = Seconds(1);

// Default maximum number of docker inspect calls docker ps will invoke
// in parallel to prevent hitting system's open file descriptor limit.
constexpr size_t DOCKER_PS_MAX_INSPECT_CALLS = 100;

// Default duration that docker containerizer will wait to check
// docker version.
// TODO(tnachen): Make this a flag.
constexpr Duration DOCKER_VERSION_WAIT_TIMEOUT = Seconds(5);

// Additional duration that docker containerizer will wait beyond the
// configured `docker_stop_timeout` for docker stop to succeed, before
// trying to kill the process by itself.
constexpr Duration DOCKER_FORCE_KILL_TIMEOUT = Seconds(1);

// Name of the default, CRAM-MD5 authenticatee.
constexpr char DEFAULT_AUTHENTICATEE[] = "crammd5";

// Name of the default, local authorizer.
constexpr char DEFAULT_AUTHORIZER[] = "local";

// Name of the agent HTTP authentication realm for read-only endpoints.
constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-readonly";

// Name of the agent HTTP authentication realm for read-write endpoints.
constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-readwrite";

// Name of the agent HTTP authentication realm for HTTP executors.
constexpr char EXECUTOR_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-executor";

// Default maximum storage space to be used by the fetcher cache.
constexpr Bytes DEFAULT_FETCHER_CACHE_SIZE = Gigabytes(2);

// If no pings received within this timeout, then the slave will
// trigger a re-detection of the master to cause a re-registration.
Duration DEFAULT_MASTER_PING_TIMEOUT();

// Name of the executable for default executor.
#ifdef __WINDOWS__
constexpr char MESOS_DEFAULT_EXECUTOR[] = "mesos-default-executor.exe";
#else
constexpr char MESOS_DEFAULT_EXECUTOR[] = "mesos-default-executor";
#endif // __WINDOWS__

// Virtual path on which agent logs are mounted in `/files/` endpoint.
constexpr char AGENT_LOG_VIRTUAL_PATH[] = "/slave/log";

std::vector<SlaveInfo::Capability> AGENT_CAPABILITIES();

} // namespace slave {
Exemplo n.º 14
0
int main()
{
    SDL_Init(SDL_INIT_VIDEO);
    
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);

    SDL_Window * window = SDL_CreateWindow("gamedev", SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED, 1024, 768,
            SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);

    if(window) {
        SDL_GLContext gl_context = SDL_GL_CreateContext(window);

        // Initialize GLEW so we can get 3.30 stuff
        // I copied this from my quaternion demo
        // TODO: Can I do this without glew?

        // This experimental flag seems to be necessary for GLEW to load entry points
        // for certain core profile functions, like glGenVertexArrays. Really 
        // looking forward to getting rid of GLEW
        glewExperimental = GL_TRUE;
        GLenum err = glewInit();
        if (err != GLEW_OK)
        {
            fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
            exit(1); // or handle the error in a nicer way
        }

        if (!GLEW_VERSION_3_3)  // 
        {
            printf("Missing OpenGL version 3.3\n");
            exit(1); // or handle the error in a nicer way
        }

        printf("GLSL version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));

        game_memory Memory = {};
        Memory.PermanentStoreSize = Megabytes(256);
        Memory.TransientStoreSize = Gigabytes(1);
        Memory.TotalSize = Memory.PermanentStoreSize + Memory.TransientStoreSize;
        void * AllocatedMemory = mmap(0, Memory.TotalSize, PROT_READ | PROT_WRITE,
                MAP_ANON | MAP_PRIVATE, 0, 0);

        if(AllocatedMemory != MAP_FAILED) {
            //TODO: zero out the memory?

            Memory.PermanentStore = (uint8*)AllocatedMemory;
            Memory.TransientStore = Memory.PermanentStore + Memory.PermanentStoreSize;

            Memory.PermanentArena.Base = Memory.PermanentStore;
            Memory.PermanentArena.Size = Memory.PermanentStoreSize;
            Memory.PermanentArena.Offset = 0;

            Memory.TransientArena.Base = Memory.TransientStore;
            Memory.TransientArena.Size = Memory.TransientStoreSize;
            Memory.TransientArena.Offset = 0;

            game_state * GameState = PushStruct(&Memory.PermanentArena, game_state);

            bool Quit = false;
            while(!Quit) {

                // Handle keyboard events
                SDL_Event Event;
                while(SDL_PollEvent(&Event)) {
                    // TODO: probably don't want to take all the events here
                    switch(Event.type) {
                        case SDL_KEYUP:
                        case SDL_KEYDOWN:
                            SDL_KeyboardEvent KB_Event = Event.key;
                            SDL_Keysym Keysym = KB_Event.keysym;
                            switch(Keysym.sym) {
                                case SDLK_q:
                                    Quit = true;
                                    break;
                            }
                            break;
                    }
                }

                // Update/draw
                UpdateAndRender(&Memory, GameState);
                SDL_GL_SwapWindow(window);
            }
        }

        SDL_GL_DeleteContext(gl_context);
    } else {
        printf("Could not initialize SDL window.");
        return 1;
    }
    return 0;
}