Path: news.cs.au.dk!news.net.uni-c.dk!howland.erols.net!news3.bellglobal.com!news1.bellglobal.com!news.uunet.ca!not-for-mail From: Karl Waclawek Newsgroups: comp.lang.beta Subject: Garbage Collector vs. cStruct, ExternalRecord, @@ Date: Sat, 23 Jan 1999 11:27:55 -0500 Organization: UUNET Canada News Transport Lines: 83 Message-ID: <36A9F88B.9CB73BD6@idirect.com> NNTP-Posting-Host: 207.136.121.140 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Mailer: Mozilla 4.5 [en] (Win95; I) X-Accept-Language: en Xref: news.cs.au.dk comp.lang.beta:11798 Can anybody tell me how the GC in BETA works with respect to cStruct patterns and the @@ operator? Basically, my question is about the difference between passing a reference (pointer) to a cStruct to an external procedure or passing the address directly (using the @@ operator). Example with cStruct (buffer initialization is very slow): ORIGIN '~beta/basiclib/v1.6/betaenv'; INCLUDE '~beta/basiclib/v1.6/external' '~beta/basiclib/v1.6/numberio'; LIBFILE nti '$/crc.lib'; -- program: Descriptor -- (# BufType: cStruct (# byteSize::< (# do 1000000->Value #) #); IntegerStruct: cStruct (# byteSize::< (# do 4->Value #); val: Long (# pos::< (# do 0->Value #) #); enter val exit val #); GetCRC32: external (# BufP: ^BufType; ByteCount: @Integer; CRC: ^IntegerStruct; enter (BufP[],ByteCount,CRC[]) do callStd #); TestBuf: @BufType; TestCRC: @IntegerStruct; do (* initialize Buffer with some data - very slow *) (for I: TestBuf.byteSize repeat (I-1,I mod 256) -> TestBuf.putByte; for); 16xFFFFFFFF->TestCRC; (* initialize CRC *) (TestBuf[],TestBuf.byteSize,TestCRC[])->GetCRC32; (16,TestCRC)->putBaseD; (* print result *) #) Example with @@ (buffer initialization is fast): ORIGIN '~beta/basiclib/v1.6/betaenv'; INCLUDE '~beta/basiclib/v1.6/external' '~beta/basiclib/v1.6/numberio'; LIBFILE nti '$/crc.lib'; -- program: Descriptor -- (# BufType: (# R: [1000000] @Char #); GetCRC32: external (# BufPtr, ByteCount, CRCPtr: @Integer; enter (BufPtr,ByteCount,CRCPtr) do callStd #); TestBuf: @BufType; TestCRC: @Integer; do (* initialize Buffer - is a lot faster than above *) (for I: 1000000 repeat (I mod 256) -> TestBuf.R[I]; for); 16xFFFFFFFF->TestCRC; (* initialize CRC *) (@@TestBuf.R[1],1000000,@@TestCRC)->GetCRC32; (16,TestCRC)->putBaseD; #) This code looks simpler (and is faster), but could the garbage collector potentially free the TestBuf pattern? Especially in this case (BufPtr, CRCPtr declared as @Integer): ... @@TestBuf.R[1] -> BufPtr; @@TestCRC -> CRCPtr; 16xFFFFFFFF->TestCRC; (BufPtr,1000000,@@TestCRC)->GetCRC32; ... the GC might assume that TestBuf and TestCRC are not use anymore after the first two lines in the code sample above, and might therefore mark them for deletion, possibly causing access violations in the external call. Can anybody shed some light on this? Is the purpose of cStruct to prevent problems with the GC? Karl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Karl Waclawek KD Soft Inc. * Phone: (905) 579-3443 * E-Mail: waclawek@idirect.com