I've been reading some topics about Memory Management and I often notice people talk about disabling interrupts in various parts of the Memory Management functions. Would disabling interrupts stop the mouse too? I mean, you can't move the mouse (read: cursor) when interrupts are disabled, or am I crazy now?
I made a little program that allocates and frees 100 megabyte blocks in a loop that iterates 1 million times. The host OS is Windows in my case, and the mouse didn't even stutter (and I even put my mouse at 2000 DPI).
Can anyone shed some light on this
disabling interrupts
disabling interrupts
Last edited by Bughunter on Sun Jun 10, 2007 8:20 am, edited 1 time in total.
Re: disabling interrupts
The mouse driver would be unable to process interrupts while they're disabled, yes.bughunter wrote:I've been reading some topics about Memory Management and I often notice people talk about disabling interrupts in various parts of the Memory Management functions. Would disabling interrupts stop the mouse too?
No, that sounds about right. (Though you can obviously move the physical mouse, the messages it sends won't be processed by the kernel until it responds to the interrupt generated so the cursor wouldn't be moved yet)I mean, you can't move the mouse when interrupts are disabled, or am I crazy now?
Typically when interrupts are disabled, they're not disabled for very long. As long as the mouse only sends one interrupt in that time you should be fine; the interrupt will be processed as soon as they're enabled again (and any higher-priority interrupts have been processed).I made a little program that allocates and frees 100 megabyte blocks in a loop that iterates 1 million times.
Note: I have no idea what happens when there are multiple unhandled messages. It may even differ for serial, PS/2 and USB mice...
If you're testing this in Windows, you're most likely using user-level malloc/free or new/delete instead of kernel-level memory management functions. these user-level memory management functions don't normally need a lot of interaction from the kernel-level MM (and can't themselves disable interrupts - though they typically perform some form of locking if they're threadsafe). They just request memory from the kernel MM when they run out, and normally don't release it when it's free'd but reuse it for later allocations instead.The host OS is Windows in my case, and the mouse didn't even stutter (and I even put my mouse at 2000 DPI).
Can anyone shed some light on this
However 100MB allocs might be exceptions, I seem to recall dlmalloc optionally using memory-mapped files for large allocations. Other malloc implementations may do something similar. Still, the system calls those require shouldn't disable interrupts for very long either. In fact, pretty much nothing should except stuff like BSODs/kernel panics.
I don't know about windows, but in theory malloc by itself should not disable any interrupts. If windows is in anyway sensible, then it will not actually give you 100MB of physical memory every time you malloc(0x10000000) but will merely increase the end of heap pointer for that particular process if the heap is not big enough to satisfy your request. Physical memory should only be allocated and mapped on access to each individual page within the heap, using the page fault interrupt.
Some implementations of malloc only increase the end of heap pointer (by a call to sbrk or similar) and do not release memory back to the kernel on a free(). Therefore, running malloc(0x10000000); free(); a million times will only cause sbrk to be run once.
The sbrk function in turn might disable interrupts for a very short time whilst it increments the end of heap pointer. Alternatively, on a multi-processor system, it will probably use a spinlock. In any case, interrupts will be disabled for probably less than 100 clock cycles. On a 1 GHz machine, that is insignificant compared with mouse updates at 1000 Hz and shouldn't have any noticable effect.
The disabling of interrupts you are reading about is probably in reference to a physical memory manager, which is entirely separate from the user-space malloc in windows which you are using to test.
Regards,
John.
Some implementations of malloc only increase the end of heap pointer (by a call to sbrk or similar) and do not release memory back to the kernel on a free(). Therefore, running malloc(0x10000000); free(); a million times will only cause sbrk to be run once.
The sbrk function in turn might disable interrupts for a very short time whilst it increments the end of heap pointer. Alternatively, on a multi-processor system, it will probably use a spinlock. In any case, interrupts will be disabled for probably less than 100 clock cycles. On a 1 GHz machine, that is insignificant compared with mouse updates at 1000 Hz and shouldn't have any noticable effect.
The disabling of interrupts you are reading about is probably in reference to a physical memory manager, which is entirely separate from the user-space malloc in windows which you are using to test.
Regards,
John.
Okay, I should modify the program to 'touch' every page by adding 0x1000 to the memory block pointer and putting something in memory or doing 'test [x], 0' in assembly, right? In that way I'll generate page faults and initialize the memory like I wanted?
Anyway, to notice any effect on the mouse cursor, should I create separate threads all doing the 'memory test'?
EDIT: After some thinking, I thought the report rate of the mouse shouldn't even matter, or should it?
EDIT: Here is the source of my new test program:
Anyway, to notice any effect on the mouse cursor, should I create separate threads all doing the 'memory test'?
EDIT: After some thinking, I thought the report rate of the mouse shouldn't even matter, or should it?
EDIT: Here is the source of my new test program:
Code: Select all
#include <stdlib.h>
#define ALLOC_TEST_SIZE 0x10000000
#define PAGE_SIZE 0x1000
int main() {
for(int counter = 0; counter < PAGE_SIZE; ++counter) {
char * pMem = malloc(ALLOC_TEST_SIZE);
for(int subcounter = 0; subcounter < ALLOC_TEST_SIZE; subcounter += PAGE_SIZE) {
pMem[subcounter] = 1;
}
free(pMem);
}
}