Merge pull request #128 from microsoft/low-memory-async
Make Lazy Decomit asynchronous
This commit is contained in:
@@ -10,8 +10,8 @@ namespace snmalloc
|
||||
{
|
||||
/**
|
||||
* This PAL supports low memory notifications. It must implement a
|
||||
* `low_memory_epoch` method that returns a `uint64_t` of the number of
|
||||
* times that a low-memory notification has been raised and an
|
||||
* `register_for_low_memory_callback` method that allows callbacks to be
|
||||
* registered when the platform detects low-memory and an
|
||||
* `expensive_low_memory_check()` method that returns a `bool` indicating
|
||||
* whether low memory conditions are still in effect.
|
||||
*/
|
||||
@@ -53,4 +53,63 @@ namespace snmalloc
|
||||
* Default Tag ID for the Apple class
|
||||
*/
|
||||
static const int PALAnonDefaultID = 241;
|
||||
|
||||
/**
|
||||
* This struct is used to represent callbacks for notification from the
|
||||
* platform. It contains a next pointer as client is responsible for
|
||||
* allocation as we cannot assume an allocator at this point.
|
||||
**/
|
||||
struct PalNotificationObject
|
||||
{
|
||||
std::atomic<PalNotificationObject*> pal_next;
|
||||
|
||||
void (*pal_notify)(PalNotificationObject* self);
|
||||
};
|
||||
|
||||
/***
|
||||
* Wrapper for managing notifications for PAL events
|
||||
**/
|
||||
class PalNotifier
|
||||
{
|
||||
/**
|
||||
* List of callbacks to notify
|
||||
**/
|
||||
std::atomic<PalNotificationObject*> callbacks = nullptr;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Register a callback object to be notified
|
||||
*
|
||||
* The object should never be deallocated by the client after calling
|
||||
* this.
|
||||
**/
|
||||
void register_notification(PalNotificationObject* callback)
|
||||
{
|
||||
callback->pal_next = nullptr;
|
||||
|
||||
auto prev = &callbacks;
|
||||
auto curr = prev->load();
|
||||
do
|
||||
{
|
||||
while (curr != nullptr)
|
||||
{
|
||||
prev = &(curr->pal_next);
|
||||
curr = prev->load();
|
||||
}
|
||||
} while (!prev->compare_exchange_weak(curr, callback));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the pal_notify of all the registered objects.
|
||||
**/
|
||||
void notify_all()
|
||||
{
|
||||
PalNotificationObject* curr = callbacks;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->pal_notify(curr);
|
||||
curr = curr->pal_next;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace snmalloc
|
||||
|
||||
@@ -20,23 +20,25 @@ namespace snmalloc
|
||||
{
|
||||
class PALWindows
|
||||
{
|
||||
/**
|
||||
* The number of times that the memory pressure notification has fired.
|
||||
*/
|
||||
static inline std::atomic<uint64_t> pressure_epoch;
|
||||
/**
|
||||
* A flag indicating that we have tried to register for low-memory
|
||||
* notifications.
|
||||
*/
|
||||
static inline std::atomic<bool> registered_for_notifications;
|
||||
static inline HANDLE lowMemoryObject;
|
||||
|
||||
/**
|
||||
* List of callbacks for low-memory notification
|
||||
**/
|
||||
static inline PalNotifier low_memory_callbacks;
|
||||
|
||||
/**
|
||||
* Callback, used when the system delivers a low-memory notification. This
|
||||
* simply increments an atomic counter each time the notification is raised.
|
||||
* calls all the handlers registered with the PAL.
|
||||
*/
|
||||
static void CALLBACK low_memory(_In_ PVOID, _In_ BOOLEAN)
|
||||
{
|
||||
pressure_epoch++;
|
||||
low_memory_callbacks.notify_all();
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -76,17 +78,6 @@ namespace snmalloc
|
||||
# endif
|
||||
;
|
||||
|
||||
/**
|
||||
* Counter values for the number of times that a low-pressure notification
|
||||
* has been delivered. Callers should compare this with a previous value
|
||||
* to see if the low memory state has been triggered since they last
|
||||
* checked.
|
||||
*/
|
||||
uint64_t low_memory_epoch()
|
||||
{
|
||||
return pressure_epoch.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the low memory state is still in effect. This is an
|
||||
* expensive operation and should not be on any fast paths.
|
||||
@@ -98,6 +89,17 @@ namespace snmalloc
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register callback object for low-memory notifications.
|
||||
* Client is responsible for allocation, and ensuring the object is live
|
||||
* for the duration of the program.
|
||||
**/
|
||||
static void
|
||||
register_for_low_memory_callback(PalNotificationObject* callback)
|
||||
{
|
||||
low_memory_callbacks.register_notification(callback);
|
||||
}
|
||||
|
||||
static void error(const char* const str)
|
||||
{
|
||||
puts(str);
|
||||
|
||||
Reference in New Issue
Block a user