|
|
Subscribe / Log in / New account

Short topics in memory management

Memory management has been a relatively quiet topic over much of the life of the 2.6.x kernels. Many of the worst problems have been solved and the MM hackers have gone on to other things. That does not mean that there is no more work to do, however; indeed, things might be about to heat up. A few recent discussions illustrate the sort of pressures which may lead to a renewed interest in memory management work in the near future.

Mel Gorman's fragmentation avoidance patches have been discussed here a few times in the past. The core idea behind Mel's work is to identify pages which can be easily moved or reclaimed and group them together. Movable pages include those allocated to user space; moving them is just a matter of changing the relevant page table entries. Reclaimable pages include kernel caches which can be released should the need arise. Grouping these pages together makes it easy for the kernel to free large blocks of memory, which is useful for enabling high-order allocations or for vacating regions of memory entirely.

In the past, reviewers of Mel's patches have disagreed over how they should work. Some argue in favor of maintaining separate free lists for the different types of allocations, while others feel that this sort of memory partitioning is just what the kernel's zone system was created to do. So, this time around, Mel has posted two sets of patches: a list-based grouping mechanism and a new ZONE_MOVABLE zone which is restricted to movable allocations.

[page distribution graphic] The difference this time around is that the two patches are designed to work together. By default, there is no movable zone, so the list-based mechanism handles the full job of keeping alike allocations together. The administrator can configure in ZONE_MOVABLE at boot time with the kernelcore= option, which specifies the amount of memory which is not to be put into that zone. In addition, Mel has posted some comprehensive information on how performance is affected by these patches. In an unusual move, Mel has included a set of videos showing just how memory allocations respond to system stress with different allocation mechanisms in place; the image at the right shows one frame from one of those videos. The demonstration is convincing, but one is left with the uneasy hope that the creation of multimedia demonstrations will not become necessary to get patches into the kernel in the future.

These patches have found their way into the -mm tree, though Andrew Morton is still unclear on whether he thinks they are worthwhile or not. Among other things, he is concerned about how they fit with other, related work, especially memory hot-unplugging and per-container memory limits. While patches addressing both areas have been posted, nothing is really at a point where it is ready to be merged. This discussion between Mel and Andrew is worth reading for those who are interested in this topic.

The hot removal of memory can clearly be helped by Mel's work - memory which is subject to removal can be restricted to movable and reclaimable allocations, allowing it to be vacated if need be. Not everybody is convinced that hot-unplugging is a useful feature, though. In particular, Linus is opposed to the idea. The biggest potential use for hot-unplugging is for virtualization; it allows a hypervisor to move memory resources between guests as their needs change. Linus points out that most virtualization mechanisms already have mechanisms which allow the addition and removal of individual pages from guests; there is, he says, no need for any other support for memory changes.

Another use for this technique is allowing systems to conserve power by turning off banks of memory when they are not needed. Clearly, one must be able to move all useful data out of a memory bank before powering it down. Linus is even more dismissive of this idea:

The whole DRAM power story is a bedtime story for gullible children. Don't fall for it. It's not realistic. The hardware support for it DOES NOT EXIST today, and probably won't for several years. And the real fix is elsewhere anyway...

More information on his objections is available here for those who are interested. In short, Linus thinks it would make much more sense to look at turning off entire NUMA nodes rather than individual memory banks. That notwithstanding, Mark Gross has posted a patch enabling memory power-down which includes some basic anti-fragmentation techniques. Says Mark:

To be clear PM-memory will not be useful unless you have workloads that can take advantage of it. The identified workloads are not desktop workloads. However; there is a non-zero number of interested users with applicable workloads that make pushing the enabling patches out to the community worth while. These workloads tend to be within network elements and servers where memory utilization tracks traffic load.

It has also been suggested that resident set size limits (generally associated with containers) can solve many of the same problems that the anti-fragmentation work is aimed at. Rik van Riel was heard to complain in response that RSS limits could aggravate the scalability problems currently being experienced by the Linux memory management system. That drew questions from people like Andrew, who were not really aware of those problems. Rik responded with a few relatively vague examples; his ability to be specific is evidently restricted by agreements with the customers experiencing the problems.

That led to a whole discussion on whether it makes any sense to try to address memory management problems without test cases which demonstrate those problems. Rik argues that fixing test cases tends to break things in the real world. Andrew responds:

Somehow I don't believe that a person or organisation which is incapable of preparing even a simple testcase will be capable of fixing problems such as this without breaking things.

Rik has put together a page describing some problem workloads in an attempt to push the discussion forward.

One of Andrew's points is that trying to fix memory management problems caused by specific workloads in the kernel will always be hard; the kernel simply does not always have the information to know which pages will be needed soon and which can be discarded. Perhaps, he says, the right answer is to make it easier for user space to communicate its expected future needs. To that end, he put together a pagecache management tool for testing. It works as an LD_PRELOAD library which intercepts file-related system calls, tracks application usage, and tells the kernel to drop pages out of the cache after they have been used. The result is that common operations (copying a kernel tree, for example) can be carried out without forcing other useful data out of the page cache.

There were some skeptical responses to this posting. There was also some interest and some discussion of how smarter, application-specific policies could be incorporated into the tool. A possible backup tool policy, for example, would force the output file out of memory immediately, track pages read from other files and force them back out - but only if they were not already in the page cache, and so on. It remains to be seen whether anybody will run with this tool and try to use it to solve real workload problems, but there is some potential there. The kernel does not always know best.

Index entries for this article
KernelHotplug/Memory
KernelMemory management


(Log in to post comments)

Short topics in memory management

Posted Mar 7, 2007 6:18 UTC (Wed) by jcm (subscriber, #18262) [Link]

I'd like to see a real memory reservation system in Linux, using kernel events to notify userland of memory pressure and having applications dynamically adjust their own caches/etc. as needed.

I brought this up on lkml a while ago, and suggested a combination of netlink events passed over D-BUS to listening applications as one way to achieve this - for example, telling Firefox that memory pressure means it needs to stop using ludicrously large in-memory caches of the last 10 pages visited so the rest of the user session isn't killed by the thrashing to disk that follows.

Having briefly played with this, I lost interest due to lack of time (and perhaps also a lack of intimate knowledge of the VM system) but I'd like to revive this if anyone is interested in helping out.

Jon.

Short topics in memory management

Posted Mar 7, 2007 9:02 UTC (Wed) by k8to (guest, #15413) [Link]

I'm ignorantly curious about the problems you're trying to address. Isn't the solution to "the firefox problem" to cache almost all data on disk? Linux seems really great about keep disk data in memory when there isn't pressure and reclaiming it when necessary. Am I misunderstanding that problem, and is what you are trying to address really a different problem?

Short topics in memory management

Posted Mar 7, 2007 11:28 UTC (Wed) by njs (subscriber, #40338) [Link]

The cache's he's referring to in the firefox case are explicitly the in-memory ones -- while in principle an app could write such caches out to disk and trust the OS to make accessing that data as efficient as reasonable, in practice this may require major restructuring of your app. Firefox *does* cache pages on disk, of course, but it also has a smaller in-memory cache of fully parsed and rendered pages; the point of this is to avoid the re-rendering (and re-executing javascript, etc.) overhead of going to the normal disk cache (which just stores html files), and there's no reasonable way to take giant in-memory object graphs and write them do disk directly.

Now OTOH one would hope Linux would be clever about reclaiming memory by writing such memory out to swap... though various things could thwart this, e.g., if Firefox has a garbage collector tromping over those pages and keeping them resident, or if its memory is sufficiently fragmented that objects that are just being kept around as a cache, and objects that are in active use, happen to share pages.

These are just potential problems, though; I have no idea if they come up in practice. The firefox I'm typing this in seems to be about 300 megabytes total, but about 100 of those have been pushed out to swap, even during active use on a lightly loaded system without much memory pressure. Now, of course, it might be that those 100 megabytes are unused because they were actually leaked or something, but it is at least suggest that the "firefox problem" is not as bad as the original poster thinks.

Short topics in memory management

Posted Mar 7, 2007 13:35 UTC (Wed) by dion (guest, #2764) [Link]

I think you might be right.

Firefox probably thinks we are living in 1970 when there wasn't anything called virtual memory, so it allocates gobs of RAM for caches and does explicit file io.

A much better way would be to have just one cache in one huge memory mapped file, that way there is never any explicit io and the kernel is free to write stuff out to disk whenever it needs to.

It would make a persistent cache a bit tricky, you could never do anything with the cached files using normal tools and crashing would be interesting, though.

Someone working on firefox should take a peek at Varnish, which is incredibly fast because it lets the kernel do all the hard memory/io work.

Stuck with 1970s VM?

Posted Mar 7, 2007 15:57 UTC (Wed) by jzbiciak (guest, #5246) [Link]

Don't forget, Firefox has to run on Windows, too. ;-)

Stuck with 1970s VM?

Posted Mar 7, 2007 16:38 UTC (Wed) by ibukanov (subscriber, #3942) [Link]

As far as I remember Windows got memory-mapped files starting at least with Windows-95. Surely the API is different, but it is straightforward to isolate the difference behind a tiny wrapper. The best thing about it is that since the memory mapping removes explicit reads/writes from the application, the end result is more portable code.

Stuck with 1970s VM?

Posted Mar 7, 2007 16:44 UTC (Wed) by jzbiciak (guest, #5246) [Link]

*whoooosh*

That's the sound of a tongue-in-cheek jab at Windows going over your head. :-)

Short topics in memory management

Posted Mar 7, 2007 16:50 UTC (Wed) by ibukanov (subscriber, #3942) [Link]

> It would make a persistent cache a bit tricky,

The trick is to use relative offsets instead of pointers in the data that goes into the mapped file. It has an extra benefit of a more secure code since it is easier to add bound-check for the offsets then checking the pointers.

Short topics in memory management

Posted Mar 7, 2007 17:47 UTC (Wed) by zlynx (guest, #2285) [Link]

Checking offset bounds may look easier than a pointer, but it isn't really. A pointer is nothing but an offset from memory location 0, after all.

if( pointer > mmap_base && pointer < mmap_end ) ...

Using an unsigned int offset instead saves you from checking the lower bound, but you lose that savings again the instant you segment your memory into different uses, like using some for text and some for graphics.

Short topics in memory management

Posted Mar 8, 2007 23:57 UTC (Thu) by jzbiciak (guest, #5246) [Link]

"A pointer is nothing but an offset from memory location 0, after all."

Well, these days it is on most architectures...

Short topics in memory management

Posted Mar 7, 2007 17:49 UTC (Wed) by zlynx (guest, #2285) [Link]

One problem with large mmaps is fragmented virtual memory. It is very possible with 32-bit addressing to end up in a situation where you *cannot* allocate a single block of virtual. Especially if you are doing things where you grow your maps, reposition them, etc. Then you need crazy stuff like a mmap defragmenter where you flush it all to disk, unmap it and remap everything again.

All the problems could be solved of course, but who is going to rewrite all that code? Again.

Short topics in memory management

Posted Mar 7, 2007 18:14 UTC (Wed) by dion (guest, #2764) [Link]

Well, the solution is to "not do that, then".

If I were to implement a browser cache in a memory mapped file then the mapping would be the first thing to get allocated and it would never change.

Garbage collection and MM

Posted Mar 7, 2007 20:11 UTC (Wed) by aanno (guest, #6082) [Link]

There are indeed indications for the opinion that collaboration of kernel MM and user space tools could improve performance. Matthew Hertz did some academic research on the topic. His bookmarking collector, a garbage collection algorithm for the Java VM is impressing.

I might be that garbage collection languages will predominant computer programming soon. I could soon be annoying that MM of many OS (including Linux) does not handle garbage collection as good as could be imagined.

Garbage collection and MM

Posted Mar 8, 2007 8:26 UTC (Thu) by ncm (guest, #165) [Link]

It would be most unfortunate if GC-ridden languages came to predominate. It is practically impossible for an OS memory manager to "handle" GC well, just as it is practically impossible for the program itself to do so. It is in the nature of GC to interact badly with caches, and we are ever more dependent on an increasing variety of caches.

Every time the above is pointed out, somebody pops up and says that some new or old wrinkle has potential to mitigate the problems. Invariably there's a paper with lots of artificial benchmarks, running on a machine dedicated to nothing but running those benchmarks. Invariably such programs interact badly with real programs on real machines.

Besides its fundamental problems, GC never advances much because it can't be encapsulated. For every place that needs it, it must be re-done from scratch. The cunning tricks of the last implementation don't work in the next.

Academia can't see limitations of GC because the ideal academic program only ever manages memory. Real-world programs must manage other much more limited resources -- network sockets, database connections, disks -- and any method sufficient to manage them suffices for memory as well. No current language threatens C++ for serious programming, however useful such a language would be. In large part this is because any such rival would first need to impress academics who, for the most part, have no clue about what makes a language actually useful.

Garbage collection and MM

Posted Mar 8, 2007 10:55 UTC (Thu) by aanno (guest, #6082) [Link]

I completly agree with you, mcn. Cache locality will probably never be fixed with GC based languages. But as far as I understand, in many GC algorithms, there is also a 'walker' that marks memory that is not reachable any more. It is a bad idea to walk onto a swapped-out page, though.

And I could imagine that this problem could be diminished. The paper I linked to takes this direction.

Even if GC based language will not predominate, they have to be taken into account more than let's say 20 years ago. The fact that many Linux users don't like Java or .NET will not make this langauges to disappear. And even if they would, what's about Python, Ruby, Perl and the like?

GC is even mentioned in this discussion to be used within firefox (see above). And I heart that the GCC suite also uses GC (beginning with version 3.0).

GC will always be problematic. But it is a thing that could be improved by collaboration of kernel and user land knowledge. My point of view is that the research of Hertz points to the right direction. I was interesting to read that this sort of collaboration could also solve other MM related problems.

Garbage collection and MM

Posted Mar 8, 2007 12:22 UTC (Thu) by nix (subscriber, #2304) [Link]

Yes, GCC 3.0 did start using GC (because the lifetime rules of objects in the compiler were unfathomably complex). It fixed an unknown but large number of bugs... and slowed down the compiler a *lot* due to cache locality issues.

Years ago now, someone (Mike Stump?) ran some benchmarks that showed GCC incurring cache stalls every *twenty instructions* or thereabouts. Small wonder that it slowed down!

Careful moves are now underway (and have been for a while) to migrate objects with simple lifetime rules back into obstacks. The obstacks are still garbage-collected, but the obstack is a *single* GCed object with good cache locality, where the myriads of objects it replaces were not.

I doubt GCC will ever leave GCC, either: for objects with complex lifetime rules, there's really no maintainable alternative. But for the simple ones, using suballocators with better cache locality (like obstacks) is a good idea.

Garbage collection and MM

Posted Mar 8, 2007 15:25 UTC (Thu) by pflugstad (subscriber, #224) [Link]

But as far as I understand, in many GC algorithms, there is also a 'walker' that marks memory that is not reachable any more. It is a bad idea to walk onto a swapped-out page, though.

This has not been the case for several years now. Most GCs (certainly in Java) systems use a generational/compacting collector. As such, dead objects aren't touched at all. And this was 3+ years ago - it's gotten even better since then. When you do Java, you really do need to re-think how you program.

As someone else said, GC is everywhere these days, even embedded. The ease and clarity of developing in a GC language (Python, Perl, Java, etc), far outweigh the performance penalty you may see with GC. This is especially true for the vast majority of programs where performance is not seriously a concern, such as those with human interactions. I've done a lot C. I've done a lot of C++. I've done Python. I've done Java. I'll take Python/Java 6 days a week (but not twice on Sundays - sometimes you do need performance :-).

Garbage collection and MM

Posted Mar 8, 2007 16:32 UTC (Thu) by aanno (guest, #6082) [Link]

Right. I oversimplified this. Generational/compacting collectors have no walker but (a) have a second indirection (that slows down things) and (b) are not memory efficient (as they roughly use twice the space that is theoretically needed). Certainly Hertz compares his GC against this type. Refer to the paper to get all the details.

Garbage collection and MM

Posted Mar 8, 2007 20:35 UTC (Thu) by ncm (guest, #165) [Link]

Python is not, at present, a GC language. Neither is Perl.

However, people are working on GC implementations. Expect complaints about cache abuse by scripts, too, soon.

Garbage collection and MM

Posted Mar 9, 2007 0:04 UTC (Fri) by njs (subscriber, #40338) [Link]

Python is certainly a GC language (since version 2.0). It happens to optimize that GC by using reference counting to catch the easy cases, and only doing mark/sweep type stuff occasionally to catch reference cycles, but it definitely has a full GC.

I'm told that some of the hottest Java GC techniques actually involve reference counting these days, because you can massively optimize your actual walking -- the only time a cycle can be created is when a reference count is decremented, and thus achieves a number greater than 0. This is pretty rare, and it also tells you that any cycle that was just created must involve that object in particular, so you don't have to tromp through all memory either.

None of this affects your original point, though, because reference counting already trashes caches by itself -- especially in the multiprocessor case, where supposedly read-only access to variables is suddenly triggering cache flushes...

Depending on your cache hierarchy and the characteristics of your GC, you can minimize its impact, though. E.g., in gcc, I thought I remember some trick where you only run the collector between passes, since you know already that that's when everything becomes garbage, and also where it doesn't matter if you trash the cache? Similarly, Graydon was saying something about in initial implementations of firefox's GC, they would just run it after page load, because no-one notices if the browser pauses for 400 milliseconds then, they're just looking at the page.

Long run: build garbage collection into the RAM hardware! That'll work around those pesky cache issues ;-)

GC languages and domination

Posted Mar 8, 2007 14:46 UTC (Thu) by kevinbsmith (guest, #4778) [Link]

For web servers, GC languages already dominate. Java, obviously, plus PHP, perl, python, and ruby. Who writes CGI in C or C++ any more? Sure, a few folks, but not many.

On the desktop, I can't think of a single GUI app that I would rather write (or see written) in C or C++ instead of one of the languages mentioned above. Heck, even command-line utilities are often (usually?) written in perl or some other scripting language (not to mention bash). I guess it depends on your definition of "serious" programming.

Like it or not, GC is pervasive, and still increasing in popularity. It just makes sense to have the inexpensive computers do the extra work instead of the expensive programmers.

GC languages and domination

Posted Mar 8, 2007 19:41 UTC (Thu) by nevyn (subscriber, #33129) [Link]

For web servers, GC languages already dominate.

Err, no. Yaws is about the only major Web server that isn't written in C. And that's entirely because C is the only thing that performs well enough.

For the CGI like "backend", yes GC languages dominate mainly because performance isn't as big a problem and the real web server can take actions to limit the performance problem of the GC'd language code. Also the person running the application is often closely tied to the person writting it, and so they can throw money at their users performance problems.

On the desktop, I can't think of a single GUI app that I would rather write (or see written) in C or C++ instead of one of the languages mentioned above.

There are still very few GUI applications that aren't written in C, and again it's mainly because of performance and memory usage. For instance the "revelation GNOME applet" is currently ~125MB big, with an RSS of 32MB; this is a python application that provides a single text entry and an icon on my panel ... it is far from unique. About the only major GC'd application I use is xemacs, and it's all too often that I reboot it due to memory usage spiraling out of control (and I wouldn't call it fast).

It just makes sense to have the inexpensive computers do the extra work instead of the expensive programmers.

That is wrong in two ways: 1) The computers are now not doing real work for their users, instead they are doing busy work for the programers (on the users time). 2) Doing it properly is often not that expensive for a good programer, who already has to manage other reasources. But, yes, users are often still letting programers charge them millions of units of work in exchange for not having to do a single unit themself. I doubt any economy can make this sustainable, long term, and you only have to look at people using dillo and/or lighttpd to see the choices being made.

GC languages and domination

Posted Mar 9, 2007 11:45 UTC (Fri) by aanno (guest, #6082) [Link]

This is a very biased opion. Dynamic web content is often delivered by J(2)EE applications - especial in (big) enterprise environments. The infrastructure for this is also Java based, like like JBoss or Tomcat. There are also desktop application that uses GC based languages: Eclipse, NetBeans, beagle.

In enterprise environments Eclipse RCP has become the plattform for fat client programming.

On the other hand there are applications written in C/C++ that waste tons of memory, like Firefox or Gaim.

GC languages and domination

Posted Mar 12, 2007 11:04 UTC (Mon) by ekj (guest, #1524) [Link]

1) The computers are now not doing real work for their users, instead they are doing busy work for the programers (on the users time).

Users are free to choose. If programs written in non-GCed languages where enough faster that this mattered to the users, they'd be perfectly free to use those programs then. For some kinds of programs this *is* the case. The inner loop of a FPS-game is probably better written with explicit memory-handling.

For other uses, this doesn't seem to be the case. Most web-apps are infact written in GCed languages. There is absolutely *nothing* stopping you from developing competing programs in say C, and if you're rigth, that the users really would prefer this, you'd make billions. I somehow think that'll fail to be the case though.

The thing you're missing is that computing-power really is cheap, and often cheap enough to be almost completely ignorable. The company I work for, for example, spend on the order of $1million/year on developing web-applications. The hardware for running all of this costs something like literally 5% of this, and that is *including* backups, sysadmin-stuff and the like.

Even if we could run the same stuff on a 486 if it was written in C, it wouldn't be worth it if that meant more than 3-4% extra development-time. 2) Doing it properly is often not that expensive for a good programer, who already has to manage other reasources.

Doing software-development "properly" is very expensive. So expensive that if you do custom-development it is going to completely -dwarf- the hardware-requirements in 95% of the cases.

Spending a year of work and $5000 of hardware for doing the same thing that could be done with 6 months of work and $10.000 of hardware is the completely unsustainable choice -- You save $5000 in hw and spend ten times that in extra development-costs.

If you can do in 12 months in C the same job that require 11 months in Python/Ruby/Php/whatever, then more power to you. Most people can't though, not even smart people.

Garbage collection and MM

Posted Mar 9, 2007 21:39 UTC (Fri) by cpeterso (guest, #305) [Link]

Perhaps this is an argument for putting GC in the kernel itself? Instead of userspace programs solving the same complicated memory management problems again and again, consolidate the solution in the kernel, close it the OS's MM code.

Garbage collection and MM

Posted Mar 12, 2007 10:50 UTC (Mon) by ekj (guest, #1524) [Link]

But the thing is, it appears, in practice, really really hard for human brains to handle memory-allocation well too.

Sure, sure, "just do it correctly" would work, in principle. Except that in *practice* we've been using C for like forever in computer-terms, and *still* the classical memory-managment problems keep coming up, even in well-audited clueful code. So, obviosuly, "just do it correctly" isn't going to solve the problem.

So, who is most likely to improve their ability of handling memory-allocation? Computers (who grow in various ways by leaps and bounds) or human beings (who's been struggling with manual memory-managment in C for decades, and this far seems to be making very very little, if any, progress.)

Also, the overwhelming part of code written does not care about performance. They don't care *enough* to be willing to take the extra hit on development-time needed to do manual memory-managment anyway.

It's not about laziness. I don't particularily care if my employer wishes to hire me for a week to do something in Python, or if he prefers paying me for 2 weeks to solve the same problem in C. (or for that matter a month and solve it in assembler)

My employer cares though. He wants a problem solved. He'll probably opt for the python-version, even if it runs 3 times slower. Especially since he knows that it's a simple thing to re-write any routines that *do* need performance in C if that should turn out to be nessecary.

Garbage collection and MM

Posted Mar 13, 2007 19:24 UTC (Tue) by pimlott (guest, #1535) [Link]

You make a good case, but ...
Real-world programs must manage other much more limited resources -- network sockets, database connections, disks -- and any method sufficient to manage them suffices for memory as well.
comparing the problem of managing memory with managing other resources is off-base. Other resources almost always have simple, obvious lifetime rules that make explicit management straight-forward. Furthermore, there are many fewer of them (so fewer places to make mistakes, easier to audit), and errors are usually detected quickly because the resource has an externally-visible behavior. And if still explicit management is too difficult, reference counting solves the problem neatly because there are not enough objects to cause a performance impact, and there is no possibility of reference loops.

Memory management is fundamentally much harder.

Garbage collection and MM

Posted Mar 15, 2007 11:21 UTC (Thu) by renox (guest, #23785) [Link]

Another paper on VM aware GCs: first link when looking for 'vm aware garbage collector' on Google.

They got significant improvement on their benchmark by making the VM and the GC communicate.
Of course whether this show real like improvement is anyone guess..

One annoying thing with these papers is that they use copying GCs which doesn't interact well with C-based libraries: they're useful only for Java not the other scripting language which tend to reuse C-based libraries..

Short topics in memory management

Posted Mar 8, 2007 12:56 UTC (Thu) by ranmachan (guest, #21283) [Link]

Andrews pagecache-management tool works great for burning DVDs.
The script I use for that first md5sums all the files, burns them with growisofs and checks the result with md5sum again.
However, the stock script doesn't work with md5sum+growisofs because the use fread/fwrite.
I also had to include linux/fadvise.h to get it to compile on my Debian system.

diff -Naru pagecache-management/fadv.c pagecache-management/fadv.c
--- pagecache-management/fadv.c 2007-03-03 20:02:20.000000000 +0100
+++ pagecache-management/fadv.c 2007-03-04 11:35:56.000000000 +0100
@@ -9,6 +9,7 @@
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
+#include <linux/fadvise.h>

int main(int argc, char *argv[])
{
diff -Naru pagecache-management/pagecache-management.c pagecache-management/pagecache-management.c
--- pagecache-management/pagecache-management.c 2007-03-03 21:14:00.000000000 +0100
+++ pagecache-management/pagecache-management.c 2007-03-04 14:55:27.000000000 +0100
@@ -15,6 +15,7 @@
#include <unistd.h>
#include <dlfcn.h>
#include <limits.h>
+#include <linux/fadvise.h>

#include "sync_file_range.h"

@@ -152,9 +157,12 @@

static ssize_t (*_write)(int fd, const void *buf, size_t count);
static ssize_t (*_pwrite)(int fd, const void *buf, size_t count, off_t offset);
+static size_t (*_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
static ssize_t (*_read)(int fd, void *buf, size_t count);
static ssize_t (*_pread)(int fd, void *buf, size_t count, off_t offset);
+static size_t (*_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
static int (*_close)(int fd);
+static int (*_fclose)(FILE *fp);
static int (*_dup2)(int oldfd, int newfd);

static int symbols_loaded;
@@ -176,6 +184,10 @@
if (dlerror())
abort();

+ _fwrite = dlsym(handle, "fwrite");
+ if (dlerror())
+ abort();
+
dlerror();
_read = dlsym(handle, "read");
if (dlerror())
@@ -185,10 +197,18 @@
if (dlerror())
abort();

+ _fread = dlsym(handle, "fread");
+ if (dlerror())
+ abort();
+
_close = dlsym(handle, "close");
if (dlerror())
abort();

+ _fclose = dlsym(handle, "fclose");
+ if (dlerror())
+ abort();
+
_dup2 = dlsym(handle, "dup2");
if (dlerror())
abort();
@@ -222,6 +242,22 @@
return (*_pwrite)(fd, buf, count, offset);
}

+size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ load_symbols();
+ write_was_called(fileno(stream), size*nmemb);
+ return (*_fwrite)(ptr, size, nmemb, stream);
+}
+
+#undef fwrite_unlocked
+
+size_t fwrite_unlocked(const void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ load_symbols();
+ write_was_called(fileno(stream), size*nmemb);
+ return (*_fwrite)(ptr, size, nmemb, stream);
+}
+
ssize_t read(int fd, void *buf, size_t count)
{
load_symbols();
@@ -236,6 +272,29 @@
return (*_pread)(fd, buf, count, offset);
}

+size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ load_symbols();
+ read_was_called(fileno(stream), size*nmemb);
+ return (*_fread)(ptr, size, nmemb, stream);
+}
+
+#undef fread_unlocked
+
+size_t fread_unlocked(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ load_symbols();
+ read_was_called(fileno(stream), size*nmemb);
+ return (*_fread)(ptr, size, nmemb, stream);
+}
+
+int fclose(FILE *fp)
+{
+ load_symbols();
+ close_was_called(fileno(fp));
+ return (*_fclose)(fp);
+}
+
int close(int fd)
{
load_symbols();


Copyright © 2007, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds