image/src/DiscardTracker.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef mozilla_imagelib_DiscardTracker_h_
michael@0 7 #define mozilla_imagelib_DiscardTracker_h_
michael@0 8
michael@0 9 #include "mozilla/Atomics.h"
michael@0 10 #include "mozilla/LinkedList.h"
michael@0 11 #include "mozilla/Mutex.h"
michael@0 12 #include "mozilla/TimeStamp.h"
michael@0 13 #include "prlock.h"
michael@0 14 #include "nsThreadUtils.h"
michael@0 15 #include "nsAutoPtr.h"
michael@0 16
michael@0 17 class nsITimer;
michael@0 18
michael@0 19 namespace mozilla {
michael@0 20 namespace image {
michael@0 21
michael@0 22 class RasterImage;
michael@0 23
michael@0 24 /**
michael@0 25 * This static class maintains a linked list of RasterImage objects which are
michael@0 26 * eligible for discarding.
michael@0 27 *
michael@0 28 * When Reset() is called, the node is removed from its position in the list
michael@0 29 * (if it was there before) and appended to the beginnings of the list.
michael@0 30 *
michael@0 31 * Periodically (on a timer and when we notice that we're using more memory
michael@0 32 * than we'd like for decoded images), we go through the list and discard
michael@0 33 * decoded data from images at the end of the list.
michael@0 34 */
michael@0 35 class DiscardTracker
michael@0 36 {
michael@0 37 public:
michael@0 38 /**
michael@0 39 * The DiscardTracker keeps a linked list of Node objects. Each object
michael@0 40 * points to a RasterImage and contains a timestamp indicating when the
michael@0 41 * node was inserted into the tracker.
michael@0 42 *
michael@0 43 * This structure is embedded within each RasterImage object, and we do
michael@0 44 * |mDiscardTrackerNode.img = this| on RasterImage construction. Thus, a
michael@0 45 * RasterImage must always call DiscardTracker::Remove() in its destructor
michael@0 46 * to avoid having the tracker point to bogus memory.
michael@0 47 */
michael@0 48 struct Node : public LinkedListElement<Node>
michael@0 49 {
michael@0 50 RasterImage *img;
michael@0 51 TimeStamp timestamp;
michael@0 52 };
michael@0 53
michael@0 54 /**
michael@0 55 * Add an image to the front of the tracker's list, or move it to the front
michael@0 56 * if it's already in the list. This function is main thread only.
michael@0 57 */
michael@0 58 static nsresult Reset(struct Node* node);
michael@0 59
michael@0 60 /**
michael@0 61 * Remove a node from the tracker; do nothing if the node is currently
michael@0 62 * untracked. This function is main thread only.
michael@0 63 */
michael@0 64 static void Remove(struct Node* node);
michael@0 65
michael@0 66 /**
michael@0 67 * Initializes the discard tracker. This function is main thread only.
michael@0 68 */
michael@0 69 static nsresult Initialize();
michael@0 70
michael@0 71 /**
michael@0 72 * Shut the discard tracker down. This should be called on XPCOM shutdown
michael@0 73 * so we destroy the discard timer's nsITimer. This function is main thread
michael@0 74 * only.
michael@0 75 */
michael@0 76 static void Shutdown();
michael@0 77
michael@0 78 /**
michael@0 79 * Discard the decoded image data for all images tracked by the discard
michael@0 80 * tracker. This function is main thread only.
michael@0 81 */
michael@0 82 static void DiscardAll();
michael@0 83
michael@0 84 /**
michael@0 85 * Inform the discard tracker that we are going to allocate some memory
michael@0 86 * for a decoded image. We use this to determine when we've allocated
michael@0 87 * too much memory and should discard some images. This function can be
michael@0 88 * called from any thread and is thread-safe. If this function succeeds, the
michael@0 89 * caller is now responsible for ensuring that InformDeallocation is called.
michael@0 90 */
michael@0 91 static bool TryAllocation(uint64_t aBytes);
michael@0 92
michael@0 93 /**
michael@0 94 * Inform the discard tracker that we've deallocated some memory for a
michael@0 95 * decoded image. This function can be called from any thread and is
michael@0 96 * thread-safe.
michael@0 97 */
michael@0 98 static void InformDeallocation(uint64_t aBytes);
michael@0 99
michael@0 100 private:
michael@0 101 /**
michael@0 102 * This is called when the discard timer fires; it calls into DiscardNow().
michael@0 103 */
michael@0 104 friend void DiscardTimeoutChangedCallback(const char* aPref, void *aClosure);
michael@0 105
michael@0 106 /**
michael@0 107 * When run, this runnable sets sDiscardRunnablePending to false and calls
michael@0 108 * DiscardNow().
michael@0 109 */
michael@0 110 class DiscardRunnable : public nsRunnable
michael@0 111 {
michael@0 112 NS_IMETHOD Run();
michael@0 113 };
michael@0 114
michael@0 115 static void ReloadTimeout();
michael@0 116 static nsresult EnableTimer();
michael@0 117 static void DisableTimer();
michael@0 118 static void MaybeDiscardSoon();
michael@0 119 static void TimerCallback(nsITimer *aTimer, void *aClosure);
michael@0 120 static void DiscardNow();
michael@0 121
michael@0 122 static LinkedList<Node> sDiscardableImages;
michael@0 123 static nsCOMPtr<nsITimer> sTimer;
michael@0 124 static bool sInitialized;
michael@0 125 static bool sTimerOn;
michael@0 126 static mozilla::Atomic<bool> sDiscardRunnablePending;
michael@0 127 static uint64_t sCurrentDecodedImageBytes;
michael@0 128 static uint32_t sMinDiscardTimeoutMs;
michael@0 129 static uint32_t sMaxDecodedImageKB;
michael@0 130 static uint32_t sHardLimitDecodedImageKB;
michael@0 131 // Lock for safegarding the 64-bit sCurrentDecodedImageBytes
michael@0 132 static PRLock *sAllocationLock;
michael@0 133 static mozilla::Mutex* sNodeListMutex;
michael@0 134 static Atomic<bool> sShutdown;
michael@0 135 };
michael@0 136
michael@0 137 } // namespace image
michael@0 138 } // namespace mozilla
michael@0 139
michael@0 140 #endif /* mozilla_imagelib_DiscardTracker_h_ */

mercurial