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

Reply via email to