Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Using SFML with a memory pool  (Read 3397 times)

0 Members and 1 Guest are viewing this topic.

Thrusty

  • Newbie
  • *
  • Posts: 16
    • View Profile
Using SFML with a memory pool
« on: November 02, 2017, 08:15:04 am »
I'm using a custom memory pool and allocators in my app, and I would like to get SFML to work with this system if possible.

There are a few things I need to check before I proceed with the attempt:

1. Using SFML's Dynamic  Link Libraries will not be possible, but will there be legal problems when using a statically compiled SFML in my commercial app?

2. Does SFML use new and delete in any of its types that dynamically allocate memory (types such as sf::Text, sf::String, sf::Texture, sf::RenderWindow, etc), or does it use malloc directly anywhere?

3. What is the largest chunk of memory that would realistically be allocated (I don't mean in cases where the user stupidly allocates memory for, say, a million characters in a sf::String, but just in the normal cases)? (the max block size, in my pool, is 2 megabytes)

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Using SFML with a memory pool
« Reply #1 on: November 02, 2017, 08:31:31 am »
1. Using SFML's Dynamic  Link Libraries will not be possible, but will there be legal problems when using a statically compiled SFML in my commercial app?
No, there's no issue, see the FAQ. Keep in mind that OpenAL has to be linked dynamically though due to it being licensed LGPL.

2. Does SFML use new and delete in any of its types that dynamically allocate memory (types such as sf::Text, sf::String, sf::Texture, sf::RenderWindow, etc), or does it use malloc directly anywhere?
SFML generally doesn't use malloc, however SFML's dependencies (C libraries) do. Also I found an odd case in the Linux implementation that uses it for some strange reason. See the GitHub search result.

3. What is the largest chunk of memory that would realistically be allocated (I don't mean in cases where the user stupidly allocates memory for, say, a million characters in a sf::String, but just in the normal cases)? (the max block size, in my pool, is 2 megabytes)
Not sure there's really a normal case, since it's really dependent on what a user does with SFML. Like you could have a vertex array with a few thousand vertices in there, you could load some large image (2048x2048px), or a user might load a huge audio file into memory, etc. On the other end a user might simply load some small texture and no audio file.
If you want to figure out the memory print of something, just run call sizeof(sf::TYPE).

What's the reasoning for using a custom memory pool and allocators?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Using SFML with a memory pool
« Reply #2 on: November 02, 2017, 09:40:44 am »
From looking into it that malloc when dealing with Xlib once is because the pixel data is freed along the image itself by XDestroyImage (despite being allocated by user and passed to XCreateImage, you need to set data to null to avoid that being freed by it). I think if XCreateImage fails there it's actually a leak because data is not freed anywhere.
Back to C++ gamedev with SFML in May 2023

Thrusty

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Using SFML with a memory pool
« Reply #3 on: November 02, 2017, 09:45:32 am »
eXpl0it3r, I'll answer your question about why I want to use my own pool shortly. For now, could you answer another question for me?

I think my question number 3 was a bit pointless because obviously I would put checks in my Editor to make sure the user doesn't load in 2000x2000 sized Images.

So, what happens when Image requests too much memory and the request fails? On my side (in the pool), it just returns null, or throws an exception (for the placement version of new). But how does sf::Image, for example, deal with this? I've heard SFML doesn't use exceptions. LoadFromFile returns false, but what happens internally if new returns null (for a request bigger than 2 mib)?

This is what the overloaded new and delete looks like:

#include <new>
#include "../Pool/Pool.hpp"

void* operator new(std::size_t s)
{
    return memory::pool::allocate_b_4096(s, 0, 0);
}

void* operator new[](std::size_t s)
{
    return memory::pool::allocate_b_4096(s, 0, 0);
}

void* operator new(std::size_t s, const std::nothrow_t&)
{
    return memory::pool::allocate_b_4096_noexcept(s, 0, 0);
}

void* operator new[](std::size_t s, const std::nothrow_t&)
{
    return memory::pool::allocate_b_4096_noexcept(s, 0, 0);
}

void operator delete(void* p) noexcept
{
    if (p) { memory::pool::free(p); }
}

void operator delete[](void* p) noexcept
{
    if (p) { memory::pool::free(p); }
}
« Last Edit: November 02, 2017, 09:50:48 am by Thrusty »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Using SFML with a memory pool
« Reply #4 on: November 02, 2017, 10:37:31 am »
Quote
LoadFromFile returns false, but what happens internally if new returns null (for a request bigger than 2 mib)?
SFML doesn't throw exceptions itself, but that doesn't mean you can't get one from a SFML call.
"new" never returns null (except when its "nothrow" variant is invoked, which SFML never does), so SFML will just let the std::bad_alloc exception proagate if it fails.
« Last Edit: November 02, 2017, 10:40:56 am by Laurent »
Laurent Gomila - SFML developer

Thrusty

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Using SFML with a memory pool
« Reply #5 on: November 04, 2017, 05:15:17 pm »
I've noticed that when moving the mouse inside the Window (main Window from RenderWindow), SFML is calling new and delete repeatedly. Is it keeping a log of the events, or are they just happening so quick that it needs a bigger structure to hold them all? Or is this allocation not related to an array, but a series of individual dynamically allocated objects that are needed whenever an event is generated?

Max block size in my app is 2 mib; nothing larger can be allocated, as I don't need anything that big.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Using SFML with a memory pool
« Reply #6 on: November 04, 2017, 05:43:46 pm »
As far as I can tell, SFML doesn't allocate dynamically on each new event. Maybe you can put a breakpoint in your overload of operator new, and have a look at the call stack to find out which SFML function triggers it.
Laurent Gomila - SFML developer

Thrusty

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Using SFML with a memory pool
« Reply #7 on: November 05, 2017, 10:15:47 am »
Sure thing...I noticed a deque being used there. What's the rationale behind this choice of container?


FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Using SFML with a memory pool
« Reply #8 on: November 05, 2017, 10:33:09 am »
It's a queue, with it's default backend which is a deque which you could have read in the code. That's because events are a FIFO, you push freshest events to the back and pop oldest events from the front.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Using SFML with a memory pool
« Reply #9 on: November 05, 2017, 11:50:21 am »
std::deque is usually implemented as a linked list of fixed-size chunks, so it should not reallocate for every push_back. It should even never reallocate if you have balanced push/pop calls, which SFML has in typical use.

I suspect this only happens with high precision mouse move, and not other events, because this one can fill the event queue a lot faster than your event loop can clear it. Do you confirm that?
Laurent Gomila - SFML developer