On Tue, 2006-07-04 at 21:14 +1000, skaller wrote:
> I have just implemented world stop garbage collection.
Well some races bugs and other stuff fixed:
-------------------------------------------------
class thread_control_t
{
unsigned int thread_counter;
bool do_world_stop;
flx_condv_t stop_guard;
flx_mutex_t stop_mutex;
public:
thread_control_t () : do_world_stop(false), thread_counter(0)
{
fprintf(stderr,"INITIALISING THREAD CONTROL OBJECT\n");
}
int thread_count() {
flx_mutex_locker_t m(stop_mutex);
return thread_counter;
}
void add_thread() {
flx_mutex_locker_t m(stop_mutex);
fprintf(stderr, "Adding thread\n");
++thread_counter;
stop_guard.broadcast();
}
void remove_thread() {
flx_mutex_locker_t m(stop_mutex);
fprintf(stderr, "Removing thread\n");
--thread_counter;
stop_guard.broadcast();
}
// stop the world!
bool world_stop() {
flx_mutex_locker_t m(stop_mutex);
fprintf(stderr,"Stopping world\n");
if (do_world_stop) return false; // race! Someone else beat us
do_world_stop = true;
--thread_counter;
while(thread_counter>0) stop_guard.wait(&stop_mutex);
fprintf(stderr,"World STOPPED\n");
return true; // we stopped the world
}
// used by mainline to wait for other threads to die
void join_all()
{
flx_mutex_locker_t m(stop_mutex);
while(do_world_stop || thread_counter>0)
stop_guard.wait(&stop_mutex);
fprintf(stderr,"World restarted: do_world_stop=%d, Yield thread
count now %d\n",do_world_stop,thread_counter);
}
// restart the world
void world_start() {
flx_mutex_locker_t m(stop_mutex);
fprintf(stderr,"Restarting world\n");
++thread_counter;
do_world_stop = false;
stop_guard.broadcast();
}
void yield() {
flx_mutex_locker_t m(stop_mutex);
if (do_world_stop)
{
fprintf(stderr,"Yield found world stop!\n");
--thread_counter;
fprintf(stderr,"Yield thread count now %d\n",thread_counter);
stop_guard.broadcast();
while(do_world_stop) stop_guard.wait(&stop_mutex);
++thread_counter;
fprintf(stderr,"World restarted: do_world_stop=%d, Yield thread
count now %d\n",do_world_stop,thread_counter);
}
}
};
-----------------------------------
and I have a little test program:
-----------------------------------------------
#import <flx.flxh>
include "pthread";
include "flx_faio";
open String;
proc randprint(n:int)
{
var i = 5;
print$ "Start Thread number "+str(n); endl;
whilst i > 0 do
var d = double_of$ Cstdlib::rand()%10;
if d == 0.0 do
print "ZERO FOUND -- collecting!"; endl;
collect;
print "collected!"; endl;
done;
print$ "Thread "+str n +" Sleep #"+str i+" for "+str d+" sec"; endl;
--i;
Faio::sleep d;
done;
print$ "Finish Thread number "+str(n); endl;
}
Pthread::spawn_pthread { randprint(1); };
Pthread::spawn_pthread { randprint(2); };
Pthread::spawn_pthread { randprint(3); };
Pthread::spawn_pthread { randprint(4); };
Pthread::spawn_pthread { randprint(5); };
print "Mainline done!"; endl;
-------------------------------------------
The output (with heaps of debugging stuff added in):
--------------------------------------------
INITIALISING THREAD CONTROL OBJECT
Adding thread
Starting new pthread, thread counter= 1
Adding thread
Starting new pthread, thread counter= 2
Adding thread
Starting new pthread, thread counter= 3
Adding thread
Starting new pthread, thread counter= 4
Adding thread
Starting new pthread, thread counter= 5
Adding thread
Mainline done!
Removing thread
MAIN THREAD FINISHED: waiting for other threads
Start Thread number 1
Thread 1 Sleep #5 for 3 sec
module 'libflx_async_dynamic' loaded!
found 'create_async_hooker'!
Spawn detached worker thread, count=1
Spawn detached worker thread, count=2
Spawn detached worker thread, count=1
initing timer sleep thread
Start Thread number 2
Thread 2 Sleep #5 for 6 sec
Spawn detached worker thread, count=1
Spawn detached worker thread, count=2
Spawn detached worker thread, count=1
Start Thread number 3
Thread 3 Sleep #5 for 7 sec
Spawn detached worker thread, count=1
Spawn detached worker thread, count=2
Start Thread number 4
Thread 4 Sleep #5 for 5 sec
Spawn detached worker thread, count=1
Spawn detached worker thread, count=2
Start Thread number 5
Thread 5 Sleep #5 for 3 sec
Spawn detached worker thread, count=1
initing timer sleep thread
Spawn detached worker thread, count=1
initing timer sleep thread
Spawn detached worker thread, count=1
initing timer sleep thread
Spawn detached worker thread, count=2
Spawn detached worker thread, count=1
initing timer sleep thread
sleeper thread
sleeper thread
sleeper thread
sleeper thread
sleeper thread
Thread 1 Sleep #4 for 5 sec
Thread 5 Sleep #4 for 6 sec
Thread 4 Sleep #4 for 2 sec
Thread 2 Sleep #4 for 9 sec
Thread 3 Sleep #4 for 1 sec
Thread 4 Sleep #3 for 2 sec
Thread 3 Sleep #3 for 7 sec
ZERO FOUND -- collecting!
COLLECT SVC GOT
Stopping world
Thread 5 Sleep #3 for 9 sec
Yield found world stop!
Yield thread count now 3
Thread 4 Sleep #2 for 3 sec
Yield found world stop!
Yield thread count now 2
Thread 2 Sleep #3 for 6 sec
Yield found world stop!
Yield thread count now 1
ZERO FOUND -- collecting!
Yield found world stop!
Yield thread count now 0
World STOPPED
ACTUALLY COLLECTING
Restarting world
collected!
Thread 1 Sleep #3 for 0 sec
World restarted: do_world_stop=0, Yield thread count now 2
COLLECT SVC GOT
Stopping world
Thread 1 Sleep #2 for 6 sec
Yield found world stop!
Yield thread count now 0
World STOPPED
ACTUALLY COLLECTING
Restarting world
collected!
Thread 3 Sleep #2 for 0 sec
World restarted: do_world_stop=0, Yield thread count now 2
World restarted: do_world_stop=0, Yield thread count now 3
World restarted: do_world_stop=0, Yield thread count now 4
World restarted: do_world_stop=0, Yield thread count now 5
Thread 3 Sleep #1 for 2 sec
Finish Thread number 3
Deleting proto async
about to delete PRIOQ
Kill detached worker thread, count=1
Kill detached worker thread, count=2
Kill detached worker thread, count=1
Deleted async_hooker_impl
Deleted async_hooker
Removing thread
Thread 4 Sleep #1 for 6 sec
Thread 1 Sleep #1 for 1 sec
Thread 2 Sleep #2 for 8 sec
Finish Thread number 1
Deleting proto async
about to delete PRIOQ
Kill detached worker thread, count=1
Kill detached worker thread, count=2
Kill detached worker thread, count=1
Deleted async_hooker_impl
Deleted async_hooker
Removing thread
Thread 5 Sleep #2 for 7 sec
Finish Thread number 4
Deleting proto async
about to delete PRIOQ
Kill detached worker thread, count=1
Kill detached worker thread, count=2
Kill detached worker thread, count=1
Deleted async_hooker_impl
Deleted async_hooker
Removing thread
Thread 2 Sleep #1 for 9 sec
Thread 5 Sleep #1 for 2 sec
Finish Thread number 5
Deleting proto async
about to delete PRIOQ
Kill detached worker thread, count=1
Kill detached worker thread, count=2
Kill detached worker thread, count=1
Deleted async_hooker_impl
Deleted async_hooker
Removing thread
Finish Thread number 2
Deleting proto async
about to delete PRIOQ
Kill detached worker thread, count=1
Kill detached worker thread, count=2
Kill detached worker thread, count=1
Deleted async_hooker_impl
Deleted async_hooker
Removing thread
World restarted: do_world_stop=0, Yield thread count now 0
ALL THREADS DEAD: mainline cleanup!
------------------------------------------------
which all seems to work!
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Felix-language mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language