HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_MemoryResource.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_MemoryResource.h (UT Library, C++)
7  *
8  * COMMENTS:
9  */
10 #ifndef UT_MemoryResource_h
11 #define UT_MemoryResource_h
12 
13 #include <SYS/SYS_Types.h>
14 
15 #include "UT_API.h"
16 #include "UT_Array.h"
17 #include "UT_Lock.h"
18 #include "UT_NonCopyable.h"
19 #include "UT_StringHolder.h"
20 #include "UT_StringMap.h"
21 #include "UT_UniquePtr.h"
22 
23 class UT_MemoryResource;
24 
25 /// Wrapper for a client of a limit memory resource.
27 {
28 public:
30  virtual ~UT_MemoryClient() {}
31 
33 
34  /// Printable English name of the client
35  virtual const char *name() const = 0;
36 
37  /// The urgency of the memory free request.
39  {
40  NORMAL_REQUEST, // Almost always use this severity.
41  FATAL_REQUEST // Memory must be freed or Houdini will become unusable.
42  };
43 
44  /// How willingly a client can free memory for other clients.
45  enum Niceness
46  {
47  SCRATCH_FREE, // Free reusable scratch memory (kept for performance)
48  READILY_FREE, // Memory that can be freed without much impact
49  NORMAL_FREE, // Memory that is important but can still be freed.
50  RELUCTANT_FREE, // Memory that should only be freed if really needed
51  CANNOT_FREE, // Client is only reporting mem and cannot free any.
52 
54  };
55 
56  /// A 'resource' is requesting 'size_in_bytes' amount of memory be
57  /// freed. If memory is freed, return true and the amount of memory freed in
58  /// 'freed_amount_in_bytes'
59  /// 'severity' - severity passed to UT_MemoryResource::requestMemoryFree()
60  /// 'nice_level' - the current niceness level being asked to free. This will
61  /// always match once of the niceness levels the client was
62  /// registered with.
63  virtual bool freeMemoryRequest(const UT_MemoryResource *resource,
64  RequestSeverity severity,
65  Niceness nice_level,
66  exint size_in_bytes,
67  exint &freed_amount_in_bytes) = 0;
68 
69  /// Report the amount of memory this client is using from 'resource'
70  /// 'in_use' refers to memory that is currently being used, where as
71  /// 'cached' refers to memory that'd being held either for reuse or scratch
72  /// buffers.
73  /// Return true if the size can be meaningully reported.
74  virtual bool memoryUse(const UT_MemoryResource *resource,
75  exint &in_use_size_bytes,
76  exint &cached_size_bytes)
77  {
78  in_use_size_bytes = 0;
79  cached_size_bytes = 0;
80  return false;
81  }
82 };
83 
84 /// A named resource that represents a limited memory pool shared by several
85 /// clients.
87 {
88 public:
89  /// Register a unqiue memory device, with a name and unique identifier.
90  /// Returns a unique name based on the given name. If another device was
91  /// already registered with the uuid, will return the same name used for it
92  static const UT_StringHolder &registerDeviceName(
93  const UT_StringHolder &name,
94  const uint8 (&uuid)[16]);
95 
96  /// Query if a named memory resource exists, optionally returning it.
97  static bool hasMemoryResource(const UT_StringHolder &name,
98  UT_MemoryResource **mem=nullptr);
99 
100  /// Find a memory resource and create if it does not exist.
101  static UT_MemoryResource *getMemoryResource(const UT_StringHolder &name);
102 
103  /// List of memory resources
104  static const UT_StringMap<UT_UniquePtr<UT_MemoryResource>> &memoryResources();
105 
106  /// Register as a client of the memory resource.
107  bool registerClient(UT_MemoryClient *client,
108  UT_MemoryClient::Niceness niceness);
109 
110  /// Register as a client of the memory resource but with several levels of
111  /// 'niceness'. In this case, the client may have some higher priority data
112  /// which it would rather hold onto, and some lower priority data which can
113  /// be readily freed. This allows other clients to fulfill the free request
114  /// at a lower priority level first, so that freeing the higher priority
115  /// data may be avoided or reduced.
116  bool registerClient(UT_MemoryClient *client,
117  const UT_Array<UT_MemoryClient::Niceness> &niceness);
118 
119  /// Remove 'client' from this memory resource.
120  bool unregisterClient(UT_MemoryClient *client);
121 
122  /// Request that other clients of the memory resource free up memory.
123  /// The 'from_client' parm is used to avoid the resource calling that client
124  /// to free memory. The 'severity' is a hint to other clients. FATAL should
125  /// be used only in cases where not respecting the request will result in
126  /// app termination, so very sparingly.
127  exint requestMemoryFree(exint size_in_bytes,
128  const UT_MemoryClient *from_client,
131 
132  /// Notify other clients that 'returning_client' is freeing up
133  /// 'size_in_bytes' of the resource. This doesn't have to be called
134  /// constantly, but after large deallocations, it may be helpful to notify
135  /// the other clients.
136  void returnMemory(const UT_MemoryClient *returning_client,
137  exint size_in_bytes);
138 
139  /// Total amount of memory in the resource (bytes).
140  exint totalMemory() const;
141 
142  /// The amount of memory currently used by clients (bytes). This calls into
143  /// all clients and asks them for their memory use, so use sparingly.
144  exint usedMemory();
145 
146  /// Query the device directly for free memory. Due to other applications,
147  /// this will likely be less than 'totalMemory()-usedMemory()'
148  // TODO.
149  ///exint freeDeviceMemory();
150 
152  { return myClients; }
153 
154  /// Set the total amount of memory the resource has.
155  void setTotalMemory(exint mem_in_bytes) { myTotalMemory = mem_in_bytes; }
156 
157 private:
158  struct PassKey {}; // passkey idiom to make ctor "private"
159 public:
160  UT_MemoryResource(const UT_StringHolder &name, PassKey);
161 
162 private:
165  int myLastClientIndex[UT_MemoryClient::MAX_NICENESS];
166  UT_Lock myLock;
167  UT_StringHolder myName;
168  exint myTotalMemory = -1; // unspecified
169  bool myAmFreeing = false;
170 };
171 
172 #endif
int64 exint
Definition: SYS_Types.h:125
#define UT_API
Definition: UT_API.h:14
void setTotalMemory(exint mem_in_bytes)
Set the total amount of memory the resource has.
unsigned char uint8
Definition: SYS_Types.h:36
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
GLenum GLenum severity
Definition: glcorearb.h:2539
GLuint const GLchar * name
Definition: glcorearb.h:786
const UT_StringMap< std::pair< UT_MemoryClient *, int > > clients() const
exint freeDeviceMemory();
virtual ~UT_MemoryClient()
Niceness
How willingly a client can free memory for other clients.
virtual bool memoryUse(const UT_MemoryResource *resource, exint &in_use_size_bytes, exint &cached_size_bytes)
Wrapper for a client of a limit memory resource.
RequestSeverity
The urgency of the memory free request.