aboutsummaryrefslogtreecommitdiff
path: root/externals
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-03-12 04:56:36 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-03-12 04:56:36 +0000
commit42a820099a1c03b6f0a84e4f16cb983c69309aa5 (patch)
treec466e6d1fb56662f5dadcb4cc7f24605ffdcefae /externals
parent27da08004c5f024a0f35e3cb4c2b3942548ebcfa (diff)
macros for 64-bit architectures
fixes for icc@linux fixes for attribute editor (to deal with large dialogs) fix lines on box text change fix for gcc strangeness no more static assignment of symbols (problems with Metrowerks) fixed bugs in SIMD code for non-power-of-2 lengths fixed shared library versioning lock-free thread management don't depend on ldconfig begin in the system path (should be in /sbin/..) fixed flext::Timer::At method new lock-free lifo and fifo svn path=/trunk/; revision=2619
Diffstat (limited to 'externals')
-rw-r--r--externals/grill/flext/buildsys/lnx/gnumake-gcc-flext.inc2
-rw-r--r--externals/grill/flext/buildsys/lnx/gnumake-icc-ext.inc2
-rw-r--r--externals/grill/flext/buildsys/lnx/gnumake-icc-flext.inc10
-rw-r--r--externals/grill/flext/buildsys/lnx/gnumake-icc.inc1
-rw-r--r--externals/grill/flext/changes.txt2
-rw-r--r--externals/grill/flext/notes.txt1
-rw-r--r--externals/grill/flext/source/flattr_ed.cpp147
-rw-r--r--externals/grill/flext/source/flcontainers.h8
-rwxr-xr-xexternals/grill/flext/source/flprefix.h30
-rwxr-xr-xexternals/grill/flext/source/flsimd.cpp4
-rw-r--r--externals/grill/flext/source/flsupport.h31
-rw-r--r--externals/grill/flext/source/flthr.cpp484
-rwxr-xr-xexternals/grill/flext/source/fltimer.cpp1
13 files changed, 365 insertions, 358 deletions
diff --git a/externals/grill/flext/buildsys/lnx/gnumake-gcc-flext.inc b/externals/grill/flext/buildsys/lnx/gnumake-gcc-flext.inc
index 93db3313..3a84d399 100644
--- a/externals/grill/flext/buildsys/lnx/gnumake-gcc-flext.inc
+++ b/externals/grill/flext/buildsys/lnx/gnumake-gcc-flext.inc
@@ -61,6 +61,6 @@ $(FLEXTLIBINST):
_install_: $(FLEXTINC) $(FLEXTLIBINST)
install $(TARGET) $(FLEXTLIBINST)
ifdef SHARED
- ldconfig -l $(TARGET)
+ /sbin/ldconfig -l $(TARGET)
endif
install $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(FLEXTINC)
diff --git a/externals/grill/flext/buildsys/lnx/gnumake-icc-ext.inc b/externals/grill/flext/buildsys/lnx/gnumake-icc-ext.inc
index 4ce1c1da..58bb7c3d 100644
--- a/externals/grill/flext/buildsys/lnx/gnumake-icc-ext.inc
+++ b/externals/grill/flext/buildsys/lnx/gnumake-icc-ext.inc
@@ -1,5 +1,7 @@
# build class specific settings
+TARGET=$(TARGETPATH)/$(OUTNAME).$(EXT)
+
INCPATH += -I$(FLEXTINC)
LIBPATH += -L$(FLEXTLIB) -L$(FLEXTSHLIB)
LIBS += -l$(FLEXTNAME)
diff --git a/externals/grill/flext/buildsys/lnx/gnumake-icc-flext.inc b/externals/grill/flext/buildsys/lnx/gnumake-icc-flext.inc
index ed06f9cf..8c106e7c 100644
--- a/externals/grill/flext/buildsys/lnx/gnumake-icc-flext.inc
+++ b/externals/grill/flext/buildsys/lnx/gnumake-icc-flext.inc
@@ -1,5 +1,12 @@
# build class specific settings
+ifdef SHARED
+SONAME=$(OUTNAME).$(EXT)
+TARGET=$(TARGETPATH)/$(OUTNAME).$(PKGVERSION).$(EXT)
+else
+TARGET=$(TARGETPATH)/$(OUTNAME).$(EXT)
+endif
+
##############################################
# default target
@@ -53,4 +60,7 @@ $(FLEXTLIBINST):
_install_: $(FLEXTINC) $(FLEXTLIBINST)
install $(TARGET) $(FLEXTLIBINST)
+ifdef SHARED
+ /sbin/ldconfig -l $(TARGET)
+endif
install $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(FLEXTINC)
diff --git a/externals/grill/flext/buildsys/lnx/gnumake-icc.inc b/externals/grill/flext/buildsys/lnx/gnumake-icc.inc
index 2797e882..96d3d642 100644
--- a/externals/grill/flext/buildsys/lnx/gnumake-icc.inc
+++ b/externals/grill/flext/buildsys/lnx/gnumake-icc.inc
@@ -2,7 +2,6 @@
OBJPATH=$(OUTPATH)/$(OUTSUB)
TARGETPATH=$(OBJPATH)
-TARGET=$(TARGETPATH)/$(OUTNAME).$(EXT)
##############################################
diff --git a/externals/grill/flext/changes.txt b/externals/grill/flext/changes.txt
index e1248969..81ed3b30 100644
--- a/externals/grill/flext/changes.txt
+++ b/externals/grill/flext/changes.txt
@@ -33,7 +33,7 @@ Version history:
- added some more SIMD functionality
- fixes to flext::Timer::At method
- eliminated misleading flext_dsp::ChannelsIn and ChannelsOut
-- added lock-free Lifo and Fifo structures and used it with message queueing
+- added lock-free Lifo and Fifo structures and used it with message queueing and thread management
0.4.7:
- added flext::GetBool (just because flext::GetInt has been there for a while)
diff --git a/externals/grill/flext/notes.txt b/externals/grill/flext/notes.txt
index 97fefdeb..aed2641b 100644
--- a/externals/grill/flext/notes.txt
+++ b/externals/grill/flext/notes.txt
@@ -40,6 +40,7 @@ TODO LIST:
- optimizations for object initialization and messaging
- speed up message handling (usage of other containers?)
- SIMD for gcc
+- lock-free code for 64-bit architectures
- update documentation
- add log messages for debugging version
diff --git a/externals/grill/flext/source/flattr_ed.cpp b/externals/grill/flext/source/flattr_ed.cpp
index 6e13e71c..16a418a3 100644
--- a/externals/grill/flext/source/flattr_ed.cpp
+++ b/externals/grill/flext/source/flattr_ed.cpp
@@ -251,46 +251,45 @@ static void tclscript()
"wm title $id $title\n"
"wm protocol $id WM_DELETE_WINDOW [concat flext_cancel $id]\n"
+ "frame $id.frame\n"
"set row 0\n"
// set grow parameters
- "grid columnconfigure $id 0 -weight 1\n" // label
- "grid columnconfigure $id {1 4} -weight 3\n" // value entry
- "grid columnconfigure $id {2 3} -weight 0\n" // copy buttons
- "grid columnconfigure $id 5 -weight 1\n" // apply button
- "grid columnconfigure $id {6 7 8} -weight 0\n" // radio buttons
+ "grid columnconfigure $id.frame 0 -weight 1\n" // label
+ "grid columnconfigure $id.frame {1 4} -weight 3\n" // value entry
+ "grid columnconfigure $id.frame {2 3} -weight 0\n" // copy buttons
+ "grid columnconfigure $id.frame 5 -weight 1\n" // apply button
+ "grid columnconfigure $id.frame {6 7 8} -weight 0\n" // radio buttons
-// "grid rowconfigure $id {0 1 2} -weight 0\n"
+ "grid rowconfigure $id.frame {0 1} -weight 0\n"
// set column labels
- "label $id.label -text {attribute} -height 2 -font {Helvetica 9 bold}\n"
- "label $id.init -text {initial value} -height 2 -font {Helvetica 9 bold}\n"
- "label $id.copy -text {copy} -height 2 -font {Helvetica 9 bold}\n"
- "label $id.val -text {current value} -height 2 -font {Helvetica 9 bold}\n"
- "label $id.apply -text {} -height 2 -font {Helvetica 9 bold}\n" // why must this be empty?
+ "label $id.frame.label -text {attribute} -font {Helvetica 9 bold}\n"
+ "label $id.frame.init -text {initial value} -font {Helvetica 9 bold}\n"
+ "label $id.frame.copy -text {copy} -font {Helvetica 9 bold}\n"
+ "label $id.frame.val -text {current value} -font {Helvetica 9 bold}\n"
+ "label $id.frame.apply -text {} -font {Helvetica 9 bold}\n" // why must this be empty?
"foreach {i txt} {0 {don't\rsave} 1 {do\rinit} 2 {always\rsave} } {\n"
- "label $id.b$i -text $txt -height 2 -font {Helvetica 9 bold}\n"
+ "label $id.frame.b$i -text $txt -font {Helvetica 7 bold}\n"
"}\n"
-// "label $id.options -text {options} -height 2\n"
-
- "grid config $id.label -column 0 -row $row \n"
- "grid config $id.init -column 1 -row $row \n"
- "grid config $id.copy -column 2 -columnspan 2 -row $row \n"
- "grid config $id.val -column 4 -row $row \n"
- "grid config $id.apply -column 5 -row $row \n"
- "foreach i {0 1 2} { grid config $id.b$i -column [expr $i + 6] -row $row }\n"
-// "grid config $id.options -column 3 -row 0 \n"
+
+ "grid config $id.frame.label -column 0 -row $row \n"
+ "grid config $id.frame.init -column 1 -row $row \n"
+ "grid config $id.frame.copy -column 2 -columnspan 2 -row $row \n"
+ "grid config $id.frame.val -column 4 -row $row \n"
+ "grid config $id.frame.apply -column 5 -row $row \n"
+ "foreach i {0 1 2} { grid config $id.frame.b$i -column [expr $i + 6] -row $row }\n"
"incr row\n"
// Separator
- "frame $id.sep -relief ridge -bd 1 -height 2\n"
- "grid config $id.sep -column 0 -columnspan 9 -row $row -pady 2 -sticky {snew}\n"
+ "frame $id.frame.sep -relief ridge -bd 1 -height 2\n"
+ "grid config $id.frame.sep -column 0 -columnspan 9 -row $row -pady 2 -sticky {snew}\n"
"incr row\n"
);
sys_vgui(
"set ix 1\n"
"foreach {an av ai atp asv afl} $attrlist {\n"
- "grid rowconfigure $id $row -weight 0\n"
+ "grid rowconfigure $id.frame $row -weight 1\n"
// get attribute name
"set var_attr_name [concat [concat var_name_$ix]_$vid ]\n"
@@ -320,8 +319,8 @@ static void tclscript()
// add dialog elements to window
// attribute label
- "label $id.label-$ix -text \"$an :\" -font {Helvetica 8 bold}\n"
- "grid config $id.label-$ix -column 0 -row $row -padx 5 -sticky {e}\n"
+ "label $id.frame.label-$ix -text \"$an :\" -font {Helvetica 8 bold}\n"
+ "grid config $id.frame.label-$ix -column 0 -row $row -padx 5 -sticky {e}\n"
);
sys_vgui(
"if { $afl != 0 } {\n"
@@ -333,45 +332,42 @@ static void tclscript()
// choose entry field type
"switch $atp {\n"
"0 - 1 {\n" // int or float
- "entry $id.init-$ix -textvariable $var_attr_init\n"
- "entry $id.val-$ix -textvariable $var_attr_val\n"
+ "entry $id.frame.init-$ix -textvariable $var_attr_init\n"
+ "entry $id.frame.val-$ix -textvariable $var_attr_val\n"
"}\n"
"2 {\n" // boolean
- "checkbutton $id.init-$ix -variable $var_attr_init\n"
- "checkbutton $id.val-$ix -variable $var_attr_val\n"
+ "checkbutton $id.frame.init-$ix -variable $var_attr_init\n"
+ "checkbutton $id.frame.val-$ix -variable $var_attr_val\n"
"}\n"
"3 {\n" // symbol
- "entry $id.init-$ix -textvariable $var_attr_init\n"
- "entry $id.val-$ix -textvariable $var_attr_val\n"
+ "entry $id.frame.init-$ix -textvariable $var_attr_init\n"
+ "entry $id.frame.val-$ix -textvariable $var_attr_val\n"
"}\n"
"4 - 5 {\n" // list or unknown
- "entry $id.init-$ix -textvariable $var_attr_init\n"
- "bind $id.init-$ix {<Control-Button-1>} \" flext_textzoom $id.init-$ix $var_attr_init { $title } $an 1\"\n"
- "entry $id.val-$ix -textvariable $var_attr_val\n"
- "bind $id.val-$ix {<Control-Button-1>} \" flext_textzoom $id.val-$ix $var_attr_val { $title } $an 1\"\n"
+ "entry $id.frame.init-$ix -textvariable $var_attr_init\n"
+ "bind $id.frame.init-$ix {<Control-Button-1>} \" flext_textzoom $id.frame.init-$ix $var_attr_init { $title } $an 1\"\n"
+ "entry $id.frame.val-$ix -textvariable $var_attr_val\n"
+ "bind $id.frame.val-$ix {<Control-Button-1>} \" flext_textzoom $id.frame.val-$ix $var_attr_val { $title } $an 1\"\n"
"}\n"
"}\n"
- "grid config $id.init-$ix -column 1 -row $row -padx 5 -sticky {ew}\n"
- "grid config $id.val-$ix -column 4 -row $row -padx 5 -sticky {ew}\n"
+ "grid config $id.frame.init-$ix -column 1 -row $row -padx 5 -sticky {ew}\n"
+ "grid config $id.frame.val-$ix -column 4 -row $row -padx 5 -sticky {ew}\n"
// copy buttons
- "button $id.b2i-$ix -text {<-} -height 1 -command \" flext_copyval $var_attr_init $var_attr_val \"\n"
- "grid config $id.b2i-$ix -column 2 -row $row -sticky {ew}\n"
- "button $id.b2c-$ix -text {->} -height 1 -command \" flext_copyval $var_attr_val $var_attr_init \"\n"
- "grid config $id.b2c-$ix -column 3 -row $row -sticky {ew}\n"
+ "button $id.frame.b2i-$ix -text {<-} -height 1 -command \" flext_copyval $var_attr_init $var_attr_val \"\n"
+ "grid config $id.frame.b2i-$ix -column 2 -row $row -sticky {ew}\n"
+ "button $id.frame.b2c-$ix -text {->} -height 1 -command \" flext_copyval $var_attr_val $var_attr_init \"\n"
+ "grid config $id.frame.b2c-$ix -column 3 -row $row -sticky {ew}\n"
// apply button
- "button $id.apply-$ix -text {Apply} -height 1 -command \" flext_apply $id $ix \"\n"
- "grid config $id.apply-$ix -column 5 -row $row -sticky {ew}\n"
-
- // "tk_optionMenu $id.opt-$ix $var_attr_save {don't save} {initialize} {always save}\n"
- // "grid config $id.opt-$ix -column 5 -row $ix \n"
+ "button $id.frame.apply-$ix -text {Apply} -height 1 -command \" flext_apply $id $ix \"\n"
+ "grid config $id.frame.apply-$ix -column 5 -row $row -sticky {ew}\n"
// radiobuttons
"foreach {i c} {0 black 1 blue 2 red} {\n"
- "radiobutton $id.b$i-$ix -value $i -foreground $c -variable $var_attr_save \n"
- "grid config $id.b$i-$ix -column [expr $i + 6] -row $row \n"
+ "radiobutton $id.frame.b$i-$ix -value $i -foreground $c -variable $var_attr_save \n"
+ "grid config $id.frame.b$i-$ix -column [expr $i + 6] -row $row \n"
"}\n"
);
sys_vgui(
@@ -383,55 +379,58 @@ static void tclscript()
// choose display field type
"switch $atp {\n"
"0 - 1 {\n" // int or float
- "entry $id.val-$ix -textvariable $var_attr_val -state disabled\n"
+ "entry $id.frame.val-$ix -textvariable $var_attr_val -state disabled\n"
"}\n"
"2 {\n" // boolean
- "checkbutton $id.val-$ix -variable $var_attr_val -state disabled\n"
+ "checkbutton $id.frame.val-$ix -variable $var_attr_val -state disabled\n"
"}\n"
"3 {\n" // symbol
- "entry $id.val-$ix -textvariable $var_attr_val -state disabled\n"
+ "entry $id.frame.val-$ix -textvariable $var_attr_val -state disabled\n"
"}\n"
"4 - 5 {\n" // list or unknown
- "entry $id.val-$ix -textvariable $var_attr_val -state disabled\n"
- "bind $id.val-$ix {<Control-Button-1>} \" flext_textzoom $id.val-$ix $var_attr_val { $title } $an 0\"\n"
+ "entry $id.frame.val-$ix -textvariable $var_attr_val -state disabled\n"
+ "bind $id.frame.val-$ix {<Control-Button-1>} \" flext_textzoom $id.frame.val-$ix $var_attr_val { $title } $an 0\"\n"
"}\n"
"}\n"
-// "entry $id.val-$ix -textvariable $var_attr_val -state disabled\n"
- "grid config $id.val-$ix -column 4 -row $row -padx 5 -sticky {ew}\n"
+// "entry $id.fval.val-$ix -textvariable $var_attr_val -state disabled\n"
+ "grid config $id.frame.val-$ix -column 4 -row $row -padx 5 -sticky {ew}\n"
- "label $id.readonly-$ix -text \"read-only\"\n"
- "grid config $id.readonly-$ix -column 6 -columnspan 3 -row $row -padx 5 -sticky {ew}\n"
+ "label $id.frame.readonly-$ix -text \"read-only\"\n"
+ "grid config $id.frame.readonly-$ix -column 6 -columnspan 3 -row $row -padx 5 -sticky {ew}\n"
"}\n"
// increase counter
"incr ix\n"
"incr row\n"
"}\n"
+
+ // empty space
+ "grid rowconfigure $id.frame $row -weight 1\n"
+ "frame $id.frame.dummy\n"
+ "grid config $id.frame.dummy -column 0 -columnspan 9 -row $row\n"
+ "incr row\n"
);
sys_vgui(
// Separator
"frame $id.sep2 -relief ridge -bd 1 -height 2\n"
-// "grid rowconfigure $id $row -weight 0\n"
- "grid config $id.sep2 -column 0 -columnspan 9 -row $row -pady 5 -sticky {snew}\n"
- "incr row\n"
// Buttons
"frame $id.buttonframe\n"
- "pack $id.buttonframe -side bottom -fill x\n"
"button $id.buttonframe.cancel -text {Leave} -width 20 -command \" flext_cancel $id \"\n"
"button $id.buttonframe.apply -text {Apply all} -width 20 -command \" flext_applyall $id $alen \"\n"
"button $id.buttonframe.ok -text {Apply & Leave} -width 20 -command \" flext_ok $id $alen \"\n"
"button $id.buttonframe.help -text {Help} -width 10 -command \" flext_help $id \"\n"
- "pack $id.buttonframe.cancel -side left -expand 1\n"
- "pack $id.buttonframe.apply -side left -expand 1\n"
- "pack $id.buttonframe.ok -side left -expand 1\n"
- "pack $id.buttonframe.help -side left -expand 1\n"
+ "grid columnconfigure $id.buttonframe {0 1 2 3} -weight 1\n"
+ "grid config $id.buttonframe.cancel $id.buttonframe.apply $id.buttonframe.ok $id.buttonframe.help -padx 2 -sticky {snew}\n"
+
+// "scrollbar $id.scroll -command \"$id.frame yview\"\n"
-// "grid rowconfigure $id $row -weight 0\n"
- "grid config $id.buttonframe -column 0 -columnspan 9 -row $row -pady 5 -sticky {ew}\n"
+ "pack $id.buttonframe $id.sep2 -pady 2 -expand 0 -side bottom -fill x\n"
+// "pack $id.scroll -side right -fill y\n"
+ "pack $id.frame -expand 1 -side top -fill both\n"
// Key bindings
"bind $id {<KeyPress-Escape>} \" flext_cancel $id \"\n"
@@ -539,7 +538,7 @@ void flext_base::cb_GfxProperties(t_gobj *c, t_glist *)
FLEXT_ASSERT(false);
}
- sys_vgui(const_cast<char *>(list?"%s {\n":"%s\n"),GetString(sym));
+ sys_vgui(const_cast<char *>(list?"%s {":"%s "),GetString(sym));
AtomList lv;
if(gattr) { // gettable attribute is present
@@ -553,12 +552,12 @@ void flext_base::cb_GfxProperties(t_gobj *c, t_glist *)
b += escapeit(b,sizeof(buf)+buf-b,tmp);
if(i < lv.Count()-1) { *(b++) = ' '; *b = 0; }
}
- sys_vgui("%s\n",buf);
+ sys_vgui("%s",buf);
}
else
- sys_vgui("{}\n");
+ sys_vgui("{}");
- sys_vgui(const_cast<char *>(list?"} {\n":" \n"));
+ sys_vgui(const_cast<char *>(list?"} {":" "));
if(pattr) {
// if there is initialization data take this, otherwise take the current data
@@ -571,10 +570,10 @@ void flext_base::cb_GfxProperties(t_gobj *c, t_glist *)
b += escapeit(b,sizeof(buf)+buf-b,tmp);
if(i < lp.Count()-1) { *(b++) = ' '; *b = 0; }
}
- sys_vgui("%s\n",buf);
+ sys_vgui("%s",buf);
}
else
- sys_vgui("{}\n");
+ sys_vgui("{}");
sys_vgui(const_cast<char *>(list?"} %i %i %i \n":" %i %i %i \n"),tp,sv,pattr?(pattr->BothExist()?2:1):0);
diff --git a/externals/grill/flext/source/flcontainers.h b/externals/grill/flext/source/flcontainers.h
index a97df172..e1121b63 100644
--- a/externals/grill/flext/source/flcontainers.h
+++ b/externals/grill/flext/source/flcontainers.h
@@ -44,7 +44,7 @@ public:
inline Cell *Avail() { return (Cell *)top; }
-#if defined(_MSC_VER) && (defined(_WIN32))
+#if defined(_MSC_VER) && FLEXT_CPU == FLEXT_CPU_IA32
#ifdef __SMP__
#define LOCK lock
#else
@@ -109,7 +109,7 @@ public:
}
inline size_t Size() const { return ic-oc; }
-#elif defined(__GNUC__) && (defined(_X86_) || defined(__i386__))
+#elif defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_IA32
#ifndef SMPLOCK
# ifdef __SMP__
# define SMPLOCK "lock ; "
@@ -180,11 +180,11 @@ public:
:"memory", "edx");
return n;
}
-#elif defined(__GNUC__) && defined(__x86_64__)
+#elif defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_X64_64
#error x86-64 architecture not supported yet
-#elif defined(__GNUC__) && defined(__POWERPC__)
+#elif defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_PPC
inline void Push(register Cell *cl)
{
register volatile long t1;
diff --git a/externals/grill/flext/source/flprefix.h b/externals/grill/flext/source/flprefix.h
index ab09390e..faaa67b9 100755
--- a/externals/grill/flext/source/flprefix.h
+++ b/externals/grill/flext/source/flprefix.h
@@ -66,10 +66,16 @@ WARRANTIES, see the file, "license.txt," in this distribution.
// --- 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
+#define FLEXT_CPU_IA32 1
+#define FLEXT_CPU_PPC 2
+#define FLEXT_CPU_MIPS 3
+#define FLEXT_CPU_ALPHA 4
+
+#define FLEXT_CPU_IA64 5 // Itanium
+#define FLEXT_CPU_X86_64 6 // AMD-K8, EMT64
+
+// compatibility
+#define FLEXT_CPU_INTEL FLEXT_CPU_IA32
// --- definitions for FLEXT_THREADS -----------------
#define FLEXT_THR_POSIX 1 // pthreads
@@ -110,8 +116,12 @@ WARRANTIES, see the file, "license.txt," in this distribution.
// and Intel C++ (as guessed)
#ifndef FLEXT_CPU
- #if defined(_M_IX86)
- #define FLEXT_CPU FLEXT_CPU_INTEL
+ #if defined(_M_AMD64)
+ #define FLEXT_CPU FLEXT_CPU_X86_64
+ #elif defined(_M_IA64)
+ #define FLEXT_CPU FLEXT_CPU_IA64
+ #elif defined(_M_IX86)
+ #define FLEXT_CPU FLEXT_CPU_IA32
#elif defined(_M_PPC)
#define FLEXT_CPU FLEXT_CPU_PPC
#elif defined(_M_MRX000)
@@ -124,7 +134,7 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#endif
#ifndef FLEXT_OS
- #if defined(_WIN32)
+ #if defined(_WIN32) || defined(_WIN64)
#define FLEXT_OS FLEXT_OS_WIN
#define FLEXT_OSAPI FLEXT_OSAPI_WIN_NATIVE
#else
@@ -211,8 +221,10 @@ WARRANTIES, see the file, "license.txt," in this distribution.
// and Intel (as suggested by Tim Blechmann)
#ifndef FLEXT_CPU
- #if defined(_X86_) || defined(__i386__) || defined(__i586__) || defined(__i686__)
- #define FLEXT_CPU FLEXT_CPU_INTEL
+ #if defined(_X86_64_) // not sure about this one
+ #define FLEXT_CPU FLEXT_CPU_X86_64
+ #elif defined(_X86_) || defined(__i386__) || defined(__i586__) || defined(__i686__)
+ #define FLEXT_CPU FLEXT_CPU_IA32
#elif defined(__POWERPC__)
#define FLEXT_CPU FLEXT_CPU_PPC
#elif defined(__MIPS__)
diff --git a/externals/grill/flext/source/flsimd.cpp b/externals/grill/flext/source/flsimd.cpp
index efeae6e3..1ed9480d 100755
--- a/externals/grill/flext/source/flsimd.cpp
+++ b/externals/grill/flext/source/flsimd.cpp
@@ -66,7 +66,7 @@ unsigned long flext::GetSIMDCapabilities() { return simdcaps; }
#ifdef FLEXT_USE_SIMD
-#if FLEXT_CPU == FLEXT_CPU_INTEL
+#if FLEXT_CPU == FLEXT_CPU_IA32 || FLEXT_CPU == FLEXT_CPU_X84_64
#define _CPU_FEATURE_MMX 0x0001
#define _CPU_FEATURE_SSE 0x0002
@@ -294,7 +294,7 @@ static int _cpuid (_p_info *pinfo)
static unsigned long setsimdcaps()
{
unsigned long simdflags = flext::simd_none;
-#if FLEXT_CPU == FLEXT_CPU_INTEL
+#if FLEXT_CPU == FLEXT_CPU_IA32 || FLEXT_CPU == FLEXT_CPU_AMD64
_p_info cpuinfo;
int feature = _cpuid(&cpuinfo);
if(cpuinfo.os_support&_CPU_FEATURE_MMX) simdflags += flext::simd_mmx;
diff --git a/externals/grill/flext/source/flsupport.h b/externals/grill/flext/source/flsupport.h
index 123f956a..c3141a16 100644
--- a/externals/grill/flext/source/flsupport.h
+++ b/externals/grill/flext/source/flsupport.h
@@ -782,40 +782,12 @@ public:
} *var;
};
- /*! \brief This represents an entry to the list of active method threads
- \internal
- */
- class FLEXT_SHARE thr_entry:
- public flext_root
- {
- public:
- thr_entry(void (*m)(thr_params *),thr_params *p,thrid_t id = GetThreadId());
-
- //! \brief Check if this class represents the current thread
- bool Is(thrid_t id = GetThreadId()) const { return IsThread(thrid,id); }
-
- FLEXT_CLASSDEF(flext_base) *This() const { return th; }
- thrid_t Id() const { return thrid; }
-
- FLEXT_CLASSDEF(flext_base) *th;
- void (*meth)(thr_params *);
- thr_params *params;
- thrid_t thrid;
- bool active,shouldexit;
-#if FLEXT_THREADS == FLEXT_THR_MP
- int weight;
-#endif
- thr_entry *nxt;
- };
-
protected:
static thrid_t thrhelpid;
static thrid_t thrmsgid;
static bool StartHelper();
- static bool StopHelper();
static void ThrHelper(void *);
- static void LaunchHelper(thr_entry *e);
//! the system's thread id
static thrid_t thrid; // the system thread
@@ -1081,6 +1053,9 @@ public:
*/
static void Sleep(double s);
+ //! Sleep for a very short amount of time, just to let other threads wake up
+ static void MiniSleep();
+
/*! \brief Class encapsulating a timer with callback functionality.
This class can either be used with FLEXT_ADDTIMER or used as a base class with an overloaded virtual Work function.
*/
diff --git a/externals/grill/flext/source/flthr.cpp b/externals/grill/flext/source/flthr.cpp
index 0750dd83..47c64354 100644
--- a/externals/grill/flext/source/flthr.cpp
+++ b/externals/grill/flext/source/flthr.cpp
@@ -13,10 +13,15 @@ WARRANTIES, see the file, "license.txt," in this distribution.
*/
#include "flext.h"
-#include "flinternal.h"
#ifdef FLEXT_THREADS
+// maximum wait time for threads to finish (in ms)
+#define MAXIMUMWAIT 100
+
+
+#include "flinternal.h"
+#include "flcontainers.h"
#include <time.h>
@@ -31,7 +36,6 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#error WIN32 threads need Windows SDK version >= 0x500
#endif
-
#include <errno.h>
//! Thread id of system thread
@@ -40,11 +44,61 @@ flext::thrid_t flext::thrid = 0;
//! Thread id of helper thread
flext::thrid_t flext::thrhelpid = 0;
-static flext::thr_entry *thrhead = NULL,*thrtail = NULL;
-static flext::ThrMutex tlmutex;
-//! Helper thread should terminate
-static bool thrhelpexit = false;
+//! \brief This represents an entry to the list of active method threads
+class thr_entry
+ : public flext
+ , public Fifo::Cell
+{
+public:
+ void thr_entry::Set(void (*m)(thr_params *),thr_params *p,thrid_t id = GetThreadId())
+ {
+ th = p?p->cl:NULL;
+ meth = m,params = p,thrid = id;
+ shouldexit = false;
+#if FLEXT_THREADS == FLEXT_THR_MP
+ weight = 100; // MP default weight
+#endif
+ }
+
+ //! \brief Check if this class represents the current thread
+ bool Is(thrid_t id = GetThreadId()) const { return IsThread(thrid,id); }
+
+ FLEXT_CLASSDEF(flext_base) *This() const { return th; }
+ thrid_t Id() const { return thrid; }
+
+ FLEXT_CLASSDEF(flext_base) *th;
+ void (*meth)(thr_params *);
+ thr_params *params;
+ thrid_t thrid;
+ bool shouldexit;
+#if FLEXT_THREADS == FLEXT_THR_MP
+ int weight;
+#endif
+};
+
+template<class T>
+class ThrFinder:
+ public T
+{
+public:
+ void Push(thr_entry *e) { T::Push(e); }
+ thr_entry *Pop() { return T::Pop(); }
+
+ thr_entry *Find(flext::thrid_t id,bool pop = false)
+ {
+ TypedLifo<thr_entry> qutmp;
+ thr_entry *fnd;
+ while((fnd = Pop()) && !fnd->Is(id)) qutmp.Push(fnd);
+ // put back entries
+ for(thr_entry *ti; ti = qutmp.Pop(); ) Push(ti);
+ if(fnd && !pop) Push(fnd);
+ return fnd;
+ }
+};
+
+static ThrFinder< PooledLifo<thr_entry,1,10> > thrpending;
+static ThrFinder< TypedLifo<thr_entry> > thractive,thrstopped;
//! Helper thread conditional
static flext::ThrCond *thrhelpcond = NULL;
@@ -53,12 +107,13 @@ static flext::ThrCond *thrhelpcond = NULL;
flext::thrid_t flext::GetSysThreadId() { return thrid; }
-void flext::LaunchHelper(thr_entry *e)
+static void LaunchHelper(thr_entry *e)
{
- e->thrid = GetThreadId();
+ e->thrid = flext::GetThreadId();
e->meth(e->params);
}
+
//! Start helper thread
bool flext::StartHelper()
{
@@ -76,7 +131,6 @@ bool flext::StartHelper()
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
- thrhelpexit = false;
ok = pthread_create (&thrhelpid,&attr,(void *(*)(void *))ThrHelper,NULL) == 0;
#elif FLEXT_THREADS == FLEXT_THR_MP
if(!MPLibraryIsLoaded())
@@ -105,17 +159,6 @@ bool flext::StartHelper()
return ok;
}
-#if 0
-/*! \brief Stop helper thread
- \note Never called!
-*/
-bool flext::StopHelper()
-{
- thrhelpexit = true;
- if(thrhelpcond) thrhelpcond->Signal();
-}
-#endif
-
//! Static helper thread function
void flext::ThrHelper(void *)
{
@@ -128,8 +171,6 @@ void flext::ThrHelper(void *)
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
#endif
-// post("Helper thread started");
-
// set thread priority one point below normal
// so thread construction won't disturb real-time audio
RelPriority(-1);
@@ -138,156 +179,151 @@ void flext::ThrHelper(void *)
// helper loop
for(;;) {
-// post("Helper loop");
-
thrhelpcond->Wait();
- if(thrhelpexit) break;
-
-// post("Helper signalled");
- tlmutex.Lock();
-// post("Helper after lock");
-
- // start all inactive threads in queue
- thr_entry *prv = NULL,*ti;
- for(ti = thrhead; ti; prv = ti,ti = ti->nxt) {
- if(!ti->active) {
- bool ok;
-
-// post("Helper start thread");
-#if FLEXT_THREADS == FLEXT_THR_POSIX
- thrid_t dummy;
- ok = pthread_create (&dummy,&attr,(void *(*)(void *))LaunchHelper,ti) == 0;
-#elif FLEXT_THREADS == FLEXT_THR_MP
- thrid_t dummy;
- ok = MPCreateTask((TaskProc)LaunchHelper,ti,0,0,0,0,0,&dummy) == noErr;
-#elif FLEXT_THREADS == FLEXT_THR_WIN32
- ok = _beginthread((void (*)(void *))LaunchHelper,0,ti) >= 0;
-#else
-#error
-#endif
- if(!ok) {
- error("flext - Could not launch thread!");
-
- // delete from queue
- if(prv)
- prv->nxt = ti->nxt;
- else
- thrhead = ti->nxt;
- if(thrtail == ti) thrtail = prv;
-
- ti->nxt = NULL;
- delete ti;
- }
- else {
-// post("Helper thread ok");
-
- // set active flag
- ti->active = true;
- }
- }
- }
-
- tlmutex.Unlock();
+ // start all inactive threads
+ thr_entry *ti;
+ while(ti = thrpending.Pop()) {
+ bool ok;
+
+ #if FLEXT_THREADS == FLEXT_THR_POSIX
+ thrid_t dummy;
+ ok = pthread_create (&dummy,&attr,(void *(*)(void *))LaunchHelper,ti) == 0;
+ #elif FLEXT_THREADS == FLEXT_THR_MP
+ thrid_t dummy;
+ ok = MPCreateTask((TaskProc)LaunchHelper,ti,0,0,0,0,0,&dummy) == noErr;
+ #elif FLEXT_THREADS == FLEXT_THR_WIN32
+ ok = _beginthread((void (*)(void *))LaunchHelper,0,ti) >= 0;
+ #else
+ #error
+ #endif
+ if(!ok) {
+ error("flext - Could not launch thread!");
+ thrpending.Free(ti); ti = NULL;
+ }
+ else
+ // insert into queue of active threads
+ thractive.Push(ti);
+ }
}
+ FLEXT_ASSERT(false);
+/*
+ // Never reached!
+
delete thrhelpcond;
thrhelpcond = NULL;
#if FLEXT_THREADS == FLEXT_THR_POSIX
pthread_attr_destroy(&attr);
#endif
+*/
}
bool flext::LaunchThread(void (*meth)(thr_params *p),thr_params *p)
{
-#ifdef FLEXT_DEBUG
- if(!thrhelpcond) {
- ERRINTERNAL();
- return false;
- }
-#endif
-
-// post("make threads");
-
- tlmutex.Lock();
+ FLEXT_ASSERT(thrhelpcond);
// make an entry into thread list
- thr_entry *nt = new thr_entry(meth,p);
- if(thrtail) thrtail->nxt = nt;
- else thrhead = nt;
- thrtail = nt;
-
- tlmutex.Unlock();
-
-// post("signal helper");
-
+ thr_entry *e = thrpending.New();
+ e->Set(meth,p);
+ thrpending.Push(e);
// signal thread helper
thrhelpcond->Signal();
return true;
}
+static bool waitforstopped(TypedFifo<thr_entry> &qufnd,float wait = 0)
+{
+ TypedLifo<thr_entry> qutmp;
+
+ double until;
+ if(wait) until = flext::GetOSTime()+wait;
+
+ for(;;) {
+ thr_entry *fnd = qufnd.Get();
+ if(!fnd) break; // no more entries -> done!
+
+ thr_entry *ti;
+ // search for entry
+ while((ti = thrstopped.Pop()) != NULL && ti != fnd) qutmp.Push(ti);
+ // put back entries
+ while((ti = qutmp.Pop()) != NULL) thrstopped.Push(ti);
+
+ if(ti) {
+ // still in thrstopped queue
+ qufnd.Put(fnd);
+ // yield to other threads
+ flext::ThrYield();
+
+ if(wait && flext::GetOSTime() > until)
+ // not successful -> remaining thread are still in qufnd queue
+ return false;
+ }
+ }
+ return true;
+}
+
bool flext::StopThread(void (*meth)(thr_params *p),thr_params *p,bool wait)
{
-#ifdef FLEXT_DEBUG
- if(!thrhelpcond) {
- ERRINTERNAL();
- return false;
- }
-#endif
+ FLEXT_ASSERT(thrhelpcond);
- int found = 0;
-
- tlmutex.Lock();
- for(thr_entry *ti = thrhead; ti; ti = ti->nxt)
- // set shouldexit if meth and params match
- if(ti->meth == meth && ti->params == p) { ti->shouldexit = true; found++; }
- tlmutex.Unlock();
-
- if(found) {
- // signal thread helper
- thrhelpcond->Signal();
-#if 0
- // ######################
- // i don't think we need to wait for a single thread to stop
- // ######################
- int cnt = 0;
- for(int wi = 0; wi < 100; ++wi) {
- // lock and count this object's threads
- cnt = 0;
- tlmutex.Lock();
- for(thr_entry *t = thrhead; t; t = t->nxt)
- if(t->meth == meth && t->params == p) ++cnt;
- tlmutex.Unlock();
-
- // if no threads are remaining, we are done
- if(!cnt) break;
-
- // Wait
- Sleep(0.01f);
- }
+ TypedLifo<thr_entry> qutmp;
+ thr_entry *ti;
- return cnt == 0;
-#endif
- return true;
- }
- else
- return false;
+ // first search pending queue
+ // --------------------------
+
+ {
+ bool found = false;
+ while((ti = thrpending.Pop()) != NULL)
+ if(ti->meth == meth && ti->params == p) {
+ // found -> thread hasn't started -> just delete
+ thrpending.Free(ti);
+ found = true;
+ }
+ else
+ qutmp.Push(ti);
+
+ // put back into pending queue (order doesn't matter)
+ while((ti = qutmp.Pop()) != NULL) thrpending.Push(ti);
+
+ if(found) return true;
+ }
+
+ // now search active queue
+ // -----------------------
+
+ TypedFifo<thr_entry> qufnd;
+
+ while((ti = thractive.Pop()) != NULL)
+ if(ti->meth == meth && ti->params == p) {
+ thrstopped.Push(ti);
+ thrhelpcond->Signal();
+ qufnd.Put(ti);
+ }
+ else
+ qutmp.Push(ti);
+
+ // put back into pending queue (order doesn't matter)
+ while((ti = qutmp.Pop()) != NULL) thractive.Push(ti);
+
+ // wakeup helper thread
+ thrhelpcond->Signal();
+
+ // now wait for entries in qufnd to have vanished from thrstopped
+ if(wait)
+ return waitforstopped(qufnd);
+ else
+ return qufnd.Size() == 0;
}
bool flext_base::ShouldExit() const
{
- bool ret = true;
-
- tlmutex.Lock();
- for(thr_entry *ti = thrhead; ti; ti = ti->nxt)
- if(ti->Is()) { ret = ti->shouldexit; break; }
- tlmutex.Unlock();
-
- // thread was not found -> EXIT!!!
- return ret;
+ thr_entry *fnd = thrstopped.Find(GetThreadId());
+ return fnd != NULL;
}
bool flext::PushThread()
@@ -299,99 +335,87 @@ bool flext::PushThread()
void flext::PopThread()
{
- tlmutex.Lock();
-
-// post("Pop thread");
-
- thr_entry *prv = NULL,*ti;
- for(ti = thrhead; ti; prv = ti,ti = ti->nxt)
- if(ti->Is()) break;
+ thrid_t id = GetThreadId();
+ thr_entry *fnd = thrstopped.Find(id,true);
+ if(!fnd) fnd = thractive.Find(id,true);
- if(ti) {
- if(prv)
- prv->nxt = ti->nxt;
- else
- thrhead = ti->nxt;
- if(thrtail == ti) thrtail = prv;
-
- ti->nxt = NULL;
- delete ti;
- }
- else {
+ if(fnd)
+ thrpending.Free(fnd);
#ifdef FLEXT_DEBUG
+ else
post("flext - INTERNAL ERROR: Thread not found!");
#endif
- }
-
- tlmutex.Unlock();
}
//! Terminate all object threads
bool flext_base::StopThreads()
{
- thr_entry *t;
+ FLEXT_ASSERT(thrhelpcond);
- // signal termination for all object's threads
- tlmutex.Lock();
- for(t = thrhead; t; t = t->nxt) {
- if(t->This() == this) t->shouldexit = true;
- }
- tlmutex.Unlock();
+ TypedLifo<thr_entry> qutmp;
+ thr_entry *ti;
- // TODO: maybe there should be a thread conditional for every thread so that it can be signalled efficiently
+ // first search pending queue
+ // --------------------------
- // wait for thread termination (1 second max.)
- int cnt;
- for(int wi = 0; wi < 100; ++wi) {
- // lock and count this object's threads
- tlmutex.Lock();
- for(cnt = 0,t = thrhead; t; t = t->nxt)
- if(t->This() == this) ++cnt;
- tlmutex.Unlock();
+ bool found = false;
+ while((ti = thrpending.Pop()) != NULL)
+ if(ti->This() == this)
+ // found -> thread hasn't started -> just delete
+ thrpending.Free(ti);
+ else
+ qutmp.Push(ti);
- // if no threads are remaining, we are done
- if(!cnt) break;
+ // put back into pending queue (order doesn't matter)
+ while((ti = qutmp.Pop()) != NULL) thrpending.Push(ti);
- // Wait
- Sleep(0.01f);
- }
+ // now search active queue
+ // -----------------------
+
+ TypedFifo<thr_entry> qufnd;
+
+ while((ti = thractive.Pop()) != NULL)
+ if(ti->This() == this) {
+ thrstopped.Push(ti);
+ thrhelpcond->Signal();
+ qufnd.Put(ti);
+ }
+ else
+ qutmp.Push(ti);
- if(cnt) {
+ // put back into pending queue (order doesn't matter)
+ while((ti = qutmp.Pop()) != NULL) thractive.Push(ti);
+
+ // wakeup helper thread
+ thrhelpcond->Signal();
+
+ // now wait for entries in qufnd to have vanished from thrstopped
+ if(!waitforstopped(qufnd,MAXIMUMWAIT*0.001f)) {
#ifdef FLEXT_DEBUG
post("flext - doing hard thread termination");
#endif
-
- // --- all object threads have terminated by now -------
- tlmutex.Lock();
// timeout -> hard termination
- for(t = thrhead; t; )
- if(t->This() == this) {
- #if FLEXT_THREADS == FLEXT_THR_POSIX
- if(pthread_cancel(t->thrid)) post("%s - Thread could not be terminated!",thisName());
- #elif FLEXT_THREADS == FLEXT_THR_MP
- MPTerminateTask(t->thrid,0);
- // here, we should use a task queue to check whether the task has really terminated!!
- #elif FLEXT_THREADS == FLEXT_THR_WIN32
- // can't use the c library function _endthread.. memory leaks will occur
- HANDLE hnd = OpenThread(THREAD_ALL_ACCESS,TRUE,t->thrid);
- TerminateThread(hnd,0);
- #else
- #error
- #endif
- thr_entry *tn = t->nxt;
- t->nxt = NULL; delete t;
- t = tn;
- }
- else t = t->nxt;
- thrhead = NULL;
-
- tlmutex.Unlock();
+ while((ti = qufnd.Get()) != NULL) {
+#if FLEXT_THREADS == FLEXT_THR_POSIX
+ if(pthread_cancel(ti->thrid))
+ post("%s - Thread could not be terminated!",thisName());
+#elif FLEXT_THREADS == FLEXT_THR_MP
+ MPTerminateTask(ti->thrid,0);
+ // here, we should use a task queue to check whether the task has really terminated!!
+#elif FLEXT_THREADS == FLEXT_THR_WIN32
+ // can't use the c library function _endthread.. memory leaks will occur
+ HANDLE hnd = OpenThread(THREAD_ALL_ACCESS,TRUE,ti->thrid);
+ TerminateThread(hnd,0);
+#else
+#error Not implemented
+#endif
+ thrpending.Free(ti);
+ }
+ return false;
}
-
-// post("All threads have terminated");
-
- return true;
+ else
+ return true;
}
bool flext::RelPriority(int dp,thrid_t ref,thrid_t id)
@@ -469,9 +493,9 @@ bool flext::RelPriority(int dp,thrid_t ref,thrid_t id)
return true;
#elif FLEXT_THREADS == FLEXT_THR_MP
- thr_entry *t;
- for(t = thrhead; t && t->Id() != id; t = t->nxt) {}
- if(t) {
+ thr_entry *ti = thrpending.Find(id);
+ if(!ti) ti = thractive.Find(id);
+ if(ti) {
// thread found in list
int w = GetPriority(id);
if(dp < 0) w /= 1<<(-dp);
@@ -488,7 +512,7 @@ bool flext::RelPriority(int dp,thrid_t ref,thrid_t id)
#endif
w = 10000;
}
- t->weight = w;
+ ti->weight = w;
return MPSetTaskWeight(id,w) == noErr;
}
else return false;
@@ -524,9 +548,9 @@ int flext::GetPriority(thrid_t id)
return pr;
#elif FLEXT_THREADS == FLEXT_THR_MP
- thr_entry *t;
- for(t = thrhead; t && t->Id() != id; t = t->nxt) {}
- return t?t->weight:-1;
+ thr_entry *ti = thrpending.Find(id);
+ if(!ti) ti = thractive.Find(id);
+ return ti?ti->weight:-1;
#else
#error
#endif
@@ -566,12 +590,9 @@ bool flext::SetPriority(int p,thrid_t id)
return true;
#elif FLEXT_THREADS == FLEXT_THR_MP
- thr_entry *t;
- for(t = thrhead; t && t->Id() != id; t = t->nxt) {}
- if(t)
- return MPSetTaskWeight(id,t->weight = p) == noErr;
- else
- return false;
+ thr_entry *ti = thrpending.Find(id);
+ if(!ti) ti = thractive.Find(id);
+ return ti && MPSetTaskWeight(id,ti->weight = p) == noErr;
#else
#error
#endif
@@ -585,17 +606,6 @@ void flext_base::thr_params::set_any(const t_symbol *s,int argc,const t_atom *ar
void flext_base::thr_params::set_list(int argc,const t_atom *argv) { var[0]._list.args = new AtomList(argc,argv); }
-flext_base::thr_entry::thr_entry(void (*m)(thr_params *),thr_params *p,thrid_t id):
- th(p?p->cl:NULL),meth(m),params(p),thrid(id),
- active(false),shouldexit(false),
-#if FLEXT_THREADS == FLEXT_THR_MP
- weight(100), // MP default weight
-#endif
- nxt(NULL)
-{}
-
-
-
#if FLEXT_THREADS == FLEXT_THR_POSIX
bool flext::ThrCond::Wait() {
Lock();
diff --git a/externals/grill/flext/source/fltimer.cpp b/externals/grill/flext/source/fltimer.cpp
index 294da438..c33716e5 100755
--- a/externals/grill/flext/source/fltimer.cpp
+++ b/externals/grill/flext/source/fltimer.cpp
@@ -109,7 +109,6 @@ void flext::Sleep(double s)
#endif
}
-
/* \param qu determines whether timed messages should be queued (low priority - only when supported by the system).
*/
flext::Timer::Timer(bool qu):