Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

core error - bus dumped


devel / comp.lang.clipper.visual-objects / Re: CreateThread vs. CreateVOThread

SubjectAuthor
* CreateThread vs. CreateVOThreadRobert Pope
`* Re: CreateThread vs. CreateVOThreadJamal
 `* Re: CreateThread vs. CreateVOThreadRobert Pope
  +- Re: CreateThread vs. CreateVOThreadJamal
  +- Re: CreateThread vs. CreateVOThreaddlzc
  `* Re: CreateThread vs. CreateVOThreadWolfgang Riedmann
   `* Re: CreateThread vs. CreateVOThreadRobert Pope
    `- Re: CreateThread vs. CreateVOThreadWolfgang Riedmann

1
CreateThread vs. CreateVOThread

<29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=902&group=comp.lang.clipper.visual-objects#902

  copy link   Newsgroups: comp.lang.clipper.visual-objects
X-Received: by 2002:a37:ccb:: with SMTP id 194mr20285128qkm.369.1627988200279;
Tue, 03 Aug 2021 03:56:40 -0700 (PDT)
X-Received: by 2002:a05:620a:5f6:: with SMTP id z22mr19625449qkg.195.1627988200056;
Tue, 03 Aug 2021 03:56:40 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.clipper.visual-objects
Date: Tue, 3 Aug 2021 03:56:39 -0700 (PDT)
Injection-Info: google-groups.googlegroups.com; posting-host=103.20.253.4; posting-account=zmD_sgoAAAAcgEYSDqXDAKJk2oQcCwKt
NNTP-Posting-Host: 103.20.253.4
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com>
Subject: CreateThread vs. CreateVOThread
From: cooeee@gmail.com (Robert Pope)
Injection-Date: Tue, 03 Aug 2021 10:56:40 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: Robert Pope - Tue, 3 Aug 2021 10:56 UTC

Hi All.

I'm wondering if anyone knows what the differences between Win32 API CreateThread() vs. VO's CreateVOThread() are? Mostly with relation to the garbage collector. I.e. if I use Win32 API's CreateThread() would I completely avoid the garbage collector running on my thread. Is there a reason why I would still be better off using CreateVOThread()?

I understand that threads and dynamic memory / the garbage collector don't play well together. I have in my ThreadFunc avoided declaring any LOCAL's and avoided calling any VO functions (because they might also have LOCAL's).. There are also no anonymous variables like a string concatenation. Where I can't avoid a variable I use a structure (ThreadData) in static memory. The thread is the only reader/writer to this structure.

Assuming I haven't missed anything, my thread is only working in static memory and only calling Windows API functions.

The thread itself is pretty simple. It calls Win32 API IsHungAppWindow() once per second and logs an event in the windows event log if that function returns true.

I'm not sure how much I trust VO's threading (or my code not to have missed some dynamic memory allocation somewhere) so I've also included runtime options to completely disable this feature if it plays up.

Cheers!
Rob.

Re: CreateThread vs. CreateVOThread

<sebpfl$vn7$1@gioia.aioe.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=903&group=comp.lang.clipper.visual-objects#903

  copy link   Newsgroups: comp.lang.clipper.visual-objects
Path: i2pn2.org!i2pn.org!aioe.org!usMzckGswq/a27BPojtwGg.user.46.165.242.75.POSTED!not-for-mail
From: nospam@example.com (Jamal)
Newsgroups: comp.lang.clipper.visual-objects
Subject: Re: CreateThread vs. CreateVOThread
Date: Tue, 3 Aug 2021 12:05:11 -0400
Organization: Aioe.org NNTP Server
Message-ID: <sebpfl$vn7$1@gioia.aioe.org>
References: <29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: gioia.aioe.org; logging-data="32487"; posting-host="usMzckGswq/a27BPojtwGg.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.12.0
X-Notice: Filtered by postfilter v. 0.9.2
Content-Language: en-US
 by: Jamal - Tue, 3 Aug 2021 16:05 UTC

According to the docs the CreateThread() and CreateVOThread() are the same:
However, "CreateVOThread() also performs some additional initializations
in the kernel runtime."

But it does not say what those initializations! But I guess it has to do
with the GC suspension during its processing.

Additionally, the docs say (Just in case you did not see it and for others):

CreateVOThread() and ExitVOThread()

"First of all, threads in a Visual Objects application should not be
created by calling the Windows API function CreateThread() directly, but
by calling the Visual Objects runtime function CreateVOThread(). This
function is called exactly like CreateThread() and actually it calls
CreateThread() internally. CreateVOThread() also performs some
additional initializations in the kernel runtime.

Similar to CreateVOThread() there is an ExitVOThread() function that
should be called instead of ExitThread(). However, try to avoid exiting
a thread in a Visual Objects application by calling ExitThread() at all.
Instead, exit your threads by returning from the thread entry point
function."

And the docs go on further:

"When multiple threads are running, each dynamic memory pointer becomes
a shared resource. One thread might load a pointer to a string into a
register. (The GC can only update memory locations, not registers.)
Before actually performing an operation with that pointer, execution is
transferred to another thread that triggers the GC. Now the string
referred to by the register in the first thread is moved, and when
execution returns to the first thread, the pointer in the register is
not valid anymore."

"The problem described above will be resolved in a future release of
Visual Objects, but right now the programmer has to be aware of it."

(I don't think this was ever resolved, and I guess will never be)

"There are two ways of avoiding problems with threads and dynamic data.
The first solution is to disable garbage collection when more than one
thread is active and enabling it only again after all threads but one
finish. This can be done through the Visual Objects runtime functions
DynLock() and DynUnlock(). The disadvantage of this approach is that no
more memory will be freed or reused while the DynLock() is active.
Depending on the application logic, memory consumption might increase
rapidly. Even when the collector runs again, the dynamic memory pool
will stay at the maximum size for future reuse. You might reduce the
size of the dynamic memory pool manually by calling DynShrink().

Disabling the collector globally while a thread is running, is a good
solution when threads only run for a short while and do not generate a
lot of dynamic data garbage. Indexing a database produces a lot of
dynamic data garbage, so that indexing in a thread is not recommended
for bigger databases.

To avoid the collector problem, the solution is not to use dynamic data
at all inside a thread. Another solution is to minimize the use of
dynamic data to very few places, so that DynLock() and DynUnlock() can
be used locally. The Web server that will be presented later is a good
example for this technique."

On 8/3/2021 6:56 AM, Robert Pope wrote:
> Hi All.
>
> I'm wondering if anyone knows what the differences between Win32 API CreateThread() vs. VO's CreateVOThread() are? Mostly with relation to the garbage collector. I.e. if I use Win32 API's CreateThread() would I completely avoid the garbage collector running on my thread. Is there a reason why I would still be better off using CreateVOThread()?
>
> I understand that threads and dynamic memory / the garbage collector don't play well together. I have in my ThreadFunc avoided declaring any LOCAL's and avoided calling any VO functions (because they might also have LOCAL's). There are also no anonymous variables like a string concatenation. Where I can't avoid a variable I use a structure (ThreadData) in static memory. The thread is the only reader/writer to this structure.
>
> Assuming I haven't missed anything, my thread is only working in static memory and only calling Windows API functions.
>
> The thread itself is pretty simple. It calls Win32 API IsHungAppWindow() once per second and logs an event in the windows event log if that function returns true.
>
> I'm not sure how much I trust VO's threading (or my code not to have missed some dynamic memory allocation somewhere) so I've also included runtime options to completely disable this feature if it plays up.
>
> Cheers!
> Rob.
>

Re: CreateThread vs. CreateVOThread

<9405fc40-7ecc-44e1-a60c-dd57eb1242f0n@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=904&group=comp.lang.clipper.visual-objects#904

  copy link   Newsgroups: comp.lang.clipper.visual-objects
X-Received: by 2002:a05:6214:332:: with SMTP id j18mr22475180qvu.21.1628010444330; Tue, 03 Aug 2021 10:07:24 -0700 (PDT)
X-Received: by 2002:ad4:5aa1:: with SMTP id u1mr9117729qvg.2.1628010444129; Tue, 03 Aug 2021 10:07:24 -0700 (PDT)
Path: i2pn2.org!i2pn.org!aioe.org!news.dns-netz.com!news.freedyn.net!newsfeed.xs4all.nl!newsfeed8.news.xs4all.nl!tr1.eu1.usenetexpress.com!feeder.usenetexpress.com!tr2.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.clipper.visual-objects
Date: Tue, 3 Aug 2021 10:07:23 -0700 (PDT)
In-Reply-To: <sebpfl$vn7$1@gioia.aioe.org>
Injection-Info: google-groups.googlegroups.com; posting-host=103.20.253.4; posting-account=zmD_sgoAAAAcgEYSDqXDAKJk2oQcCwKt
NNTP-Posting-Host: 103.20.253.4
References: <29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com> <sebpfl$vn7$1@gioia.aioe.org>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <9405fc40-7ecc-44e1-a60c-dd57eb1242f0n@googlegroups.com>
Subject: Re: CreateThread vs. CreateVOThread
From: cooeee@gmail.com (Robert Pope)
Injection-Date: Tue, 03 Aug 2021 17:07:24 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Lines: 130
 by: Robert Pope - Tue, 3 Aug 2021 17:07 UTC

On Wednesday, August 4, 2021 at 2:05:19 AM UTC+10, Jamal wrote:
> According to the docs the CreateThread() and CreateVOThread() are the same:
> However, "CreateVOThread() also performs some additional initializations
> in the kernel runtime."
>
> But it does not say what those initializations! But I guess it has to do
> with the GC suspension during its processing.
>
> Additionally, the docs say (Just in case you did not see it and for others):
>
> CreateVOThread() and ExitVOThread()
>
> "First of all, threads in a Visual Objects application should not be
> created by calling the Windows API function CreateThread() directly, but
> by calling the Visual Objects runtime function CreateVOThread(). This
> function is called exactly like CreateThread() and actually it calls
> CreateThread() internally. CreateVOThread() also performs some
> additional initializations in the kernel runtime.
>
> Similar to CreateVOThread() there is an ExitVOThread() function that
> should be called instead of ExitThread(). However, try to avoid exiting
> a thread in a Visual Objects application by calling ExitThread() at all.
> Instead, exit your threads by returning from the thread entry point
> function."
>
> And the docs go on further:
>
> "When multiple threads are running, each dynamic memory pointer becomes
> a shared resource. One thread might load a pointer to a string into a
> register. (The GC can only update memory locations, not registers.)
> Before actually performing an operation with that pointer, execution is
> transferred to another thread that triggers the GC. Now the string
> referred to by the register in the first thread is moved, and when
> execution returns to the first thread, the pointer in the register is
> not valid anymore."
>
>
>
> "The problem described above will be resolved in a future release of
> Visual Objects, but right now the programmer has to be aware of it."
>
> (I don't think this was ever resolved, and I guess will never be)
>
>
> "There are two ways of avoiding problems with threads and dynamic data.
> The first solution is to disable garbage collection when more than one
> thread is active and enabling it only again after all threads but one
> finish. This can be done through the Visual Objects runtime functions
> DynLock() and DynUnlock(). The disadvantage of this approach is that no
> more memory will be freed or reused while the DynLock() is active.
> Depending on the application logic, memory consumption might increase
> rapidly. Even when the collector runs again, the dynamic memory pool
> will stay at the maximum size for future reuse. You might reduce the
> size of the dynamic memory pool manually by calling DynShrink().
>
> Disabling the collector globally while a thread is running, is a good
> solution when threads only run for a short while and do not generate a
> lot of dynamic data garbage. Indexing a database produces a lot of
> dynamic data garbage, so that indexing in a thread is not recommended
> for bigger databases.
>
> To avoid the collector problem, the solution is not to use dynamic data
> at all inside a thread. Another solution is to minimize the use of
> dynamic data to very few places, so that DynLock() and DynUnlock() can
> be used locally. The Web server that will be presented later is a good
> example for this technique."
> On 8/3/2021 6:56 AM, Robert Pope wrote:
> > Hi All.
> >
> > I'm wondering if anyone knows what the differences between Win32 API CreateThread() vs. VO's CreateVOThread() are? Mostly with relation to the garbage collector. I.e. if I use Win32 API's CreateThread() would I completely avoid the garbage collector running on my thread. Is there a reason why I would still be better off using CreateVOThread()?
> >
> > I understand that threads and dynamic memory / the garbage collector don't play well together. I have in my ThreadFunc avoided declaring any LOCAL's and avoided calling any VO functions (because they might also have LOCAL's). There are also no anonymous variables like a string concatenation. Where I can't avoid a variable I use a structure (ThreadData) in static memory.. The thread is the only reader/writer to this structure.
> >
> > Assuming I haven't missed anything, my thread is only working in static memory and only calling Windows API functions.
> >
> > The thread itself is pretty simple. It calls Win32 API IsHungAppWindow() once per second and logs an event in the windows event log if that function returns true.
> >
> > I'm not sure how much I trust VO's threading (or my code not to have missed some dynamic memory allocation somewhere) so I've also included runtime options to completely disable this feature if it plays up.
> >
> > Cheers!
> > Rob.
> >

Thanks for replying.

I have seen that documentation / white paper.

In my case locking dynamic memory isn't an option. The thread continues for the lifetime of the application, and this isn't a small application. So yeah, as per my original post, my approach is to avoid using dynamic memory at all in the thread.

What I really hope is that the garbage collector would only ever be called from the main thread. I don't want the worker thread to start the GC. Hence why I'm hoping that calling the Windows API's CreateThread() over VO's CreateVOThread() might be more ideal in that regard. If VO doesn't know my second thread exists, hopefully the garbage collection would never initiate on it. Since the thread is using no dynamic memory it would be unaffected by the GC running on another (the main) thread concurrently.

I guess I'm hoping that someone with internal knowledge of VO threading might still be lurking around these parts to provide some undocumented knowledge. :)

Cheers.

Re: CreateThread vs. CreateVOThread

<secect$9fo$1@gioia.aioe.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=905&group=comp.lang.clipper.visual-objects#905

  copy link   Newsgroups: comp.lang.clipper.visual-objects
Path: i2pn2.org!i2pn.org!aioe.org!usMzckGswq/a27BPojtwGg.user.46.165.242.75.POSTED!not-for-mail
From: nospam@example.com (Jamal)
Newsgroups: comp.lang.clipper.visual-objects
Subject: Re: CreateThread vs. CreateVOThread
Date: Tue, 3 Aug 2021 18:02:08 -0400
Organization: Aioe.org NNTP Server
Message-ID: <secect$9fo$1@gioia.aioe.org>
References: <29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com>
<sebpfl$vn7$1@gioia.aioe.org>
<9405fc40-7ecc-44e1-a60c-dd57eb1242f0n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: gioia.aioe.org; logging-data="9720"; posting-host="usMzckGswq/a27BPojtwGg.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.12.0
X-Notice: Filtered by postfilter v. 0.9.2
Content-Language: en-US
 by: Jamal - Tue, 3 Aug 2021 22:02 UTC

You can post to the X# forum and Robert may know.

On 8/3/2021 1:07 PM, Robert Pope wrote:
> On Wednesday, August 4, 2021 at 2:05:19 AM UTC+10, Jamal wrote:
>> According to the docs the CreateThread() and CreateVOThread() are the same:
>> However, "CreateVOThread() also performs some additional initializations
>> in the kernel runtime."
>>
>> But it does not say what those initializations! But I guess it has to do
>> with the GC suspension during its processing.
>>
>> Additionally, the docs say (Just in case you did not see it and for others):
>>
>> CreateVOThread() and ExitVOThread()
>>
>> "First of all, threads in a Visual Objects application should not be
>> created by calling the Windows API function CreateThread() directly, but
>> by calling the Visual Objects runtime function CreateVOThread(). This
>> function is called exactly like CreateThread() and actually it calls
>> CreateThread() internally. CreateVOThread() also performs some
>> additional initializations in the kernel runtime.
>>
>> Similar to CreateVOThread() there is an ExitVOThread() function that
>> should be called instead of ExitThread(). However, try to avoid exiting
>> a thread in a Visual Objects application by calling ExitThread() at all.
>> Instead, exit your threads by returning from the thread entry point
>> function."
>>
>> And the docs go on further:
>>
>> "When multiple threads are running, each dynamic memory pointer becomes
>> a shared resource. One thread might load a pointer to a string into a
>> register. (The GC can only update memory locations, not registers.)
>> Before actually performing an operation with that pointer, execution is
>> transferred to another thread that triggers the GC. Now the string
>> referred to by the register in the first thread is moved, and when
>> execution returns to the first thread, the pointer in the register is
>> not valid anymore."
>>
>>
>>
>> "The problem described above will be resolved in a future release of
>> Visual Objects, but right now the programmer has to be aware of it."
>>
>> (I don't think this was ever resolved, and I guess will never be)
>>
>>
>> "There are two ways of avoiding problems with threads and dynamic data.
>> The first solution is to disable garbage collection when more than one
>> thread is active and enabling it only again after all threads but one
>> finish. This can be done through the Visual Objects runtime functions
>> DynLock() and DynUnlock(). The disadvantage of this approach is that no
>> more memory will be freed or reused while the DynLock() is active.
>> Depending on the application logic, memory consumption might increase
>> rapidly. Even when the collector runs again, the dynamic memory pool
>> will stay at the maximum size for future reuse. You might reduce the
>> size of the dynamic memory pool manually by calling DynShrink().
>>
>> Disabling the collector globally while a thread is running, is a good
>> solution when threads only run for a short while and do not generate a
>> lot of dynamic data garbage. Indexing a database produces a lot of
>> dynamic data garbage, so that indexing in a thread is not recommended
>> for bigger databases.
>>
>> To avoid the collector problem, the solution is not to use dynamic data
>> at all inside a thread. Another solution is to minimize the use of
>> dynamic data to very few places, so that DynLock() and DynUnlock() can
>> be used locally. The Web server that will be presented later is a good
>> example for this technique."
>> On 8/3/2021 6:56 AM, Robert Pope wrote:
>>> Hi All.
>>>
>>> I'm wondering if anyone knows what the differences between Win32 API CreateThread() vs. VO's CreateVOThread() are? Mostly with relation to the garbage collector. I.e. if I use Win32 API's CreateThread() would I completely avoid the garbage collector running on my thread. Is there a reason why I would still be better off using CreateVOThread()?
>>>
>>> I understand that threads and dynamic memory / the garbage collector don't play well together. I have in my ThreadFunc avoided declaring any LOCAL's and avoided calling any VO functions (because they might also have LOCAL's). There are also no anonymous variables like a string concatenation. Where I can't avoid a variable I use a structure (ThreadData) in static memory. The thread is the only reader/writer to this structure.
>>>
>>> Assuming I haven't missed anything, my thread is only working in static memory and only calling Windows API functions.
>>>
>>> The thread itself is pretty simple. It calls Win32 API IsHungAppWindow() once per second and logs an event in the windows event log if that function returns true.
>>>
>>> I'm not sure how much I trust VO's threading (or my code not to have missed some dynamic memory allocation somewhere) so I've also included runtime options to completely disable this feature if it plays up.
>>>
>>> Cheers!
>>> Rob.
>>>
>
> Thanks for replying.
>
> I have seen that documentation / white paper.
>
> In my case locking dynamic memory isn't an option. The thread continues for the lifetime of the application, and this isn't a small application. So yeah, as per my original post, my approach is to avoid using dynamic memory at all in the thread.
>
> What I really hope is that the garbage collector would only ever be called from the main thread. I don't want the worker thread to start the GC. Hence why I'm hoping that calling the Windows API's CreateThread() over VO's CreateVOThread() might be more ideal in that regard. If VO doesn't know my second thread exists, hopefully the garbage collection would never initiate on it. Since the thread is using no dynamic memory it would be unaffected by the GC running on another (the main) thread concurrently.
>
> I guess I'm hoping that someone with internal knowledge of VO threading might still be lurking around these parts to provide some undocumented knowledge. :)
>
> Cheers.
>

Re: CreateThread vs. CreateVOThread

<0c77ee01-c11f-427f-a56a-e093d9f8c599n@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=906&group=comp.lang.clipper.visual-objects#906

  copy link   Newsgroups: comp.lang.clipper.visual-objects
X-Received: by 2002:a05:620a:29cf:: with SMTP id s15mr26729795qkp.363.1628087531253; Wed, 04 Aug 2021 07:32:11 -0700 (PDT)
X-Received: by 2002:ac8:7594:: with SMTP id s20mr23000536qtq.357.1628087531064; Wed, 04 Aug 2021 07:32:11 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!feeder1.feed.usenet.farm!feed.usenet.farm!tr1.eu1.usenetexpress.com!feeder.usenetexpress.com!tr2.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.clipper.visual-objects
Date: Wed, 4 Aug 2021 07:32:10 -0700 (PDT)
In-Reply-To: <9405fc40-7ecc-44e1-a60c-dd57eb1242f0n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=68.107.209.13; posting-account=7bF0GwoAAABMFHX6V4fON4-1F6LFJ834
NNTP-Posting-Host: 68.107.209.13
References: <29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com> <sebpfl$vn7$1@gioia.aioe.org> <9405fc40-7ecc-44e1-a60c-dd57eb1242f0n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <0c77ee01-c11f-427f-a56a-e093d9f8c599n@googlegroups.com>
Subject: Re: CreateThread vs. CreateVOThread
From: dlzc1@cox.net (dlzc)
Injection-Date: Wed, 04 Aug 2021 14:32:11 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Lines: 15
 by: dlzc - Wed, 4 Aug 2021 14:32 UTC

Dear Robert Pope:

On Tuesday, August 3, 2021 at 10:07:25 AM UTC-7, Robert Pope wrote:
....
> If VO doesn't know my second thread exists, hopefully the garbage
> collection would never initiate on it. Since the thread is using no
> dynamic memory it would be unaffected by the GC running on
> another (the main) thread concurrently.

Did you write the "second" thread in VO? Does it access VO-defined data / structures / open DBFs? Are all of its memory accesses to global variables? Does it call VO or user functions? If any of these answers is "yes", I think you are going to be in trouble. Consider that the code could be triggered to run while GC is running in the "foreground".

David A. Smith (not a VO-er)

Re: CreateThread vs. CreateVOThread

<imvoouFss3fU1@mid.individual.net>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=907&group=comp.lang.clipper.visual-objects#907

  copy link   Newsgroups: comp.lang.clipper.visual-objects
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: wriedmann@gmail.com (Wolfgang Riedmann)
Newsgroups: comp.lang.clipper.visual-objects
Subject: Re: CreateThread vs. CreateVOThread
Date: Wed, 4 Aug 2021 17:07:10 +0200
Lines: 151
Message-ID: <imvoouFss3fU1@mid.individual.net>
References: <29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com> <sebpfl$vn7$1@gioia.aioe.org> <9405fc40-7ecc-44e1-a60c-dd57eb1242f0n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
X-Trace: individual.net ZZcBLNQeGA0BqGgzf2SThQ2BkRb2oVB0nF+jxUfAkmiyzHiV0=
Cancel-Lock: sha1:sw8cSuvkuc2mkMEKUVdV1Wd7fNQ=
User-Agent: XanaNews/1.18.1.6
 by: Wolfgang Riedmann - Wed, 4 Aug 2021 15:07 UTC

Hi Robert,

please be aware that you cannot use any VO specific datatype in the
thread like strings, floats or objects because they are collected when
not used.

I would strongly recommend to no use threads in a VO application, and
use rather a second application instead of a second thread linked by
some collaboration mechanism.

Or you may have another alternative: use X# instead. In X# not only the
garbage collector is thread safe, but also the RDDs if you need them.

Wolfgang

Robert Pope wrote:

> On Wednesday, August 4, 2021 at 2:05:19 AM UTC+10, Jamal wrote:
> > According to the docs the CreateThread() and CreateVOThread() are
> > the same: However, "CreateVOThread() also performs some additional
> > initializations in the kernel runtime."
> >
> > But it does not say what those initializations! But I guess it has
> > to do with the GC suspension during its processing.
> >
> > Additionally, the docs say (Just in case you did not see it and for
> > others):
> >
> > CreateVOThread() and ExitVOThread()
> >
> > "First of all, threads in a Visual Objects application should not
> > be created by calling the Windows API function CreateThread()
> > directly, but by calling the Visual Objects runtime function
> > CreateVOThread(). This function is called exactly like
> > CreateThread() and actually it calls CreateThread() internally.
> > CreateVOThread() also performs some additional initializations in
> > the kernel runtime.
> >
> > Similar to CreateVOThread() there is an ExitVOThread() function
> > that should be called instead of ExitThread(). However, try to
> > avoid exiting a thread in a Visual Objects application by calling
> > ExitThread() at all. Instead, exit your threads by returning from
> > the thread entry point function."
> >
> > And the docs go on further:
> >
> > "When multiple threads are running, each dynamic memory pointer
> > becomes a shared resource. One thread might load a pointer to a
> > string into a register. (The GC can only update memory locations,
> > not registers.) Before actually performing an operation with that
> > pointer, execution is transferred to another thread that triggers
> > the GC. Now the string referred to by the register in the first
> > thread is moved, and when execution returns to the first thread,
> > the pointer in the register is not valid anymore."
> >
> >
> >
> > "The problem described above will be resolved in a future release
> > of Visual Objects, but right now the programmer has to be aware of
> > it."
> >
> > (I don't think this was ever resolved, and I guess will never be)
> >
> >
> > "There are two ways of avoiding problems with threads and dynamic
> > data. The first solution is to disable garbage collection when
> > more than one thread is active and enabling it only again after all
> > threads but one finish. This can be done through the Visual Objects
> > runtime functions DynLock() and DynUnlock(). The disadvantage of
> > this approach is that no more memory will be freed or reused while
> > the DynLock() is active. Depending on the application logic,
> > memory consumption might increase rapidly. Even when the collector
> > runs again, the dynamic memory pool will stay at the maximum size
> > for future reuse. You might reduce the size of the dynamic memory
> > pool manually by calling DynShrink().
> >
> > Disabling the collector globally while a thread is running, is a
> > good solution when threads only run for a short while and do not
> > generate a lot of dynamic data garbage. Indexing a database
> > produces a lot of dynamic data garbage, so that indexing in a
> > thread is not recommended for bigger databases.
> >
> > To avoid the collector problem, the solution is not to use dynamic
> > data at all inside a thread. Another solution is to minimize the
> > use of dynamic data to very few places, so that DynLock() and
> > DynUnlock() can be used locally. The Web server that will be
> > presented later is a good example for this technique."
> > On 8/3/2021 6:56 AM, Robert Pope wrote:
> > > Hi All.
> > >
> > > I'm wondering if anyone knows what the differences between Win32
> > > API CreateThread() vs. VO's CreateVOThread() are? Mostly with
> > > relation to the garbage collector. I.e. if I use Win32 API's
> > > CreateThread() would I completely avoid the garbage collector
> > > running on my thread. Is there a reason why I would still be
> > > better off using CreateVOThread()?
> > >
> > > I understand that threads and dynamic memory / the garbage
> > > collector don't play well together. I have in my ThreadFunc
> > > avoided declaring any LOCAL's and avoided calling any VO
> > > functions (because they might also have LOCAL's). There are also
> > > no anonymous variables like a string concatenation. Where I can't
> > > avoid a variable I use a structure (ThreadData) in static memory.
> > > The thread is the only reader/writer to this structure.
> > >
> > > Assuming I haven't missed anything, my thread is only working in
> > > static memory and only calling Windows API functions.
> > >
> > > The thread itself is pretty simple. It calls Win32 API
> > > IsHungAppWindow() once per second and logs an event in the
> > > windows event log if that function returns true.
> > >
> > > I'm not sure how much I trust VO's threading (or my code not to
> > > have missed some dynamic memory allocation somewhere) so I've
> > > also included runtime options to completely disable this feature
> > > if it plays up.
> > >
> > > Cheers!
> > > Rob.
> > >
>
> Thanks for replying.
>
> I have seen that documentation / white paper.
>
> In my case locking dynamic memory isn't an option. The thread
> continues for the lifetime of the application, and this isn't a small
> application. So yeah, as per my original post, my approach is to
> avoid using dynamic memory at all in the thread.
>
> What I really hope is that the garbage collector would only ever be
> called from the main thread. I don't want the worker thread to start
> the GC. Hence why I'm hoping that calling the Windows API's
> CreateThread() over VO's CreateVOThread() might be more ideal in that
> regard. If VO doesn't know my second thread exists, hopefully the
> garbage collection would never initiate on it. Since the thread is
> using no dynamic memory it would be unaffected by the GC running on
> another (the main) thread concurrently.
>
> I guess I'm hoping that someone with internal knowledge of VO
> threading might still be lurking around these parts to provide some
> undocumented knowledge. :)
>
> Cheers.

--

Re: CreateThread vs. CreateVOThread

<e6812d0d-4359-4ab8-8844-bf4c8ad7a064n@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=908&group=comp.lang.clipper.visual-objects#908

  copy link   Newsgroups: comp.lang.clipper.visual-objects
X-Received: by 2002:a37:96c2:: with SMTP id y185mr513783qkd.6.1628097487386; Wed, 04 Aug 2021 10:18:07 -0700 (PDT)
X-Received: by 2002:a37:994:: with SMTP id 142mr438811qkj.277.1628097487139; Wed, 04 Aug 2021 10:18:07 -0700 (PDT)
Path: i2pn2.org!i2pn.org!news.swapon.de!news.uzoreto.com!tr1.eu1.usenetexpress.com!feeder.usenetexpress.com!tr3.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.clipper.visual-objects
Date: Wed, 4 Aug 2021 10:18:06 -0700 (PDT)
In-Reply-To: <imvoouFss3fU1@mid.individual.net>
Injection-Info: google-groups.googlegroups.com; posting-host=103.20.253.4; posting-account=zmD_sgoAAAAcgEYSDqXDAKJk2oQcCwKt
NNTP-Posting-Host: 103.20.253.4
References: <29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com> <sebpfl$vn7$1@gioia.aioe.org> <9405fc40-7ecc-44e1-a60c-dd57eb1242f0n@googlegroups.com> <imvoouFss3fU1@mid.individual.net>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <e6812d0d-4359-4ab8-8844-bf4c8ad7a064n@googlegroups.com>
Subject: Re: CreateThread vs. CreateVOThread
From: cooeee@gmail.com (Robert Pope)
Injection-Date: Wed, 04 Aug 2021 17:18:07 +0000
Content-Type: text/plain; charset="UTF-8"
Lines: 233
 by: Robert Pope - Wed, 4 Aug 2021 17:18 UTC

On Thursday, August 5, 2021 at 1:07:12 AM UTC+10, Wolfgang Riedmann wrote:
> Hi Robert,
>
> please be aware that you cannot use any VO specific datatype in the
> thread like strings, floats or objects because they are collected when
> not used.
>
> I would strongly recommend to no use threads in a VO application, and
> use rather a second application instead of a second thread linked by
> some collaboration mechanism.
>
> Or you may have another alternative: use X# instead. In X# not only the
> garbage collector is thread safe, but also the RDDs if you need them.
>
> Wolfgang
> Robert Pope wrote:
>
> > On Wednesday, August 4, 2021 at 2:05:19 AM UTC+10, Jamal wrote:
> > > According to the docs the CreateThread() and CreateVOThread() are
> > > the same: However, "CreateVOThread() also performs some additional
> > > initializations in the kernel runtime."
> > >
> > > But it does not say what those initializations! But I guess it has
> > > to do with the GC suspension during its processing.
> > >
> > > Additionally, the docs say (Just in case you did not see it and for
> > > others):
> > >
> > > CreateVOThread() and ExitVOThread()
> > >
> > > "First of all, threads in a Visual Objects application should not
> > > be created by calling the Windows API function CreateThread()
> > > directly, but by calling the Visual Objects runtime function
> > > CreateVOThread(). This function is called exactly like
> > > CreateThread() and actually it calls CreateThread() internally.
> > > CreateVOThread() also performs some additional initializations in
> > > the kernel runtime.
> > >
> > > Similar to CreateVOThread() there is an ExitVOThread() function
> > > that should be called instead of ExitThread(). However, try to
> > > avoid exiting a thread in a Visual Objects application by calling
> > > ExitThread() at all. Instead, exit your threads by returning from
> > > the thread entry point function."
> > >
> > > And the docs go on further:
> > >
> > > "When multiple threads are running, each dynamic memory pointer
> > > becomes a shared resource. One thread might load a pointer to a
> > > string into a register. (The GC can only update memory locations,
> > > not registers.) Before actually performing an operation with that
> > > pointer, execution is transferred to another thread that triggers
> > > the GC. Now the string referred to by the register in the first
> > > thread is moved, and when execution returns to the first thread,
> > > the pointer in the register is not valid anymore."
> > >
> > >
> > >
> > > "The problem described above will be resolved in a future release
> > > of Visual Objects, but right now the programmer has to be aware of
> > > it."
> > >
> > > (I don't think this was ever resolved, and I guess will never be)
> > >
> > >
> > > "There are two ways of avoiding problems with threads and dynamic
> > > data. The first solution is to disable garbage collection when
> > > more than one thread is active and enabling it only again after all
> > > threads but one finish. This can be done through the Visual Objects
> > > runtime functions DynLock() and DynUnlock(). The disadvantage of
> > > this approach is that no more memory will be freed or reused while
> > > the DynLock() is active. Depending on the application logic,
> > > memory consumption might increase rapidly. Even when the collector
> > > runs again, the dynamic memory pool will stay at the maximum size
> > > for future reuse. You might reduce the size of the dynamic memory
> > > pool manually by calling DynShrink().
> > >
> > > Disabling the collector globally while a thread is running, is a
> > > good solution when threads only run for a short while and do not
> > > generate a lot of dynamic data garbage. Indexing a database
> > > produces a lot of dynamic data garbage, so that indexing in a
> > > thread is not recommended for bigger databases.
> > >
> > > To avoid the collector problem, the solution is not to use dynamic
> > > data at all inside a thread. Another solution is to minimize the
> > > use of dynamic data to very few places, so that DynLock() and
> > > DynUnlock() can be used locally. The Web server that will be
> > > presented later is a good example for this technique."
> > > On 8/3/2021 6:56 AM, Robert Pope wrote:
> > > > Hi All.
> > > >
> > > > I'm wondering if anyone knows what the differences between Win32
> > > > API CreateThread() vs. VO's CreateVOThread() are? Mostly with
> > > > relation to the garbage collector. I.e. if I use Win32 API's
> > > > CreateThread() would I completely avoid the garbage collector
> > > > running on my thread. Is there a reason why I would still be
> > > > better off using CreateVOThread()?
> > > >
> > > > I understand that threads and dynamic memory / the garbage
> > > > collector don't play well together. I have in my ThreadFunc
> > > > avoided declaring any LOCAL's and avoided calling any VO
> > > > functions (because they might also have LOCAL's). There are also
> > > > no anonymous variables like a string concatenation. Where I can't
> > > > avoid a variable I use a structure (ThreadData) in static memory.
> > > > The thread is the only reader/writer to this structure.
> > > >
> > > > Assuming I haven't missed anything, my thread is only working in
> > > > static memory and only calling Windows API functions.
> > > >
> > > > The thread itself is pretty simple. It calls Win32 API
> > > > IsHungAppWindow() once per second and logs an event in the
> > > > windows event log if that function returns true.
> > > >
> > > > I'm not sure how much I trust VO's threading (or my code not to
> > > > have missed some dynamic memory allocation somewhere) so I've
> > > > also included runtime options to completely disable this feature
> > > > if it plays up.
> > > >
> > > > Cheers!
> > > > Rob.
> > > >
> >
> > Thanks for replying.
> >
> > I have seen that documentation / white paper.
> >
> > In my case locking dynamic memory isn't an option. The thread
> > continues for the lifetime of the application, and this isn't a small
> > application. So yeah, as per my original post, my approach is to
> > avoid using dynamic memory at all in the thread.
> >
> > What I really hope is that the garbage collector would only ever be
> > called from the main thread. I don't want the worker thread to start
> > the GC. Hence why I'm hoping that calling the Windows API's
> > CreateThread() over VO's CreateVOThread() might be more ideal in that
> > regard. If VO doesn't know my second thread exists, hopefully the
> > garbage collection would never initiate on it. Since the thread is
> > using no dynamic memory it would be unaffected by the GC running on
> > another (the main) thread concurrently.
> >
> > I guess I'm hoping that someone with internal knowledge of VO
> > threading might still be lurking around these parts to provide some
> > undocumented knowledge. :)
> >
> > Cheers.
> --

I guess I will post the code of my thread func, given the responses I'm getting :)
And the question I'm trying to have answered: Would the garbage collector ever initiate on this thread if I start it with CreateThread()? I don't want it to.

STRUCT HeartBeatMonitor_ThreadData

MEMBER hWnd AS PTR
MEMBER hEventSource AS PTR
MEMBER pszEventSource AS PSZ
MEMBER RootDirectory AS PSZ
MEMBER sTimeStart AS _winSYSTEMTIME
MEMBER sTimeEnd AS _winSYSTEMTIME

FUNCTION HeartbeatMonitor(sHeartBeatMonitor_ThreadData AS HeartBeatMonitor_ThreadData) AS DWORD PASCAL

// Do not declare any locals here. Garbage collector is not thread safe.
// Also must not call any functions including VO builtins that might allocate memory.

DO WHILE TRUE
IF sHeartBeatMonitor_ThreadData.hWnd != NULL_PTR

IF IsHungAppWindow(sHeartBeatMonitor_ThreadData.hWnd)
IF sHeartBeatMonitor_ThreadData.sTimeStart == NULL_PTR

sHeartBeatMonitor_ThreadData.sTimeStart := MemAlloc(_SizeOf(_winSYSTEMTIME))
GetLocalTime(sHeartBeatMonitor_ThreadData.sTimeStart)

sHeartBeatMonitor_ThreadData.hEventSource := RegisterEventSource(NULL_PSZ, sHeartBeatMonitor_ThreadData.pszEventSource)
ReportEvent(sHeartBeatMonitor_ThreadData.hEventSource, EVENTLOG_WARNING_TYPE, 0, MSG_APPLICATION_HANG, NULL_PTR, 1, 0, @sHeartBeatMonitor_ThreadData.RootDirectory, NULL_PTR)
DeregisterEventSource(sHeartBeatMonitor_ThreadData.hEventSource)
sHeartBeatMonitor_ThreadData.hEventSource := NULL_PTR


Click here to read the complete article
Re: CreateThread vs. CreateVOThread

<in1qcrFb905U1@mid.individual.net>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=909&group=comp.lang.clipper.visual-objects#909

  copy link   Newsgroups: comp.lang.clipper.visual-objects
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: wriedmann@gmail.com (Wolfgang Riedmann)
Newsgroups: comp.lang.clipper.visual-objects
Subject: Re: CreateThread vs. CreateVOThread
Date: Thu, 5 Aug 2021 11:47:06 +0200
Lines: 20
Message-ID: <in1qcrFb905U1@mid.individual.net>
References: <29915aac-da35-4455-b403-c1fec00692e3n@googlegroups.com> <sebpfl$vn7$1@gioia.aioe.org> <9405fc40-7ecc-44e1-a60c-dd57eb1242f0n@googlegroups.com> <imvoouFss3fU1@mid.individual.net> <e6812d0d-4359-4ab8-8844-bf4c8ad7a064n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
X-Trace: individual.net VOdCYFHZFhOiXSzId5kh4QIk1B5OKBy/3muFhZPneGC50YS9Y=
Cancel-Lock: sha1:3t7cAiifTxAEMxD+N3Y/bZVjbYM=
User-Agent: XanaNews/1.18.1.6
 by: Wolfgang Riedmann - Thu, 5 Aug 2021 09:47 UTC

Hi Robert,

> I guess I will post the code of my thread func, given the responses
> I'm getting :) And the question I'm trying to have answered: Would
> the garbage collector ever initiate on this thread if I start it with
> CreateThread()? I don't want it to.

this code should be safe, but nevertheless I would use CreateVOThread.

But I think that the GC would never kick in here as you have no local
variables or other things that could make him kick in.

But as Jamal wrote: the only person you can give a correct answer is
Robert v.d.Hulst, and you can reach him through the X# forum.
I would do that as fast as possible as it is holiday time and he may be
absent the next weeks for holiday.

Wolfgang

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor