Amiga-Development

Please login or register.

Login with username, password and session length
Advanced search  

News:

Created for developers of all Amiga camps

Pages: [1] 2

Author Topic: Can VBCC make Pure Residentable code easily?  (Read 7318 times)

0 Members and 1 Guest are viewing this topic.

Team Chaos Leader

  • Administrator
  • Sr. Member
  • *****
  • Posts: 484
  • JC + Asm Coder
    • View Profile
Can VBCC make Pure Residentable code easily?
« on: June 19, 2013, 09:55:39 AM »

I searched the manual for "pure" or "resident" and neither word was found!

Sometimes I like to compile pure cli commands in an ez way like with my SASC.  Pure code r0xx0rz! :)
Logged

Matt Hey

  • Sr. Member
  • ****
  • Posts: 293
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #1 on: June 19, 2013, 08:48:10 PM »

I searched the manual for "pure" or "resident" and neither word was found!

Sometimes I like to compile pure cli commands in an ez way like with my SASC.  Pure code r0xx0rz! :)

It depends on what your definition of "ez" is. I don't know of anything currently which makes pure executables "ez". Pure code (including libraries) generally requires the programmer to follow certain guidelines like not using shared global variables. Does SAS/C have a mode that warns you when you write something that is bad or give separate global variable space to apps?
« Last Edit: June 20, 2013, 02:28:16 AM by Matt Hey »
Logged

SamuraiCrow

  • Administrator
  • Sr. Member
  • *****
  • Gender: Male
  • Posts: 380
  • Coolness is compiled
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #2 on: June 19, 2013, 11:13:12 PM »

I've heard it's possible to write shared libraries with VBCC.  I'd imagine it would be similarly possible to write reentrant code for executables as well.  The only thing is that the heap is local to every instance of the program.  Is that what you're trying to say, Matt Hey?
Logged

Matt Hey

  • Sr. Member
  • ****
  • Posts: 293
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #3 on: June 20, 2013, 02:45:34 AM »

I've heard it's possible to write shared libraries with VBCC.  I'd imagine it would be similarly possible to write reentrant code for executables as well.  The only thing is that the heap is local to every instance of the program.  Is that what you're trying to say, Matt Hey?

It depends on what the definition of heap is on the Amiga. On Unix/Linux, the heap is well defined and a commonly used term but a little different than any memory areas on the Amiga. On the Amiga, each process/task gets it's own stack which is a safe place to store data for pure/re-entrant code. Local data is allocated on this stack so it is safe. Global data is usually placed in a hunk's data or bss memory which is not normally a safe place as it's shared. I believe there is some code on Aminet that shows how to make a shared library base that works with several compilers.

Here is some old C= documentation that describes how to write re-entrant code in C:

http://www.heywheel.com/matthey/Amiga/WritingReentrantC.txt

Vbcc's minstart.asm should minimize the amount of unusable resources opened when writing a re-entrant program. A re-entrant C program of a few hundred bytes is possible.
« Last Edit: June 20, 2013, 03:02:12 AM by Matt Hey »
Logged

Team Chaos Leader

  • Administrator
  • Sr. Member
  • *****
  • Posts: 484
  • JC + Asm Coder
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #4 on: June 20, 2013, 11:28:36 AM »

With SASC you just write your code as you normally would.  That means you get to use Global variables as usual.  You don't have to do anything weird.  In other words: "Its dead ez".*

When you link your program you link with cres.o as your startup code and voila!  Your program is pure and reentrant.

I look forward to this feature appearing in a future vbcc :)

*Technically you have to compile with DATA=NEAR which you should always do anyway unless you have a giant program, of course.
« Last Edit: June 20, 2013, 12:00:38 PM by Team Chaos Leader »
Logged

Team Chaos Leader

  • Administrator
  • Sr. Member
  • *****
  • Posts: 484
  • JC + Asm Coder
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #5 on: June 20, 2013, 12:15:22 PM »

Here is some old C= documentation that describes how to write re-entrant code in C:

http://www.heywheel.com/matthey/Amiga/WritingReentrantC.txt
I read code using that technique many many years ago and it scared me away from writing reentrant code.

C is already such an ugly language.

Being forced to make it even uglier with all those v-> in front of every global var.  ARGH!

Nobody wants to write
v->x=v->a+v->b-v->c
instead of
x=a+b-c

Its just 12 extra chars of ugliness.

With SASC you can write code the normal way.
Logged

SamuraiCrow

  • Administrator
  • Sr. Member
  • *****
  • Gender: Male
  • Posts: 380
  • Coolness is compiled
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #6 on: June 20, 2013, 10:14:32 PM »

It's been years since I've emailed Volker Barthelman with ideas for VBCC.  When writing reentrant code in SAS/C or other languages, it's commonplace to have the heap pointer pinned into A4 the same way as the library base is pinned into A6.  A5 is used by the debugger to identify the base of the current stack frame and is freed up when using code that is not in debugger mode.  Are you still in contact with Volker, Matt?
Logged

Matt Hey

  • Sr. Member
  • ****
  • Posts: 293
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #7 on: June 20, 2013, 11:05:25 PM »

It's been years since I've emailed Volker Barthelman with ideas for VBCC.  When writing reentrant code in SAS/C or other languages, it's commonplace to have the heap pointer pinned into A4 the same way as the library base is pinned into A6.  A5 is used by the debugger to identify the base of the current stack frame and is freed up when using code that is not in debugger mode.  Are you still in contact with Volker, Matt?

I have never contacted Volker. I have always gone through Frank Wille. GCC default:

A6 - library base
A5 - stack frame pointer (on stack)
A4 - small data base pointer if used

Vbcc currently defaults to:

A6 - library base
A4 - small data base pointer if used

Vbcc currently does not use a stack frame pointer by default on the 68k. It allocates a frame on the stack with the stack pointer (SP/A7). This is real code vbbc generated:

Code: [Select]
_get_microsecs:
   lea (-$14,sp),sp  ;allocate stack storage (stack frame) without LINK or A5
   movem.l d2-d3/a2/a6,-(sp)
   lea ($10,sp),a2
   movea.l _DOSBase,a6
   lea ($18,sp),a0
   move.l a0,d1
   jsr (-$c0,a6)
   ...
   lea ($10,sp),sp  ;deallocate parameters from calling a function
   move.l ($14,sp),d3
   moveq #0,d2
   add.l d3,d1
   addx.l d2,d0
   movem.l (sp)+,d2-d3/a2/a6
   lea ($14,sp),sp  ;free stack storage without UNLNK
   rts

I think it would be better to save the registers 1st like this:

Code: [Select]
__get_microsecs:
   movem.l d2-d3/a2/a6,-(sp)
   lea (-$14,sp),sp  ;allocate stack storage (stack frame) without LINK or A5
   lea (0,sp),a2  ;optimizes to move.l sp,a2 saving 2 bytes, 68060 can do in parallel
   movea.l _DOSBase,a6
   lea ($8,sp),a0
   move.l a0,d1
   jsr (-$c0,a6)
   ...
;   lea ($10,sp),sp  ;delay deallocate parameters from calling a function saves 4 bytes
   move.l ($14,sp),d3
   moveq #0,d2
   add.l d3,d1
   addx.l d2,d0
   lea ($24,sp),sp  ;free stack storage without UNLNK, 68060 can sometimes do in parallel
   movem.l (sp)+,d2-d3/a2/a6
   rts

I think this will generate better code on average. I haven't suggested it yet. Do you see any downside? What does the SAS/C code do in reentrant mode?

P.S. Your name is still mentioned in the vbcc manual as a contributor with some other Amiga legends ;).
« Last Edit: June 20, 2013, 11:07:40 PM by Matt Hey »
Logged

SamuraiCrow

  • Administrator
  • Sr. Member
  • *****
  • Gender: Male
  • Posts: 380
  • Coolness is compiled
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #8 on: June 21, 2013, 10:38:53 AM »

@Matt Hey

I think all that is necessary to make the code pure and residentable is to allocate the heap manually using AllocMem in the startup code (putting the pointer in A4), then free it in the shutdown code using FreeMem.  This alleviates the fact that LoadSeg won't occur when the code hunk is already in memory.

Also, the only reason for using the frame pointer that I know of is to work with GDB.  A better debugger might not require the frame pointer in A5 to be able to work.  What debugger does VBCC use?  Did you compile the code with debugger code enabled?

Also, I think you've got a good suggestion with the rearranging so the used registers go to the stack before the frame is allocated.  But shouldn't the code look more like this?
Code: [Select]
__get_microsecs:
   movem.l d2-d3/a2/a6,-(sp)
   lea (-$14,sp),sp  ;allocate stack storage (stack frame) without LINK or A5
   lea (0,sp),a2  ;optimizes to move.l sp,a2 saving 2 bytes, 68060 can do in parallel
   movea.l _DOSBase,a6
   lea ($8,sp),a0
   move.l a0,d1
   jsr (-$c0,a6)
   ...
;   lea ($10,sp),sp  ;delay deallocate parameters from calling a function saves 4 bytes
;   move.l ($14,sp),d3  ;wrong offset
   move.l ($24,sp),d3
   moveq #0,d2
   add.l d3,d1
   addx.l d2,d0
   lea ($24,sp),sp  ;free stack storage without UNLNK, 68060 can sometimes do in parallel
   movem.l (sp)+,d2-d3/a2/a6
   rts
« Last Edit: June 21, 2013, 11:13:40 AM by SamuraiCrow »
Logged

Matt Hey

  • Sr. Member
  • ****
  • Posts: 293
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #9 on: June 21, 2013, 04:19:55 PM »

I think all that is necessary to make the code pure and residentable is to allocate the heap manually using AllocMem in the startup code (putting the pointer in A4), then free it in the shutdown code using FreeMem.  This alleviates the fact that LoadSeg won't occur when the code hunk is already in memory.

That makes sense and sounds easy enough. Each task/process started would allocate it's own global/static variable space with a dynamic memory allocation instead of using a hunk. Treat the allocated memory as a small data hunk with A4 pointing to the middle and we have up to 65536 bytes of storage for each task/process of the re-entrant program.

Also, the only reason for using the frame pointer that I know of is to work with GDB.  A better debugger might not require the frame pointer in A5 to be able to work.  What debugger does VBCC use?  Did you compile the code with debugger code enabled?

Vbcc does not have a debugger included. It can output LINEDEBUG or DWARF2 with symbol debugging information. BDebug (Barfly) and CodeProbe (SAS/C) work well enough including source level debugging with LINEDEBUG debugging information. They don't have a problem without the A5 stack frame pointer which doesn't matter for the LINEDEBUG source level debugging. Someone used the A5 stack frames may prefer them visually but the difference is pretty minor IMO. A5 stack frames can be turned on with a command line switch.

Also, I think you've got a good suggestion with the rearranging so the used registers go to the stack before the frame is allocated.  But shouldn't the code look more like this?

My example is a little confusing because the MOVEM.L register saving is $10=16 bytes as well as the function call parameter size which I didn't show all of. I was trying to show that the parameter stack popping of the last function call could be delayed and combined with the SP/A7 frame pointer deallocation saving a 4 byte instruction in this case. The compiler can keep track of all this information although I think saving/restoring the registers with MOVEM.L first/last is more readable for a human.
« Last Edit: June 21, 2013, 04:25:55 PM by Matt Hey »
Logged

Team Chaos Leader

  • Administrator
  • Sr. Member
  • *****
  • Posts: 484
  • JC + Asm Coder
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #10 on: June 22, 2013, 12:56:57 AM »

Why does SASC limit me to only using DATA=NEAR in a PURE Residentable program?

Why can't I read and write my own vars in the FAR data section?

I am only allowed to READ data in the FAR data section.  Well a PURE program can always READ data from anywhere anytime.

Logged

Matt Hey

  • Sr. Member
  • ****
  • Posts: 293
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #11 on: June 22, 2013, 03:59:11 AM »

Why does SASC limit me to only using DATA=NEAR in a PURE Residentable program?

Because the allocated memory of each pure/re-entrant task/process is treated in the same way as a small data hunk with A4 pointing into this global storage. The difference for the programmer is that the pure/re-entrant static/global variables are only for the current task/process of a pure program instead of shared between them which can cause problems.

Why can't I read and write my own vars in the FAR data section?

I am only allowed to READ data in the FAR data section.  Well a PURE program can always READ data from anywhere anytime.

Sharing data that can be modified between 2 or more running tasks/processes is very tricky. It can be done only with caution. Semaphores, atomic writes, CAS/TAS instructions, etc. are generally needed.
Logged

Team Chaos Leader

  • Administrator
  • Sr. Member
  • *****
  • Posts: 484
  • JC + Asm Coder
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #12 on: June 22, 2013, 11:39:35 AM »

I am not a compiler wizard like u so I don't understand why the compiler can't do an AllocVec() to hold all the far data in the same manner as the near data?
Logged

SamuraiCrow

  • Administrator
  • Sr. Member
  • *****
  • Gender: Male
  • Posts: 380
  • Coolness is compiled
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #13 on: June 22, 2013, 11:51:21 AM »

The Far data model supports multiple data segments in memory at once.  If you really really want to try making a big program reentrant, you'll have to research the use of the slow but steady 32-bit offset from a pointer on a 68020+ because that will lift the size of the data segment to 2 or even 4 gigs of RAM if the pointer is center justified in the segment.

The large code model will be more difficult as well since it supports loading of multiple code segments.  There will have to be relocation code for each jump that won't work in order for reentrancy.  If you want to make a huge program work, 32-bit relative branches are there for you to make a bigger code segment than 64k.  (32-bit relative branches are slower than absolute jump instructions.)
Logged

Team Chaos Leader

  • Administrator
  • Sr. Member
  • *****
  • Posts: 484
  • JC + Asm Coder
    • View Profile
Re: Can VBCC make Pure Residentable code easily?
« Reply #14 on: June 24, 2013, 12:26:21 PM »

Note to self:

If I want to make a giant program be pure and residentable using any C compiler, I will need to either:

A: have __stack=4000000L; // 4 million bytes stack
Then have my giant struct with all my global vars on the stack inside Main()

or
B: Var=malloc(sizeof(GlobalVarStruct)); // 3.5MB GlobalVar struct

And maybe do a
#define V Var->

Cause there is no way in hell I am writing -> millions of times.
Logged
Pages: [1] 2