mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 21:45:41 +00:00
A free Windows-compatible Operating System - mirrored from GitHub
![]() Complete rewrite reserving and releasing of System PTEs. The previous algorithm, in a nutshell, worked as follows: - PTE clusters are in a singly linked list, ordered by their base address. - All PTEs in the clusters are zeroed (except for cluster list bookkeeping). - Upon reservation: Walk the list to get the first cluster that's large enough, cut the requested amount of PTEs off its tail and return them. - Upon release: Create a new cluster using the PTEs to release, and merge it together with possible adjacent clusters. Problems with the previous algorithm: - While the idea is that all PTEs in clusters are zeroed, which requesters rely on, cluster bookkeeping isn't zeroed on merges. The side effect of this was that PTEs that weren't really zeroed were randomly delivered to requesters. - 99% of the time, allocations are serviced using the first cluster in the list, which is virtually always the first suitable cluster. This is so because the ordering is based on the base address of the clusters, and allocations are serviced using the cluster tail. Because the first cluster starts out as the whole pool, and the pool is quite sizable, it can deal with virtually allocations.. for a while. - A corollary of the previous point is *massive fragmentation* because: as long as an allocation isn't released back into the pool, the space of previous allocations that have been released isn't reused because the first cluster can't suck them up, and enough allocations remain in use. - The combined effect of the previous two points: a first cluster that effectively shrinks mostly, with small clusters forming behind it. Once the first cluster has shrunk far enough (which of course takes a long time), 90% of the space may still be free, scattered in mostly small clusters. This would make decent sized allocations fail because of the heavy fragmentation. - An implementation detail that caused the head of the list to be treated as a genuine cluster when the first cluster in the list was too small. The algorithm (as explained above) made this case quite unlikely until your system has been running for a while, after which it could happily corrupt list heads of other pools, depending on where the list head is with respect to its own pool. Empirically obtained data revealed that after just *booting to the desktop*, the pool for System Pte Space entries contained roughly 70 (unusable) clusters, blocking 15 to 20% of the pool. These figures increased to roughly 100 clusters and 30 to 35% after opening a foxy browser and using it to visit a mathematically inspired search engine. The same data also showed that over 95% of allocations requested just a single PTE, and a noticable allocation spike also occured in the range of 65-128 PTEs. It should be clear optimizing for small allocations is a good idea, and preferably encourage reuse the same PTEs for such allocations. And the new algorithm was born: - PTE clusters are in a singly linked list, ordered by increasing cluster size. - All PTEs in the clusters are zeroed (except for cluster list bookkeeping) .. really this time! - Upon reservation: Walk the list to get the first cluster that's large enough, cut the requested amount of PTEs off its tail and return them. - Upon release: Create a new cluster using the PTEs to release, and merge it together with possible adjacent clusters. - Both in the reservation and release actions, insertions into the list preserve the increasing cluster size order. Empirically obtained data now revealed that after just booting to the desktop, the pool for System Pte Space entries contained exactly 2 clusters. This increased to 10 clusters after some minor internet browsing and watching a 5 minute video using a media player. svn path=/trunk/; revision=50347 |
||
---|---|---|
reactos | ||
rosapps | ||
rostests | ||
wallpaper |