From a5b45e8e2e99686ea73fa2793d7fec84f0d1a3ed Mon Sep 17 00:00:00 2001
From: Thomas Grill <xovo@users.sourceforge.net>
Date: Tue, 17 Dec 2002 04:36:31 +0000
Subject:  ""

svn path=/trunk/; revision=303
---
 externals/grill/flext/flext.cw                    | Bin 202097 -> 202097 bytes
 externals/grill/flext/flext.doxy                  |  15 +-
 externals/grill/flext/flext.dsp                   |   2 +-
 externals/grill/flext/readme.txt                  |   8 +-
 externals/grill/flext/source/flclass.h            |  41 +----
 externals/grill/flext/source/flext.cpp            |   2 +-
 externals/grill/flext/source/flprefix.h           |  50 ++++--
 externals/grill/flext/source/flsupport.h          |  37 +++++
 externals/grill/flext/source/flthr.cpp            | 180 ++++++++--------------
 externals/grill/flext/tutorial/thread1/thread1.cw | Bin 68426 -> 68426 bytes
 10 files changed, 156 insertions(+), 179 deletions(-)

(limited to 'externals/grill/flext')

diff --git a/externals/grill/flext/flext.cw b/externals/grill/flext/flext.cw
index e6e05add..0cb21636 100644
Binary files a/externals/grill/flext/flext.cw and b/externals/grill/flext/flext.cw differ
diff --git a/externals/grill/flext/flext.doxy b/externals/grill/flext/flext.doxy
index 553294ee..a1aa48f9 100644
--- a/externals/grill/flext/flext.doxy
+++ b/externals/grill/flext/flext.doxy
@@ -1,10 +1,10 @@
-# Doxyfile 1.2.17
+# Doxyfile 1.3-rc2
 
 #---------------------------------------------------------------------------
 # General configuration options
 #---------------------------------------------------------------------------
 PROJECT_NAME           = flext
-PROJECT_NUMBER         = "version 0.4.0"
+PROJECT_NUMBER         = "version 0.4.1"
 OUTPUT_DIRECTORY       = f:/prog/max/flext/doc/
 OUTPUT_LANGUAGE        = English
 EXTRACT_ALL            = NO
@@ -14,6 +14,7 @@ EXTRACT_LOCAL_CLASSES  = YES
 HIDE_UNDOC_MEMBERS     = YES
 HIDE_UNDOC_CLASSES     = YES
 HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
 BRIEF_MEMBER_DESC      = YES
 REPEAT_BRIEF           = YES
 ALWAYS_DETAILED_SEC    = NO
@@ -21,7 +22,6 @@ INLINE_INHERITED_MEMB  = NO
 FULL_PATH_NAMES        = NO
 STRIP_FROM_PATH        = 
 INTERNAL_DOCS          = YES
-STRIP_CODE_COMMENTS    = YES
 CASE_SENSE_NAMES       = YES
 SHORT_NAMES            = NO
 HIDE_SCOPE_NAMES       = NO
@@ -51,6 +51,7 @@ SHOW_USED_FILES        = YES
 QUIET                  = NO
 WARNINGS               = YES
 WARN_IF_UNDOCUMENTED   = NO
+WARN_IF_DOC_ERROR      = YES
 WARN_FORMAT            = "$file:$line: $text"
 WARN_LOGFILE           = 
 #---------------------------------------------------------------------------
@@ -73,6 +74,7 @@ FILTER_SOURCE_FILES    = NO
 #---------------------------------------------------------------------------
 SOURCE_BROWSER         = YES
 INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
 REFERENCED_BY_RELATION = YES
 REFERENCES_RELATION    = YES
 #---------------------------------------------------------------------------
@@ -142,6 +144,13 @@ XML_DTD                =
 #---------------------------------------------------------------------------
 GENERATE_AUTOGEN_DEF   = NO
 #---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
 # Configuration options related to the preprocessor   
 #---------------------------------------------------------------------------
 ENABLE_PREPROCESSING   = YES
diff --git a/externals/grill/flext/flext.dsp b/externals/grill/flext/flext.dsp
index 1de1cb26..d13680e9 100644
--- a/externals/grill/flext/flext.dsp
+++ b/externals/grill/flext/flext.dsp
@@ -89,7 +89,7 @@ LIB32=link.exe -lib
 # PROP Intermediate_Dir "pd-msvc\td"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GR /ZI /Od /I "c:\programme\audio\pd\src" /I "." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "PD" /D "NT" /D "FLEXT_THREADS" /FR /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "c:\programme\audio\pd\src" /I "f:\prog\packs\sndobj\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D FLEXT_SYS=2 /D "FLEXT_THREADS" /FR /YX"flext.h" /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "c:\programme\audio\pd\src" /I "f:\prog\packs\sndobj\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "FLEXT_SYS_PD" /D "FLEXT_THREADS" /FR /YX"flext.h" /FD /GZ /c
 # ADD BASE RSC /l 0xc07 /d "_DEBUG"
 # ADD RSC /l 0xc07 /d "_DEBUG"
 BSC32=bscmake.exe
diff --git a/externals/grill/flext/readme.txt b/externals/grill/flext/readme.txt
index b58df39c..7fbcc8dc 100644
--- a/externals/grill/flext/readme.txt
+++ b/externals/grill/flext/readme.txt
@@ -111,6 +111,10 @@ Version history:
 - SndObjs: fixed typo (numbers of output slots was wrong) and init bug
 - introduced a helper thread for launching flext threads in the background
 - threads are now handled on class (as opposed to object) level
+- threads can now be terminated separately
+- put more flext functions into flext static class
+- replaced ChangePriority by RefPriority
+- fixed setting of priorities...  problems were caused by a compiler bug (MSVC 6)
 
 0.4.0:
 - the use of the const keyword is enforced (e.g. the preferred type for symbols is now "const t_symbol *")
@@ -274,12 +278,8 @@ TODO list:
 general:
 - documentation
 - add log messages for debugging version
-- where to put flext source/lib in linux: /usr/local/lib,/usr/local/include ?
-- clean up headers (eliminate flstdc.h?)
-- check that SetupInOut is only called once
 - feed assist function with in/outlet description
 - MaxMSP: how to call separate help files for objects in a library?
-- MaxMSP for OSX: add support 
 
 bugs:
 - PD: problems with timed buffer redrawing (takes a lot of cpu time)
diff --git a/externals/grill/flext/source/flclass.h b/externals/grill/flext/source/flclass.h
index 6f74b5fe..66da8e7a 100644
--- a/externals/grill/flext/source/flclass.h
+++ b/externals/grill/flext/source/flclass.h
@@ -392,37 +392,8 @@ public:
 		@{ 
 	*/
 
-	/*! \brief Check if current thread should terminate
-		\todo Check for currently running thread
-	*/
-	bool ShouldExit() const { return shouldexit; }
-
-	//! Check if current thread is the realtime system's thread
-	bool IsSystemThread() const { pthread_t cur = pthread_self(); return pthread_equal(cur,thrid) != 0; }
-
-	/*! \brief Yield to other threads
-		\remark A call to this is only needed for systems with cooperative multitasking like MacOS<=9
-	*/
-	static void ThrYield() { sched_yield(); }
-
-	typedef pthread_t thrid_t;
-
-	/*! \brief Get current thread id
-	*/
-	static thrid_t GetThreadId();
-
-	/*! \brief Increase/Decrease priority of a thread
-	*/
-	static bool ChangePriority(int dp,thrid_t thr = GetThreadId());
-
-	/*! \brief Get priority of a thread
-	*/
-	static int GetPriority(thrid_t thr = GetThreadId());
-
-	/*! \brief Set priority of a thread
-	*/
-	static bool SetPriority(int p,thrid_t thr = GetThreadId());
-
+	//! Check if current thread should terminate
+	bool ShouldExit() const;
 
 #endif // FLEXT_THREADS
 
@@ -467,12 +438,12 @@ protected:
 	class thr_entry 
 	{
 	public:
-		thr_entry(flext_base *t,void *(*m)(thr_params *),thr_params *p,pthread_t id = pthread_self()): th(t),meth(m),params(p),thrid(id),active(false),nxt(NULL) {}
+		thr_entry(flext_base *t,void *(*m)(thr_params *),thr_params *p,pthread_t id = pthread_self());
 
 		//! \brief Check if this class represents the current thread
 		bool Is(pthread_t id = pthread_self()) const { return pthread_equal(thrid,id) != 0; }
 
-		bool active;
+		bool active,shouldexit;
 		pthread_t thrid;
 		void *(*meth)(thr_params *);
 		thr_params *params;
@@ -660,10 +631,6 @@ private:
 	static bool cb_SetAttrib(flext_base *c,const t_symbol *s,int argc,const t_atom *argv) { return c->SetAttrib(s,argc,argv); }
 
 #ifdef FLEXT_THREADS
-	bool shouldexit;
-	int thrcount;
-	
-	static pthread_t thrid;  // the thread that created the object (the system thread)
 	ThrMutex qmutex;
 
 	static thr_entry *thrhead,*thrtail;
diff --git a/externals/grill/flext/source/flext.cpp b/externals/grill/flext/source/flext.cpp
index d0fdb766..764bfa98 100644
--- a/externals/grill/flext/source/flext.cpp
+++ b/externals/grill/flext/source/flext.cpp
@@ -130,7 +130,7 @@ flext_base::flext_base():
 	LOG1("%s - flext logging is on",thisName());
 
 #ifdef FLEXT_THREADS
-	shouldexit = false;
+//	shouldexit = false;
 //	thrhead = thrtail = NULL;
 #endif
 	qhead = qtail = NULL;
diff --git a/externals/grill/flext/source/flprefix.h b/externals/grill/flext/source/flprefix.h
index 34debe69..d2c7f173 100755
--- a/externals/grill/flext/source/flprefix.h
+++ b/externals/grill/flext/source/flprefix.h
@@ -15,41 +15,61 @@ WARRANTIES, see the file, "license.txt," in this distribution.
 #ifndef __FLEXT_PREFIX_H
 #define __FLEXT_PREFIX_H
 
-// definitions for FLEXT_SYS
+// --- definitions for FLEXT_SYS ---------------------
 #define FLEXT_SYS_UNKNOWN	0
-#define FLEXT_SYS_MAX	1
-#define FLEXT_SYS_PD	2
 
-// definitions for FLEXT_OS
+#ifndef FLEXT_SYS_MAX
+	#define FLEXT_SYS_MAX	1
+#else
+	// already defined
+	#undef FLEXT_SYS_MAX
+	#define FLEXT_SYS_MAX	1
+	#define FLEXT_SYS FLEXT_SYS_MAX
+#endif
+
+#ifndef FLEXT_SYS_PD
+	#define FLEXT_SYS_PD	2
+#else
+	// already defined
+	#undef FLEXT_SYS_PD
+	#define FLEXT_SYS_PD	2
+	#define FLEXT_SYS FLEXT_SYS_PD
+#endif
+
+// --- definitions for FLEXT_OS ----------------------
 #define FLEXT_OS_UNKNOWN	0
 #define FLEXT_OS_WIN	1
 #define FLEXT_OS_MACOS	2  
 #define FLEXT_OS_LINUX	3
 #define FLEXT_OS_IRIX	4
 
-// definitions for FLEXT_CPU
+// --- definitions for FLEXT_CPU ---------------------
 #define FLEXT_CPU_UNKNOWN	0
 #define FLEXT_CPU_INTEL 1
 #define FLEXT_CPU_PPC 	2
 #define FLEXT_CPU_MIPS	3
 #define FLEXT_CPU_ALPHA	4
 
-
-
-// Old definitions
-#if defined(MAXMSP)
-	#define FLEXT_SYS FLEXT_SYS_MAX
-//	#undef MAXMSP
-#elif defined(PD)
-	#define FLEXT_SYS FLEXT_SYS_PD
-//	#undef PD
-//	#undef NT
+// ---------------------------------------------------
+// support old definitions
+
+#ifndef FLEXT_SYS
+	#if defined(MAXMSP)
+		#define FLEXT_SYS FLEXT_SYS_MAX
+	//	#undef MAXMSP
+	#elif defined(PD)
+		#define FLEXT_SYS FLEXT_SYS_PD
+	//	#undef PD
+	//	#undef NT
+	#endif
 #endif
 
 #if defined(_DEBUG)
 	#define FLEXT_DEBUG
 #endif
 
+// ---------------------------------------------------
+
 // Definition of supported real-time systems
 #if FLEXT_SYS == FLEXT_SYS_MAX
 #elif FLEXT_SYS == FLEXT_SYS_PD
diff --git a/externals/grill/flext/source/flsupport.h b/externals/grill/flext/source/flsupport.h
index 08036ff5..9429599d 100644
--- a/externals/grill/flext/source/flsupport.h
+++ b/externals/grill/flext/source/flsupport.h
@@ -391,6 +391,43 @@ public:
 		@{ 
 	*/
 
+	//! thread type
+	typedef pthread_t thrid_t;
+
+protected:
+	//! system's thread id
+	static thrid_t thrid;  // the system thread
+
+public:
+
+	//! Check if current thread is the realtime system's thread
+	static bool IsSystemThread() { pthread_t cur = pthread_self(); return pthread_equal(cur,thrid) != 0; }
+
+	/*! \brief Yield to other threads
+		\remark A call to this is only needed for systems with cooperative multitasking like MacOS<=9
+	*/
+	static void ThrYield() { sched_yield(); }
+
+	/*! \brief Get current thread id
+	*/
+	static thrid_t GetThreadId() { return pthread_self(); }
+
+	/*! \brief Get current thread id
+	*/
+	static thrid_t GetSysThreadId() { return thrid; }
+
+	/*! \brief Increase/Decrease priority of a thread
+	*/
+	static bool RelPriority(int dp,thrid_t ref = GetSysThreadId(),thrid_t thr = GetThreadId());
+
+	/*! \brief Get priority of a thread
+	*/
+	static int GetPriority(thrid_t thr = GetThreadId());
+
+	/*! \brief Set priority of a thread
+	*/
+	static bool SetPriority(int p,thrid_t thr = GetThreadId());
+
 	/*! \brief Thread mutex
 		\sa pthreads documentation
 	*/
diff --git a/externals/grill/flext/source/flthr.cpp b/externals/grill/flext/source/flthr.cpp
index 97da5584..36184025 100644
--- a/externals/grill/flext/source/flthr.cpp
+++ b/externals/grill/flext/source/flthr.cpp
@@ -24,10 +24,10 @@ WARRANTIES, see the file, "license.txt," in this distribution.
 #include <errno.h>
 
 //! Thread id of system thread
-pthread_t flext_base::thrid;
+flext::thrid_t flext::thrid;
 
 //! Thread id of helper thread
-pthread_t flext_base::thrhelpid;
+flext::thrid_t flext_base::thrhelpid;
 
 flext_base::thr_entry *flext_base::thrhead = NULL,*flext_base::thrtail = NULL;
 flext::ThrMutex flext_base::tlmutex;
@@ -35,8 +35,17 @@ flext::ThrMutex flext_base::tlmutex;
 //! Helper thread should terminate
 bool thrhelpexit = false;
 
+//! Helper thread conditional
 flext::ThrCond *thrhelpcond = NULL;
 
+
+flext_base::thr_entry::thr_entry(flext_base *t,void *(*m)(thr_params *),thr_params *p,pthread_t id): 
+	th(t),meth(m),params(p),thrid(id),
+	active(false),shouldexit(false),
+	nxt(NULL) 
+{}
+
+
 //! Start helper thread
 bool flext_base::StartHelper()
 {
@@ -75,15 +84,7 @@ void flext_base::ThrHelper(void *)
 
 	// set thread priority one point below normal
 	// so thread construction won't disturb real-time audio
-	sched_param parm;
-	int policy;
-	pthread_getschedparam(thrhelpid,&policy,&parm);
-	int prio = parm.sched_priority;
-	int schmin = sched_get_priority_min(policy);
-	if(prio > schmin) {
-		parm.sched_priority = prio-1;
-		pthread_setschedparam(thrhelpid,policy,&parm);
-	}
+	RelPriority(-1);
 
 	thrhelpcond = new ThrCond;
 
@@ -151,105 +152,19 @@ bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *me
 	return true;
 }
 
-/*
-bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *methname)
+bool flext_base::ShouldExit() const 
 {
-#ifdef FLEXT_DEBUG
-	if(!p) {
-		ERRINTERNAL(); 
-		return false;
-	}
-#endif
-
-	static bool init = false;
-	static pthread_attr_t attr;
-	if(!init) {
-		pthread_attr_init(&attr);
-		pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
-		init = true;
-	}
+	for(thr_entry *ti = thrhead; ti; ti = ti->nxt)
+		if(ti->Is()) return ti->shouldexit;
 
-	// set thread priority one point below normal
-	// so thread construction won't disturb real-time audio
-	pthread_t id = pthread_self();
-	sched_param parm;
-	int policy;
-	pthread_getschedparam(id,&policy,&parm);
-	int prio = parm.sched_priority;
-	int schmin = sched_get_priority_min(policy);
-	if(prio > schmin) {
-		parm.sched_priority = prio-1;
-		pthread_setschedparam(id,policy,&parm);
-	}
-	
-	pthread_t thrid; 
-	int ret = pthread_create (&thrid,&attr,(void *(*)(void *))meth,p);
-
-	// set thread priority back to normal
-	parm.sched_priority = prio;
-	pthread_setschedparam(id,policy,&parm);
-
-	if(ret) { 
-#ifdef FLEXT_DEBUG	
-		error((char *)(ret == EAGAIN?"%s - Unsufficient resources to launch thread!":"%s - Could not launch method!"),methname); 
-#else
-		error((char *)("%s - Could not launch method!"),methname); 
-#endif		
-
-		delete p; 
-		return false;
-	}
-	else
-		return true;
+	// thread was not found -> EXIT!!!
+	return true;
 }
-*/
 
 bool flext_base::PushThread()
 {
-	tlmutex.Lock();
-
-//	post("Push thread");
-
-/*
-	// make an entry into thread list
-	thr_entry *nt = new thr_entry;
-	if(thrtail) thrtail->nxt = nt; 
-	else thrhead = nt;
-	thrtail = nt;
-*/
-	{
-#if FLEXT_OS == FLEXT_OS_WIN
-	// set detached thread to lower priority class
-	DWORD err;
-	HANDLE thr = GetCurrentThread();
-	DWORD cl = GetThreadPriority(thr);
-	if(!cl && (err = GetLastError()))
-		post("flext - error getting thread priority");
-	else {
-		BOOL ret = SetThreadPriority(thr,cl-2);
-		if(!ret) {
-			err = GetLastError();
-			if(!err) post("flext - error setting thread priority");
-		}
-	}
-#else
-	// set initial detached thread priority two points below normal
-	sched_param parm;
-	int policy;
-	if(pthread_getschedparam(nt->thrid,&policy,&parm))
-		post("flext - can't get thread parameters");
-	int prio = parm.sched_priority;
-	int schmin = sched_get_priority_min(policy);
-	if(prio > schmin) {
-		parm.sched_priority = prio-2;
-		if(pthread_setschedparam(nt->thrid,policy,&parm))
-			post("flext - can't set thread parameters");
-	}
-#endif
-	}
-
-	tlmutex.Unlock();
-	
+	// set priority of newly created thread one point below the system thread's
+	RelPriority(-1);
 	return true;
 }
 
@@ -284,17 +199,33 @@ void flext_base::PopThread()
 	tlmutex.Unlock();
 }
 
+//! Terminate all object threads
 void flext_base::TermThreads()
 {
+	thr_entry *t;
+
+	// signal termination
+	for(t = thrhead; t; t = t->nxt)
+		if(t->th == this) t->shouldexit = true;
+
+	// TODO: maybe there should be a thread conditional for every thread so that it can be signaled
+
 	// wait for thread termination
-	shouldexit = true;
-	for(int wi = 0; thrhead && wi < 100; ++wi) Sleep(0.01f);
+	for(int wi = 0; wi < 100; ++wi) {
+		int cnt = 0;
+		for(t = thrhead; t; t = t->nxt)
+			if(t->th == this) ++cnt;
+		if(!cnt) break;
+		Sleep(0.01f);
+	}
+
+	// --- all object threads have terminated by now -------
 
 	qmutex.Lock(); // Lock message queue
 	tlmutex.Lock();
 
 	// timeout -> hard termination
-	for(thr_entry *t = thrhead; t; )
+	for(t = thrhead; t; )
 		if(t->th == this) {
 			if(pthread_cancel(t->thrid)) post("%s - Thread could not be terminated!",thisName());
 			thr_entry *tn = t->nxt;
@@ -307,26 +238,39 @@ void flext_base::TermThreads()
 	qmutex.Unlock();
 }
 
-flext_base::thrid_t flext_base::GetThreadId() 
-{ 
-	return pthread_self(); 
-}
-
-bool flext_base::ChangePriority(int dp,thrid_t id)
+bool flext::RelPriority(int dp,thrid_t ref,thrid_t id)
 {
 	sched_param parm;
 	int policy;
-	if(pthread_getschedparam(id,&policy,&parm) < 0) {
+	if(pthread_getschedparam(ref,&policy,&parm) < 0) {
 #ifdef FLEXT_DEBUG
-		post("flext - failed to get parms");
+		post("flext - failed to get thread priority");
 #endif
 		return false;
 	}
 	else {
 		parm.sched_priority += dp;
+
+		// MSVC++ 6 produces wrong code with the following lines!!!
+//		int schmin = sched_get_priority_min(policy);
+//		int schmax = sched_get_priority_max(policy);
+
+		if(parm.sched_priority < sched_get_priority_min(policy)) {
+#ifdef FLEXT_DEBUG		
+			post("flext - minimum thread priority reached");
+#endif
+			parm.sched_priority = sched_get_priority_min(policy);
+		}
+		else if(parm.sched_priority > sched_get_priority_max(policy)) {
+#ifdef FLEXT_DEBUG		
+			post("flext - maximum thread priority reached");
+#endif
+			parm.sched_priority = sched_get_priority_max(policy);
+		}
+		
 		if(pthread_setschedparam(id,policy,&parm) < 0) {
 #ifdef FLEXT_DEBUG		
-			post("flext - failed to change priority");
+			post("flext - failed to change thread priority");
 #endif
 			return false;
 		}
@@ -335,7 +279,7 @@ bool flext_base::ChangePriority(int dp,thrid_t id)
 }
 
 
-int flext_base::GetPriority(thrid_t id)
+int flext::GetPriority(thrid_t id)
 {
 	sched_param parm;
 	int policy;
@@ -349,7 +293,7 @@ int flext_base::GetPriority(thrid_t id)
 }
 
 
-bool flext_base::SetPriority(int p,thrid_t id)
+bool flext::SetPriority(int p,thrid_t id)
 {
 	sched_param parm;
 	int policy;
diff --git a/externals/grill/flext/tutorial/thread1/thread1.cw b/externals/grill/flext/tutorial/thread1/thread1.cw
index f5cb4b53..3e7cce36 100644
Binary files a/externals/grill/flext/tutorial/thread1/thread1.cw and b/externals/grill/flext/tutorial/thread1/thread1.cw differ
-- 
cgit v1.2.1