allocator.h - Engine C API Reference

allocator.h
  1. #pragma once
  2. #include "../engine_plugin_api/plugin_api.h"
  3. #define _XKEYCHECK_H
  4. #define alignof(x) __alignof(x)
  5. namespace stingray_plugin_foundation {
  6. // Abstract base class for allocators.
  7. //
  8. // Allocators can be thread-safe or not, see the separate documentation for each
  9. // alloactor.
  10. class Allocator
  11. {
  12. Allocator(const Allocator &);
  13. Allocator & operator=(const Allocator &);
  14. public:
  15. static const int DEFAULT_ALIGN = 4;
  16. Allocator() {}
  17. virtual ~Allocator() {}
  18. // Convenience method for allocating when you don't care about allocated size.
  19. virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) = 0;
  20. // Frees the memory pointed to by p, the memory must have been allocated by the allocate()
  21. // function. Returns the size of the allocated memomry.
  22. virtual size_t deallocate(void *p) = 0;
  23. };
  24. // Allocator class that wraps the AllocatorApi exposed by the engine's plugin interface.
  25. class ApiAllocator : public Allocator
  26. {
  27. AllocatorObject *_object;
  28. AllocatorApi *_api;
  29. public:
  30. ApiAllocator(AllocatorApi *api, AllocatorObject *object) : _object(object), _api(api) {}
  31. ApiAllocator(const ApiAllocator &a) : _object(a._object), _api(a._api) {}
  32. ApiAllocator & operator=(const ApiAllocator &a) { _object = a._object; _api = a._api; return *this; }
  33. virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) override {return _api->allocate(_object, size, align);}
  34. virtual size_t deallocate(void *p) override {return _api->deallocate(_object, p);}
  35. AllocatorObject *object() { return _object; }
  36. AllocatorApi *api() { return _api; }
  37. };
  38. template <class T> void make_delete(Allocator &a, T *p) {
  39. if (p) {
  40. p->~T();
  41. a.deallocate(p);
  42. }
  43. }
  44. // Allocator that allocates from a static buffer.
  45. class StaticAllocator : public Allocator
  46. {
  47. char *_start;
  48. char *_p;
  49. char *_end;
  50. public:
  51. StaticAllocator(char *p, char *end) : _start(p), _p(p), _end(end) {}
  52. virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) override
  53. {
  54. if (size == 0)
  55. return nullptr;
  56. unsigned rem = (_p - (const char *)0) % align;
  57. if (rem)
  58. _p += (align - rem);
  59. char *ret = _p + size > _end ? nullptr : _p;
  60. _p += size;
  61. return ret;
  62. }
  63. size_t deallocate(void *p) override { return 0; }
  64. char *start() {return _start;}
  65. bool out_of_memory() {return _p > _end;}
  66. size_t wanted_memory() {return (size_t)(_p - _start);}
  67. };
  68. // Allocations released only by destructor
  69. class TempAllocator : public ApiAllocator
  70. {
  71. public:
  72. TempAllocator(AllocatorApi *api) : ApiAllocator(api, api->make_temp_allocator()) {}
  73. virtual ~TempAllocator() { api()->destroy_temp_allocator(object()); }
  74. };
  75. // Add this in the public section of classes to specify that they want to be initialized with an
  76. // allocator.
  77. #define ALLOCATOR_AWARE typedef int allocator_aware
  78. // Macro versions of make_new and make_delete to avoid template combinatorial explosion and
  79. // make sure errors are reported in the file where the macro is called.
  80. #define MAKE_NEW(a, T, ...) (new ((a).allocate(sizeof(T), alignof(T))) T(__VA_ARGS__))
  81. #define MAKE_DELETE(a, p) (make_delete(a,p))
  82. #define MAKE_DELETE_TYPE(a, T, p) do {if (p) {(p)->~T(); (a).deallocate(p);}} while (0)
  83. } // namespace stingray_plugin_foundation