* [ECOS] Seeking Thread join / waitpid equivalent.
@ 2004-08-27 0:46 John Carter
2004-08-27 2:41 ` Billy
2004-08-27 13:25 ` Andrew Lunn
0 siblings, 2 replies; 9+ messages in thread
From: John Carter @ 2004-08-27 0:46 UTC (permalink / raw)
To: ecos-discuss
We have just been bitten by the "Don't free the thread into in the
destructor" problem as discussed so comprehensively by Ivan Horvat in
April.
http://sources.redhat.com/ml/ecos-discuss/2004-04/msg00122.html
Thanks Ivan!
Unfortunately the thread exiting is explicitly our lowest priority
thread, so Reaper in a mbox trick won't work.
However, in languages such as Ruby, you have the nifty thread.join
primitive. With processes under posix systems you have waitpid.
Isn't there something like that in ecos, where an arbitrary thread may wait
for another thread to exit?
John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand
The universe is absolutely plastered with the dashed lines exactly one
space long.
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ECOS] Seeking Thread join / waitpid equivalent.
2004-08-27 0:46 [ECOS] Seeking Thread join / waitpid equivalent John Carter
@ 2004-08-27 2:41 ` Billy
2004-08-27 3:44 ` John Carter
2004-08-27 13:25 ` Andrew Lunn
1 sibling, 1 reply; 9+ messages in thread
From: Billy @ 2004-08-27 2:41 UTC (permalink / raw)
To: John Carter; +Cc: ecos-discuss
On Fri, Aug 27, 2004 at 12:02:00PM +1200, John Carter wrote:
> We have just been bitten by the "Don't free the thread into in the
> destructor" problem as discussed so comprehensively by Ivan Horvat in
> April.
> http://sources.redhat.com/ml/ecos-discuss/2004-04/msg00122.html
>
> Thanks Ivan!
>
> Unfortunately the thread exiting is explicitly our lowest priority
> thread, so Reaper in a mbox trick won't work.
I think the cyg_thread destruction question above is different from the
thread.join question below.
> However, in languages such as Ruby, you have the nifty thread.join
> primitive. With processes under posix systems you have waitpid.
> Isn't there something like that in ecos, where an arbitrary thread may wait
> for another thread to exit?
I dealt with this by hand, by applying a thin veneer of plastic wrap to
the eCos thread API. What it did was associate a death_semaphore with
each my thread objects. The cyg_thread_entry function I gave to eCos
looked something like:
void
thread_entry_function(cyg_addrword_t data)
{
struct myThreadType *thread = (struct myThreadType*)data;
(*thread->entry_function)(thread->data);
cyg_semaphore_post(&thread->death_semaphore);
}
So thread_join() was implemented as a wait() on that thread's
death_semaphore:
void
thread_join(struct myThreadType *thread)
{
cyg_semaphore_wait(&thread->death_semaphore);
}
Obviously nobody's trying to join() your lowest priority thread, so
the post would go unnoticed.
Semaphores aren't the best sync primative for this, but that's what I
did. If I redo it, I'll probably use condition variables or event flags.
So I have intercepted the death of the thread by wrapping the
entry_function. If you wanted to dig into Cyg_Thread::exit() and
put the post() in there, I guess it would be more seamless, but
then you're changing eCos code, which I try to avoid.
Just my 0.02
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ECOS] Seeking Thread join / waitpid equivalent.
2004-08-27 2:41 ` Billy
@ 2004-08-27 3:44 ` John Carter
2004-08-27 5:50 ` John Carter
2004-08-27 6:47 ` Billy
0 siblings, 2 replies; 9+ messages in thread
From: John Carter @ 2004-08-27 3:44 UTC (permalink / raw)
To: Billy; +Cc: ecos-discuss
On Thu, 26 Aug 2004, Billy wrote:
> On Fri, Aug 27, 2004 at 12:02:00PM +1200, John Carter wrote:
> I think the cyg_thread destruction question above is different from the
> thread.join question below.
Yes and no. What the guy was trying to do via a thread destructor
would have been much more simply achieved via a thread.join in a
reaper thread.
thread_join(thread);
cyg_thread_delete(thread.handle);
free(thread.stack);
> void
> thread_entry_function(cyg_addrword_t data)
> {
> struct myThreadType *thread = (struct myThreadType*)data;
> (*thread->entry_function)(thread->data);
> cyg_semaphore_post(&thread->death_semaphore);
> }
>
> void
> thread_join(struct myThreadType *thread)
> {
> cyg_semaphore_wait(&thread->death_semaphore);
> }
>
So if you are doing something like..
thread_join( &thread);
cyg_thread_delete( thread.handle);
unless the thread doing the join is of lower priority than the
exiting thread there exists a narrow gap between the post and the end
of cyg_thread_exit during which cyg_thread_delete can fail.
ie. Fundamentally _any_ userland fix to this problem is not going to
work.
The only hack I can think of is to use something like your thread
join, do the delete, test the result, if it failed sleep for a period,
repeat with exponential fall off on the sleep period.
Ugly ugly ugly.
John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand
The universe is absolutely plastered with the dashed lines exactly one
space long.
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ECOS] Seeking Thread join / waitpid equivalent.
2004-08-27 3:44 ` John Carter
@ 2004-08-27 5:50 ` John Carter
2004-09-03 5:35 ` sandeep
2004-08-27 6:47 ` Billy
1 sibling, 1 reply; 9+ messages in thread
From: John Carter @ 2004-08-27 5:50 UTC (permalink / raw)
To: ecos-discuss
I have just found this rather ugly code in the tftp_server.c
So it kills the tftp server thread...
cyg_thread_kill(server->thread_handle);
whangs the priority of the thread it killed as high as possible.
cyg_thread_set_priority(server->thread_handle, 0);
Waits a random period for it to die
cyg_thread_delay(1); // Make sure it gets to die...
Deletes the thread...
if (cyg_thread_delete(server->thread_handle)) {
If deleting the thread actually worked...
// Success shutting down the thread
Frees the memory associated with the thread..
free(server); // Give up memory
return 1;
}
Else ... we have a memory leak.
See why I'm looking for a cleaner way to do this?
On Fri, 27 Aug 2004, John Carter wrote:
>
> Yes and no. What the guy was trying to do via a thread destructor
> would have been much more simply achieved via a thread.join in a
> reaper thread.
>
> thread_join(thread);
> cyg_thread_delete(thread.handle);
> free(thread.stack);
>
>> void
>> thread_entry_function(cyg_addrword_t data)
>> {
>> struct myThreadType *thread = (struct myThreadType*)data;
>> (*thread->entry_function)(thread->data);
>> cyg_semaphore_post(&thread->death_semaphore);
>> }
>>
>
>> void
>> thread_join(struct myThreadType *thread)
>> {
>> cyg_semaphore_wait(&thread->death_semaphore);
>> }
>>
>
>
> So if you are doing something like..
>
> thread_join( &thread);
> cyg_thread_delete( thread.handle);
>
> unless the thread doing the join is of lower priority than the
> exiting thread there exists a narrow gap between the post and the end
> of cyg_thread_exit during which cyg_thread_delete can fail.
>
> ie. Fundamentally _any_ userland fix to this problem is not going to
> work.
>
> The only hack I can think of is to use something like your thread
> join, do the delete, test the result, if it failed sleep for a period,
> repeat with exponential fall off on the sleep period.
>
> Ugly ugly ugly.
>
>
>
>
>
> John Carter Phone : (64)(3) 358 6639
> Tait Electronics Fax : (64)(3) 359 4632
> PO Box 1645 Christchurch Email : john.carter@tait.co.nz
> New Zealand
>
> The universe is absolutely plastered with the dashed lines exactly one
> space long.
>
John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand
The universe is absolutely plastered with the dashed lines exactly one
space long.
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ECOS] Seeking Thread join / waitpid equivalent.
2004-08-27 3:44 ` John Carter
2004-08-27 5:50 ` John Carter
@ 2004-08-27 6:47 ` Billy
1 sibling, 0 replies; 9+ messages in thread
From: Billy @ 2004-08-27 6:47 UTC (permalink / raw)
To: John Carter; +Cc: Billy, ecos-discuss
On Fri, Aug 27, 2004 at 02:41:41PM +1200, John Carter wrote:
> On Thu, 26 Aug 2004, Billy wrote:
>
> >On Fri, Aug 27, 2004 at 12:02:00PM +1200, John Carter wrote:
> >I think the cyg_thread destruction question above is different from the
> >thread.join question below.
>
> Yes and no. What the guy was trying to do via a thread destructor
> would have been much more simply achieved via a thread.join in a
> reaper thread.
>
> thread_join(thread);
> cyg_thread_delete(thread.handle);
> free(thread.stack);
True only if his reaper were stalking a single thread. If his reaper is
stalking more than one, which would he join with first? Maybe this is
why I thought they were different questions.
> > void
> > thread_entry_function(cyg_addrword_t data)
> > {
> > struct myThreadType *thread = (struct myThreadType*)data;
> > (*thread->entry_function)(thread->data);
> > cyg_semaphore_post(&thread->death_semaphore);
> > }
> >
>
> > void
> > thread_join(struct myThreadType *thread)
> > {
> > cyg_semaphore_wait(&thread->death_semaphore);
> > }
> >
>
>
> So if you are doing something like..
>
> thread_join( &thread);
> cyg_thread_delete( thread.handle);
>
> unless the thread doing the join is of lower priority than the
> exiting thread there exists a narrow gap between the post and the end
> of cyg_thread_exit during which cyg_thread_delete can fail.
That's true. I see that I was only getting away with it because I don't
ever actually delete the expired thread.
> ie. Fundamentally _any_ userland fix to this problem is not going to
> work.
Apparently so! There are no hooks to mark the end of cyg_thread_exit()
and the thread_delete()-ability of a thread. Seems like they might be
useful in order to make cyg_thread_delete() practical without resorting
to priority acrobatics and unnecessary thread_delay calls. I'd hope
such a proposal would be more waitpid()-ish than join()-ish, to enable a
peer-priority reaper to stalk multiple victims.
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ECOS] Seeking Thread join / waitpid equivalent.
2004-08-27 0:46 [ECOS] Seeking Thread join / waitpid equivalent John Carter
2004-08-27 2:41 ` Billy
@ 2004-08-27 13:25 ` Andrew Lunn
1 sibling, 0 replies; 9+ messages in thread
From: Andrew Lunn @ 2004-08-27 13:25 UTC (permalink / raw)
To: John Carter; +Cc: ecos-discuss
On Fri, Aug 27, 2004 at 12:02:00PM +1200, John Carter wrote:
> We have just been bitten by the "Don't free the thread into in the
> destructor" problem as discussed so comprehensively by Ivan Horvat in
> April.
> http://sources.redhat.com/ml/ecos-discuss/2004-04/msg00122.html
>
> Thanks Ivan!
>
> Unfortunately the thread exiting is explicitly our lowest priority
> thread, so Reaper in a mbox trick won't work.
Not a problem. Change the priority of the thread as it exits to
something higher than the reaper thread.
Andrew
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ECOS] Seeking Thread join / waitpid equivalent.
2004-08-27 5:50 ` John Carter
@ 2004-09-03 5:35 ` sandeep
2004-09-03 17:22 ` Billy
0 siblings, 1 reply; 9+ messages in thread
From: sandeep @ 2004-09-03 5:35 UTC (permalink / raw)
To: John Carter; +Cc: ecos-discuss
John Carter wrote:
> I have just found this rather ugly code in the tftp_server.c
>
> So it kills the tftp server thread...
> cyg_thread_kill(server->thread_handle);
>
> whangs the priority of the thread it killed as high as possible.
> cyg_thread_set_priority(server->thread_handle, 0);
>
> Waits a random period for it to die
> cyg_thread_delay(1); // Make sure it gets to die...
how can you ensure that delay of 1 or N ticks that you put here, makes sure that
it gets to die??? unless ofcourse you never have any thread in your system that
runs at priority 0 (highest) apart from these cases where you boost priority of
thread you killed, to 0.
for, if you have some threads running at priority 0 already, you need to know
the maximum no. of them that can be there in runqueue at any point of time, that
will be before your boosted-priority thread (considering round robin scheduling
and no-SMP) to find a sure-value that can be given to above cyg_thread_delay.
> Deletes the thread...
> if (cyg_thread_delete(server->thread_handle)) {
>
> If deleting the thread actually worked...
>
> // Success shutting down the thread
> Frees the memory associated with the thread..
> free(server); // Give up memory
> return 1;
> }
> Else ... we have a memory leak.
--
sandeep
--------------------------------------------------------------------------
"I do not know myself, and God forbid that I should."
--------------------------------------------------------------------------
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ECOS] Seeking Thread join / waitpid equivalent.
2004-09-03 5:35 ` sandeep
@ 2004-09-03 17:22 ` Billy
0 siblings, 0 replies; 9+ messages in thread
From: Billy @ 2004-09-03 17:22 UTC (permalink / raw)
To: sandeep; +Cc: John Carter, ecos-discuss
On Fri, Sep 03, 2004 at 11:15:45AM +0530, sandeep wrote:
> John Carter wrote:
> >I have just found this rather ugly code in the tftp_server.c
> >
> >So it kills the tftp server thread...
> > cyg_thread_kill(server->thread_handle);
> >
> >whangs the priority of the thread it killed as high as possible.
> > cyg_thread_set_priority(server->thread_handle, 0);
> >
> >Waits a random period for it to die
> > cyg_thread_delay(1); // Make sure it gets to die...
> how can you ensure that delay of 1 or N ticks that you put here, makes sure
> that it gets to die???
> unless ofcourse you never have any thread in your
> system that runs at priority 0 (highest) apart from these cases where you
> boost priority of thread you killed, to 0.
You can't be sure. It's unreliable code. At the least, it places
spooky taboos (regarding thread priorities) on applications that need to
integrate the tftp server.
This was John's point, I think.
> for, if you have some threads running at priority 0 already, you need to
> know the maximum no. of them that can be there in runqueue at any point of
> time, that will be before your boosted-priority thread (considering round
> robin scheduling and no-SMP) to find a sure-value that can be given to
> above cyg_thread_delay.
> >Deletes the thread...
> > if (cyg_thread_delete(server->thread_handle)) {
> >
> >If deleting the thread actually worked...
> >
> > // Success shutting down the thread
> >Frees the memory associated with the thread..
> > free(server); // Give up memory
> > return 1;
> > }
> >Else ... we have a memory leak.
A replacing the 'if' with 'while' and bringing the
cyg_thread_delay inside would be better, I guess...
Still a clumsy hack which could be avoided if there were
a mechanism to wait on a thread's 'delete'-ability.
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
* [ECOS] Seeking Thread join / waitpid equivalent.
@ 2004-09-06 10:32 Øyvind Harboe
0 siblings, 0 replies; 9+ messages in thread
From: Øyvind Harboe @ 2004-09-06 10:32 UTC (permalink / raw)
To: ecos-discuss, john.carter
How about:
struct args
{
cyg_handle_t caller;
};
static void invoker(cyg_addrword_t userData)
{
args *a=(args *)userData;
// this fn returns when the terminate flag is set
doWork();
// once the thread runs off the end of the universe, the
scheduler is
// unlocked => it is not necessary to unlock the scheduler from
// the "caller" thread below.
cyg_scheduler_lock();
cyg_thread_resume(a->caller);
}
void foo()
{
....
cyg_thread_create(0,
invoker,
(cyg_addrword_t)&a,
"work",
stack,
stackSize,
&threadHandle,
&thread);
// start thread
cyg_thread_resume(threadHandle);
doSomethingElse();
// we do not want anyone else to run at this point
cyg_sched_lock();
setThreadTerminateFlag();
// at this point we will do nothing but wait for the other
// thread to complete.
// we'll be resumed by the thread above when it exits
cyg_thread_suspend(a.caller);
cyg_sched_unlock();
if (!cyg_thread_delete(threadHandle))
{
CYG_FAIL("Thread should be terminated by now");
}
}
--
Øyvind Harboe
http://www.zylin.com
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-09-06 10:32 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-27 0:46 [ECOS] Seeking Thread join / waitpid equivalent John Carter
2004-08-27 2:41 ` Billy
2004-08-27 3:44 ` John Carter
2004-08-27 5:50 ` John Carter
2004-09-03 5:35 ` sandeep
2004-09-03 17:22 ` Billy
2004-08-27 6:47 ` Billy
2004-08-27 13:25 ` Andrew Lunn
2004-09-06 10:32 Øyvind Harboe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).