🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
25 messages
25 total messages Started by Robert G. Hoover Mon, 12 Mar 2007 15:39
VC++ CSemaphore equivalent?
#2306
Author: Robert G. Hoover
Date: Mon, 12 Mar 2007 15:39
48 lines
2750 bytes
Hi,

I've written a video streaming application in Borland C++ Builder v5,6,2006 that
is experiencing a drastic performance decline on the new Intel D 935 (dual core)
processor. My camera supplier recommended using the Micro$oft CSemaphore classes
which is impractical as I use Borland products exclusively to develop my code.
Is there a Borland equivalent? Can I use the CreateSemaphore(), OpenSemaphore(),
ReleaseSemaphore() to keep my video grab/display thread from hiccuping so badly?
For reference, I have appended my thread code which uses simple bool variables.
If I utilize this Sleep() command at the bottom of the loop, performance is
improved, though not like it was on older machines. My 4-year-old laptop is
outperforming my tricked-out desktop!!! Any advice is welcome!

Thanks so much!

Rob

_________________________________________________________________________________

        // grab, process, display live video as normal
        while (!terminated)
        {
            // give primary thread time to process frozen image
            if (frozen)
                Sleep(100);

            // grab, process, and display video data
            else
            {
                // set semiphore
                busy = true;

                // grab video frame(s) from camera
                Grab(live_grabbing_count);

                // process image data
                Process();

                // display current image on screen
                Display();

                // clear semiphore
                busy = false;

                // preserve process time
//              Sleep(FrameRateTimeOut);
            }
        }
Re: VC++ CSemaphore equivalent?
#2307
Author: Dennis Jones
Date: Mon, 12 Mar 2007 16:29
75 lines
3494 bytes
"Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote in message 
news:45f57403@newsgroups.borland.com...
> Hi,
>
> I've written a video streaming application in Borland C++ Builder 
> v5,6,2006 that
> is experiencing a drastic performance decline on the new Intel D 935 (dual 
> core)
> processor. My camera supplier recommended using the Micro$oft CSemaphore 
> classes
> which is impractical as I use Borland products exclusively to develop my 
> code.
> Is there a Borland equivalent? Can I use the CreateSemaphore(), 
> OpenSemaphore(),
> ReleaseSemaphore() to keep my video grab/display thread from hiccuping so 
> badly?
> For reference, I have appended my thread code which uses simple bool 
> variables.
> If I utilize this Sleep() command at the bottom of the loop, performance 
> is
> improved, though not like it was on older machines. My 4-year-old laptop 
> is
> outperforming my tricked-out desktop!!! Any advice is welcome!
>
> Thanks so much!
>
> Rob
>
> _________________________________________________________________________________
>
>        // grab, process, display live video as normal
>        while (!terminated)
>        {
>            // give primary thread time to process frozen image
>            if (frozen)
>                Sleep(100);
>
>            // grab, process, and display video data
>            else
>            {
>                // set semiphore
>                busy = true;
>
>                // grab video frame(s) from camera
>                Grab(live_grabbing_count);
>
>                // process image data
>                Process();
>
>                // display current image on screen
>                Display();
>
>                // clear semiphore
>                busy = false;
>
>                // preserve process time
> //              Sleep(FrameRateTimeOut);
>            }
>        }

First, your code doesn't really give enough information to go on -- it 
doesn't show where the 'busy' flag is being tested, and doesn't provide any 
context to make sense of the problem you are having.  You should probably 
post a more complete example.

Second, if a Semaphore is needed, you can of course use the Win32 Semaphore 
functions (CSemaphore is merely a wrapper around those functions), or you 
can write your own semaphore class/wrapper.

Third, do you really need a semaphore?  Semaphores are typically used for 
resource counting.  If you just need to synchronize access to data, a 
critical section is simpler and faster.

- Dennis 
Re: VC++ CSemaphore equivalent?
#2309
Author: Robert G. Hoover
Date: Mon, 12 Mar 2007 16:47
41 lines
2928 bytes
Hi Dennis,

You know, I've been asking myself the same (#3) question. The 'busy' flag is not
being tested in my main process at all until the point of termination. (Wait
until !busy before terminating parent process)

So, is my problem semaphore-related? Or rather processor related? I can't
imagine implementing the Win32 Semaphore functions and seeing any different
results. My Borland BDS 2006 (C++ Builder) is compiling my program the same way
as always, before this new chip was introduced to the market. Is it possible
that the compiler is not compiling optimally for this new chip? Can BDS be set
to compile differently for this dual-core chip? Can I use 1 half of the
processor for my main application thread and the 2nd half for my video thread so
that they are executed in true parallel? This certainly seems to be a problem
related to the processor itself as that's the only thing that has changed. I've
been compiling in Borland for near 14 years, MANY different computers,
processors, peripherals, etc, and never seen this kind of behavior...

Thanks,

Rob



> 
> First, your code doesn't really give enough information to go on -- it 
> doesn't show where the 'busy' flag is being tested, and doesn't provide any 
> context to make sense of the problem you are having.  You should probably 
> post a more complete example.
> 
> Second, if a Semaphore is needed, you can of course use the Win32 Semaphore 
> functions (CSemaphore is merely a wrapper around those functions), or you 
> can write your own semaphore class/wrapper.
> 
> Third, do you really need a semaphore?  Semaphores are typically used for 
> resource counting.  If you just need to synchronize access to data, a 
> critical section is simpler and faster.
> 
> - Dennis 
> 
> 
Re: VC++ CSemaphore equivalent?
#2310
Author: Dennis Jones
Date: Mon, 12 Mar 2007 17:30
80 lines
4376 bytes
"Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote in message 
news:45f583fb$1@newsgroups.borland.com...
> Hi Dennis,
>
> You know, I've been asking myself the same (#3) question. The 'busy' flag 
> is not
> being tested in my main process at all until the point of termination. 
> (Wait
> until !busy before terminating parent process)

Is your "parent process" a thread, separate from the thread that is doing 
the work?  What is your parent process/thread doing to wait?  Is it in a 
loop, like this:

while (!busy)
    ;  // do nothing

That would be very processor intensive, though it would be every bit as much 
of a problem on a single processor as on a dual (if not more so).

If you are having serious problems with a dual processor but none on a 
single processor, it could indicate a more fundamental problem with thread 
synchronization, as there are some thread-related problems that will not 
manifest themselves in a single processor environment (which is not true 
multi-tasking) but will blow up in a dual processor environment due to race 
conditions, dead-lock, etc.


> So, is my problem semaphore-related? Or rather processor related? I can't
> imagine implementing the Win32 Semaphore functions and seeing any 
> different
> results.

I can't either.  Given your explanation of how you are using 'busy' and 
depending on how you are waiting on it, I would expect the program to behave 
badly (or marginally) on a single processor, but better (though still not 
optimally) on a dual.  Using a thread synchronization object in your code 
would be a good idea regardless, and given what little I know so far, a 
semaphore might not be such a bad choice after all.


> My Borland BDS 2006 (C++ Builder) is compiling my program the same way
> as always, before this new chip was introduced to the market. Is it 
> possible
> that the compiler is not compiling optimally for this new chip? Can BDS be 
> set
> to compile differently for this dual-core chip?

I doubt it.


> Can I use 1 half of the
> processor for my main application thread and the 2nd half for my video 
> thread so
> that they are executed in true parallel?

I don't know -- that is a good question.  I do not have a dual processor 
system, so I've never experienced it myself, but I've always sort of assumed 
that if you were using multiple threads, that the OS would/may decide to 
distribute a processes threads across the CPU's for you.  Perhaps someone 
with more mulit-processor knowledge than I will jump in here.


> This certainly seems to be a problem
> related to the processor itself as that's the only thing that has changed. 
> I've
> been compiling in Borland for near 14 years, MANY different computers,
> processors, peripherals, etc, and never seen this kind of behavior...

And you've probably never had an app run on a dual-core/dual-processor 
machine before either -- it's a whole different kind of animal when it comes 
to multi-threading.  I have an app that runs on single- and dual-processor 
machines, and I was initially a little concerned with whether my app would 
handle multi-processor machines, but so far I haven't had any reports of 
problems.  Maybe I got lucky, or maybe I wrote my thread synchronzation 
correctly the first time -- the point is, you might never have a problem 
until multiple processors come into play.

- Dennis 
Re: VC++ CSemaphore equivalent?
#2314
Author: Robert G. Hoover
Date: Mon, 12 Mar 2007 17:42
132 lines
6108 bytes
Hi Dennis,

Wow! I appreciate the insight.

The parent thread is my main application thread, TApplication with TCustomForm,
etc. My understanding of this process loop is:

while (Message != WM_CLOSE)
{
	GetMessage()
	ProcessMessage()
}

ie, the standard windows thread. So, I spawn a thread in my
TShellForm::FormCreate() function...


	// spawn thread for advanced grab/display routines
	hThread = (HANDLE)BeginThread(THREAD_PRIORITY_NORMAL,
				      0, VideoGrabbingThread,
				      this, 0, ThreadID);

	// set thread priority
	SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST);


This is the only other thread I've got running, besides a TTimer here and there
for GUI countdowns... nothing that should impede my video loop.

It just seems like when the video is streaming, the mouse is unresponsive for a
second or 2, every 5-10 seconds or so. Reminds me of my college days and the
notorious lag monster!


I guess I need to do some more research on the dual-processor and multi-threaded
semaphore environment. This is certainly outside my expertise. As you guessed,
I've never used a dual-processor, nor have we delivered one, nor has my program
been run on one to the best of my knowledge.


Thanks again! I really appreciate the advice!

Rob


Any advice from you multi-thread guys? I'm kinda flyin' blind here. :)




Dennis Jones wrote:
> "Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote in message 
> news:45f583fb$1@newsgroups.borland.com...
>> Hi Dennis,
>>
>> You know, I've been asking myself the same (#3) question. The 'busy' flag 
>> is not
>> being tested in my main process at all until the point of termination. 
>> (Wait
>> until !busy before terminating parent process)
> 
> Is your "parent process" a thread, separate from the thread that is doing 
> the work?  What is your parent process/thread doing to wait?  Is it in a 
> loop, like this:
> 
> while (!busy)
>     ;  // do nothing
> 
> That would be very processor intensive, though it would be every bit as much 
> of a problem on a single processor as on a dual (if not more so).
> 
> If you are having serious problems with a dual processor but none on a 
> single processor, it could indicate a more fundamental problem with thread 
> synchronization, as there are some thread-related problems that will not 
> manifest themselves in a single processor environment (which is not true 
> multi-tasking) but will blow up in a dual processor environment due to race 
> conditions, dead-lock, etc.
> 
> 
>> So, is my problem semaphore-related? Or rather processor related? I can't
>> imagine implementing the Win32 Semaphore functions and seeing any 
>> different
>> results.
> 
> I can't either.  Given your explanation of how you are using 'busy' and 
> depending on how you are waiting on it, I would expect the program to behave 
> badly (or marginally) on a single processor, but better (though still not 
> optimally) on a dual.  Using a thread synchronization object in your code 
> would be a good idea regardless, and given what little I know so far, a 
> semaphore might not be such a bad choice after all.
> 
> 
>> My Borland BDS 2006 (C++ Builder) is compiling my program the same way
>> as always, before this new chip was introduced to the market. Is it 
>> possible
>> that the compiler is not compiling optimally for this new chip? Can BDS be 
>> set
>> to compile differently for this dual-core chip?
> 
> I doubt it.
> 
> 
>> Can I use 1 half of the
>> processor for my main application thread and the 2nd half for my video 
>> thread so
>> that they are executed in true parallel?
> 
> I don't know -- that is a good question.  I do not have a dual processor 
> system, so I've never experienced it myself, but I've always sort of assumed 
> that if you were using multiple threads, that the OS would/may decide to 
> distribute a processes threads across the CPU's for you.  Perhaps someone 
> with more mulit-processor knowledge than I will jump in here.
> 
> 
>> This certainly seems to be a problem
>> related to the processor itself as that's the only thing that has changed. 
>> I've
>> been compiling in Borland for near 14 years, MANY different computers,
>> processors, peripherals, etc, and never seen this kind of behavior...
> 
> And you've probably never had an app run on a dual-core/dual-processor 
> machine before either -- it's a whole different kind of animal when it comes 
> to multi-threading.  I have an app that runs on single- and dual-processor 
> machines, and I was initially a little concerned with whether my app would 
> handle multi-processor machines, but so far I haven't had any reports of 
> problems.  Maybe I got lucky, or maybe I wrote my thread synchronzation 
> correctly the first time -- the point is, you might never have a problem 
> until multiple processors come into play.
> 
> - Dennis 
> 
> 
Re: VC++ CSemaphore equivalent?
#2312
Author: Bob Gonder
Date: Mon, 12 Mar 2007 17:44
16 lines
1508 bytes
Robert G. Hoover wrote:

>So, is my problem semaphore-related?

Do you Synchronize() your Display() ?

> Or rather processor related? I can't

What's the clock rate (per core) on this new super-duper cpu?
It might actually be slower than your old cpu on a per-core basis.

> Can I use 1 half of the
>processor for my main application thread and the 2nd half for my video thread so

There is an affinity mask.
See the help topic "Multiple Processors"
Re: VC++ CSemaphore equivalent?
#2311
Author: Jonathan Benedicto
Date: Mon, 12 Mar 2007 17:56
29 lines
1714 bytes
Robert G. Hoover wrote:
>                // set semiphore
>                busy = true;

What is the semaphore used for?


>                // grab video frame(s) from camera
>                Grab(live_grabbing_count);

What does Grab do?


>                // process image data
>                Process();

What does Process do?


>                // display current image on screen
>                Display();

What does Display do?

I asked these questions because if the code inside any of those 3 functions 
is not thread-safe, a multi-core processor will cause your application to 
behave erratically.

Jon 
Re: VC++ CSemaphore equivalent?
#2313
Author: Robert G. Hoover
Date: Mon, 12 Mar 2007 17:56
53 lines
2672 bytes
Hi Bob,

Here's the specs I have...

Also, is it possible that my BeginThread() call is the improper function to
start my thread? Could it be bypassing some protocol to establish proper
multi-threading? The semaphores really aren't being used. They were put there
for future use which I never needed. The video is honestly just a grab and
splash, "set it and forget it". Should I use CreateThread() instead of
BeginThread()?

Thanks,

Rob

___________________________________________________


Processor
Type / Form Factor: Intel Pentium D 935
Multi-Core Technology: Dual-Core
64-bit Computing: Yes
Processor Qty: 1
Clock Speed: 3.2 GHz
Bus Speed: 800 MHz
Compatible Processor Socket: LGA775 Socket
Manufacturing Process: 65 nm
Thermal Design Power: 130 W
Architecture Features: Enhanced SpeedStep technology, streaming SIMD extensions
3, Intel Extended Memory 64 Technology, Execute Disable Bit capability

_________________________________________________________________


Bob Gonder wrote:
> Robert G. Hoover wrote:
> 
>> So, is my problem semaphore-related?
> 
> Do you Synchronize() your Display() ?
> 
>> Or rather processor related? I can't
> 
> What's the clock rate (per core) on this new super-duper cpu?
> It might actually be slower than your old cpu on a per-core basis.
> 
>> Can I use 1 half of the
>> processor for my main application thread and the 2nd half for my video thread so
> 
> There is an affinity mask.
> See the help topic "Multiple Processors"
> 
> 
Re: VC++ CSemaphore equivalent?
#2315
Author: Robert G. Hoover
Date: Mon, 12 Mar 2007 18:09
85 lines
3402 bytes
Hi Jon,

'busy' is unused throughout the rest of the application during execution. When
the user closes the main window, I set 'terminated' to true and wait until
'!grabbing'  Sorry for the confusion. I appended the total thread loop below.
'busy' is unused. Again, included for future use, not implemented in any other
part of the program.


'grab()' calls my camera supplier's video GrabSingleFrame() call which I have
been assured but cannot validate is thread-safe.


'process()' does nothing unless check marks are set in additional GUI window. No
functions are called from this routine as no checkmarks are checked.
ex. if (VideoForm->BlurImage->Checked) BlurVideoImage();


'display()' calls SendDIBitsToDevice()



Really, these threads should run independent of each other (I hope). The parent
thread (Main Application Thread embedded in Borland's TApplication?) listens for
Windows' events (WM_MOUSEMOVE, WM_CLOSE, etc.) and the child thread
Grab-And-Display video images. I guess I have no guarantee that the actual call
to the camera hardware to fill by bit-bucket (uchar buffer) is not causing the
problem. :(

Thanks,

Rob

___________________________________________________________________________


// background thread for live video display and processing
void VideoClass::LiveVideoGrabbingThread()
{
	// set semiphores
	terminated = false;
	busy       = false;
	grabbing   = true;

	// log event
	Global_UpdateStatusPrivate(String("entering ") + __FUNC__ + "()...");

	// grab, process, display live video as normal
	while (!terminated)
	{
		// give primary thread time to process frozen image
		if (frozen)
			Sleep(100);
	
		// grab, process, and display video data
		else
		{
			// set semiphore
			busy = true;

			// grab video frame from camera
			Grab();

			// process image data
			Process();

			// display current image on screen
			Display();

			// clear semiphore
			busy = false;

			// preserve process time
			Sleep(FrameRateTimeOut);
		}
	}
}

// log event
Global_UpdateStatusPrivate(String("exiting ") + __FUNC__ + "()...");

	// clear semiphore allowing main process to continue
	grabbing = false;
}
//---------------------------------------------------------------------------
Re: VC++ CSemaphore equivalent?
#2316
Author: Jonathan Benedicto
Date: Mon, 12 Mar 2007 18:16
42 lines
2485 bytes
Robert G. Hoover wrote:
> 'busy' is unused throughout the rest of the application during execution. 
> When
> the user closes the main window, I set 'terminated' to true and wait until
> '!grabbing'  Sorry for the confusion. I appended the total thread loop 
> below.
> 'busy' is unused. Again, included for future use, not implemented in any 
> other
> part of the program.

Ok.


> 'grab()' calls my camera supplier's video GrabSingleFrame() call which I 
> have
> been assured but cannot validate is thread-safe.

Ok.


> 'process()' does nothing unless check marks are set in additional GUI 
> window. No
> functions are called from this routine as no checkmarks are checked.
> ex. if (VideoForm->BlurImage->Checked) BlurVideoImage();

That does not sound like that function is thread-safe. I'd use a couple 
bools to store the state of the checkboxes, and then check the bools in the 
thread, instead of checking the actual checkboxes.


> 'display()' calls SendDIBitsToDevice()

Where do you get the device handle to pass to SendDIBitsToDevice?


> Really, these threads should run independent of each other (I hope).

Yes they do, however, they access data that is used by both threads, and if 
the access is not written in a thread-safe manner, it will not work 
properly.

Jon 
Win32 Semaphores in TThread?
#2317
Author: Robert G. Hoover
Date: Mon, 12 Mar 2007 18:21
12 lines
1687 bytes
I assume that the Win32 Semaphore functions are implemented in TThread? I've had
great success relying on Borland objects in the past for low-level routines
which I don't understand. :) Threads is certainly one of those, though I
understand the idea, I don't understand the implementation. Could I just use a
TThread instead of calling BeginThread on my own? Will all my problems go away?
(One can only hope!) I realize I'm still going to be susceptible to
non-thread-safe calls by thirdparty DLLs. I just need to eliminate all
possibilities within my power.

Thanks,

Rob
Re: Win32 Semaphores in TThread?
#2318
Author: Jonathan Benedicto
Date: Mon, 12 Mar 2007 18:27
16 lines
1695 bytes
Robert G. Hoover wrote:
>I assume that the Win32 Semaphore functions are implemented in TThread?

No they aren't. You'll still have to use the Win32 functions directly.

> I've had great success relying on Borland objects in the past for 
> low-level routines
> which I don't understand. :) Threads is certainly one of those, though I
> understand the idea, I don't understand the implementation. Could I just 
> use a
> TThread instead of calling BeginThread on my own? Will all my problems go 
> away?

No, your code is almost the same as what you'd use with TThread.

Jon 
Re: VC++ CSemaphore equivalent?
#2319
Author: Robert G. Hoover
Date: Mon, 12 Mar 2007 18:31
46 lines
2705 bytes
Hmm.... that makes sense about the checkboxes. On further review, I realize that
my code does exactly what you say. I have internal bool variables that are
altered by the GUI checkboxes. I must have run into something similar a few
years back. ;)

Display() uses...

HDC hDC = GetDC(hWindow);

hWindow is passed in as ShellForm->Handle which I assume is the handle to the
window? (ShellForm is my main window, built from TCustomForm by BDS)

So if both threads are accessing the same memory then they'll still be waiting
on each other, and I wouldn't have seen it until now with this new
dual-processor? And TThread won't help me one bit, eh? ;)

Thanks,

Rob



Jonathan Benedicto wrote:
> 
>> 'process()' does nothing unless check marks are set in additional GUI
>> window. No
>> functions are called from this routine as no checkmarks are checked.
>> ex. if (VideoForm->BlurImage->Checked) BlurVideoImage();
> 
> That does not sound like that function is thread-safe. I'd use a couple
> bools to store the state of the checkboxes, and then check the bools in
> the thread, instead of checking the actual checkboxes.
> 
> 
>> 'display()' calls SendDIBitsToDevice()
> 
> Where do you get the device handle to pass to SendDIBitsToDevice?
> 
> 
>> Really, these threads should run independent of each other (I hope).
> 
> Yes they do, however, they access data that is used by both threads, and
> if the access is not written in a thread-safe manner, it will not work
> properly.
> 
> Jon
Re: VC++ CSemaphore equivalent?
#2320
Author: Jonathan Benedicto
Date: Mon, 12 Mar 2007 18:40
34 lines
2138 bytes
Robert G. Hoover wrote:
> Display() uses...
>
> HDC hDC = GetDC(hWindow);
>
> hWindow is passed in as ShellForm->Handle which I assume is the handle to 
> the
> window? (ShellForm is my main window, built from TCustomForm by BDS)

Try commenting out the call to Display() and see if that cures the mouse 
lag. If it does, then it is highly likely that there is a sync issue in 
Display() causing the video to hiccup.


> So if both threads are accessing the same memory then they'll still be 
> waiting
> on each other

If two threads try to access the same data, they will access it, but it will 
cause problems with the threading, causing, in your case, the video to 
hiccup.


> and I wouldn't have seen it until now with this new
> dual-processor?

Correct.


> And TThread won't help me one bit, eh? ;)

Correct again. All TThread does is hide the BeginThread stuff.

Jon 
Multi-Thread HDC and video display
#2321
Author: Robert G. Hoover
Date: Mon, 12 Mar 2007 19:40
36 lines
2443 bytes
Hi Jon,

Sorry this had morphed into a video app discussion....

I commented out the Display() routine and there is no noticeable lag. :) But,
now how do I display my video without using
SendDIBitsToDevice(ShellForm->Handle)? I use GetDC to get the DC of the window
instead of using ShellForm->Canvas->Handle. Can I get the handle to the window
in such a way that gets around the TApplication like this? This Display()
function is just for quick splashing of video, meant to be as fast as possible.
That's why I'm calling low-level Win32 API call SendDIBitsToDevice instead of
using something like ShellForm->Canvas->Draw(0, 0, MyTBitmap). Should I be doing
this instead?

Many thanks,

Rob



Jonathan Benedicto wrote:
> Robert G. Hoover wrote:
>> Display() uses...
>>
>> HDC hDC = GetDC(hWindow);
>>
>> hWindow is passed in as ShellForm->Handle which I assume is the handle
>> to the
>> window? (ShellForm is my main window, built from TCustomForm by BDS)
> 
> Try commenting out the call to Display() and see if that cures the mouse
> lag. If it does, then it is highly likely that there is a sync issue in
> Display() causing the video to hiccup.
> 
> 
> Jon
Re: Multi-Thread HDC and video display
#2322
Author: Jonathan Benedicto
Date: Mon, 12 Mar 2007 20:15
31 lines
2404 bytes
Robert G. Hoover wrote:
> Sorry this had morphed into a video app discussion....

No problem. I've done work with multi-threading video applications, so I'm 
somewhat familiar with it :-)

> I commented out the Display() routine and there is no noticeable lag. :) 
> But,
> now how do I display my video without using
> SendDIBitsToDevice(ShellForm->Handle)? I use GetDC to get the DC of the 
> window
> instead of using ShellForm->Canvas->Handle. Can I get the handle to the 
> window
> in such a way that gets around the TApplication like this? This Display()
> function is just for quick splashing of video, meant to be as fast as 
> possible.
> That's why I'm calling low-level Win32 API call SendDIBitsToDevice instead 
> of
> using something like ShellForm->Canvas->Draw(0, 0, MyTBitmap). Should I be 
> doing
> this instead?

SetDIBitsToDevice is not a thread-safe function. I'd suggest looking up the 
DrawDib functions for simplicity because you'd need to convert your DIB to a 
DDB before blitting it to the screen.

The VCL draw functions aren't thread-safe either.

HTH

Jon 
Re: Win32 Semaphores in TThread?
#2323
Author: Bob Gonder
Date: Tue, 13 Mar 2007 00:10
11 lines
1446 bytes
Jonathan Benedicto wrote:

>Robert G. Hoover wrote:
>>Could I just  use a  TThread instead of calling BeginThread on my own?
>> Will all my problems go  away?
>
>No, your code is almost the same as what you'd use with TThread.

But don't you want the MainThread to do the drawing since it owns the
canvas?
That's why I mentioned TThread::Synchronize( &Display );
Re: Win32 Semaphores in TThread?
#2324
Author: Jonathan Benedicto
Date: Tue, 13 Mar 2007 00:35
10 lines
1533 bytes
Bob Gonder wrote:
> But don't you want the MainThread to do the drawing since it owns the
> canvas?
> That's why I mentioned TThread::Synchronize( &Display );

No, because that would penalize the speed. Ideally, the video thread should 
perform the rendering, you just can't use SetDIBitsToDevice as it is not 
thread-safe.

Jon 
Re: VC++ CSemaphore equivalent?
#2325
Author: DreamChaser
Date: Tue, 13 Mar 2007 01:15
27 lines
2171 bytes
Robert G. Hoover wrote:
> Hi Dennis,
> ie, the standard windows thread. So, I spawn a thread in my
> TShellForm::FormCreate() function...
> 
> 
> 	// spawn thread for advanced grab/display routines
> 	hThread = (HANDLE)BeginThread(THREAD_PRIORITY_NORMAL,
> 				      0, VideoGrabbingThread,
> 				      this, 0, ThreadID);
> 
> 	// set thread priority
> 	SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST);
> 
> 
Hey D,
Before CPP police show up, thought I would throw this in.
FormCreate() is only there because Pascal (i.e Delphi) needs it, not 
C++. You should all of your construction stuff in the form constructor. 
I have seen numerous references in these groups and elsewhere that 
FromCreate() "could" be fired prior to the Constructor being called. 
Although as near as I can tell it has something to do with the Phase of 
the Moon and the amount of rainfall in Africa that effects when this 
happens. ;)

This of course may or may not have anything to with your problem, but....
DC
Re: Multi-Thread HDC and video display
#2326
Author: Robert G. Hoover
Date: Tue, 13 Mar 2007 01:27
36 lines
2251 bytes
Hi Jon,

I looked up the DrawDib stuff and implemented it fairly quickly as I already
have the bmiHeader as part of the bmInfo structure.

I found and adapted the example from the Platform SDK : Windows Multimedia page

DrawDibBegin  (hDD, hDC, ???, ???,
		&(LiveImage->bmInfo.bmiHeader),
		LiveImage->Width, LiveImage->Height, NULL);

DrawDibRealize(hDD, hDC, 0);


What should I use for the "MM_TEXT client units" fields in DrawDibBegin? This is
not my destination size in pixels, right?

For reference, LiveImage is my wrapper for a BITMAP and BITMAPINFO structure.

Thanks SO much!!!

Rob



Jonathan Benedicto wrote:
> 
> SetDIBitsToDevice is not a thread-safe function. I'd suggest looking up
> the DrawDib functions for simplicity because you'd need to convert your
> DIB to a DDB before blitting it to the screen.
> 
> The VCL draw functions aren't thread-safe either.
> 
> HTH
> 
> Jon
Re: Multi-Thread HDC and video display
#2327
Author: Jonathan Benedicto
Date: Tue, 13 Mar 2007 01:31
10 lines
1583 bytes
Robert G. Hoover wrote:
> What should I use for the "MM_TEXT client units" fields in DrawDibBegin? 
> This is
> not my destination size in pixels, right?

I believe it is the destination size in pixels.

HTH

Jon 
Re: Multi-Thread HDC and video display
#2331
Author: Joe C. Hecht
Date: Tue, 13 Mar 2007 18:06
25 lines
2301 bytes
> SendDIBitsToDevice(ShellForm->Handle)? I use GetDC to get the DC of the window

Not trying to veer off track, but simply trying to provide a little advice.

If you mean SetDiBitsToDevice(), I would really recommend using StretchDIBits().

I say this as a guy who writes Windows graphic drivers, and can testify that:

1) Of the calls in a driver that work with DIBs, most (internally) are stubbed out to
eventually call a single output function in the driver (usually  modeled for StretchDIBits()),
so if speed is an issue, this is usually the fastest call.

2) The internals for the call that comes though  when you call SetDiBitsToDevice()
is so complex and so lacking in documentation, that some drivers get it wrong,
so there is a possibility for a lot of "flaky code". The support code is a nighmare.

Of course, the above only applies to monolithic graphic drivers.

Joe
-- 
Delphi, graphics, and printing specialist available - $35/hr
http://www.code4sale.com/codeit/index.htm
Joe Hecht Associates
121 Louise Drive
Crestview, FL 32536
Multi-Thread Processing on Dual-Core CPU
#2334
Author: Robert G. Hoover
Date: Wed, 14 Mar 2007 15:51
75 lines
3892 bytes
Hi Jon,

Yep, that did the trick. Makes sense, I suppose if you ignore the "MM_TEXT"
description???  ;)


As this thread has been incredibly helpful for my understanding of multi-thread
parallel processing, I'd like to throw another log on the fire....

I'm now realizing how little I know about multi-thread processing as my other
threads in my program are crashing out. For example, my commport listening
thread causes a program fault when I change the value of the indexing variable.
When I set RXSize to 0 in my main thread/process, the fault occurs, I assume
because it's fighting with the ReadFile() line below. This code has no
semaphores in it at all. If I place simple bool variables like 'busy' and
'waiting' into the code, will I run into the same problem, accessing the bool
variables from both sides at once? Is this a good case for the Win32 Semaphore
functions? Are they overkill for this little thing? My experience is very
limited because I never had this problem with single-processor systems, and of
course this code functions with no problem on my older machines. But the
dual-core.... no dice. :(

Thanks,

Rob

_____________________________________________________________

void CommPortClass::TransferThread()
{
	// log event
	Global_UpdateStatusPrivate(String("entering ") + __FUNC__ + "()...");

	// set semiphore
	ThreadTerminated = false;
	ThreadFinished   = false;

	// listen for incoming data, transfer outgoing data as needed
	while (!ThreadTerminated)
	{
		// number of bytes read from port
		DWORD BytesRead;

		// read from port in case data is coming in
		ReadFile(hComm, &(RXBuffer[RXSize]),
                         RXBufferLength - RXSize, BytesRead, NULL);

		// check for incoming data
		if (BytesRead)
		{
			// increase buffer count to reflect presence of new data
			RXSize += BytesRead;
		}

		// check for data to write
		if (TXSize)
		{
			// number of bytes written to port
			DWORD BytesOut;

			// write data to commport
			::WriteFile(hComm, TXBuffer, TXSize, &BytesOut, NULL);

			// decrement buffer count to reflect transfer of data
			TXSize -= BytesOut;
		}
	}

	// clear semaphore - allow class to exit
	ThreadFinished = true;

	// log event
	Global_UpdateStatusPrivate(String("exiting ") + __FUNC__ + "()...");
}
//---------------------------------------------------------------------------
Re: Multi-Thread Processing on Dual-Core CPU
#2336
Author: Jonathan Benedicto
Date: Wed, 14 Mar 2007 16:12
41 lines
2761 bytes
Robert G. Hoover wrote:
> Yep, that did the trick. Makes sense, I suppose if you ignore the 
> "MM_TEXT"
> description???  ;)

Good :-)

> I'm now realizing how little I know about multi-thread processing as my 
> other
> threads in my program are crashing out. For example, my commport listening
> thread causes a program fault when I change the value of the indexing 
> variable.
> When I set RXSize to 0 in my main thread/process, the fault occurs, I 
> assume
> because it's fighting with the ReadFile() line below.

Possibly. I would use a critical section for that code.

> This code has no semaphores in it at all. If I place simple bool variables 
> like
> 'busy' and 'waiting' into the code, will I run into the same problem, 
> accessing the
> bool variables from both sides at once?

Possibly. I personally wouldn't take any risks, and would just use 
semaphores, critical sections or events here.

> Is this a good case for the Win32 Semaphore
> functions? Are they overkill for this little thing?

I would say it is a good case for the Win32 syncronization functions. You 
can use critical sections, events or semaphores, depending on what you need 
to synchronize.

Read the topics in this page for some more detail on the thread 
syncronization functions that Windows has:
http://msdn2.microsoft.com/en-us/library/ms686353.aspx

HTH

Jon 
Re: Multi-Thread Processing on Dual-Core CPU
#2337
Author: Bob Gonder
Date: Wed, 14 Mar 2007 17:33
33 lines
2320 bytes
Robert G. Hoover wrote:

>When I set RXSize to 0 in my main thread/process, the fault occurs, I assume
>because it's fighting with the ReadFile() line below.

That doesn't sound like a very good idea.
For example:

>	ReadFile(hComm, &(RXBuffer[RXSize]),

RXSize is 1000
Start reading into RxBuffer[ 1000 ];
Main resets RXSize to 0
Read finishes 100 bytes

>		if (BytesRead)
>		{	RXSize += BytesRead;

RXSize is 100;
100 bytes are at RxBuffer[ 1000 ];
Who remembers those bytes?
Next read will take place at RxBuffer[100], not 0.

Other than CriticalSections, a nice way to keep order is to setup
pairs of variables.	V1 is read/writable by main, but read-only by
thread. V2 is read-only by main but read/writable by thread.

In this case, main would write I want you to read N bytes, and I have
read X bytes from your buffer.
Thread would write I have Y bytes avilable in the buffer at location
Z.

Likewise for TXSize. You have 2 threads modifying it.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads