iPAQ WinCE memory problem workaround

Craig Latta Craig.Latta at NetJam.ORG
Sat Jun 23 00:01:30 UTC 2001


	Yay!

	Apparently my attempts to write large buffers to main-memory files took
too much CPU away from the WinCE file compressor, causing it to use more
file space than I had. (And of course the compressor's file space usage
isn't taken into account when you ask the system how much available file
space there is, either because it's "hidden" or because by the time you
can ask it's no longer in use.) This would lead to the system reporting
ample available file space before and after a write (and reporting the
correct size for the file to which I was writing), but failing the write
with a "file space full" error.

	Not knowing how to turn off the compressor, I rewrote
sqImageFileWrite() to write in passes, sleeping a bit between each one.
Now I can snapshot.

	So now I have a small handheld system which runs Smalltalk with the
same bits I use on any other machine (no shrinking, full sources). I've
been waiting for this for quite some time. :)  Of course, I'm still
interested in getting iPAQ Linux Squeak working (I need to get Linux to
see all 64 on my machine), so I can have sources for the entire system,
but this will do quite nicely in the meantime.

	My version of sqImageFileWrite() is below.


-C

***

int sqImageFileWrite(void *elements, int elementSize, int numberToWrite,
sqImageFile file) {
	DWORD				numberWrittenLastPass;
	DWORD				numberWrittenSoFar = 0;
	int					result, error, pass;
	int					numberOfPasses = 10;
	int					bytesPerPass = (numberToWrite * elementSize) / numberOfPasses;
	DWORD				fileSize;
	STORE_INFORMATION	filesystemInfo;


#ifdef _WIN32_WCE
	/*
	 * Apparently, writing blocks larger than about 13M all at once
	 * starves the WinCE compressor, leading to "filesystem full" errors
	 * (on a 206MHz 64M iPAQ, anyway). So write large blocks in passes,
	 * sleeping a bit between each one.
	 */

	if ((numberToWrite * elementSize) < 10) {
		WriteFile(
			(HANDLE) (file - 1),
			(LPCVOID) ((unsigned char *) elements + numberWrittenSoFar),
			(DWORD) ((numberToWrite * elementSize) - numberWrittenSoFar),
			(LPDWORD) &numberWrittenLastPass,
			NULL);}
	else {
		for (pass = 0; pass < (numberOfPasses - 1); pass++) {

			/* a useful place to break and inspect if things aren't working... */
			GetStoreInformation(&filesystemInfo);

			result = WriteFile(
						(HANDLE) (file - 1),
						(LPCVOID) ((unsigned char *) elements + numberWrittenSoFar),
						(DWORD) bytesPerPass,
						(LPDWORD) &numberWrittenLastPass,
						NULL);
			if (result == 0) {
				GetStoreInformation(&filesystemInfo);
				fileSize = GetFileSize(
							(HANDLE) (file - 1),
							NULL);
				error = GetLastError();
				return numberWrittenSoFar;}

			numberWrittenSoFar += numberWrittenLastPass;
			Sleep((DWORD) 50);}

		/* a useful place to break and inspect if things aren't working... */
		GetStoreInformation(&filesystemInfo);

		result = WriteFile(
					(HANDLE) (file - 1),
					(LPCVOID) ((unsigned char *) elements + numberWrittenSoFar),
					(DWORD) ((numberToWrite * elementSize) - numberWrittenSoFar),
					(LPDWORD) &numberWrittenLastPass,
					NULL);
		if (result == 0) {
			GetStoreInformation(&filesystemInfo);
			fileSize = GetFileSize(
						(HANDLE) (file - 1),
						NULL);
			error = GetLastError();
			return numberWrittenSoFar;}}

	return numberToWrite;
#else
	WriteFile(
		(HANDLE) (file - 1),
		(LPCVOID) elements,
		(DWORD) numberToWrite * elementSize,
		(LPDWORD) &numberWrittenLastPass,
		NULL);

	return (numberWrittenLastPass / elementSize);
#endif
}

--
Craig Latta
composer and computer scientist
craig.latta at netjam.org
www.netjam.org
crl at watson.ibm.com
Smalltalkers do: [:it | All with: Class, (And love: it)]





More information about the Squeak-dev mailing list