suspender.h

00001 /*
00002  *  Copyright (C) 2006  Helmut Grohne
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 #ifndef LIBMUTH_SUSPENDER_H
00020 #define LIBMUTH_SUSPENDER_H
00021 
00022 #include <assert.h>
00023 #include "suspender_decls.h"
00024 #include "currentthread.h"
00025 
00026 template<class T> T Suspender<T>::suspend() {
00027         this->lock.acquire();
00028         assert(this->microthread == NULL);
00029         if(!this->wakened) {
00030                 Microthread *m(this->microthread = &getcurrentthread());
00031                 this->lock.release();
00032                 m->delayme();
00033         } else
00034                 this->lock.release();
00035         assert(this->wakened == true);
00036         return this->retval;
00037 }
00038 
00039 template<class T> bool Suspender<T>::wakeup(const T &rv) {
00040         this->lock.acquire();
00041         if(this->wakened) {
00042                 this->lock.release();
00043                 return false;
00044         }
00045         this->retval = rv;
00046         this->wakened = true;
00047         if(Microthread *m = this->microthread) {
00048                 this->lock.release();
00049                 m->scheduleme();
00050         } else
00051                 this->lock.release();
00052         return true;
00053 }
00054 
00055 template<class T> bool Suspender<T>::cooperativewakeup(const T &rv) {
00056         this->lock.acquire();
00057         if(this->wakened) {
00058                 this->lock.release();
00059                 return false;
00060         }
00061         this->wakened = true;
00062         this->retval = rv;
00063         if(Microthread *m = this->microthread) {
00064                 this->lock.release();
00065                 Microthread &me(getcurrentthread());
00066                 me.scheduleme();
00067                 me.swapto(*m);
00068         } else
00069                 this->lock.release();
00070         return true;
00071 }
00072 
00073 template<class T> inline bool Suspender<T>::issuspended() const {
00074         /* TODO: unlocked! necessary? */
00075         return this->microthread != NULL && !this->wakened;
00076 }
00077 
00078 template<class T> inline bool Suspender<T>::iswakened() const {
00079         /* TODO: unlocked! necessary? */
00080         return this->wakened;
00081 }
00082 
00083 template<class T> inline bool Suspender<T>::iscompleted() const {
00084         /* TODO: unlocked! necessary? */
00085         return this->microthread != NULL && this->wakened;
00086 }
00087 
00088 #endif

Generated on Sat Feb 7 01:26:50 2009 by  doxygen 1.5.1