[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
> - I create a new semaphore in the BDirectWindow constructor, initializing the
> counter to 0.
> - Inside the window redrawer thread, before doing the update I do an
> acquire_sem() on that sem, releasing it only at the end of the window update.
> - In the line switching read/write routine I do an acquire_sem() on the same
> sem, if the sem has not been yet acquired, and I release it on the unwrite_bank
> routine.
Problem, initializing a semaphore to 0 means you create it already
aquired. So, if both your threads then try to acquire it, then they both
are waiting for it to be released.
For an example of starting and stopping a thread when you want it too,
look at the mouse code. It only works when there is a graphics mode set
because I use a semaphore to stop the thread if there is no 'window view'
(the client area of a window) for it to be attached to.
The semaphore is created with a count of 0
In the mouse thread I acquire the semaphore, so if there is no graphics
mode it will wait here until...
After I create and attach a mouse view, the semaphore is released so the
mouse can run, then...
When I shutdown graphics I acquire the semaphore again which stops the
mouse thread.
To shutdown the mouse thread, I set the loop variable for the mouse thread
to false, then release the semaphore which causes it to return from the
thread function.
So here is the strategy:
Init:
create a semaphore with a 0 count
In the controlled thread:
acquire the semaphore before entering the critical section
release the semephore when done
In the controlling thread:
release the semaphore when you want the controlled thread to work
acquire the semaphore when you want it to stop
Shutdown:
set the loop variable for the thread to false
release the semaphore so the thread can exit
destroy the semaphore
Hmm, I am thinking that maybe this is not the right strategy for what you
are doing. You want the drawing thread to only draw if there are dirty
lines right? So we use the bank switch functions to mark those lines
dirty and wake the drawing thread up to take care them. Since only the
drawing thread knows when its done, it would make more sense if it could
put itself back to sleep.
I _think_ that this will work
Init:
create a semaphore with count 0
In the bank switch code:
release the semaphore after marking a line dirty
In the drawing thread:
acquire the semaphore at the top of a loop that updates dirty lines
for(;;) {
acquire_sem()
if (!running) {
release_sem()
return 0;
}
update dirty lines
}
Shutdown:
exit the thread (using a variable, like before)
destroy the semaphore
This will only allow the loop to run once for every bank switch. Now, I do
not remember if semaphores in Be count or not (i.e., if it is a counting
semphore, if I release it 5 times it has to be acquire 5 times). If they
don't then it means that the loop will only run once even if you release
the semaphore a dozen times. If it is counting that means the loop will
run a dozen times if you release the semaphore a dozen times.
In either case it should work (although in the counting case it would be
less efficent because one pass over the bitmap is enough to catch all the
dirty lines).
My big question is: Doesn't the BeDirectWindow give you direct access to
the windows video memory? Does the pointer to this memory change
everytime you acquire it?
--
The Phoenix -- The Artistic Intuition Company
Runica * Phoenix Quake * Caelius * Zen-X * Mirror Reflex * Infinite Realms