From: Harold Roman Newsgroups: comp.os.msdos.djgpp Subject: Re: UNchain_protected_mode_interrupt_vector? Date: Thu, 14 Jan 1999 09:44:23 -0500 Organization: GigaNet Inc. Lines: 91 Message-ID: <369E02C7.A7206CB1@giganet.com> References: NNTP-Posting-Host: pepsi.giganet.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Mailer: Mozilla 4.04 [en] (X11; U; HP-UX B.10.20 9000/780) To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Eli Zaretskii replied: > > I believe that the "chain" > > call creates a wrapper for the new interrupt handler. And, I > > believe that this wrapper is not free'd when the "set" call > > is used to unhook the interrpt handler. > > The wrapper is allocated by a call to _go32_dpmi_allocate_iret_wrapper, > not by the function that chains. If you don't need the wrapper > anymore, you should deallocate it by calling > _go32_dpmi_free_iret_wrapper. The documentation for the _go323_dpmi_chain_protected_mode_interrupt_vector function says "This function is used to chain a protected mode interrupt. It will build a suitable wrapper that will call your function and then jump to the next handler." The documentation for the _go32_dpmi_set_protected_mode_interrupt_vector function says "The following should be noted: ... This function will not wrap the handler for you. The _go32_dpmi_allocate_iret_wrapper and _go32_dpmi_chain_protected_mode_interrupt_vector functions can wrap your function if you want." So it seems that the "chain" function creates the wrapper. On the other hand it seems the "set" function does not create the wrapper and requires use of the _go32_dpmi_allocate_iret_wrapper and the _go32_dpmi_free_iret_wrapper functions. How would I use the "free_iret" function with the "chain" function? I found the following example for the "set" function: _go32_dpmi_seginfo info; info.pm_offset = my_handler; _go32_dpmi_allocate_iret_wrapper(&info); _go32_dpmi_set_protected_mode_interrupt_handler(0x75, &info); ... _go32_dpmi_free_iret_wrapper(&info); This makes the call to the "set" function with the seginfo for an allocated wrapper, and then frees the wrapper when done. I found the folowing for the "chain" function: _go32_dpmi_seginfo old_handler, new_handler; _go32_dpmi_get_protected_mode_interrupt_vector(8, &old_handler); new_handler.pm_offset = (int)tic_handler; new_handler.pm_selector = _go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(8, &new_handler); ... _go32_dpmi_set_protected_mode_interrupt_vector(8, &old_handler); This makes the call to the "chain" function with the seginfo for the new handler and no wrapper is explicitly created. Are you suggesting that the two should be combined? that I should create a wrapper for the handler then call the "chain" function with the seginfo of the wrapper? It seems that I would be double wrapping the handler if the "chain" function also creates a wrapper. > > I believe this is > > causing a memory leak that eventually kills my app. > > I find this hard to believe. Memory allocated for the wrapper is less > than 100 bytes, plus a 32KB stack that is only allocated once (i.e. it > is shared by all interrupt handlers). So, unless you allocate > thousands of wrappers, I don't see how this can kill your application. Well, it is a strange application for sure :). It is a test program that exercises and tests a PCI card. It has a main loop that calls sub-tests that test the card in different ways. Each sub-test will register it's own interrupt handlers, and then de-register them. So, in a long test run, thousands of wrappers may be allocated. I observed that memory is disapearing faster than a 100 bytes at a time. I put calls to _go32_dpmi_remaining_virtual_memory around the "chain" function and I observed that some times no memory is consumed, other times 64KB is lost. (Perhaps this really a memory fragmentation problem?)