Solar OS API - Articles

Share the world...
We are all The ONE and The ONE is all.


SOLAR OS and Private Variables

Everything is shared

The exact same code is executed for each new instance of an application. Even more all app defined global variables (at compile time) are also shared (curently). This makes thing very simple as all applications can intercomunicate via global variables or memory zones. The API is very fast and easy to call because of this also.

Of course LOCAL variables are not shared since they are created on stack at each code execution.

I have choosen the optimistic side considering that:

Will bring greater benefits than keeping application inside an protective golden cage of fears.

But Every Choice has its consequences...

This choice raises the problem of global variables that are not shared.

For example an application might need a private counter for how many times its client area was clicked. If this variable is simply defined as:

	my_counter	dd	0

And on the ACT_LEFT_UP_CHILD message on application's callback:

My_App_Callback PROC STDCALL
	USES	ebx,ecx,edx,esi,edi
	ARG	@@wnd_handle:DWORD,@@wnd_action:DWORD,@@wnd_param1:DWORD,@@wnd_param2:DWORD

	;--------------------------------------
	; a case based on message/event value
	;--------------------------------------
	.IF [@@wnd_action]==ACT_LEFT_UP_CHILD
		inc	[my_counter]

	.ENDIF

	xor	eax,eax
	ret
ENDP

Then all instances of the application will increment the same variable and this might not be what we intended (but sometime is). Basically we need a method of having variables that are private (specific) to each instance of an application.

A few tested solutions are below:

1)Use the space provided inside window structure itself

If the size of variables is smaller then use the space proviced in sol_window structure. This works for approximative 32 dwords and is the fastest and most simple solution. As a new window structure is alocated at each window creation this space is private to each instance.

The Small Sample application uses this method to store the click counter in window_data01.

2)Dynamically alocate memory and store pointer in window private structure

If the size of your variables is greater or can grow greater then you can dynamically allocate memory on the application initialization phase and store pointer to this private data zones in the window_data01... variables.

The memory alocated there should be dealocated on ACT_CLOSE_CHILD message.

HDD FAT32 explorer and DebugView applications use this method.

A few other theoretical solutions:

3)Use relocation info in your application

One Solution is to add relocation to your application and in the application init phase copy the base code to another location and fix the relocations yourself.

Disadvantages:

4)Make new selectors and callgates

Create a new set of selectors for the application and make it believe it will run at the same address all the time. This avoids relocations but since the application uses different selectors than the kernel, a new method of calling the API is required.

This will also need Callgates for calling all and any of the OS API/functions.

This looks like a good idea for a development environment because if this application has a crash, theoretically it will not crash the whole system also. Because of the cooperative nature of SOLAR OS multitasking a watchdog of some kind shoulf be installed on IRQ-0 also...

Disadvantages:


Side Note: This is the opposite situation from "other" operating systems where global variables are not shared and we have the problem of sharing data for interprocess comunications.
In SOLAR OS we only have a problem when we are not sharing :D

Sample code:

This sample code ilustrates how an application could define and initialize private variables.


;------------------------------------------
;define this structure for easy acces to
;private variables
;------------------------------------------
My_App_Private_Vars STRUC
	my_strings_count	dword	?
	my_strings_mem_handle	dword	?
	my_strings_lp		dword	?
ENDS
...
	;init this application instance

	;---------------------------------------------
	; get access to windows's private data
	; since we need each instance
	; to have it's own variables
	;---------------------------------------------
	Call	API_Window_Get_Addr_Private STDCALL,[@@wnd_handle]
	mov	edi,eax
	mov	[edi.my_strings_count],-1	;no strings
	;-----------------------------
	; alloc some memory
	;-----------------------------
	Call	API_Memory_Alocate,1		;get 4k for start
	mov	[edi.my_strings_mem_handle],eax	;store handle as we need it for Release
	mov	[edi.my_strings_lp],esi		;store pointer

...