Examples

Memory Allocation

Memory allocation is an important topic in any language. In CellSpeak every cell has its own protected memory in the form of the global cell variables and in the form of allocated memory. Memory that is allocated to global cell variables remains available until it is de-allocated - it never goes out of scope, so it can also not be recuperated automatically. Memory that is allocated to non-global variables, goes out of scope at the latest as soon as a message has been handled. Therefore these allocations are done to what is called the scratchpad memory, which is reset each time a new message is being handled. The compiler and run-time keep track of which variable or parameter refer to permanent memory and which not and will do the allocations as required. Release of scratchpad memory is automatic and very fast. A cell that is destroyed automatically returns all the memory it holds - no user actions are required. It is therefore never necessary to do any memory management chores in the destructor of a cell.

06 Memory Allocation.celsrc
use Windows, Math, Strings, Editor, System, Structures

-- We define a record to keep satellite data in a doubly linked list
type DataRecord is DoubleLinked.Record with	
	word32[,] 			Content		-- the data - whatever it is ..
	int 				Nr			-- the nr of the data record
end

-. The main cell: the universe .-

design Universe is

	-- We create a cell for output
	cell Window = create MenuWindow("Memory allocation")
	
	-- We send the output to the system to be used as stdout
	system <- Io.SetStdOut( Window )
	
	-- and we create a planet
	cell Earth = create Planet( "Earth", Window )

end
--------------------------------------------------------------------------
--	The design of a planet 

design Planet(ansi Name, cell Window ) is 
	
	-- Keep the parameters
	keep Name, Window
	
	-- The timer cell
	cell Timer		
	
	-- a record for the details of a satellite
	type SatRecord is record 	
		cell	Cell		-- satellite cell
		ansi 	Name		-- Name of the satellite
		word	Orbit 		-- Orbit time in milliseconds		
	end 
	
	-- The list with satellites
	SatRecord SatList[] = [ 	[null, "TelStar", 7300],
								[null, "Hubble",  17100] ]
	
	-- The constructor
	constructor is 
	
		-- The planet needs a timer
		system <- Service.Get("Timer")

		-- create the satellites in the sat list
		for each Sat in SatList do
			Sat.Cell = create Satellite( Sat.Orbit, Sat.Name, self , Window)		
		end
		
	end
	
	-- Here we get services we requested - we only request a timer ..
	on Service.Provider(ansi ServiceName, cell Timer) do
	
		-- save the timer
		keep Timer
				
		-- Request a timer event for taking a picture 
		Timer <- Subscribe.Interval( 500w, "Interval.Collect")
		
		-- Request a timer event for transmitting pictures 
		Timer <- Subscribe.Interval( 3900w, "Interval.Transmit" )
				
	end
	
	on Service.NoProvider(ansi Name) do
		Window <- print("\nNo provider for this service : [Name]")
	end
	
	-- we use an interface for the timer messages
	interface Interval is
	
		-- Timer message when we want the satellites to collect data
		on Collect( word ms ) do 
			for each Sat in SatList do 	
				Sat.Cell <- CollectData		
			end
		end 
		
		-- Timer message for requesting a transmission
		on Transmit( word ms ) do
			for each Sat in SatList do 
				Sat.Cell <- TransmitData
			end
		end
	
	interface end
	
	-- a transmission from the satellite
	on Transmission(ansi Satellite, ansi TextMessage, word32[,] Content) do

		-- just confir the reception
		Window <- print("\n[Name] received [TextMessage] from [Satellite]")
	end

end 

--------------------------------------------------------------------------
--	The design of a sattelite 

design Satellite( word Orbit, ansi Name, cell Planet, cell Window) is

	-- Keep the parameters..
	keep Orbit, Name, Planet, Window
	
	-- The list of images maintained by the Satellite - we use the 
	-- template for a doubly linked list for that
	use template DoubleLinked.List for DataListType, DataRecord
	
	-- Create a variable of the type declared above
	DataListType DataList
	
	-- Counter
	int Counter = 0
	
	-- keep track of visibility
	bool Visible = true
	
	-- Get the virtual machine manager object
	VirtualMachineManagerClass	VMMgr  = VMMgr.Get()
	
	constructor is
		
		-- Give a message
		Window <- print("\n\t[Name] is in orbit")
		
		-- The satellite needs the timer service
		system <- Service.Get("Timer")
		
	end
	
	on Service.Provider( ansi ServiceName , cell Timer) do
		
		-- The satellite is visible from the planet only half its period 
		Timer <- Subscribe.Interval(  Orbit / 2 , "ToggleVisible")
		
		-- Every 5 sec the satellite shows its memory status
		Timer <- Subscribe.Interval( 5000w, "MemoryStatus" )
		
	end
	
	-- just toggle the visibility when this message is received
	on ToggleVisible(word when) => Visible = not Visible
	
	-- allocate an array of data - in this example the size is fixed, but it does not have to be	
	on CollectData do
	
		-- check
		not Visible ? yield
		
		-- Get new data
		var NewData := DataList.New()
				
		-- Check
		not NewData ? yield
					
		-- Now we create some space for data  - we use setsize for that - the array size is 400x600x4 = 960 Kbyte
		sel NewData.Content[400,600]
			
		-- and set the nr of the image (numbering starts at 0)
		NewData.Nr = Counter +~ 1

		-- some feedback
		Window <- print("\n\t[Name] collects data [NewData.Nr]")
		
		-- add to the list
		DataList.Push(NewData)
		
	end
	
	-- When this message is received the satellite transmits 
	-- all data it has collected back to the planet
	on TransmitData do
	
		DataRecord.ptr Data
		
		-- check
		not Visible ? yield		
			
		-- For every image
		while Data := DataList.Pop() do
	
			-- Transmit the data 
			Planet <- Transmission("[Name]","Data [Data.Nr]", Data.Content)
					
			-- delete the data 
			delete Data.Content
			
			-- and now delete the data record
			delete Data
			
		end
	end
	
	on MemoryStatus( word time ) do 
	
		CellMemoryUsage Usage = [0,0 ]
		
		-- Get the memory usage
		Usage = VMMgr.GetCellMemoryUsage( self )
		
		-- display
		Window <- print("\n*** [ time / 1000 ] *** Memory Status [Name]: [Usage.NrOfItems] items - [Usage.BytesAllocated] bytes.")
	
	end

end -- Satellite