English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System

 
 
Thread Tools
Old 04 July 2024, 10:37   #21
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,555
I didn't read everything, so just as a side note: I think that Small Data is generally a bad choice for a shared library. You have to save and restore the Small Data base pointer (to the __MERGED section in A4) in every single library function and callback (using
__saveds
). Additionally you steal register A4 from the code generator. This is quite some waste as a good library shouldn't have any static data sections at all. Best practice is to store everything in the library base structure, which also provides you fast base-relative addressing (with A4 still available).
I wouldn't be surprised if this also solves your static variable problems.

Edit: And constant data, like your TagItem structure, should get a
const
attribute, so the compiler can place it into the code section for PC-relative addressing.

Last edited by phx; 04 July 2024 at 10:44. Reason: cost
phx is offline  
Old 04 July 2024, 11:33   #22
hceline
Registered User
 
Join Date: Nov 2009
Location: Top of the world
Posts: 181
Quote:
Originally Posted by Thomas Richter View Post
This is an indication that the base pointer addressing the __MERGED segment is not setup correctly in the library function that uses the static variable. Is there possibly a __saveds missing?
I tried adding __saveds to new_app_entry(), who the variable is local to, earlier. After finding that was one of few differences I could see between that, and the only other example I could find of a function-local static variable in the library code (See earlier post).

To be on the safe side, I tested again now.
It does not seem to make any difference.

The library was at 084c08a4.
And the variable in question at 0811DA9A again.

I also checked that all library functions that call new_app_entry() has __saveds, and they do.
They are all in the same .c file, and are the previously mentioned L_WB_AddAppMenuItem(), L_WB_AddAppIcon() and L_WB_AddAppWindow().

Attaching disassembly of the file in question with __saveds added to new_app_entry().

Quote:
Originally Posted by phx View Post
I didn't read everything, so just as a side note: I think that Small Data is generally a bad choice for a shared library. You have to save and restore the Small Data base pointer (to the __MERGED section in A4) in every single library function and callback (using
__saveds
). Additionally you steal register A4 from the code generator. This is quite some waste as a good library shouldn't have any static data sections at all.
You might be right about that.
But as I understand it there is no way to avoid using __saveds when making libraries the "SAS/C way", because it uses the the presence of the combination of __asm and __saveds to identify the functions that should be exported by the library.


Quote:
Originally Posted by phx View Post
Best practice is to store everything in the library base structure, which also provides you fast base-relative addressing (with A4 still available).
I wouldn't be surprised if this also solves your static variable problems.
Also, since you did not read everything; I did approximately that* to solve it to begin with. This thread is me trying to solve the mystery of why this variable behaved like this in the first place. Mostly to learn from it.

*Edit: For this variable only, not everything. And I must admit that I did not trace back the original allocation of the struct I put it in. It might be a allocated with AllocVec().

Quote:
Originally Posted by phx View Post
Edit: And constant data, like your TagItem structure, should get a
const
attribute, so the compiler can place it into the code section for PC-relative addressing.
Yea, I do believe my first task after this is to go trough the library code and add const to maybe all the static variables. While I found only on function-local example, there where lots of similar examples outside function scope.
Attached Files
File Type: zip wb_savedstest_disassembly.zip (36.7 KB, 3 views)

Last edited by hceline; 04 July 2024 at 15:06. Reason: Correction and clarification of previous edit
hceline is offline  
Old 04 July 2024, 19:51   #23
hceline
Registered User
 
Join Date: Nov 2009
Location: Top of the world
Posts: 181
To know for sure the disassembly matched the code I was running I put a MuForce hit after the first KPrinF() in both L_AddScrollBars() and new_app_entry() like this:
Code:
    {
        volatile char *a = 0;
        *a = 0;
    }
I found that the code that is run matches the disassembly. And that this is the right diagnostic even with __saveds:
Quote:
Originally Posted by Thomas Richter View Post
This is an indication that the base pointer addressing the __MERGED segment is not setup correctly in the library function that uses the static variable.
The library was at 08fa568c during this test.
And A4 is 08FA56BC in the hit from L_AddScrollBars(), and 08394EC4 in the hit from new_app_entry().
I attached two files with the first hit from each function.


I am beginning to get an idea of what is happening, even if I do not understand exactly why.
I would have realized sooner if I had just looked at the top of the .c file in question earlier.
This is one of the "different .c files", as I've called them in my head in lacking the means to put a more descriptive term on it.

I encountered them when I was adding library based resource tracking to the code-base. They are usually CreateNewProc() or LoadSeg() but some seem unrelated to these functions (Or maybe I just have not realized the connection yet).
Code in these files would fail to find the library base for my resource tracking library even if it was available everywhere SysBase or ExecBase was.
And I quickly discovered that all these files start with something like:
Code:
#define UtilityBase    (wb_data->utility_base)
#define ExecLib        ((struct ExecBase *)*((ULONG *)4))
And I would have to add equivalents for my resource tracking library base, where used.

I have just now come to realize that I can refer to them as the ".c files that are unable to get correct A4 value" or "where __saveds does not really work".

I get a feeling that this issue might be very specifically tied to uncommon things this code-base does.
And I do not expect other people to dig trough the whole library code to find an explanation for me.
So unless someone immediately recognizes this off the top of their head, from my half-explanation, I'll declare the quest for at truth of the immortal variable over.

Yet again, thank you everyone for the help.
Attached Files
File Type: txt new_app_entry_MuForce_Hit.txt (13.1 KB, 3 views)
File Type: txt L_AddScrollBars_MuForce_Hit.txt (11.3 KB, 2 views)
hceline is offline  
Old 08 July 2024, 10:17   #24
hceline
Registered User
 
Join Date: Nov 2009
Location: Top of the world
Posts: 181
A few corrections to my statements in this thread. Replying to myself here, because it feels wrong to edit the original posts after such a long time.

Quote:
Originally Posted by hceline View Post
I use SAS/C.
You are right, it uses its own _LibInit(), _LibOpen(), _LibClose() and _LibExpunge()
Quote:
Originally Posted by hceline View Post
In place of lib:libinit.o it uses its own init.o.
But I do not understand why, as I can not see any difference from the original except the removing of code pertaining to Devices and libraries with separate data section for each opener.
After discovering that lib:libinit.o was replaced in my debug build only. I remembered that this change was made by me, to get debug symbols in it.

Quote:
Originally Posted by hceline View Post
But as I understand it there is no way to avoid using __saveds when making libraries the "SAS/C way", because it uses the the presence of the combination of __asm and __saveds to identify the functions that should be exported by the library.
This is apparently not how it works. As there are several functions in the library in question that are declared with __asm only, but are clearly exported by the library.


Quote:
Originally Posted by hceline View Post
Not related but since you mention it, I've been wondering. Does KPrintF() from debug.lib break Forbid()?
I've been thinking, it is a IO operation and all IO operations can break Forbid(), so yes?
I seem to have forgot that the statement is usually/always "dos.library I/O functions" not "I/O functions".
Anyway I finally found a statement, in "The Guru Book", to the fact that none of the (d)debug.lib functions break Forbid().
hceline is offline  
Old 08 July 2024, 21:04   #25
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,355
Quote:
Originally Posted by hceline View Post
I seem to have forgot that the statement is usually/always "dos.library I/O functions" not "I/O functions".
Anyway I finally found a statement, in "The Guru Book", to the fact that none of the (d)debug.lib functions break Forbid().
They don't, indeed. Actually, they would be not very valuable if they would. Even if they are patched by Sashimi or the syslog module of 3.2.
Thomas Richter is offline  
Old 09 July 2024, 06:32   #26
hceline
Registered User
 
Join Date: Nov 2009
Location: Top of the world
Posts: 181
Quote:
Originally Posted by Thomas Richter View Post
They don't, indeed. Actually, they would be not very valuable if they would. Even if they are patched by Sashimi or the syslog module of 3.2.
Yea, it sounds logical when you put it that way.
Thank you for confirming this.

In other news, I tried moving on to other things, but my mind would not let this issue go. And I kept coming up with possible explanations as to the "why" of it.
And finally it dawned on me, that this might be due to SetFunction() anyway, albeit indirectly.

So I put back the static variable declaration, the KPrintF() line and the MuForce hit for one final test, to check the contents of A6.
And upon every call to the function i question A6 contained the base address for workbench.library.
Case closed (for real this time).
hceline is offline  
Old 09 July 2024, 08:42   #27
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 193
Quote:
Originally Posted by hceline View Post
The smallest memory loss ...

Some memory loss you see may be fake news. The OS for example may cache cliprects (used to divide layers/windows into visible/hidden parts and for user installed clipping regions). So for example opening and closing a window immediately after may seem like it leaks memory, but it doesn't. It may just have cached cliprects in other windows/layers behind which were created when their visible/hidden areas changed because of your window hiding them (partly). Do check at least twice and compare last 2 results.



avail flush
prog
avail flush
prog
avail flush


Also the console/shell may cache/buffer things for stuff like scrollback if you are using one that features this.
aros-sg is offline  
Old 09 July 2024, 10:01   #28
hceline
Registered User
 
Join Date: Nov 2009
Location: Top of the world
Posts: 181
Quote:
Originally Posted by aros-sg View Post
Some memory loss you see may be fake news. The OS for example may cache cliprects (used to divide layers/windows into visible/hidden parts and for user installed clipping regions). So for example opening and closing a window immediately after may seem like it leaks memory, but it doesn't. It may just have cached cliprects in other windows/layers behind which were created when their visible/hidden areas changed because of your window hiding them (partly). Do check at least twice and compare last 2 results.
Thank you for bringing this to my attention.
Does this also hold true when the windows I open is on a screen that I open and close between the measurements?



Quote:
Originally Posted by aros-sg View Post
avail flush
prog
avail flush
prog
avail flush
As a matter of fact, if I do what you describe, there is usually* no loss between the state after the second and third FLUSH.
So this might account for some, if not all, of the loss I am seeing.

*Apparently randomly there would still be a loss. And if I continue repeating the steps, it would sometimes lose a little more, sometimes not.
The loss has been varying between around 1k to around at-least 6k of fast ram, and 0 to around 2k of chip.

But then again this was while the library was writhing to memory it did not own.

Quote:
Originally Posted by aros-sg View Post
Also the console/shell may cache/buffer things for stuff like scrollback if you are using one that features this.
This I've been bitten by before. That is how I learned to use MemLeakZ in place of Avail FLUSH.
hceline is offline  
Old 10 July 2024, 12:29   #29
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,355
I suggest:

http://aminet.net/dev/debug/MemLog.lha

which can restrict the analysis to a particular task or process and will also provide you the symbols or functions within which the memory was allocated if SegTracker is also installed (recommended).
Thomas Richter is offline  
Old 10 July 2024, 14:55   #30
hceline
Registered User
 
Join Date: Nov 2009
Location: Top of the world
Posts: 181
Quote:
Originally Posted by hceline View Post
But then again this was while the library was writhing to memory it did not own.
I really should have ran new tests with the non-memory-trashing version, before answering that last post.

But the result is not very different from before.
After a few tests it seems the fast ram losses are a little smaller.
And It seems the the apparent random losses when continuing to repeat the steps are fewer and and require more repetitions to trigger.

Quote:
Originally Posted by Thomas Richter View Post
I suggest:

http://aminet.net/dev/debug/MemLog.lha

which can restrict the analysis to a particular task or process and will also provide you the symbols or functions within which the memory was allocated if SegTracker is also installed (recommended).
Tried it, and all the other resource trackers I could find on Aminet.
None of them are really usable on this code-base due to it's multi-library design, and it's heavy reliance on CreateNewProc() and friends.
I've had to roll my own by converting one of the link-library based ones to a real Amiga .library.
It works by redefining the functions to itself like:
Code:
#define Open(file,mode)         __rtl_Open(file,mode,__FILE__,__LINE__)
It is limited by my knowledge of which functions I should track, and my inability to redefine functions that take "struct TagItem *, ..." as parameters* without ugly workarounds.
And it clearly can not account for memory the OS uses on my behalf.

*As I understand this would require C99.

Last edited by hceline; 10 July 2024 at 14:57. Reason: Forgot the [CODE] tag.
hceline is offline  
Old 12 July 2024, 21:29   #31
hceline
Registered User
 
Join Date: Nov 2009
Location: Top of the world
Posts: 181
Quote:
Originally Posted by Thomas Richter View Post
I suggest:

http://aminet.net/dev/debug/MemLog.lha

which can restrict the analysis to a particular task or process and will also provide you the symbols or functions within which the memory was allocated if SegTracker is also installed (recommended).
Quote:
Originally Posted by hceline View Post
Tried it, and all the other resource trackers I could find on Aminet.
Correction, I tested most of them. Some I just read the documentation and concluded that they would not work.
I can not guarantee I tried yours, but I believe I did as I had apparently copied it to C: on my test setup.
Anyway, to make sure I did not misstate the facts again, I tried it without supplying TASKNAME or MODULE on the commandline now.
And with a memory loss of 1744 bytes, the resulting file, where I redirected the output, was 747666 lines and ended with:
Code:
0x00983E02 bytes required in total, 0x005F92C5 not yet released.
This tool would be helpful in this situation if it had a commandline switch to to not care what task/process did the allocation/de-allocation when called without TASKNAME.
And even more helpful if it was wired up to make use of the nice new ability you added to segtracker of locating functions and line-numbers from debug hunks.
EDIT: I meant to write "function- and source file-names"

Last edited by hceline; 12 July 2024 at 22:00.
hceline is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Did LEFT-Amiga M survive? nolunchman Amiga scene 6 12 November 2018 05:25
Static adres jarre Coders. General 5 24 September 2018 11:59
Helping Amiga love survive elronnightshade support.Hardware 19 08 June 2010 15:21
Help me survive in DM - Chaos Strikes Back NewDeli support.Games 18 19 August 2009 16:07

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 21:34.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.13890 seconds with 14 queries