diff options
author | edwardgao <edwardgao@9a26d1b7-1c8f-445c-8fdd-6576f508279d> | 2011-12-31 02:09:08 +0400 |
---|---|---|
committer | edwardgao <edwardgao@9a26d1b7-1c8f-445c-8fdd-6576f508279d> | 2011-12-31 02:09:08 +0400 |
commit | 4d210b9dd09daf3c6897c462b56297c799dda571 (patch) | |
tree | fd26d23c9f9b91102b2914f6c044714bd08cb67c | |
parent | 23a14e354c21af641a91055deee97d8c86ca7961 (diff) |
50 files changed, 3481 insertions, 273 deletions
diff --git a/mgizapp/CMakeLists.txt b/mgizapp/CMakeLists.txt index 6f9955f..1e80a21 100644 --- a/mgizapp/CMakeLists.txt +++ b/mgizapp/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT (srlextract) +PROJECT (mgiza) SET(MGIZA_VERSION_MAJOR "0") SET(MGIZA_VERSION_MINOR "6") @@ -43,7 +43,7 @@ set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) -FIND_PACKAGE( Boost 1.46) +FIND_PACKAGE( Boost 1.46 COMPONENTS thread) IF(Boost_FOUND) IF (NOT _boost_IN_CACHE) diff --git a/mgizapp/src/ATables.h b/mgizapp/src/ATables.h index 83518b4..9db77b1 100644 --- a/mgizapp/src/ATables.h +++ b/mgizapp/src/ATables.h @@ -96,7 +96,9 @@ public: static float smooth_factor; amodel(bool flag = false) : a(MAX_SENTENCE_LENGTH+1,0.0), is_distortion(flag), MaxSentLength(MAX_SENTENCE_LENGTH) - {}; + {lock = new Mutex();}; + + ~amodel(){delete lock;}; protected: VALTYPE&getRef(WordIndex aj, WordIndex j, WordIndex l, WordIndex m){ @@ -107,20 +109,20 @@ protected: } public: void setValue(WordIndex aj, WordIndex j, WordIndex l, WordIndex m, VALTYPE val) { - lock.lock(); + lock->lock(); getRef(aj, j, l, m)=val; - lock.unlock(); + lock->unlock(); } - Mutex lock; + Mutex* lock; public: /** By Qin */ void addValue(WordIndex aj, WordIndex j, WordIndex l, WordIndex m, VALTYPE val) { - lock.lock(); + lock->lock(); getRef(aj, j, l, m)+=val; - lock.unlock(); + lock->unlock(); } bool merge(amodel<VALTYPE>& am); VALTYPE getValue(WordIndex aj, WordIndex j, WordIndex l, WordIndex m) const{ diff --git a/mgizapp/src/AlignTables.cpp b/mgizapp/src/AlignTables.cpp index de75107..8c35b77 100644 --- a/mgizapp/src/AlignTables.cpp +++ b/mgizapp/src/AlignTables.cpp @@ -23,7 +23,7 @@ USA. bool alignmodel::insert(Vector<WordIndex>& aj, LogProb val) { - hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment >::iterator i; + alignment_hash::iterator i; i = a.find(aj); if(i != a.end() || val <= 0) return false ; @@ -35,7 +35,7 @@ bool alignmodel::insert(Vector<WordIndex>& aj, LogProb val) LogProb alignmodel::getValue(Vector<WordIndex>& align) const { const LogProb zero = 0.0 ; - hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment >::const_iterator i; + alignment_hash::const_iterator i; i = a.find(align); if(i == a.end()) return zero; diff --git a/mgizapp/src/AlignTables.h b/mgizapp/src/AlignTables.h index 773b172..78c77e4 100644 --- a/mgizapp/src/AlignTables.h +++ b/mgizapp/src/AlignTables.h @@ -1,124 +1,154 @@ -/* - -EGYPT Toolkit for Statistical Machine Translation -Written by Yaser Al-Onaizan, Jan Curin, Michael Jahr, Kevin Knight, John Lafferty, Dan Melamed, David Purdy, Franz Och, Noah Smith, and David Yarowsky. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -USA. - -*/ -#ifndef _aligntables_h -#define _aligntables_h 1 - -#include "defs.h" - - -#include <cassert> - -#include <iostream> -#include <algorithm> -#include <functional> -#include <map> -#include <set> -//#include <vector> -#include "Vector.h" -#include <utility> -#if __GNUC__>2 -#include <ext/hash_map> -using __gnu_cxx::hash_map; -#else -#include <hash_map> -#endif -#include <math.h> -#include <fstream> -#include "transpair_model1.h" - - -/* ----------------- Class Defintions for hashmyalignment -------------------- - Objective: This class is used to define a hash mapping function to map - an alignment (defined as a vector of integers) into a hash key - ----------------------------------------------------------------------------*/ - -class hashmyalignment : public unary_function< Vector<WordIndex>, size_t > -{ -public: - size_t operator() (const Vector<WordIndex>& key) const - // to define the mapping function. it takes an alignment (a vector of - // integers) and it returns an integer value (hash key). - { - WordIndex j ; - size_t s ; - size_t key_sum = 0 ; - // logmsg << "For alignment:" ; - for (j = 1 ; j < key.size() ; j++){ - // logmsg << " " << key[j] ; - key_sum += (size_t) (int) pow(double(key[j]), double((j % 6)+1)); - } - // logmsg << " , Key value was : " << key_sum; - s = key_sum % 1000000 ; - // logmsg << " h(k) = " << s << endl ; - return(s); - } -}; - -class equal_to_myalignment{ - // returns true if two alignments are the same (two vectors have same enties) -public: - bool operator()(const Vector<WordIndex> t1, - const Vector<WordIndex> t2) const - {WordIndex j ; - if (t1.size() != t2.size()) - return(false); - for (j = 1 ; j < t1.size() ; j++) - if (t1[j] != t2[j]) - return(false); - return(true); - } - -}; - -/* ---------------- End of Class Defnition for hashmyalignment --------------*/ - - -/* ------------------ Class Defintions for alignmodel ----------------------- - Class Name: alignmodel - Objective: Alignments neighborhhoods (collection of alignments) are stored in - a hash table (for easy lookup). Each alignment vector is mapped into a hash - key using the operator defined above. - *--------------------------------------------------------------------------*/ - -class alignmodel{ -private: - hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment > a; -private: - // void erase(Vector<WordIndex>&); -public: - - // methods; - - inline hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment >::iterator begin(void){return a.begin();} // begining of hash - inline hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment >::iterator end(void){return a.end();} // end of hash - inline const hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment >& getHash() const {return a;}; // reference to hash table - bool insert(Vector<WordIndex>&, LogProb val=0.0); // add a alignmnet - // void setValue(Vector<WordIndex>&, LogProb val); // not needed - LogProb getValue(Vector<WordIndex>&)const; // retrieve prob. of alignment - inline void clear(void){ a.clear();}; // clear hash table - // void printTable(const char* filename); - inline void resize(WordIndex n) {a.resize(n);}; // resize table - -}; - -/* -------------- End of alignmode Class Definitions ------------------------*/ -#endif +/*
+
+EGYPT Toolkit for Statistical Machine Translation
+Written by Yaser Al-Onaizan, Jan Curin, Michael Jahr, Kevin Knight, John Lafferty, Dan Melamed, David Purdy, Franz Och, Noah Smith, and David Yarowsky.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA.
+
+*/
+#ifndef _aligntables_h
+#define _aligntables_h 1
+
+#include "defs.h"
+
+
+#include <cassert>
+
+#include <iostream>
+#include <algorithm>
+#include <functional>
+#include <map>
+#include <set>
+//#include <vector>
+#include "Vector.h"
+#include <utility>
+#if __GNUC__>2
+#include <ext/hash_map>
+using __gnu_cxx::hash_map;
+#else
+#include <hash_map>
+#endif
+#include <math.h>
+#include <fstream>
+#include "transpair_model1.h"
+
+
+/* ----------------- Class Defintions for hashmyalignment --------------------
+ Objective: This class is used to define a hash mapping function to map
+ an alignment (defined as a vector of integers) into a hash key
+ ----------------------------------------------------------------------------*/
+
+class hashmyalignment : public unary_function< Vector<WordIndex>, size_t >
+{
+public:
+ size_t operator() (const Vector<WordIndex>& key) const
+ // to define the mapping function. it takes an alignment (a vector of
+ // integers) and it returns an integer value (hash key).
+ {
+ WordIndex j ;
+ size_t s ;
+ size_t key_sum = 0 ;
+ // logmsg << "For alignment:" ;
+ for (j = 1 ; j < key.size() ; j++){
+ // logmsg << " " << key[j] ;
+ key_sum += (size_t) (int) pow(double(key[j]), double((j % 6)+1));
+ }
+ // logmsg << " , Key value was : " << key_sum;
+ s = key_sum % 1000000 ;
+ // logmsg << " h(k) = " << s << endl ;
+ return(s);
+ }
+#ifdef WIN32
+ enum
+ { // parameters for hash table
+ bucket_size = 1 // 0 < bucket_size
+ };
+
+ bool operator()(const Vector<WordIndex> t1,
+ const Vector<WordIndex> t2) const
+ {WordIndex j ;
+ if (t1.size() != t2.size())
+ return(false);
+ for (j = 1 ; j < t1.size() ; j++)
+ if (t1[j] != t2[j])
+ return(false);
+ return(true);
+ }
+#endif
+};
+
+#ifndef WIN32
+class equal_to_myalignment{
+ // returns true if two alignments are the same (two vectors have same enties)
+public:
+ bool operator()(const Vector<WordIndex> t1,
+ const Vector<WordIndex> t2) const
+ {WordIndex j ;
+ if (t1.size() != t2.size())
+ return(false);
+ for (j = 1 ; j < t1.size() ; j++)
+ if (t1[j] != t2[j])
+ return(false);
+ return(true);
+ }
+
+};
+#endif
+
+/* ---------------- End of Class Defnition for hashmyalignment --------------*/
+
+
+/* ------------------ Class Defintions for alignmodel -----------------------
+ Class Name: alignmodel
+ Objective: Alignments neighborhhoods (collection of alignments) are stored in
+ a hash table (for easy lookup). Each alignment vector is mapped into a hash
+ key using the operator defined above.
+ *--------------------------------------------------------------------------*/
+
+class alignmodel{
+private:
+#ifdef WIN32
+ typedef hash_map<Vector<WordIndex>, LogProb, hashmyalignment > alignment_hash;
+
+#else
+ typedef hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment > alignment_hash;
+
+#endif
+ alignment_hash a;
+private:
+ // void erase(Vector<WordIndex>&);
+public:
+
+ // methods;
+
+ inline alignment_hash::iterator begin(void){return a.begin();} // begining of hash
+ inline alignment_hash::iterator end(void){return a.end();} // end of hash
+ inline const alignment_hash& getHash() const {return a;}; // reference to hash table
+ bool insert(Vector<WordIndex>&, LogProb val=0.0); // add a alignmnet
+ // void setValue(Vector<WordIndex>&, LogProb val); // not needed
+ LogProb getValue(Vector<WordIndex>&)const; // retrieve prob. of alignment
+ inline void clear(void){ a.clear();}; // clear hash table
+ // void printTable(const char* filename);
+ inline void resize(WordIndex n) {
+#ifndef WIN32
+ return a.resize();
+#endif
+ }; // resize table
+
+};
+
+/* -------------- End of alignmode Class Definitions ------------------------*/
+#endif
diff --git a/mgizapp/src/CMakeLists.txt b/mgizapp/src/CMakeLists.txt index b4b4f65..beb8746 100644 --- a/mgizapp/src/CMakeLists.txt +++ b/mgizapp/src/CMakeLists.txt @@ -11,8 +11,12 @@ ADD_DEFINITIONS("-DNDEBUG") ADD_DEFINITIONS("-DWORDINDEX_WITH_4_BYTE") ADD_DEFINITIONS("-DBINARY_SEARCH_FOR_TTABLE") ADD_DEFINITIONS("-DDEBUG") +IF (WIN32) + +ELSE() ADD_DEFINITIONS("-Wno-deprecated") ADD_DEFINITIONS("-Wno-write-strings") +ENDIF() SET( LIBMGIZA_SRC alignment.cpp alignment.h @@ -61,6 +65,11 @@ SET( LIBMGIZA_SRC ADD_LIBRARY(mgiza STATIC ${LIBMGIZA_SRC}) INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR} ) +IF (WIN32) + INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/w32 ) + LINK_DIRECTORIES ( ${PROJECT_SOURCE_DIR}/w32 ) + SET(CMAKE_THREAD_LIBS_INIT pthread) +ENDIF() INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/ ) LINK_DIRECTORIES ( ${LIBRARY_OUTPUT_PATH} ) diff --git a/mgizapp/src/D4Tables.h b/mgizapp/src/D4Tables.h index 9ec3a02..3e60dc8 100644 --- a/mgizapp/src/D4Tables.h +++ b/mgizapp/src/D4Tables.h @@ -273,6 +273,18 @@ public: p->second[i].second+=it->second[i].second; } } +#ifdef WIN32 + map<m4_key,Vpff,compareb1 >::iterator it1; + for (it1 = d.Db1.begin(); it1!=d.Db1.end(); it1++) { + map<m4_key,Vpff,compareb1 >::iterator p=Db1.find(it->first); + if (p==Db1.end()) + p=Db1.insert(make_pair(it1->first,Vpff(msl*2+1,pair<COUNT,PROB>(0.0,0.0)))).first; + int i; + for (i=0; i<it->second.size(); i++) { + p->second[i].second+=it1->second[i].second; + } + } +#else for (it = d.Db1.begin(); it!=d.Db1.end(); it++) { map<m4_key,Vpff,compare1 >::iterator p=Db1.find(it->first); if (p==Db1.end()) @@ -282,6 +294,7 @@ public: p->second[i].second+=it->second[i].second; } } +#endif } bool augCount(const char* fD1, const char* fDb) { diff --git a/mgizapp/src/FlexArray.h b/mgizapp/src/FlexArray.h index c7365f7..1dd73ed 100644 --- a/mgizapp/src/FlexArray.h +++ b/mgizapp/src/FlexArray.h @@ -42,8 +42,13 @@ public: {return p[i-start];} int low()const{return start;} int high()const{return End;} +#ifdef WIN32 + T*begin(){return const_cast<double*>(&p[0]);} + T*end(){return const_cast<double*>(&(p[0])+p.size());} +#else T*begin(){return conv<double>(p.begin());} T*end(){return conv<double>(p.end());} +#endif }; template<class T> diff --git a/mgizapp/src/ForwardBackward.cpp b/mgizapp/src/ForwardBackward.cpp index 969316a..e477dd0 100644 --- a/mgizapp/src/ForwardBackward.cpp +++ b/mgizapp/src/ForwardBackward.cpp @@ -33,7 +33,11 @@ double ForwardBackwardTraining(const HMMNetwork&net,Array<double>&g,Array<Array2 Array<double> alpha(N,0),beta(N,0),sum(J); for(int i=0;i<I;i++) beta[N-I+i]=net.getBetainit(i); +#ifdef WIN32 + double * cur_beta=const_cast<double*>(&(beta[0]))+N-I-1; +#else double * cur_beta=conv<double>(beta.begin())+N-I-1; +#endif for(int j=J-2;j>=0;--j) for(int ti=I-1;ti>=0;--ti,--cur_beta) { const double *next_beta=conv<double>(beta.begin())+(j+1)*I; @@ -49,8 +53,14 @@ double ForwardBackwardTraining(const HMMNetwork&net,Array<double>&g,Array<Array2 } for(int i=0;i<I;i++) alpha[i]=net.getAlphainit(i)*net.nodeProb(i,0); +#ifdef WIN32 + double* cur_alpha=const_cast<double*>(&(alpha[0]))+I; + cur_beta=const_cast<double*>(&(beta[0]))+I; +#else double* cur_alpha=conv<double>(alpha.begin())+I; cur_beta=conv<double>(beta.begin())+I; +#endif + for(int j=1;j<J;j++){ Array2<double>&e=E[ (E.size()==1)?0:(j-1) ]; if( (E.size()!=1) || j==1 ) @@ -91,6 +101,16 @@ double ForwardBackwardTraining(const HMMNetwork&net,Array<double>&g,Array<Array2 esum2=0.0; if(!(esum2==0.0||mfabs(esum2-bsum)/bsum<1e-3*I)) cout << "ERROR2: " << esum2 <<" " <<bsum << " " << esum << net << endl; +#ifdef WIN32 + double * sumptr=const_cast<double*>(&(sum[0])); + double* ge=const_cast<double*>(&(g[0])+g.size()); + for(double* gp=const_cast<double*>(&(g[0]));gp!=ge;gp+=I) + { + *sumptr++=normalize_if_possible(gp,gp+I); + if(bsum && !(mfabs((*(sumptr-1)-bsum)/bsum)<1e-3*I)) + cout << "ERROR: " << *(sumptr-1) << " " << bsum << " " << mfabs((*(sumptr-1)-bsum)/bsum) << ' ' << I << ' ' << J << endl; + } +#else double * sumptr=conv<double>(sum.begin()); double* ge=conv<double>(g.end()); for(double* gp=conv<double>(g.begin());gp!=ge;gp+=I) @@ -99,6 +119,7 @@ double ForwardBackwardTraining(const HMMNetwork&net,Array<double>&g,Array<Array2 if(bsum && !(mfabs((*(sumptr-1)-bsum)/bsum)<1e-3*I)) cout << "ERROR: " << *(sumptr-1) << " " << bsum << " " << mfabs((*(sumptr-1)-bsum)/bsum) << ' ' << I << ' ' << J << endl; } +#endif for(unsigned int j=0;j<(unsigned int)E.size();j++) { Array2<double>&e=E[j]; @@ -122,7 +143,11 @@ void HMMViterbi(const HMMNetwork&net,Array<int>&vit) { Array<Array2<double> >e(1); ForwardBackwardTraining(net,g,e); for(int j=0;j<J;j++) { +#ifdef WIN32 + double * begin=const_cast<double*>(&(g[0]))+I*j; +#else double * begin=conv<double>(g.begin())+I*j; +#endif vit[j]=max_element(begin,begin+I)-begin; } } @@ -130,7 +155,11 @@ void HMMViterbi(const HMMNetwork&net,Array<double>&g,Array<int>&vit) { const int I=net.size1(),J=net.size2(); vit.resize(J); for(int j=0;j<J;j++) { +#ifdef WIN32 + double* begin=const_cast<double*>(&(g[0]))+I*j; +#else double* begin=conv<double>(g.begin())+I*j; +#endif vit[j]=max_element(begin,begin+I)-begin; } } @@ -149,8 +178,13 @@ double HMMRealViterbi(const HMMNetwork&net,Array<int>&vitar,int pegi,int pegj,bo alpha[i]=0; // only first empty word can be chosen bp[i]=0; } +#ifdef WIN32 + double *cur_alpha=const_cast<double*>(&alpha[0])+I; + double **cur_bp=const_cast<double**>(&bp[0])+I; +#else double *cur_alpha=conv<double>(alpha.begin())+I; double **cur_bp=conv<double*>(bp.begin())+I; +#endif for(int j=1;j<J;j++) { if( pegj+1==j) @@ -158,7 +192,11 @@ double HMMRealViterbi(const HMMNetwork&net,Array<int>&vitar,int pegi,int pegj,bo if( (pegi!=-1&&ti!=pegi)||(pegi==-1&&ti<I/2) ) (cur_alpha-I)[ti]=0.0; for(int ti=0;ti<I;++ti,++cur_alpha,++cur_bp) { +#ifdef WIN32 + double* prev_alpha=const_cast<double*>(&(alpha[0]))+I*(j-1); +#else double* prev_alpha=conv<double>(alpha.begin())+I*(j-1); +#endif double this_node=net.nodeProb(ti,j); const double *alprob= &net.outProb(j-1,0,ti); for(int pi=0;pi<I;++pi,++prev_alpha,(alprob+=I)){ @@ -180,7 +218,11 @@ double HMMRealViterbi(const HMMNetwork&net,Array<int>&vitar,int pegi,int pegj,bo (alpha)[N-I+ti]=0.0; int j=J-1; +#ifdef WIN32 + cur_alpha=const_cast<double*>(&(alpha[0]))+j*I; +#else cur_alpha=conv<double>(alpha.begin())+j*I; +#endif vitar[J-1]=max_element(cur_alpha,cur_alpha+I)-cur_alpha; double ret= *max_element(cur_alpha,cur_alpha+I); while(bp[vitar[j]+j*I]) diff --git a/mgizapp/src/HMMTables.cpp b/mgizapp/src/HMMTables.cpp index 4e5acd1..5482a55 100644 --- a/mgizapp/src/HMMTables.cpp +++ b/mgizapp/src/HMMTables.cpp @@ -73,25 +73,27 @@ template<class CLS, class MAPPERCLASSTOSTRING> double HMMTables<CLS, default: abort(); } - lock.lock(); + lock->lock(); typename map<AlDeps<CLS>,FlexArray<double> >::const_iterator p= alProb.find(AlDeps<CLS>(sentLength, istrich, j, w1, w2)); if (p!=alProb.end() ) { - lock.unlock(); + lock->unlock(); return (p->second)[pos]; } else { if (iter>0&&iter<5000) cout << "WARNING: Not found: " << ' ' << J << ' ' << sentLength << '\n';; - lock.unlock(); + lock->unlock(); return 1.0/(2*sentLength-1); } - lock.unlock(); + lock->unlock(); } template<class CLS, class MAPPERCLASSTOSTRING> void HMMTables<CLS, MAPPERCLASSTOSTRING>::addAlCount(int istrich, int k, int sentLength, int J, CLS w1, CLS w2, int j, double value, double valuePredicted) { + + int pos=istrich-k; switch (PredictionInAlignments) { case 0: @@ -112,25 +114,25 @@ template<class CLS, class MAPPERCLASSTOSTRING> void HMMTables<CLS, abort(); } + AlDeps<CLS> deps(AlDeps<CLS>(sentLength, istrich, j, w1, w2)); { - lock.lock(); + lock->lock(); typename map<AlDeps<CLS>,FlexArray<double> >::iterator p= alProb.find(deps); if (p==alProb.end() ) { if ( (CompareAlDeps&1)==0) - p - =alProb.insert(make_pair(deps,FlexArray<double> (-MAX_SENTENCE_LENGTH,MAX_SENTENCE_LENGTH,0.0))).first; + p=alProb.insert(make_pair(deps,FlexArray<double> (-MAX_SENTENCE_LENGTH,MAX_SENTENCE_LENGTH,0.0))).first; else p=alProb.insert(make_pair(deps,FlexArray<double> (-sentLength,sentLength,0.0))).first; } p->second[pos]+=value; - lock.unlock(); + lock->unlock(); } if (valuePredicted) { - lock.lock(); + lock->lock(); typename map<AlDeps<CLS>,FlexArray<double> >::iterator p= alProbPredicted.find(deps); if (p==alProbPredicted.end() ) { @@ -141,65 +143,74 @@ template<class CLS, class MAPPERCLASSTOSTRING> void HMMTables<CLS, p=alProbPredicted.insert(make_pair(deps,FlexArray<double> (-sentLength,sentLength,0.0))).first; } p->second[pos]+=valuePredicted; - lock.unlock(); + lock->unlock(); } + } template<class CLS, class MAPPERCLASSTOSTRING> -pair<Array<double>,Mutex>&HMMTables<CLS,MAPPERCLASSTOSTRING>::doGetAlphaInit(int I) +hmmentry_type& HMMTables<CLS,MAPPERCLASSTOSTRING>::doGetAlphaInit(int I) { - alphalock.lock(); + alphalock->lock(); if( !init_alpha.count(I) ){ - init_alpha[I]=pair<Array<double>,Mutex>(Array<double>(I,0),Mutex()); +#ifdef WIN32 + init_alpha[I]=hmmentry_type(Array<double>(I,0),new Mutex()); +#else + init_alpha[I]=hmmentry_type(Array<double>(I,0),Mutex()); +#endif } - pair<Array<double>,Mutex>& ret = init_alpha[I]; - alphalock.unlock(); + hmmentry_type& ret = init_alpha[I]; + alphalock->unlock(); return ret; } template<class CLS, class MAPPERCLASSTOSTRING> -pair<Array<double>,Mutex>&HMMTables<CLS,MAPPERCLASSTOSTRING>::doGetBetaInit(int I) +hmmentry_type& HMMTables<CLS,MAPPERCLASSTOSTRING>::doGetBetaInit(int I) { - betalock.lock(); + betalock->lock(); if( !init_beta.count(I) ){ +#ifdef WIN32 + init_beta[I]=hmmentry_type(Array<double>(I,0),new Mutex()); +#else init_beta[I]=pair<Array<double>,Mutex>(Array<double>(I,0),Mutex()); +#endif } - pair<Array<double>,Mutex>& ret = init_beta[I]; - betalock.unlock(); + hmmentry_type& ret = init_beta[I]; + betalock->unlock(); return ret; } template<class CLS, class MAPPERCLASSTOSTRING> bool HMMTables<CLS, MAPPERCLASSTOSTRING>::getAlphaInit(int I, Array<double>&x) const { - alphalock.lock(); - hash_map<int,pair<Array<double>,Mutex> >::const_iterator i=init_alpha.find(I); + alphalock->lock(); + hash_map<int,hmmentry_type >::const_iterator i=init_alpha.find(I); if (i==init_alpha.end() ){ - alphalock.unlock(); + alphalock->unlock(); return 0; } else { x=i->second.first; - alphalock.unlock(); + alphalock->unlock(); for (unsigned int j=x.size()/2+1; j<x.size(); ++j) // only first empty word can be chosen x[j]=0; return 1; } - alphalock.unlock(); + alphalock->unlock(); } template<class CLS, class MAPPERCLASSTOSTRING> bool HMMTables<CLS, MAPPERCLASSTOSTRING>::getBetaInit(int I, Array<double>&x) const { - betalock.lock(); - hash_map<int,pair<Array<double>,Mutex> >::const_iterator i=init_beta.find(I); + betalock->lock(); + hash_map<int,hmmentry_type >::const_iterator i=init_beta.find(I); if (i==init_beta.end() ){ - betalock.unlock(); + betalock->unlock(); return 0; } else { x=i->second.first; - betalock.unlock(); + betalock->unlock(); return 1; } - betalock.unlock(); + betalock->unlock(); } /*********************************** @@ -264,7 +275,7 @@ template<class CLS, class MAPPERCLASSTOSTRING> bool HMMTables<CLS, return false; } cerr << "Dumping HMM table to " << alpha << endl; - for (typename hash_map<int,pair<Array<double>,Mutex> >::const_iterator i= + for (typename hash_map<int,hmmentry_type>::const_iterator i= init_alpha.begin(); i!=init_alpha.end(); i++) { ofs << i->first << " " << i->second.first.size() <<" "; int j; @@ -282,7 +293,7 @@ template<class CLS, class MAPPERCLASSTOSTRING> bool HMMTables<CLS, return false; } cerr << "Dumping HMM table to " << beta << endl; - for (typename hash_map<int,pair<Array<double>,Mutex> >::const_iterator i= + for (typename hash_map<int,hmmentry_type>::const_iterator i= init_beta.begin(); i!=init_beta.end(); i++) { ofs << i->first << " " << i->second.first.size() << " "; int j; @@ -393,16 +404,25 @@ template<class CLS, class MAPPERCLASSTOSTRING> bool HMMTables<CLS, cerr << "Mismatch in alpha init table!" << endl; return false; } - pair<Array<double>, Mutex>&alp = doGetAlphaInit(id); + hmmentry_type&alp = doGetAlphaInit(id); Array<double>& gk = alp.first; int j; double v; +#ifdef WIN32 + alp.second->lock(); +#else alp.second.lock(); +#endif for (j=0; j<gk.size(); j++) { ss >> v; gk[j]+=v; } +#ifdef WIN32 + alp.second->unlock(); +#else alp.second.unlock(); +#endif + } } } @@ -427,17 +447,25 @@ template<class CLS, class MAPPERCLASSTOSTRING> bool HMMTables<CLS, cerr << "Mismatch in alpha init table!" << endl; return false; } - pair<Array<double>, Mutex>&bet1 = doGetBetaInit(id); + hmmentry_type&bet1 = doGetBetaInit(id); Array<double>&bet = bet1.first; int j; double v; +#ifdef WIN32 + bet1.second->lock(); +#else bet1.second.lock(); +#endif for (j=0; j<bet.size(); j++) { ss >> v; bet[j]+=v; } +#ifdef WIN32 + bet1.second->unlock(); +#else bet1.second.unlock(); +#endif } } } @@ -476,18 +504,18 @@ template<class CLS, class MAPPERCLASSTOSTRING> bool HMMTables<CLS, } - for (typename hash_map<int,pair<Array<double>,Mutex> >::const_iterator i= + for (typename hash_map<int,hmmentry_type>::iterator i= ht.init_alpha.begin(); i!=ht.init_alpha.end(); i++) { - pair<Array<double>,Mutex> alp = doGetAlphaInit(i->first); + hmmentry_type& alp = doGetAlphaInit(i->first); int j; double v; for (j=0; j<alp.first.size(); j++) { alp.first[j]+=i->second.first[j]; } } - for (typename hash_map<int,pair<Array<double>,Mutex> >::const_iterator i= + for (typename hash_map<int,hmmentry_type>::iterator i= ht.init_beta.begin(); i!=ht.init_beta.end(); i++) { - pair<Array<double>,Mutex>&alp = doGetBetaInit(i->first); + hmmentry_type&alp = doGetBetaInit(i->first); int j; double v; for (j=0; j<alp.first.size(); j++) { @@ -506,7 +534,68 @@ template<class CLS, class MAPPERCLASSTOSTRING> HMMTables<CLS, probabilityForEmpty(mfabs(_probForEmpty)), updateProbabilityForEmpty(_probForEmpty<0.0), mapper1(&m1), mapper2(&m2) { + lock = new Mutex(); + alphalock = new Mutex(); + betalock = new Mutex(); } + +template<class CLS, class MAPPERCLASSTOSTRING> HMMTables<CLS, + MAPPERCLASSTOSTRING>::HMMTables(const HMMTables& ref): +mapper1(ref.mapper1), mapper2(ref.mapper2) +{ + probabilityForEmpty=ref.probabilityForEmpty; + updateProbabilityForEmpty=ref.updateProbabilityForEmpty; + init_alpha=ref.init_alpha; + init_beta=ref.init_beta; + alProb=ref.alProb; + alProbPredicted=ref.alProbPredicted; + globalCounter=ref.globalCounter; + divSum=ref.divSum; + p0_count=ref.p0_count; + np0_count=ref.np0_count; +} +template<class CLS, class MAPPERCLASSTOSTRING> void HMMTables<CLS, + MAPPERCLASSTOSTRING>::operator=(const HMMTables& ref){ + probabilityForEmpty=ref.probabilityForEmpty; + updateProbabilityForEmpty=ref.updateProbabilityForEmpty; + init_alpha=ref.init_alpha; + init_beta=ref.init_beta; + alProb=ref.alProb; + alProbPredicted=ref.alProbPredicted; + globalCounter=ref.globalCounter; + divSum=ref.divSum; + p0_count=ref.p0_count; + np0_count=ref.np0_count; +} + + template<class CLS, class MAPPERCLASSTOSTRING> HMMTables<CLS, MAPPERCLASSTOSTRING>::~HMMTables() { +#if WIN32 + for (typename hash_map<int,hmmentry_type>::iterator i= + init_alpha.begin(); i!=init_alpha.end(); i++) { + i->second.second->unlock(); + } + for (typename hash_map<int,hmmentry_type>::iterator i= + init_beta.begin(); i!=init_beta.end(); i++) { + i->second.second->unlock(); + } +#endif + + lock->unlock(); + alphalock->unlock(); + betalock->unlock(); + delete lock; + delete alphalock; + delete betalock; +#if WIN32 + for (typename hash_map<int,hmmentry_type>::iterator i= + init_alpha.begin(); i!=init_alpha.end(); i++) { + delete i->second.second; + } + for (typename hash_map<int,hmmentry_type>::iterator i= + init_beta.begin(); i!=init_beta.end(); i++) { + delete i->second.second; + } +#endif } diff --git a/mgizapp/src/HMMTables.h b/mgizapp/src/HMMTables.h index efb7215..944b173 100644 --- a/mgizapp/src/HMMTables.h +++ b/mgizapp/src/HMMTables.h @@ -98,16 +98,23 @@ public: } }; +#ifdef WIN32 +typedef pair<Array<double>,Mutex*> hmmentry_type; +#else +typedef pair<Array<double>,Mutex> hmmentry_type; +#endif + template<class CLS,class MAPPERCLASSTOSTRING> class HMMTables { - Mutex lock; - Mutex alphalock,betalock; + Mutex* lock; + Mutex* alphalock,*betalock; public: + double probabilityForEmpty; bool updateProbabilityForEmpty; - hash_map<int, pair<Array<double>,Mutex> > init_alpha; - hash_map<int, pair<Array<double>,Mutex> > init_beta; + hash_map<int, hmmentry_type > init_alpha; + hash_map<int, hmmentry_type > init_beta; map<AlDeps<CLS>,FlexArray<double> > alProb; map<AlDeps<CLS>,FlexArray<double> > alProbPredicted; int globalCounter; @@ -119,6 +126,8 @@ public: bool merge(HMMTables<CLS,MAPPERCLASSTOSTRING> & ht); const HMMTables<CLS,MAPPERCLASSTOSTRING>*getThis()const {return this;} HMMTables(double _probForEmpty,const MAPPERCLASSTOSTRING&m1,const MAPPERCLASSTOSTRING&m2); + HMMTables(const HMMTables& ref); + void operator=(const HMMTables& ref); virtual ~HMMTables(); virtual double getAlProb(int i,int k,int sentLength,int J,CLS w1,CLS w2,int j,int iter=0) const; virtual void writeJumps(ostream&) const; @@ -129,8 +138,8 @@ public: virtual void readJumps(istream&); virtual bool getAlphaInit(int I,Array<double>&x)const; virtual bool getBetaInit(int I,Array<double> &x)const; - pair<Array<double>, Mutex> &doGetAlphaInit(int I); - pair<Array<double>, Mutex> &doGetBetaInit(int I); + hmmentry_type &doGetAlphaInit(int I); + hmmentry_type &doGetBetaInit(int I); virtual double getProbabilityForEmpty()const {return probabilityForEmpty;} void performGISIteration(const HMMTables<CLS,MAPPERCLASSTOSTRING>*old){ diff --git a/mgizapp/src/Parameter.cpp b/mgizapp/src/Parameter.cpp index c313a16..1175ec7 100644 --- a/mgizapp/src/Parameter.cpp +++ b/mgizapp/src/Parameter.cpp @@ -22,7 +22,12 @@ USA. */ #include "Parameter.h" #include "fstream" +#ifndef WIN32 #include "unistd.h" +#else +#include <direct.h> +#define getcwd _getcwd +#endif #include <strstream> diff --git a/mgizapp/src/Parameter.h b/mgizapp/src/Parameter.h index 8429fda..312bfbc 100644 --- a/mgizapp/src/Parameter.h +++ b/mgizapp/src/Parameter.h @@ -31,6 +31,10 @@ USA. #include <fstream> #include <string.h> +#ifdef WIN32 +#define strcasecmp _strcmpi +#endif + inline unsigned int mConvert(const string&s,unsigned int &i) { if( strcasecmp(s.c_str(),"yes")==0 || strcasecmp(s.c_str(),"y")==0 || strcasecmp(s.c_str(),"true")==0 || strcasecmp(s.c_str(),"t")==0 ) { cerr << "TRUE\n";return i=1; } diff --git a/mgizapp/src/TTables.h b/mgizapp/src/TTables.h index 2120ef6..dec2963 100644 --- a/mgizapp/src/TTables.h +++ b/mgizapp/src/TTables.h @@ -70,6 +70,7 @@ using __gnu_cxx::hash_map; typedef pair<WordIndex, WordIndex> wordPairIds; + class hashpair : public unary_function< pair<WordIndex, WordIndex>, size_t > { public: @@ -80,6 +81,15 @@ public: unique id for each unique pair */ } + #ifdef WIN32 + inline bool operator() (const pair<WordIndex, WordIndex>& key, const pair<WordIndex, WordIndex>& key2){ + return key.first==key2.first && key.second==key2.second; + } + enum
+ { // parameters for hash table
+ bucket_size = 1 // 0 < bucket_size
+ }; + #endif }; @@ -155,7 +165,7 @@ public: //vector<pair<unsigned int,CPPair> > fs; //vector<unsigned int> es; vector< vector<pair<unsigned int,CPPair> >* > lexmat; - vector< Mutex > mutex; + vector< Mutex* > mutex; void erase(WordIndex e, WordIndex f){ CPPair *p=find(e,f); @@ -237,9 +247,19 @@ public: count2+=lexmat[olde]->capacity(); cout << "There are " << count << " " << count2 << " entries in table" << '\n'; mutex.resize(lexmat.size()); + for(int _i = 0; _i< lexmat.size();_i++){ + mutex[_i] = new Mutex(); + } /* Create mutex */ } + ~tmodel(){ + for(int _i = 0; _i< lexmat.size();_i++){ + delete mutex[_i]; + } + + } + /* tmodel(const string&fn) { @@ -288,9 +308,9 @@ public: if( inc ){ CPPair *p=find(e,f); if( p ){ - mutex[e].lock(); + mutex[e]->lock(); p->count += inc ; - mutex[e].unlock(); + mutex[e]->unlock(); } } } diff --git a/mgizapp/src/cmd.c b/mgizapp/src/cmd.c index 5e4a907..323b5a9 100644 --- a/mgizapp/src/cmd.c +++ b/mgizapp/src/cmd.c @@ -6,11 +6,13 @@ #include <ctype.h> #include <string.h> + #include "cmd.h" #ifdef WIN32 # define popen _popen # define pclose _pclose +#include <stdarg.h> #endif static Enum_T BoolEnum[] = { @@ -54,11 +56,15 @@ static char *SepString = " \t\n"; #include <stdarg.h> int DeclareParams(char *ParName, ...) #else +#ifdef WIN32 +int DeclareParams(char *ParName, ...) +#else #include <varargs.h> int DeclareParams(ParName, va_alist) char *ParName; va_dcl #endif +#endif { va_list args; static int ParamN = 0; @@ -66,7 +72,7 @@ va_dcl c; char *s; -#if defined(__STDC__) +#if defined(__STDC__) || defined (WIN32) va_start(args, ParName); #else va_start(args); diff --git a/mgizapp/src/cmd.h b/mgizapp/src/cmd.h index 6c64d2d..6d39753 100644 --- a/mgizapp/src/cmd.h +++ b/mgizapp/src/cmd.h @@ -32,9 +32,10 @@ typedef struct { extern "C" { #endif -#if defined(__STDC__) +#if defined(__STDC__) || defined(WIN32) int DeclareParams(char *, ...); #else + int DeclareParams(); #endif diff --git a/mgizapp/src/d4norm.cxx b/mgizapp/src/d4norm.cxx index 91db0d7..7a1da31 100644 --- a/mgizapp/src/d4norm.cxx +++ b/mgizapp/src/d4norm.cxx @@ -119,6 +119,7 @@ Vector<map< pair<int,int>,char > > ReferenceAlignment; double ErrorsInAlignment(const map< pair<int,int>,char >&reference, const Vector<WordIndex>&test, int l, int&missing, int&toomuch, int&eventsMissing, int&eventsToomuch, int pair_no){ + return 0; } void printGIZAPars(ostream&out){ diff --git a/mgizapp/src/file_spec.h b/mgizapp/src/file_spec.h index d61746c..945aa5b 100644 --- a/mgizapp/src/file_spec.h +++ b/mgizapp/src/file_spec.h @@ -36,7 +36,7 @@ USA. char *Get_File_Spec (){ struct tm *local; time_t t; - char *user; + const char *user; char time_stmp[57]; char *file_spec = 0; @@ -46,7 +46,11 @@ char *Get_File_Spec (){ sprintf(time_stmp, "%02d-%02d-%02d.%02d%02d%02d.", local->tm_year, (local->tm_mon + 1), local->tm_mday, local->tm_hour, local->tm_min, local->tm_sec); +#ifdef WIN32 + user = "WINUSER"; +#else user = getenv("USER"); +#endif file_spec = (char *)malloc(sizeof(char) * (strlen(time_stmp) + strlen(user) + 1)); diff --git a/mgizapp/src/getSentence.cpp b/mgizapp/src/getSentence.cpp index cd86808..ec1ad9d 100644 --- a/mgizapp/src/getSentence.cpp +++ b/mgizapp/src/getSentence.cpp @@ -55,8 +55,8 @@ sentenceHandler::sentenceHandler(const char* filename, vcbList* elist, // This method is the constructor of the class, it also intitializes the // sentence pair sequential number (count) to zero. { - pthread_mutex_init(&readsent_mutex,NULL); - pthread_mutex_init(&setprob_mutex,NULL); + readsent_mutex=new boost::mutex(); + setprob_mutex = new boost::mutex(); position = 0; readflag = false ; @@ -114,8 +114,8 @@ sentenceHandler::sentenceHandler(const char* filename, vcbList* elist, // This method is the constructor of the class, it also intitializes the // sentence pair sequential number (count) to z { - pthread_mutex_init(&readsent_mutex,NULL); - pthread_mutex_init(&setprob_mutex,NULL); + readsent_mutex=new boost::mutex(); + setprob_mutex=new boost::mutex(); position = 0; readflag = false ; allInMemory = false ; @@ -165,6 +165,7 @@ sentenceHandler::sentenceHandler(const char* filename, vcbList* elist, void sentenceHandler::rewind() { + readsent_mutex->lock(); position = 0; currentSentence = 0; readflag = false ; @@ -185,12 +186,13 @@ void sentenceHandler::rewind() cerr << "\nERROR:(b) Cannot open " << inputFilename << " " << (int)errno; } } + readsent_mutex->unlock(); } int sentenceHandler::getNextSentence(sentPair& sent, vcbList* elist, vcbList* flist) { - pthread_mutex_lock(&readsent_mutex); + readsent_mutex->lock(); do{ sentPair s ; @@ -264,10 +266,10 @@ int sentenceHandler::getNextSentence(sentPair& sent, vcbList* elist, vcbList* fl else sent.realCount=(*realCount)[sent.getSentenceNo()-1]; } - pthread_mutex_unlock(&readsent_mutex); + readsent_mutex->unlock(); return position ; }while(false); - pthread_mutex_unlock(&readsent_mutex); + readsent_mutex->unlock(); return 0; } bool sentenceHandler::readNextSentence(sentPair& sent) @@ -411,7 +413,7 @@ void sentenceHandler::setProbOfSentence(const sentPair&s,double d) if( realCount==0 ) return; else{ - pthread_mutex_lock(&setprob_mutex); + setprob_mutex->lock(); if( s.noOcc<=0 ) { double ed=exp(d); @@ -431,7 +433,7 @@ void sentenceHandler::setProbOfSentence(const sentPair&s,double d) oldPairs.push_back(s); oldProbs.push_back(ed); } - pthread_mutex_unlock(&setprob_mutex); + setprob_mutex->unlock(); } } diff --git a/mgizapp/src/getSentence.h b/mgizapp/src/getSentence.h index 424c49e..d7d4e53 100644 --- a/mgizapp/src/getSentence.h +++ b/mgizapp/src/getSentence.h @@ -48,6 +48,7 @@ USA. #include "defs.h" #include "vocab.h" #include "Globals.h" +#include <boost/thread/mutex.hpp> /*----------------------- Class Prototype Definition ------------------------* Class Name: sentenceHandleer Objective: This class is defined to handle training sentece pairs from the @@ -116,9 +117,10 @@ public: Vector<sentPair> oldPairs; Vector<double> oldProbs; - sentenceHandler(){}; + sentenceHandler(){readsent_mutex=new boost::mutex();setprob_mutex=new boost::mutex();}; sentenceHandler(const char* filename, vcbList* elist=0, vcbList* flist=0); sentenceHandler(const char* filename, vcbList* elist, vcbList* flist,set<WordIndex>& eapp, set<WordIndex>& fapp); + ~sentenceHandler(){delete readsent_mutex; delete setprob_mutex;} void rewind(); int getNextSentence(sentPair&, vcbList* = 0, vcbList* = 0); // will be defined in the definition file, this int getTotalNoPairs1()const {return totalPairs1;}; @@ -126,8 +128,9 @@ public: // method will read the next pair of sentence from memory buffer void setProbOfSentence(const sentPair&s,double d); private: - pthread_mutex_t readsent_mutex; - pthread_mutex_t setprob_mutex; + + boost::mutex* readsent_mutex; + boost::mutex* setprob_mutex; bool readNextSentence(sentPair&); // will be defined in the definition file, this }; diff --git a/mgizapp/src/hmm.cpp b/mgizapp/src/hmm.cpp index b76126f..a5f33cb 100644 --- a/mgizapp/src/hmm.cpp +++ b/mgizapp/src/hmm.cpp @@ -76,7 +76,8 @@ void smooth_standard(T*a,T*b,double p) hmm::hmm(model2&m2,WordClasses &e, WordClasses& f) : ewordclasses(e), fwordclasses(f),model2(m2),counts(GLOBALProbabilityForEmpty,ewordclasses,fwordclasses), probs(GLOBALProbabilityForEmpty,ewordclasses,fwordclasses) -{ } +{ +} void hmm::initialize_table_uniformly(sentenceHandler&){} @@ -117,7 +118,7 @@ int hmm::em_with_tricks(int noIterations,bool dumpCount, st = time(NULL) ; sHandler1.rewind(); cout << "\n==========================================================\n"; - cout << modelName << " Training Started at: " << ctime(&st); + cout << modelName << " Training Started at: " << my_ctime(&st); vector<hmm_em_loop_t> th; th.resize(NCPUS); for(int it=1; it <= noIterations ; it++){ @@ -302,9 +303,9 @@ HMMNetwork *hmm::makeHMMNetwork(const Vector<WordIndex>& es,const Vector<WordInd for(unsigned int i2=0;i2<l;i2++) al[i2]=probs.getAlProb(i1real,i2,l,m,ewordclasses.getClass(es[1+i1real]),frenchClass ,j+1); - normalize_if_possible(conv<double>(al.begin()),conv<double>(al.end())); + normalize_if_possible(const_cast<double*>(&al[0]),const_cast<double*>((&al[0])+al.size())); if( SmoothHMM&2 ) - smooth_standard(conv<double>(al.begin()),conv<double>(al.end()),HMMAlignmentModelSmoothFactor); + smooth_standard(const_cast<double*>(&al[0]),const_cast<double*>((&al[0])+al.size()),HMMAlignmentModelSmoothFactor); for(unsigned int i2=0;i2<I;i2++) { CLASSIFY(i2,empty_i2,i2real); net->e[j](i1,i2) = al[i2real]; @@ -337,8 +338,8 @@ HMMNetwork *hmm::makeHMMNetwork(const Vector<WordIndex>& es,const Vector<WordInd } } massert( net->alphainit.size()==I );massert( net->betainit.size()==I ); - normalize_if_possible(conv<double>(net->alphainit.begin()),conv<double>(net->alphainit.end())); - normalize_if_possible(conv<double>(net->betainit.begin()),conv<double>(net->betainit.end())); + normalize_if_possible(const_cast<double*>(&(net->alphainit[0])),const_cast<double*>(&(net->alphainit[0])+net->alphainit.size())); + normalize_if_possible(const_cast<double*>(&(net->betainit[0])),const_cast<double*>(&(net->betainit[0])+net->betainit.size())); transform(net->betainit.begin(),net->betainit.end(),net->betainit.begin(),bind1st(multiplies<double>(),2*l)); return net; } @@ -372,13 +373,22 @@ void hmm::em_loop(Perplexity& perp, sentenceHandler& sHandler1, bool DependencyOfJ=(CompareAlDeps&(16|8))||(PredictionInAlignments==2); bool DependencyOfPrevAJ=(CompareAlDeps&(2|4))||(PredictionInAlignments==0); HMMNetwork *net=makeHMMNetwork(es,fs,doInit); + Array<double> gamma; Array<Array2<double> > epsilon(DependencyOfJ?(m-1):1); double trainProb; trainProb=ForwardBackwardTraining(*net,gamma,epsilon); + if( !test ){ + +#ifdef WIN32 + double *gp=const_cast<double*>(&(gamma[0])); +#else double *gp=conv<double>(gamma.begin()); - for(unsigned int i2=0;i2<J;i2++)for(unsigned int i1=0;i1<I;++i1,++gp){ +#endif + + for(unsigned int i2=0;i2<J;i2++) + for(unsigned int i1=0;i1<I;++i1,++gp){ if( *gp>MINCOUNTINCREASE ) { COUNT add= *gp*so; if( i1>=l ){ @@ -416,7 +426,9 @@ void hmm::em_loop(Perplexity& perp, sentenceHandler& sHandler1, if( i_empty ) p0c+=*ep * mult; else{ - counts.addAlCount(i_befreal,ireal,l,m,ewordclasses.getClass(es[1+i_befreal]), + int v = ewordclasses.getClass(es[1+i_befreal]); + //cerr << v <<" " << es.size() << " "<< i_befreal << endl; + counts.addAlCount(i_befreal,ireal,l,m,v, frenchClass ,jj+1,*ep * mult,0.0); np0c+=*ep * mult; } @@ -425,13 +437,22 @@ void hmm::em_loop(Perplexity& perp, sentenceHandler& sHandler1, } } } + +#ifdef WIN32 + double *gp1=const_cast<double *>(&(gamma[0])),*gp2=const_cast<double*>(&(gamma[0])+gamma.size())-I; +#else double *gp1=conv<double>(gamma.begin()),*gp2=conv<double>(gamma.end())-I; - pair<Array<double>,Mutex >&ai0=counts.doGetAlphaInit(I); +#endif + hmmentry_type&ai0=counts.doGetAlphaInit(I); Array<double>&ai = ai0.first; - pair<Array<double>,Mutex >&bi0=counts.doGetBetaInit(I); + hmmentry_type&bi0=counts.doGetBetaInit(I); Array<double>&bi = bi0.first; int firstFrenchClass=(fs.size()>1)?(fwordclasses.getClass(fs[1+0])):0; - ai0.second.lock(); +#ifdef WIN32 + ai0.second->lock(); +#else + ai0.second.lock(); +#endif for(i=0;i<I;i++,gp1++){ CLASSIFY(i,i_empty,ireal); ai[i]+= *gp1; @@ -445,16 +466,23 @@ void hmm::em_loop(Perplexity& perp, sentenceHandler& sHandler1, } } } - ai0.second.unlock(); - bi0.second.lock(); +#ifdef WIN32 + ai0.second->unlock(); + bi0.second->lock(); +#else + ai0.second.unlock(); + bi0.second.lock(); +#endif + for(i=0;i<I;i++,gp2++){ CLASSIFY(i,i_empty,ireal); bi[i]+= *gp2; } - bi0.second.unlock(); + bi0.second->unlock(); if( Verbose ) cout << "l: " << l << "m: " << m << " p0c: " << p0c << " np0c: " << np0c << endl; } + cross_entropy+=log(max(trainProb,1e-100))+log(max(net->finalMultiply,1e-100)); Array<int>vit; double viterbi_score=1.0; @@ -472,10 +500,12 @@ void hmm::em_loop(Perplexity& perp, sentenceHandler& sHandler1, viterbi_perp.addFactor(log(viterbi_score)+log(max(net->finalMultiply,1e-100)), so, l, m,1); if( Verbose ) cout << "Viterbi-perp: " << log(viterbi_score) << ' ' << log(max(net->finalMultiply,1e-100)) << ' ' << viterbi_score << ' ' << net->finalMultiply << ' ' << *net << "gamma: " << gamma << endl; + delete net;net=0; if (dump_alignment||(FEWDUMPS&&sent.getSentenceNo()<1000) ) printAlignToFile(es, fs, Elist.getVocabList(), Flist.getVocabList(), of2, viterbi_alignment, sent.getSentenceNo(), viterbi_score); addAL(viterbi_alignment,sent.getSentenceNo(),l); + pair_no++; } /* of while */ @@ -820,7 +850,7 @@ CTTableDiff<COUNT,PROB>* hmm::em_one_step(int it){ st = time(NULL) ; sHandler1.rewind(); cout << "\n==========================================================\n"; - cout << modelName << " Training Started at: " << ctime(&st); + cout << modelName << " Training Started at: " << my_ctime(&st); pair_no = 0; cout << endl << "-----------\n" << modelName << ": Iteration " << it << '\n'; @@ -958,7 +988,7 @@ int multi_thread_em(int noIter, int noThread, hmm* base){ } st = time(NULL); cout << "\n==========================================================\n"; - cout << modelName << " Training Started at: " << ctime(&st); + cout << modelName << " Training Started at: " << my_ctime(&st); for(i=1;i<=noIter;i++){ base->perp.clear(); diff --git a/mgizapp/src/hmmnorm.cxx b/mgizapp/src/hmmnorm.cxx index 90c71eb..9d737c5 100644 --- a/mgizapp/src/hmmnorm.cxx +++ b/mgizapp/src/hmmnorm.cxx @@ -128,6 +128,7 @@ Vector<map< pair<int,int>,char > > ReferenceAlignment; double ErrorsInAlignment(const map< pair<int,int>,char >&reference, const Vector<WordIndex>&test, int l, int&missing, int&toomuch, int&eventsMissing, int&eventsToomuch, int pair_no){ + return 0; } void printGIZAPars(ostream&out){ diff --git a/mgizapp/src/logprob.cpp b/mgizapp/src/logprob.cpp index 9035f80..97464a7 100644 --- a/mgizapp/src/logprob.cpp +++ b/mgizapp/src/logprob.cpp @@ -42,7 +42,7 @@ const double LogProb::logb2 = log(b); const int LogProb::nmax = round(300.0E0 * log(1.0E1) / logb2); const int LogProb::nmin = -nmax; const int LogProb::tblbnd = round(log((b-1.0E0)/2.0E0)/logb2); -const int LogProb::zeron = round(pow(-2, 23)); +const int LogProb::zeron = round(pow((double)-2, (double)23)); const int LogProb::onen = 0; const int LogProb::infn = onen - zeron; diff --git a/mgizapp/src/logprob.h b/mgizapp/src/logprob.h index 14696ac..1dfbb72 100644 --- a/mgizapp/src/logprob.h +++ b/mgizapp/src/logprob.h @@ -33,12 +33,14 @@ USA. //#define MAX(A,B) ((A) > (B) ? (A) : (B)) //#define MIN(A,B) ((A) > (B) ? (B) : (A)) - +#ifdef WIN32 +#define round(x) floor(x+0.5) +#endif class LogProb { public: // mj for cross entropy double base2() const { - return (logr * logb2 / log(2)); + return (logr * logb2 / log((double)2)); } // Constructors diff --git a/mgizapp/src/main.cpp b/mgizapp/src/main.cpp index b0e6677..dc46822 100644 --- a/mgizapp/src/main.cpp +++ b/mgizapp/src/main.cpp @@ -1121,7 +1121,7 @@ int main(int argc, char* argv[]) { cout << '\n' << "Entire Training took: " << difftime(fn, st1) << " seconds\n"; - cout << "Program Finished at: "<< ctime(&fn) << '\n'; + cout << "Program Finished at: "<< my_ctime(&fn) << '\n'; cout << "==========================================================\n"; return 0; } diff --git a/mgizapp/src/mkcls/CMakeLists.txt b/mgizapp/src/mkcls/CMakeLists.txt index 3554fb7..d94d92a 100644 --- a/mgizapp/src/mkcls/CMakeLists.txt +++ b/mgizapp/src/mkcls/CMakeLists.txt @@ -8,8 +8,12 @@ SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) ADD_DEFINITIONS("-DNDEBUG") +IF (WIN32) + +ELSE() ADD_DEFINITIONS("-Wno-deprecated") ADD_DEFINITIONS("-Wno-write-strings") +ENDIF() SET( MKCLS_SRC Array.h diff --git a/mgizapp/src/mkcls/KategProblemKBC.cpp b/mgizapp/src/mkcls/KategProblemKBC.cpp index 97c40fc..10a10d9 100644 --- a/mgizapp/src/mkcls/KategProblemKBC.cpp +++ b/mgizapp/src/mkcls/KategProblemKBC.cpp @@ -25,8 +25,15 @@ USA. #include <stdlib.h> +#include <math.h> #include "KategProblem.h" +#ifdef WIN32 +#include <boost\math\special_functions\erf.hpp> +using namespace boost::math; +#endif + + double rhoLo=0.75; #define MAX_VERFAELSCHUNG 5000 double verfTab[MAX_VERFAELSCHUNG],verfTabSigma=-1.0; @@ -35,6 +42,7 @@ double verfaelsche(int a,double b) if( a>=0&&verfTabSigma==b&&a<MAX_VERFAELSCHUNG ) { + massert(verfTab[a]== b*(erf(10000.0) - erf(a/b))/2+a); return verfTab[a]; } diff --git a/mgizapp/src/mkcls/general.cpp b/mgizapp/src/mkcls/general.cpp index ddd5fe4..cb3f27d 100644 --- a/mgizapp/src/mkcls/general.cpp +++ b/mgizapp/src/mkcls/general.cpp @@ -30,9 +30,14 @@ USA. extern "C" { + +#ifndef WIN32 #include <sys/time.h> #include <sys/resource.h> - +#else +#define srand48 srand +#define drand48() (rand()/RAND_MAX) +#endif } @@ -109,6 +114,9 @@ int randomInt(int exclusive) double clockSec() { +#ifdef WIN32 + return 0; +#else #ifdef linux enum __rusage_who who=RUSAGE_SELF; #else @@ -117,4 +125,5 @@ double clockSec() struct rusage rusage; getrusage(who, &rusage); return rusage.ru_utime.tv_sec+rusage.ru_utime.tv_usec/1000000.0; +#endif } diff --git a/mgizapp/src/mkcls/mkcls.cpp b/mgizapp/src/mkcls/mkcls.cpp index 90ebfde..a2bf695 100644 --- a/mgizapp/src/mkcls/mkcls.cpp +++ b/mgizapp/src/mkcls/mkcls.cpp @@ -22,7 +22,9 @@ USA. */ - +#ifdef WIN32 +#define strcasecmp strcmpi +#endif #include <stdio.h> #include <iostream> @@ -127,7 +129,7 @@ void printUsage(int r) " (generates 80 classes for the corpus 'in' and writes the classes in 'out')\n" "Literature: \n" " Franz Josef Och: »Maximum-Likelihood-Schätzung von Wortkategorien mit Verfahren\n" - " der kombinatorischen Optimierung« Studienarbeit, Universität Erlangen-Nürnberg,\n" + " der kombinatorischen Optimierung?Studienarbeit, Universität Erlangen-Nürnberg,\n" " Germany,1995. \n"; exit(r); } diff --git a/mgizapp/src/mkcls/myleda.h b/mgizapp/src/mkcls/myleda.h index 6fc936b..4c2e67b 100644 --- a/mgizapp/src/mkcls/myleda.h +++ b/mgizapp/src/mkcls/myleda.h @@ -27,6 +27,9 @@ USA. #define myleda_HEADER_defined using namespace std; #include "myassert.h" +#ifdef WIN32 +#include<list> +#endif #if defined(USE_LEDA_array)||defined(USE_LEDA) @@ -64,16 +67,36 @@ template<class T> leda_set<T> operator&(const leda_set<T>&a,const leda_set<T>&b) { leda_set<T>c; + +#ifdef WIN32 + std::list<T> lst; + set_intersection(a.begin(),a.end(),b.begin(),b.end(),lst.begin()); + for(std::list<T>::iterator it = lst.begin() ;it!=lst.end();it++){ + c.insert(*it); + } +#else insert_iterator<set<T> > iter(c,c.begin()); set_intersection(a.begin(),a.end(),b.begin(),b.end(),iter); +#endif return c; } template<class T> leda_set<T> operator-(const leda_set<T>&a,const leda_set<T>&b) { + leda_set<T>c; + + +#ifdef WIN32 + std::list<T> lst; + set_difference(a.begin(),a.end(),b.begin(),b.end(),lst.begin()); + for(std::list<T>::iterator it = lst.begin() ;it!=lst.end();it++){ + c.insert(*it); + } +#else insert_iterator<set<T> > iter(c,c.begin()); set_difference(a.begin(),a.end(),b.begin(),b.end(),iter); +#endif return c; } @@ -135,16 +158,34 @@ double used_time(); #else -template<class T> +template<class T ,class _Pr = less<T> > class my_hash { public: int operator()(const T&t)const {return Hash(t);} +#ifdef WIN32 + enum
+ { // parameters for hash table
+ bucket_size = 1 // 0 < bucket_size
+ }; + my_hash()
+ : comp()
+ { // construct with default comparator
+ }
+
+ my_hash(_Pr _Pred)
+ : comp(_Pred)
+ { // construct with _Pred comparator
+ } +protected:
+ _Pr comp; +public: + int operator()(const T&t , const T&t1)const {return comp(t,t1);} +#endif }; inline int Hash(int value) { return value; } #define MY_HASH_BASE hash_map<A,B,my_hash<A> > - #if __GNUC__>2 #include <ext/hash_map> using __gnu_cxx::hash_map; @@ -164,25 +205,25 @@ public: bool defined(const A&a) const { return find(a)!=this->end(); } const B&operator[](const A&a)const - { - typename MY_HASH_BASE::const_iterator pos=this->find(a); - - if( pos==this->end() ) - return init; - else - return pos->second; - } + { + typename MY_HASH_BASE::const_iterator pos=this->find(a); + + if( pos==this->end() ) + return init; + else + return pos->second; + } B&operator[](const A&a) - { - typename MY_HASH_BASE::iterator pos=this->find(a); - if( pos==this->end() ) - { - insert(typename MY_HASH_BASE::value_type(a,init)); - pos=this->find(a); - iassert(pos!=this->end()); - } - return pos->second; - } + { + typename MY_HASH_BASE::iterator pos=this->find(a); + if( pos==this->end() ) + { + insert(typename MY_HASH_BASE::value_type(a,init)); + pos=this->find(a); + iassert(pos!=this->end()); + } + return pos->second; + } }; #define forall_defined_h(a,b,c,d) for(typename leda_h_array<a,b>::const_iterator __jj__=(d).begin();__jj__!=(d).end()&&((c=__jj__->first),1); ++__jj__) diff --git a/mgizapp/src/model1.cpp b/mgizapp/src/model1.cpp index 315a825..122869f 100644 --- a/mgizapp/src/model1.cpp +++ b/mgizapp/src/model1.cpp @@ -100,7 +100,7 @@ int model1::em_thread(int noIterations, int nthread, /*Perplexity& perp, sentenc int pair_no; bool dump_files = false ; cout << "==========================================================\n"; - cout << modelName << " Training Started at: "<< ctime(&st) << "\n"; + cout << modelName << " Training Started at: "<< my_ctime(&st) << "\n"; int it = noIterations; pair_no = 0 ; it_st = time(NULL); @@ -133,7 +133,7 @@ int model1::em_with_tricks(int noIterations, /*Perplexity& perp, sentenceHandler st = time(NULL); sHandler1.rewind(); cout << "==========================================================\n"; - cout << modelName << " Training Started at: "<< ctime(&st) << "\n"; + cout << modelName << " Training Started at: "<< my_ctime(&st) << "\n"; for(int it = 1; it <= noIterations; it++){ pair_no = 0 ; it_st = time(NULL); @@ -266,9 +266,17 @@ void model1::em_loop(int it,Perplexity& perp, sentenceHandler& sHandler1, bool s Vector<WordIndex> viterbi_alignment(fs.size()); double viterbi_score = 1 ; +#ifdef WIN32 + bool *eindict = new bool[l + 1]; + bool *findict = new bool[m + 1]; + bool **indict = new bool*[m + 1]; + for(int _i = 0; _i < m+1; _i++) + indict[_i] = new bool[l + 1]; +#else bool eindict[l + 1]; bool findict[m + 1]; bool indict[m + 1][l + 1]; +#endif if(it == 1 && useDict){ for(unsigned int dummy = 0; dummy <= l; dummy++) eindict[dummy] = false; for(unsigned int dummy = 0; dummy <= m; dummy++){ @@ -386,6 +394,13 @@ void model1::em_loop(int it,Perplexity& perp, sentenceHandler& sHandler1, bool s printAlignToFile(es, fs, evlist, fvlist, of2, viterbi_alignment, sent.sentenceNo, viterbi_score); addAL(viterbi_alignment,sent.sentenceNo,l); pair_no++; +#ifdef WIN32 + delete[] eindict; + delete[] findict; + for(int _i = 0; _i < m+1; _i++) + delete[] indict[_i]; + delete[] indict; +#endif } /* of while */ } @@ -401,7 +416,7 @@ CTTableDiff<COUNT,PROB>* model1::one_step_em(int it, bool seedModel1, st = time(NULL); sHandler1.rewind(); cout << "==========================================================\n"; - cout << modelName << " Training Started at: "<< ctime(&st) << "\n"; + cout << modelName << " Training Started at: "<< my_ctime(&st) << "\n"; pair_no = 0 ; it_st = time(NULL); cout << "-----------\n" << modelName << ": Iteration " << it << '\n'; @@ -468,10 +483,18 @@ void model1::em_loop_1(CTTableDiff<COUNT,PROB> *diff,int it,Perplexity& perp, se cross_entropy = log(1.0); Vector<WordIndex> viterbi_alignment(fs.size()); double viterbi_score = 1 ; - - bool eindict[l + 1]; - bool findict[m + 1]; - bool indict[m + 1][l + 1]; + +#ifdef WIN32 + bool *eindict = new bool[l + 1]; + bool *findict = new bool[m + 1]; + bool **indict = new bool*[m + 1]; + for(int _i = 0; _i < m+1; _i++) + indict[_i] = new bool[l + 1]; +#else + bool eindict[l + 1]; + bool findict[m + 1]; + bool indict[m + 1][l + 1]; +#endif if(it == 1 && useDict){ for(unsigned int dummy = 0; dummy <= l; dummy++) eindict[dummy] = false; for(unsigned int dummy = 0; dummy <= m; dummy++){ @@ -593,9 +616,17 @@ void model1::em_loop_1(CTTableDiff<COUNT,PROB> *diff,int it,Perplexity& perp, se printAlignToFile(es, fs, evlist, fvlist, of2, viterbi_alignment, sent.sentenceNo, viterbi_score); addAL(viterbi_alignment,sent.sentenceNo,l); pair_no++; +#ifdef WIN32 + delete[] eindict; + delete[] findict; + for(int _i = 0; _i < m+1; _i++) + delete[] indict[_i]; + delete[] indict; +#endif } /* of while */ sHandler1.rewind(); perp.record("Model1"); viterbi_perp.record("Model1"); errorReportAL(cout, "IBM-1"); + } diff --git a/mgizapp/src/model2.cpp b/mgizapp/src/model2.cpp index affa0bd..dddde77 100644 --- a/mgizapp/src/model2.cpp +++ b/mgizapp/src/model2.cpp @@ -66,7 +66,7 @@ int model2::em_with_tricks(int noIterations,bool dumpCount, st = time(NULL) ; sHandler1.rewind(); cout << "\n==========================================================\n"; - cout << modelName << " Training Started at: " << ctime(&st) << " iter: " << noIterations << "\n"; + cout << modelName << " Training Started at: " << my_ctime(&st) << " iter: " << noIterations << "\n"; for(int it=1; it <= noIterations ; it++){ pair_no = 0; it_st = time(NULL) ; diff --git a/mgizapp/src/model2to3.cpp b/mgizapp/src/model2to3.cpp index d4db81a..4c6d729 100644 --- a/mgizapp/src/model2to3.cpp +++ b/mgizapp/src/model2to3.cpp @@ -288,7 +288,7 @@ void model3::transferSimple(/*model1& m1, model2& m2, */ sentenceHandler& sHandl st = time(NULL); cerr << "==========================================================\n"; - cerr << "\nTransfer started at: "<< ctime(&st) << '\n'; + cerr << "\nTransfer started at: "<< my_ctime(&st) << '\n'; cerr << "Simple tranfer of Model2 --> Model3 (i.e. estimating initial parameters of Model3 from Model2 tables)\n"; @@ -297,7 +297,7 @@ void model3::transferSimple(/*model1& m1, model2& m2, */ sentenceHandler& sHandl cerr << "\nTransfer: TRAIN CROSS-ENTROPY " << perp.cross_entropy() << " PERPLEXITY " << perp.perplexity() << '\n'; cerr << "\nTransfer took: " << difftime(fn, st) << " seconds\n"; - cerr << "\nTransfer Finished at: "<< ctime(&fn) << '\n'; + cerr << "\nTransfer Finished at: "<< my_ctime(&fn) << '\n'; cerr << "==========================================================\n"; } @@ -312,7 +312,7 @@ void model3::transfer(sentenceHandler& sHandler1,bool dump_files, Perplexity& pe st = time(NULL); cerr << "==========================================================\n"; - cerr << "\nTransfer started at: "<< ctime(&st) << '\n'; + cerr << "\nTransfer started at: "<< my_ctime(&st) << '\n'; cerr << "Transfering Model2 --> Model3 (i.e. estimating initial parameters of Model3 from Model2 tables)\n"; p1_count = p0_count = 0 ; @@ -390,7 +390,7 @@ void model3::transfer(sentenceHandler& sHandler1,bool dump_files, Perplexity& pe // cerr << "tTable contains " << tTable.getHash().bucket_count() // << " buckets and " << tTable.getHash().size() << " entries." ; cerr << "\nTransfer took: " << difftime(fn, st) << " seconds\n"; - cerr << "\nTransfer Finished at: "<< ctime(&fn) << endl; + cerr << "\nTransfer Finished at: "<< my_ctime(&fn) << endl; cerr << "==========================================================\n"; } diff --git a/mgizapp/src/model3.cpp b/mgizapp/src/model3.cpp index 5b04ae0..797dd58 100644 --- a/mgizapp/src/model3.cpp +++ b/mgizapp/src/model3.cpp @@ -393,7 +393,7 @@ int model3::viterbi(int noIterationsModel3, int noIterationsModel4, trainingString+='6'; cout << "\n==========================================================\n"; cout << "Starting "<<trainingString<<": Viterbi Training"; - cout << "\n "<<trainingString<<" Training Started at: "<< ctime(&st) + cout << "\n "<<trainingString<<" Training Started at: "<< my_ctime(&st) << '\n'; @@ -682,7 +682,7 @@ int model3::viterbi(int noIterationsModel3, int noIterationsModel4, << difftime(it_fn, it_st) << " seconds\n"; } /* of iterations */ fn = time(NULL); - cout << trainingString <<" Training Finished at: " << ctime(&fn) << "\n"; + cout << trainingString <<" Training Finished at: " << my_ctime(&fn) << "\n"; cout << "\n" << "Entire Viterbi "<<trainingString<<" Training took: " << difftime(fn, st) << " seconds\n"; cout << "==========================================================\n"; @@ -703,7 +703,7 @@ int model3::viterbi_hto3() { alignfile, number, test_alignfile, d4file, d5file, zeroFertFile; st = time(NULL); cout << "Starting HMM To Model 3 Viterbi Training"; - cout << "\n hto3 Training Started at: "<< ctime(&st) << '\n'; + cout << "\n hto3 Training Started at: "<< my_ctime(&st) << '\n'; string modelName="H23"; //cout <<"\n---------------------\n"<<modelName<<": Iteration " << it<<'\n'; int it = 1; @@ -784,7 +784,7 @@ int model3::viterbi_3to3() { alignfile, number, test_alignfile, d4file, d5file, zeroFertFile; st = time(NULL); cout << "Starting HMM To Model 3 Viterbi Training"; - cout << "\n hto3 Training Started at: "<< ctime(&st) << '\n'; + cout << "\n hto3 Training Started at: "<< my_ctime(&st) << '\n'; string modelName="H23"; int it = 1; @@ -875,7 +875,7 @@ d4model* model3::viterbi_3to4() { alignfile, number, test_alignfile, d4file, d5file, zeroFertFile; st = time(NULL); cout << "Starting Model 3 To Model 4 Viterbi Training"; - cout << "\n hto3 Training Started at: "<< ctime(&st) << '\n'; + cout << "\n hto3 Training Started at: "<< my_ctime(&st) << '\n'; string modelName="34"; int it = 1; //cout <<"\n---------------------\n"<<modelName<<": Iteration " << it<<'\n'; @@ -1106,7 +1106,7 @@ void multi_thread_m34_em(model3& m3, int ncpu, int Model3_Iterations, trainingString+='4'; cout << "\n==========================================================\n"; cout << "Starting "<<trainingString<<": Viterbi Training"; - cout << "\n "<<trainingString<<" Training Started at: "<< ctime(&st) + cout << "\n "<<trainingString<<" Training Started at: "<< my_ctime(&st) << '\n'; for (i=0; i<Model3_Iterations+Model4_Iterations; i++) { @@ -1361,7 +1361,7 @@ void multi_thread_m34_em(model3& m3, int ncpu, int Model3_Iterations, << difftime(it_fn, it_st) << " seconds\n"; } fn = time(NULL); - cout << trainingString <<" Training Finished at: " << ctime(&fn) << "\n"; + cout << trainingString <<" Training Finished at: " << my_ctime(&fn) << "\n"; cout << "\n" << "Entire Viterbi "<<trainingString<<" Training took: " << difftime(fn, st) << " seconds\n"; cout << "==========================================================\n"; diff --git a/mgizapp/src/model3_viterbi.cpp b/mgizapp/src/model3_viterbi.cpp index 8c95310..9398116 100644 --- a/mgizapp/src/model3_viterbi.cpp +++ b/mgizapp/src/model3_viterbi.cpp @@ -22,6 +22,13 @@ #include "model3.h" #include "utility.h" #include "Globals.h" +#include "AlignTables.h" +#ifdef WIN32 +typedef hash_map<Vector<WordIndex>, LogProb, hashmyalignment > alignment_hash; +#else +typedef hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment > alignment_hash; + +#endif LogProb model3::prob_of_target_and_alignment_given_source(Vector<WordIndex>& A, Vector<WordIndex>& Fert, tmodel<COUNT, PROB>& tTable, @@ -498,8 +505,7 @@ void model3::viterbi_loop(Perplexity& perp, Perplexity& viterbiPerp, if (Verbose) cerr << "\nCollecting counts over found alignments, total prob: " << align_total_count << "\n"; - hash_map<Vector<WordIndex>, LogProb, hashmyalignment, equal_to_myalignment >::iterator - align; + alignment_hash::iterator align; int acount = 0; if (align_total_count == 0) { cerr << " WARNINIG: For the following sentence pair : \n"; diff --git a/mgizapp/src/mystl.h b/mgizapp/src/mystl.h index 65c5ca1..29fa778 100644 --- a/mgizapp/src/mystl.h +++ b/mgizapp/src/mystl.h @@ -160,11 +160,31 @@ bool operator<(const tri<A,B,C>&x,const tri<A,B,C>&y) double used_time(); -template<class T> + +template<class T ,class _Pr = less<T> > class my_hash { public: - int operator()(const T&t)const {return Hash(t);} + int operator()(const T&t)const {return Hash(t);} +#ifdef WIN32 + enum
+ { // parameters for hash table
+ bucket_size = 1 // 0 < bucket_size
+ }; + my_hash()
+ : comp()
+ { // construct with default comparator
+ }
+
+ my_hash(_Pr _Pred)
+ : comp(_Pred)
+ { // construct with _Pred comparator
+ } +protected:
+ _Pr comp; +public: + int operator()(const T&t , const T&t1)const {return comp(t,t1);} +#endif }; inline int Hash(int value) { return value; } diff --git a/mgizapp/src/plain2snt.cpp b/mgizapp/src/plain2snt.cpp index 6e8f0b7..a6ee2e7 100644 --- a/mgizapp/src/plain2snt.cpp +++ b/mgizapp/src/plain2snt.cpp @@ -44,10 +44,16 @@ int main(int argc,char**argv) string vocab1(w1),vocab2(w2),snt1,snt2; unsigned int slashpos=vocab1.rfind('/')+1; +#ifdef WIN32 + if(slashpos==0) slashpos=vocab1.rfind('\\')+1; +#endif if( slashpos>=vocab1.length() ) slashpos=0; string vocab1x(vocab1.substr(slashpos,vocab1.length())); cout << vocab1 << " -> " << vocab1x << endl; slashpos=vocab2.rfind('/')+1; +#ifdef WIN32 + if(slashpos==0) slashpos=vocab1.rfind('\\')+1; +#endif if( slashpos>=vocab2.length() ) slashpos=0; string vocab2x(vocab2.substr(slashpos,vocab2.length())); cout << vocab2 << " -> " << vocab2x << endl; diff --git a/mgizapp/src/syncObj.h b/mgizapp/src/syncObj.h index 1c1b31d..86af946 100644 --- a/mgizapp/src/syncObj.h +++ b/mgizapp/src/syncObj.h @@ -6,19 +6,45 @@ #include <pthread.h> #include <iostream> +#ifdef WIN32 +#include <boost/thread/mutex.hpp> class Mutex{ private: - mutable pthread_mutex_t mutex; - + mutable boost::mutex* my_mutex; + Mutex(const Mutex&){ + + } public: - Mutex(){pthread_mutex_init(&mutex,NULL);}; - ~Mutex(){pthread_mutex_destroy(&mutex);} - + Mutex(){ + my_mutex = new boost::mutex(); + }; + ~Mutex(){delete my_mutex;my_mutex = 0;} + + inline void operator=(const Mutex& ref){} + public: - inline void lock() const{pthread_mutex_lock(&mutex);}; - inline void unlock() const{pthread_mutex_unlock(&mutex);}; + inline void lock() const{my_mutex->lock();}; + inline void unlock() const{my_mutex->unlock();}; }; +#else + +class Mutex{ +private: + mutable pthread_mutex_t mutex; + +public: + Mutex(){ + pthread_mutex_init(&mutex,NULL); + }; + ~Mutex(){pthread_mutex_destroy(&mutex);} + +public: + inline void lock() const{pthread_mutex_lock(&mutex);}; + inline void unlock() const{pthread_mutex_unlock(&mutex);}; +}; + +#endif class SyncDouble{ private: double i; diff --git a/mgizapp/src/ttableDiff.hpp b/mgizapp/src/ttableDiff.hpp index 0a5f3fb..419c990 100644 --- a/mgizapp/src/ttableDiff.hpp +++ b/mgizapp/src/ttableDiff.hpp @@ -42,7 +42,12 @@ private: INT32 noFrenchWords; // total number of unique target words /*! Store only the counting*/ - hash_map<wordPairIds, COUNT, hashpair, equal_to<wordPairIds> > ef; +#ifdef WIN32 + typedef hash_map<wordPairIds, COUNT, hashpair> wordpair_hash; +#else + typedef hash_map<wordPairIds, COUNT, hashpair, equal_to<wordPairIds> > wordpair_hash; +#endif + wordpair_hash ef; public: INT32 SaveToFile(const char* filename){ @@ -50,7 +55,7 @@ public: if(!ofs.is_open()){ return -1; }else{ - typename hash_map<wordPairIds, COUNT, hashpair, equal_to<wordPairIds> >::iterator it; + wordpair_hash::iterator it; for( it = ef.begin() ; it != ef.end(); it++){ ofs << it->first.first << " " << it->first.second << " " << it->second << std::endl; @@ -85,7 +90,7 @@ public: COUNT * GetPtr(WordIndex e, WordIndex f){ // look up this pair and return its position - typename hash_map<wordPairIds, COUNT, hashpair, equal_to<wordPairIds> >::iterator i = ef.find(wordPairIds(e, f)); + wordpair_hash::iterator i = ef.find(wordPairIds(e, f)); if(i != ef.end()) // if it exists, return a pointer to it. return(&((*i).second)); else return(0) ; // else return NULL pointer @@ -100,8 +105,7 @@ public: } INT32 AugmentTTable(tmodel<COUNT,PROB>& ttable){ - typename hash_map<wordPairIds, COUNT, hashpair, - equal_to<wordPairIds> >::iterator it; + wordpair_hash::iterator it; for( it = ef.begin() ; it != ef.end(); it++){ ttable.incCount(it->first.first,it->first.second,it->second); } diff --git a/mgizapp/src/utility.cpp b/mgizapp/src/utility.cpp index 4e9607a..dcbc5ce 100644 --- a/mgizapp/src/utility.cpp +++ b/mgizapp/src/utility.cpp @@ -19,8 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <string> +#include <time.h> #include "mymath.h" +using namespace std; + double factorial(int n) { double f=1; @@ -28,3 +32,9 @@ double factorial(int n) f *= i; return f; } + +string my_ctime(const time_t* t){ + char buffer[256]; + ctime_s(buffer,256,t); + return buffer; +} diff --git a/mgizapp/src/utility.h b/mgizapp/src/utility.h index 078a2a0..fc6cded 100644 --- a/mgizapp/src/utility.h +++ b/mgizapp/src/utility.h @@ -22,6 +22,7 @@ USA. #ifndef utility_h #define utility_h #include <iostream> +#include <time.h> #include "Perplexity.h" #include "Vector.h" #include "TTables.h" @@ -51,4 +52,8 @@ extern void printAlignToFile(const Vector<WordIndex>& es, const Vector<WordInde extern double factorial(int) ; +string my_ctime(const time_t* t); + + + #endif diff --git a/mgizapp/w32/benchtest.h b/mgizapp/w32/benchtest.h new file mode 100644 index 0000000..8090578 --- /dev/null +++ b/mgizapp/w32/benchtest.h @@ -0,0 +1,70 @@ +/* + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + */ + +#include "../config.h" + +enum { + OLD_WIN32CS, + OLD_WIN32MUTEX +}; + +extern int old_mutex_use; + +struct old_mutex_t_ { + HANDLE mutex; + CRITICAL_SECTION cs; +}; + +typedef struct old_mutex_t_ * old_mutex_t; + +struct old_mutexattr_t_ { + int pshared; +}; + +typedef struct old_mutexattr_t_ * old_mutexattr_t; + +extern BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION); +extern HINSTANCE ptw32_h_kernel32; + +#define PTW32_OBJECT_AUTO_INIT ((void *) -1) + +void dummy_call(int * a); +void interlocked_inc_with_conditionals(int *a); +void interlocked_dec_with_conditionals(int *a); +int old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr); +int old_mutex_lock(old_mutex_t *mutex); +int old_mutex_unlock(old_mutex_t *mutex); +int old_mutex_trylock(old_mutex_t *mutex); +int old_mutex_destroy(old_mutex_t *mutex); +/****************************************************************************************/ diff --git a/mgizapp/w32/config.h b/mgizapp/w32/config.h new file mode 100644 index 0000000..d6638df --- /dev/null +++ b/mgizapp/w32/config.h @@ -0,0 +1,134 @@ +/* config.h */ + +#ifndef PTW32_CONFIG_H +#define PTW32_CONFIG_H + +/********************************************************************* + * Defaults: see target specific redefinitions below. + *********************************************************************/ + +/* We're building the pthreads-win32 library */ +#define PTW32_BUILD + +/* Do we know about the C type sigset_t? */ +#undef HAVE_SIGSET_T + +/* Define if you have the <signal.h> header file. */ +#undef HAVE_SIGNAL_H + +/* Define if you have the Borland TASM32 or compatible assembler. */ +#undef HAVE_TASM32 + +/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */ +#undef NEED_DUPLICATEHANDLE + +/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */ +#undef NEED_CREATETHREAD + +/* Define if you don't have Win32 errno. (eg. WinCE) */ +#undef NEED_ERRNO + +/* Define if you don't have Win32 calloc. (eg. WinCE) */ +#undef NEED_CALLOC + +/* Define if you don't have Win32 ftime. (eg. WinCE) */ +#undef NEED_FTIME + +/* Define if you don't have Win32 semaphores. (eg. WinCE 2.1 or earlier) */ +#undef NEED_SEM + +/* Define if you need to convert string parameters to unicode. (eg. WinCE) */ +#undef NEED_UNICODE_CONSTS + +/* Define if your C (not C++) compiler supports "inline" functions. */ +#undef HAVE_C_INLINE + +/* Do we know about type mode_t? */ +#undef HAVE_MODE_T + +/* Define if you have the timespec struct */ +#undef HAVE_STRUCT_TIMESPEC + +/* Define if you don't have the GetProcessAffinityMask() */ +#undef NEED_PROCESS_AFFINITY_MASK + +/* +# ---------------------------------------------------------------------- +# The library can be built with some alternative behaviour to better +# facilitate development of applications on Win32 that will be ported +# to other POSIX systems. +# +# Nothing described here will make the library non-compliant and strictly +# compliant applications will not be affected in any way, but +# applications that make assumptions that POSIX does not guarantee are +# not strictly compliant and may fail or misbehave with some settings. +# +# PTW32_THREAD_ID_REUSE_INCREMENT +# Purpose: +# POSIX says that applications should assume that thread IDs can be +# recycled. However, Solaris (and some other systems) use a [very large] +# sequence number as the thread ID, which provides virtual uniqueness. +# This provides a very high but finite level of safety for applications +# that are not meticulous in tracking thread lifecycles e.g. applications +# that call functions which target detached threads without some form of +# thread exit synchronisation. +# +# Usage: +# Set to any value in the range: 0 <= value < 2^wordsize. +# Set to 0 to emulate reusable thread ID behaviour like Linux or *BSD. +# Set to 1 for unique thread IDs like Solaris (this is the default). +# Set to some factor of 2^wordsize to emulate smaller word size types +# (i.e. will wrap sooner). This might be useful to emulate some embedded +# systems. +# +# define PTW32_THREAD_ID_REUSE_INCREMENT 0 +# +# ---------------------------------------------------------------------- + */ +#undef PTW32_THREAD_ID_REUSE_INCREMENT + + +/********************************************************************* + * Target specific groups + * + * If you find that these are incorrect or incomplete please report it + * to the pthreads-win32 maintainer. Thanks. + *********************************************************************/ +#ifdef WINCE +#define NEED_DUPLICATEHANDLE +#define NEED_CREATETHREAD +#define NEED_ERRNO +#define NEED_CALLOC +#define NEED_FTIME +//#define NEED_SEM +#define NEED_UNICODE_CONSTS +#define NEED_PROCESS_AFFINITY_MASK +#endif + +#ifdef _UWIN +#define HAVE_MODE_T +#define HAVE_STRUCT_TIMESPEC +#endif + +#ifdef __GNUC__ +#define HAVE_C_INLINE +#endif + +#ifdef __MINGW32__ +#define HAVE_MODE_T +#endif + +#ifdef __BORLANDC__ +#endif + +#ifdef __WATCOMC__ +#endif + +#ifdef __DMC__ +#define HAVE_SIGNAL_H +#define HAVE_C_INLINE +#endif + + + +#endif diff --git a/mgizapp/w32/implement.h b/mgizapp/w32/implement.h new file mode 100644 index 0000000..3d96483 --- /dev/null +++ b/mgizapp/w32/implement.h @@ -0,0 +1,710 @@ +/* + * implement.h + * + * Definitions that don't need to be public. + * + * Keeps all the internals out of pthread.h + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _IMPLEMENT_H +#define _IMPLEMENT_H + +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x400 + +#include <windows.h> + +/* + * In case windows.h doesn't define it (e.g. WinCE perhaps) + */ +#ifdef WINCE +typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam); +#endif + +/* + * note: ETIMEDOUT is correctly defined in winsock.h + */ +#include <winsock.h> + +/* + * In case ETIMEDOUT hasn't been defined above somehow. + */ +#ifndef ETIMEDOUT +# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +#endif + +#if !defined(malloc) +#include <malloc.h> +#endif + +#if !defined(INT_MAX) +#include <limits.h> +#endif + +/* use local include files during development */ +#include "semaphore.h" +#include "sched.h" + +#if defined(HAVE_C_INLINE) || defined(__cplusplus) +#define INLINE inline +#else +#define INLINE +#endif + +#if defined (__MINGW32__) || (_MSC_VER >= 1300) +#define PTW32_INTERLOCKED_LONG long +#define PTW32_INTERLOCKED_LPLONG long* +#else +#define PTW32_INTERLOCKED_LONG PVOID +#define PTW32_INTERLOCKED_LPLONG PVOID* +#endif + +#if defined(__MINGW32__) +#include <stdint.h> +#elif defined(__BORLANDC__) +#define int64_t ULONGLONG +#else +#define int64_t _int64 +#endif + +typedef enum +{ + /* + * This enumeration represents the state of the thread; + * The thread is still "alive" if the numeric value of the + * state is greater or equal "PThreadStateRunning". + */ + PThreadStateInitial = 0, /* Thread not running */ + PThreadStateRunning, /* Thread alive & kicking */ + PThreadStateSuspended, /* Thread alive but suspended */ + PThreadStateCancelPending, /* Thread alive but is */ + /* has cancelation pending. */ + PThreadStateCanceling, /* Thread alive but is */ + /* in the process of terminating */ + /* due to a cancellation request */ + PThreadStateException, /* Thread alive but exiting */ + /* due to an exception */ + PThreadStateLast +} +PThreadState; + + +typedef struct ptw32_thread_t_ ptw32_thread_t; + +struct ptw32_thread_t_ +{ +#ifdef _UWIN + DWORD dummy[5]; +#endif + DWORD thread; + HANDLE threadH; /* Win32 thread handle - POSIX thread is invalid if threadH == 0 */ + pthread_t ptHandle; /* This thread's permanent pthread_t handle */ + ptw32_thread_t * prevReuse; /* Links threads on reuse stack */ + volatile PThreadState state; + void *exitStatus; + void *parms; + int ptErrno; + int detachState; + pthread_mutex_t threadLock; /* Used for serialised access to public thread state */ + int sched_priority; /* As set, not as currently is */ + pthread_mutex_t cancelLock; /* Used for async-cancel safety */ + int cancelState; + int cancelType; + HANDLE cancelEvent; +#ifdef __CLEANUP_C + jmp_buf start_mark; +#endif /* __CLEANUP_C */ +#if HAVE_SIGSET_T + sigset_t sigmask; +#endif /* HAVE_SIGSET_T */ + int implicit:1; + void *keys; + void *nextAssoc; +}; + + +/* + * Special value to mark attribute objects as valid. + */ +#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE) + +struct pthread_attr_t_ +{ + unsigned long valid; + void *stackaddr; + size_t stacksize; + int detachstate; + struct sched_param param; + int inheritsched; + int contentionscope; +#if HAVE_SIGSET_T + sigset_t sigmask; +#endif /* HAVE_SIGSET_T */ +}; + + +/* + * ==================== + * ==================== + * Semaphores, Mutexes and Condition Variables + * ==================== + * ==================== + */ + +struct sem_t_ +{ + int value; + pthread_mutex_t lock; + HANDLE sem; +#ifdef NEED_SEM + int leftToUnblock; +#endif +}; + +#define PTW32_OBJECT_AUTO_INIT ((void *) -1) +#define PTW32_OBJECT_INVALID NULL + +struct pthread_mutex_t_ +{ + LONG lock_idx; /* Provides exclusive access to mutex state + via the Interlocked* mechanism. + 0: unlocked/free. + 1: locked - no other waiters. + -1: locked - with possible other waiters. + */ + int recursive_count; /* Number of unlocks a thread needs to perform + before the lock is released (recursive + mutexes only). */ + int kind; /* Mutex type. */ + pthread_t ownerThread; + HANDLE event; /* Mutex release notification to waiting + threads. */ +}; + +struct pthread_mutexattr_t_ +{ + int pshared; + int kind; +}; + +/* + * Possible values, other than PTW32_OBJECT_INVALID, + * for the "interlock" element in a spinlock. + * + * In this implementation, when a spinlock is initialised, + * the number of cpus available to the process is checked. + * If there is only one cpu then "interlock" is set equal to + * PTW32_SPIN_USE_MUTEX and u.mutex is a initialised mutex. + * If the number of cpus is greater than 1 then "interlock" + * is set equal to PTW32_SPIN_UNLOCKED and the number is + * stored in u.cpus. This arrangement allows the spinlock + * routines to attempt an InterlockedCompareExchange on "interlock" + * immediately and, if that fails, to try the inferior mutex. + * + * "u.cpus" isn't used for anything yet, but could be used at + * some point to optimise spinlock behaviour. + */ +#define PTW32_SPIN_UNLOCKED (1) +#define PTW32_SPIN_LOCKED (2) +#define PTW32_SPIN_USE_MUTEX (3) + +struct pthread_spinlock_t_ +{ + long interlock; /* Locking element for multi-cpus. */ + union + { + int cpus; /* No. of cpus if multi cpus, or */ + pthread_mutex_t mutex; /* mutex if single cpu. */ + } u; +}; + +struct pthread_barrier_t_ +{ + unsigned int nCurrentBarrierHeight; + unsigned int nInitialBarrierHeight; + int iStep; + int pshared; + sem_t semBarrierBreeched[2]; +}; + +struct pthread_barrierattr_t_ +{ + int pshared; +}; + +struct pthread_key_t_ +{ + DWORD key; + void (*destructor) (void *); + pthread_mutex_t keyLock; + void *threads; +}; + + +typedef struct ThreadParms ThreadParms; +typedef struct ThreadKeyAssoc ThreadKeyAssoc; + +struct ThreadParms +{ + pthread_t tid; + void *(*start) (void *); + void *arg; +}; + + +struct pthread_cond_t_ +{ + long nWaitersBlocked; /* Number of threads blocked */ + long nWaitersGone; /* Number of threads timed out */ + long nWaitersToUnblock; /* Number of threads to unblock */ + sem_t semBlockQueue; /* Queue up threads waiting for the */ + /* condition to become signalled */ + sem_t semBlockLock; /* Semaphore that guards access to */ + /* | waiters blocked count/block queue */ + /* +-> Mandatory Sync.LEVEL-1 */ + pthread_mutex_t mtxUnblockLock; /* Mutex that guards access to */ + /* | waiters (to)unblock(ed) counts */ + /* +-> Optional* Sync.LEVEL-2 */ + pthread_cond_t next; /* Doubly linked list */ + pthread_cond_t prev; +}; + + +struct pthread_condattr_t_ +{ + int pshared; +}; + +#define PTW32_RWLOCK_MAGIC 0xfacade2 + +struct pthread_rwlock_t_ +{ + pthread_mutex_t mtxExclusiveAccess; + pthread_mutex_t mtxSharedAccessCompleted; + pthread_cond_t cndSharedAccessCompleted; + int nSharedAccessCount; + int nExclusiveAccessCount; + int nCompletedSharedAccessCount; + int nMagic; +}; + +struct pthread_rwlockattr_t_ +{ + int pshared; +}; + +/* + * MCS lock queue node - see ptw32_MCS_lock.c + */ +struct ptw32_mcs_node_t_ +{ + struct ptw32_mcs_node_t_ **lock; /* ptr to tail of queue */ + struct ptw32_mcs_node_t_ *next; /* ptr to successor in queue */ + LONG readyFlag; /* set after lock is released by + predecessor */ + LONG nextFlag; /* set after 'next' ptr is set by + successor */ +}; + +typedef struct ptw32_mcs_node_t_ ptw32_mcs_local_node_t; +typedef struct ptw32_mcs_node_t_ *ptw32_mcs_lock_t; + + +struct ThreadKeyAssoc +{ + /* + * Purpose: + * This structure creates an association between a thread and a key. + * It is used to implement the implicit invocation of a user defined + * destroy routine for thread specific data registered by a user upon + * exiting a thread. + * + * Graphically, the arrangement is as follows, where: + * + * K - Key with destructor + * (head of chain is key->threads) + * T - Thread that has called pthread_setspecific(Kn) + * (head of chain is thread->keys) + * A - Association. Each association is a node at the + * intersection of two doubly-linked lists. + * + * T1 T2 T3 + * | | | + * | | | + * K1 -----+-----A-----A-----> + * | | | + * | | | + * K2 -----A-----A-----+-----> + * | | | + * | | | + * K3 -----A-----+-----A-----> + * | | | + * | | | + * V V V + * + * Access to the association is guarded by two locks: the key's + * general lock (guarding the row) and the thread's general + * lock (guarding the column). This avoids the need for a + * dedicated lock for each association, which not only consumes + * more handles but requires that: before the lock handle can + * be released - both the key must be deleted and the thread + * must have called the destructor. The two-lock arrangement + * allows the resources to be freed as soon as either thread or + * key is concluded. + * + * To avoid deadlock: whenever both locks are required, the key + * and thread locks are always acquired in the order: key lock + * then thread lock. An exception to this exists when a thread + * calls the destructors, however this is done carefully to + * avoid deadlock. + * + * An association is created when a thread first calls + * pthread_setspecific() on a key that has a specified + * destructor. + * + * An association is destroyed either immediately after the + * thread calls the key destructor function on thread exit, or + * when the key is deleted. + * + * Attributes: + * thread + * reference to the thread that owns the + * association. This is actually the pointer to the + * thread struct itself. Since the association is + * destroyed before the thread exits, this can never + * point to a different logical thread to the one that + * created the assoc, i.e. after thread struct reuse. + * + * key + * reference to the key that owns the association. + * + * nextKey + * The pthread_t->keys attribute is the head of a + * chain of associations that runs through the nextKey + * link. This chain provides the 1 to many relationship + * between a pthread_t and all pthread_key_t on which + * it called pthread_setspecific. + * + * prevKey + * Similarly. + * + * nextThread + * The pthread_key_t->threads attribute is the head of + * a chain of assoctiations that runs through the + * nextThreads link. This chain provides the 1 to many + * relationship between a pthread_key_t and all the + * PThreads that have called pthread_setspecific for + * this pthread_key_t. + * + * prevThread + * Similarly. + * + * Notes: + * 1) As soon as either the key or the thread is no longer + * referencing the association, it can be destroyed. The + * association will be removed from both chains. + * + * 2) Under WIN32, an association is only created by + * pthread_setspecific if the user provided a + * destroyRoutine when they created the key. + * + * + */ + ptw32_thread_t * thread; + pthread_key_t key; + ThreadKeyAssoc *nextKey; + ThreadKeyAssoc *nextThread; + ThreadKeyAssoc *prevKey; + ThreadKeyAssoc *prevThread; +}; + + +#ifdef __CLEANUP_SEH +/* + * -------------------------------------------------------------- + * MAKE_SOFTWARE_EXCEPTION + * This macro constructs a software exception code following + * the same format as the standard Win32 error codes as defined + * in WINERROR.H + * Values are 32 bit values layed out as follows: + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +---+-+-+-----------------------+-------------------------------+ + * |Sev|C|R| Facility | Code | + * +---+-+-+-----------------------+-------------------------------+ + * + * Severity Values: + */ +#define SE_SUCCESS 0x00 +#define SE_INFORMATION 0x01 +#define SE_WARNING 0x02 +#define SE_ERROR 0x03 + +#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \ +( (DWORD) ( ( (_severity) << 30 ) | /* Severity code */ \ + ( 1 << 29 ) | /* MS=0, User=1 */ \ + ( 0 << 28 ) | /* Reserved */ \ + ( (_facility) << 16 ) | /* Facility Code */ \ + ( (_exception) << 0 ) /* Exception Code */ \ + ) ) + +/* + * We choose one specific Facility/Error code combination to + * identify our software exceptions vs. WIN32 exceptions. + * We store our actual component and error code within + * the optional information array. + */ +#define EXCEPTION_PTW32_SERVICES \ + MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \ + PTW32_SERVICES_FACILITY, \ + PTW32_SERVICES_ERROR ) + +#define PTW32_SERVICES_FACILITY 0xBAD +#define PTW32_SERVICES_ERROR 0xDEED + +#endif /* __CLEANUP_SEH */ + +/* + * Services available through EXCEPTION_PTW32_SERVICES + * and also used [as parameters to ptw32_throw()] as + * generic exception selectors. + */ + +#define PTW32_EPS_EXIT (1) +#define PTW32_EPS_CANCEL (2) + + +/* Useful macros */ +#define PTW32_MAX(a,b) ((a)<(b)?(b):(a)) +#define PTW32_MIN(a,b) ((a)>(b)?(b):(a)) + + +/* Declared in global.c */ +extern PTW32_INTERLOCKED_LONG (WINAPI * + ptw32_interlocked_compare_exchange) + (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG); + +/* Declared in pthread_cancel.c */ +extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD); + +/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */ +#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *) 1) + +extern int ptw32_processInitialized; +extern ptw32_thread_t * ptw32_threadReuseTop; +extern ptw32_thread_t * ptw32_threadReuseBottom; +extern pthread_key_t ptw32_selfThreadKey; +extern pthread_key_t ptw32_cleanupKey; +extern pthread_cond_t ptw32_cond_list_head; +extern pthread_cond_t ptw32_cond_list_tail; + +extern int ptw32_mutex_default_kind; + +extern int ptw32_concurrency; + +extern int ptw32_features; + +extern BOOL ptw32_smp_system; /* True: SMP system, False: Uni-processor system */ + +extern CRITICAL_SECTION ptw32_thread_reuse_lock; +extern CRITICAL_SECTION ptw32_mutex_test_init_lock; +extern CRITICAL_SECTION ptw32_cond_list_lock; +extern CRITICAL_SECTION ptw32_cond_test_init_lock; +extern CRITICAL_SECTION ptw32_rwlock_test_init_lock; +extern CRITICAL_SECTION ptw32_spinlock_test_init_lock; + +#ifdef _UWIN +extern int pthread_count; +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ===================== + * ===================== + * Forward Declarations + * ===================== + * ===================== + */ + + int ptw32_is_attr (const pthread_attr_t * attr); + + int ptw32_cond_check_need_init (pthread_cond_t * cond); + int ptw32_mutex_check_need_init (pthread_mutex_t * mutex); + int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock); + + PTW32_INTERLOCKED_LONG WINAPI + ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location, + PTW32_INTERLOCKED_LONG value, + PTW32_INTERLOCKED_LONG comparand); + + LONG WINAPI + ptw32_InterlockedExchange (LPLONG location, + LONG value); + + DWORD + ptw32_RegisterCancelation (PAPCFUNC callback, + HANDLE threadH, DWORD callback_arg); + + int ptw32_processInitialize (void); + + void ptw32_processTerminate (void); + + void ptw32_threadDestroy (pthread_t tid); + + void ptw32_pop_cleanup_all (int execute); + + pthread_t ptw32_new (void); + + pthread_t ptw32_threadReusePop (void); + + void ptw32_threadReusePush (pthread_t thread); + + int ptw32_getprocessors (int *count); + + int ptw32_setthreadpriority (pthread_t thread, int policy, int priority); + + void ptw32_rwlock_cancelwrwait (void *arg); + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + unsigned __stdcall +#else + void +#endif + ptw32_threadStart (void *vthreadParms); + + void ptw32_callUserDestroyRoutines (pthread_t thread); + + int ptw32_tkAssocCreate (ptw32_thread_t * thread, pthread_key_t key); + + void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc); + + int ptw32_semwait (sem_t * sem); + + DWORD ptw32_relmillisecs (const struct timespec * abstime); + + void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node); + + void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node); + +#ifdef NEED_FTIME + void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft); + void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts); +#endif + +/* Declared in misc.c */ +#ifdef NEED_CALLOC +#define calloc(n, s) ptw32_calloc(n, s) + void *ptw32_calloc (size_t n, size_t s); +#endif + +/* Declared in private.c */ + void ptw32_throw (DWORD exception); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#ifdef _UWIN_ +# ifdef _MT +# ifdef __cplusplus +extern "C" +{ +# endif + _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *), + unsigned, void *); + _CRTIMP void __cdecl _endthread (void); + _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned, + unsigned (__stdcall *) (void *), + void *, unsigned, unsigned *); + _CRTIMP void __cdecl _endthreadex (unsigned); +# ifdef __cplusplus +} +# endif +# endif +#else +# include <process.h> +#endif + + +/* + * Defaults. Could be overridden when building the inlined version of the dll. + * See ptw32_InterlockedCompareExchange.c + */ +#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE +#define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_interlocked_compare_exchange +#endif + +#ifndef PTW32_INTERLOCKED_EXCHANGE +#define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange +#endif + + +/* + * Check for old and new versions of cygwin. See the FAQ file: + * + * Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32? + * + * Patch by Anders Norlander <anorland@hem2.passagen.se> + */ +#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD) + +/* + * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE + * in order to avoid warnings because of return type + */ + +#define _beginthreadex(security, \ + stack_size, \ + start_proc, \ + arg, \ + flags, \ + pid) \ + CreateThread(security, \ + stack_size, \ + (LPTHREAD_START_ROUTINE) start_proc, \ + arg, \ + flags, \ + pid) + +#define _endthreadex ExitThread + +#endif /* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD */ + + +#endif /* _IMPLEMENT_H */ diff --git a/mgizapp/w32/need_errno.h b/mgizapp/w32/need_errno.h new file mode 100644 index 0000000..2609f8d --- /dev/null +++ b/mgizapp/w32/need_errno.h @@ -0,0 +1,132 @@ +/*** +* errno.h - system wide error numbers (set by system calls) +* +* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. +* +* Purpose: +* This file defines the system-wide error numbers (set by +* system calls). Conforms to the XENIX standard. Extended +* for compatibility with Uniforum standard. +* [System V] +* +* [Public] +* +****/ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#ifndef _INC_ERRNO +#define _INC_ERRNO + +#if !defined(_WIN32) && !defined(_MAC) +#error ERROR: Only Mac or Win32 targets supported! +#endif + +#include <winsock.h> + +#ifdef __cplusplus +extern "C" { +#endif + + + +/* Define _CRTIMP */ + +#ifndef _CRTIMP +#ifdef _DLL +#define _CRTIMP __declspec(dllimport) +#else /* ndef _DLL */ +#define _CRTIMP +#endif /* _DLL */ +#endif /* _CRTIMP */ + + +/* Define __cdecl for non-Microsoft compilers */ + +#if ( !defined(_MSC_VER) && !defined(__cdecl) ) +#define __cdecl +#endif + +/* Define _CRTAPI1 (for compatibility with the NT SDK) */ + +#ifndef _CRTAPI1 +#if _MSC_VER >= 800 && _M_IX86 >= 300 +#define _CRTAPI1 __cdecl +#else +#define _CRTAPI1 +#endif +#endif + + +/* declare reference to errno */ + +#if (defined(_MT) || defined(_MD) || defined(_DLL)) && !defined(_MAC) +_CRTIMP extern int * __cdecl _errno(void); +#define errno (*_errno()) +#else /* ndef _MT && ndef _MD && ndef _DLL */ +_CRTIMP extern int errno; +#endif /* _MT || _MD || _DLL */ + +/* Error Codes */ + +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 36 + +/* defined differently in winsock.h on WinCE */ +#ifndef ENAMETOOLONG +#define ENAMETOOLONG 38 +#endif + +#define ENOLCK 39 +#define ENOSYS 40 + +/* defined differently in winsock.h on WinCE */ +#ifndef ENOTEMPTY +#define ENOTEMPTY 41 +#endif + +#define EILSEQ 42 + +/* + * Support EDEADLOCK for compatibiity with older MS-C versions. + */ +#define EDEADLOCK EDEADLK + +#ifdef __cplusplus +} +#endif + +#endif /* _INC_ERRNO */ diff --git a/mgizapp/w32/pthread.dll b/mgizapp/w32/pthread.dll Binary files differnew file mode 100644 index 0000000..212db2c --- /dev/null +++ b/mgizapp/w32/pthread.dll diff --git a/mgizapp/w32/pthread.h b/mgizapp/w32/pthread.h new file mode 100644 index 0000000..f3d2dac --- /dev/null +++ b/mgizapp/w32/pthread.h @@ -0,0 +1,1368 @@ +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +/* + * See the README file for an explanation of the pthreads-win32 version + * numbering scheme and how the DLL is named etc. + */ +#define PTW32_VERSION 2,8,0,0 +#define PTW32_VERSION_STRING "2, 8, 0, 0\0" + +/* There are three implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The three implementations are: + * + * WIN32 SEH + * C + * C++ + * + * Please note that exiting a push/pop block via + * "return", "exit", "break", or "continue" will + * lead to different behaviour amongst applications + * depending upon whether the library was built + * using SEH, C++, or C. For example, a library built + * with SEH will call the cleanup routine, while both + * C++ and C built versions will not. + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) +# define __CLEANUP_C +#endif + +#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) +#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. +#endif + +/* + * Stop here if we are being included by the resource compiler. + */ +#ifndef RC_INVOKED + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#ifdef _UWIN +# define HAVE_STRUCT_TIMESPEC 1 +# define HAVE_SIGNAL_H 1 +# undef HAVE_CONFIG_H +# pragma comment(lib, "pthread") +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + * Provides an implementation of PThreads based upon the + * standard: + * + * POSIX 1003.1-2001 + * and + * The Single Unix Specification version 3 + * + * (these two are equivalent) + * + * in order to enhance code portability between Windows, + * various commercial Unix implementations, and Linux. + * + * See the ANNOUNCE file for a full list of conforming + * routines and defined constants, and a list of missing + * routines and constants not defined in this implementation. + * + * Authors: + * There have been many contributors to this library. + * The initial implementation was contributed by + * John Bossom, and several others have provided major + * sections or revisions of parts of the implementation. + * Often significant effort has been contributed to + * find and fix important bugs and other problems to + * improve the reliability of the library, which sometimes + * is not reflected in the amount of code which changed as + * result. + * As much as possible, the contributors are acknowledged + * in the ChangeLog file in the source code distribution + * where their changes are noted in detail. + * + * Contributors are listed in the CONTRIBUTORS file. + * + * As usual, all bouquets go to the contributors, and all + * brickbats go to the project maintainer. + * + * Maintainer: + * The code base for this project is coordinated and + * eventually pre-tested, packaged, and made available by + * + * Ross Johnson <rpj@callisto.canberra.edu.au> + * + * QA Testers: + * Ultimately, the library is tested in the real world by + * a host of competent and demanding scientists and + * engineers who report bugs and/or provide solutions + * which are then fixed or incorporated into subsequent + * versions of the library. Each time a bug is fixed, a + * test case is written to prove the fix and ensure + * that later changes to the code don't reintroduce the + * same error. The number of test cases is slowly growing + * and therefore so is the code reliability. + * + * Compliance: + * See the file ANNOUNCE for the list of implemented + * and not-implemented routines and defined options. + * Of course, these are all defined is this file as well. + * + * Web site: + * The source code and other information about this library + * are available from + * + * http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +/* Try to avoid including windows.h */ +#if defined(__MINGW32__) && defined(__cplusplus) +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#ifdef PTW32_INCLUDE_WINDOWS_H +#include <windows.h> +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) +/* + * VC++6.0 or early compiler's header has no DWORD_PTR type. + */ +typedef unsigned long DWORD_PTR; +#endif +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifndef NEED_FTIME +#include <time.h> +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if HAVE_SIGNAL_H +#include <signal.h> +#endif /* HAVE_SIGNAL_H */ + +#include <setjmp.h> +#include <limits.h> + +/* + * Boolean values to make us independent of system includes. + */ +enum { + PTW32_FALSE = 0, + PTW32_TRUE = (! PTW32_FALSE) +}; + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include <errno.h> +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define some error numbers. + */ +#ifndef ENOTSUP +# define ENOTSUP 48 /* This is the value in Solaris. */ +#endif + +#ifndef ETIMEDOUT +# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +#endif + +#ifndef ENOSYS +# define ENOSYS 140 /* Semi-arbitrary value */ +#endif + +#ifndef EDEADLK +# ifdef EDEADLOCK +# define EDEADLK EDEADLOCK +# else +# define EDEADLK 36 /* This is the value in MSVC. */ +# endif +#endif + +#include <sched.h> + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. + */ +#ifndef PTW32_INCLUDE_WINDOWS_H +#ifndef HANDLE +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#ifndef DWORD +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#ifndef HAVE_STRUCT_TIMESPEC +#define HAVE_STRUCT_TIMESPEC 1 +struct timespec { + long tv_sec; + long tv_nsec; +}; +#endif /* HAVE_STRUCT_TIMESPEC */ + +#ifndef SIG_BLOCK +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#ifndef SIG_UNBLOCK +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#ifndef SIG_SETMASK +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in <unistd.h>, which is not provided + * with pthreads-win32. + * + * For conformance with the Single Unix Specification (version 3), all of the + * options below are defined, and have a value of either -1 (not supported) + * or 200112L (supported). + * + * These options can neither be left undefined nor have a value of 0, because + * either indicates that sysconf(), which is not implemented, may be used at + * runtime to check the status of the option. + * + * _POSIX_THREADS (== 200112L) + * If == 200112L, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) + * If == 200112L, you can control the size of a thread's + * stack + * pthread_attr_getstacksize + * pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (== -1) + * If == 200112L, you can allocate and control a thread's + * stack. If not supported, the following functions + * will return ENOSYS, indicating they are not + * supported: + * pthread_attr_getstackaddr + * pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) + * If == 200112L, you can use realtime scheduling. + * This option indicates that the behaviour of some + * implemented functions conforms to the additional TPS + * requirements in the standard. E.g. rwlocks favour + * writers over readers when threads have equal priority. + * + * _POSIX_THREAD_PRIO_INHERIT (== -1) + * If == 200112L, you can create priority inheritance + * mutexes. + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (== -1) + * If == 200112L, you can create priority ceiling mutexes + * Indicates the availability of: + * pthread_mutex_getprioceiling + * pthread_mutex_setprioceiling + * pthread_mutexattr_getprioceiling + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprioceiling + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PROCESS_SHARED (== -1) + * If set, you can create mutexes and condition + * variables that can be shared with another + * process.If set, indicates the availability + * of: + * pthread_mutexattr_getpshared + * pthread_mutexattr_setpshared + * pthread_condattr_getpshared + * pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) + * If == 200112L you can use the special *_r library + * functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (== 200112L) + * If == 200112L, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (== 200112L) + * If == 200112L, you can use spin locks + * + * _POSIX_BARRIERS (== 200112L) + * If == 200112L, you can use barriers + * + * + These functions provide both 'inherit' and/or + * 'protect' protocol, based upon these macro + * settings. + * + * ------------------------------------------------------------- + */ + +/* + * POSIX Options + */ +#undef _POSIX_THREADS +#define _POSIX_THREADS 200112L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200112L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200112L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200112L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200112L + +/* + * The following options are not supported + */ +#undef _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR -1 + +#undef _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT -1 + +#undef _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT -1 + +/* TPS is not fully supported. */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +#undef _POSIX_THREAD_PROCESS_SHARED +#define _POSIX_THREAD_PROCESS_SHARED -1 + + +/* + * POSIX 1003.1-2001 Limits + * =========================== + * + * These limits are normally set in <limits.h>, which is not provided with + * pthreads-win32. + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Maximum number of attempts to destroy + * a thread's thread-specific data on + * termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + * Maximum number of thread-specific data keys + * available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + * Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + * Maximum number of threads supported per + * process (must be at least 64). + * + * SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (must be at least 256) + * + * SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (must be at least 32767) + * + */ +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 + +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX 128 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 + +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX 64 + + /* Arbitrary value */ +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + + /* Arbitrary value */ +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX 32767 + +#undef SEM_VALUE_MAX +#define SEM_VALUE_MAX INT_MAX + + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * The Open Watcom C/C++ compiler uses a non-standard calling convention + * that passes function args in registers unless __cdecl is explicitly specified + * in exposed function prototypes. + * + * We force all calls to cdecl even though this could slow Watcom code down + * slightly. If you know that the Watcom compiler will be used to build both + * the DLL and application, then you can probably define this as a null string. + * Remember that pthread.h (this file) is used for both the DLL and application builds. + */ +#define PTW32_CDECL __cdecl + +#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX +# include <sys/types.h> +#else +/* + * Generic handle type - intended to extend uniqueness beyond + * that available with a simple pointer. It should scale for either + * IA-32 or IA-64. + */ +typedef struct { + void * p; /* Pointer to actual object */ + unsigned int x; /* Extra information - reuse count etc */ +} ptw32_handle_t; + +typedef ptw32_handle_t pthread_t; +typedef struct pthread_attr_t_ * pthread_attr_t; +typedef struct pthread_once_t_ pthread_once_t; +typedef struct pthread_key_t_ * pthread_key_t; +typedef struct pthread_mutex_t_ * pthread_mutex_t; +typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; +typedef struct pthread_cond_t_ * pthread_cond_t; +typedef struct pthread_condattr_t_ * pthread_condattr_t; +#endif +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +typedef struct pthread_spinlock_t_ * pthread_spinlock_t; +typedef struct pthread_barrier_t_ * pthread_barrier_t; +typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; + +/* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + +enum { +/* + * pthread_attr_{get,set}detachstate + */ + PTHREAD_CREATE_JOINABLE = 0, /* Default */ + PTHREAD_CREATE_DETACHED = 1, + +/* + * pthread_attr_{get,set}inheritsched + */ + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, /* Default */ + +/* + * pthread_{get,set}scope + */ + PTHREAD_SCOPE_PROCESS = 0, + PTHREAD_SCOPE_SYSTEM = 1, /* Default */ + +/* + * pthread_setcancelstate paramters + */ + PTHREAD_CANCEL_ENABLE = 0, /* Default */ + PTHREAD_CANCEL_DISABLE = 1, + +/* + * pthread_setcanceltype parameters + */ + PTHREAD_CANCEL_ASYNCHRONOUS = 0, + PTHREAD_CANCEL_DEFERRED = 1, /* Default */ + +/* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1, + +/* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} + +struct pthread_once_t_ +{ + int done; /* indicates if user function has been executed */ + void * lock; + int reserved1; + int reserved2; +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3) + +/* + * Compatibility with LinuxThreads + */ +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) + + +/* + * Mutex types. + */ +enum +{ + /* Compatibility with LinuxThreads */ + PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, + /* For compatibility with POSIX */ + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; + + +typedef struct ptw32_cleanup_t ptw32_cleanup_t; + +#if defined(_MSC_VER) +/* Disable MSVC 'anachronism used' warning */ +#pragma warning( disable : 4229 ) +#endif + +typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); + +#if defined(_MSC_VER) +#pragma warning( default : 4229 ) +#endif + +struct ptw32_cleanup_t +{ + ptw32_cleanup_callback_t routine; + void *arg; + struct ptw32_cleanup_t *prev; +}; + +#ifdef __CLEANUP_SEH + /* + * WIN32 SEH version of cancel cleanup. + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ + _cleanup.arg = (_arg); \ + __try \ + { \ + +#define pthread_cleanup_pop( _execute ) \ + } \ + __finally \ + { \ + if( _execute || AbnormalTermination()) \ + { \ + (*(_cleanup.routine))( _cleanup.arg ); \ + } \ + } \ + } + +#else /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_C + + /* + * C implementation of PThreads cancel cleanup + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ + (void) ptw32_pop_cleanup( _execute ); \ + } + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX + + /* + * C++ version of cancel cleanup. + * - John E. Bossom. + */ + + class PThreadCleanup { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + ptw32_cleanup_callback_t cleanUpRout; + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( 0 ), + obj( 0 ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + ptw32_cleanup_callback_t routine, + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) + { + (void) (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ + (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ + cleanup.execute( _execute ); \ + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + +/* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + +/* + * PThread Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, + int *detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, + void **stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, + size_t * stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, + int detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, + void *stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, + size_t stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (pthread_attr_t *, + int *); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, + int inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr, + int * inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, + int *); + +/* + * PThread Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(*start) (void *), + void *arg); + +PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); + +PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, + pthread_t t2); + +PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); + +PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, + void **value_ptr); + +PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, + int *oldstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, + int *oldtype); + +PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, + void (*init_routine) (void)); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); + +PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, + void (*routine) (void *), + void *arg); +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread Specific Data Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, + void (*destructor) (void *)); + +PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); + +PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, + const void *value); + +PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); + + +/* + * Mutex Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, + int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); + +/* + * Barrier Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, + int pshared); + +/* + * Mutex Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, + const pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); + +/* + * Spinlock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); + +/* + * Barrier Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, + unsigned int count); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); + +/* + * Condition Variable Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, + int pshared); + +/* + * Condition Variable Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, + const pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, + pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); + +/* + * Scheduling + */ +PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, + int policy, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, + int *policy, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); + +PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); + +/* + * Read-Write Lock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, + const pthread_rwlockattr_t *attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, + int pshared); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 + +/* + * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32 + * already have signal.h that don't define these. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); + +/* + * Non-portable functions + */ + +/* + * Compatibility with Linux. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, + int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, + int *kind); + +/* + * Possibly supported by other POSIX threads implementations + */ +PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); +PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); + +/* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); + +/* + * Features that are auto-detected at load/run time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); +enum ptw32_features { + PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ + PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ +}; + +/* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ +PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); + +#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* + * Returns the Win32 HANDLE for the POSIX thread. + */ +PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); + + +/* + * Protected Methods + * + * This function blocks until the given WIN32 handle + * is signaled or pthread_cancel had been called. + * This function allows the caller to hook into the + * PThreads cancel mechanism. It is implemented using + * + * WaitForMultipleObjects + * + * on 'waitHandle' and a manually reset WIN32 Event + * used to implement pthread_cancel. The 'timeout' + * argument to TimedWait is simply passed to + * WaitForMultipleObjects. + */ +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, + DWORD timeout); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread-Safe C Runtime Library Mappings. + */ +#ifndef _UWIN +# if defined(NEED_ERRNO) + PTW32_DLLPORT int * PTW32_CDECL _errno( void ); +# else +# ifndef errno +# if (defined(_MT) || defined(_DLL)) + __declspec(dllimport) extern int * __cdecl _errno(void); +# define errno (*_errno()) +# endif +# endif +# endif +#endif + +/* + * WIN32 C runtime library had been made thread-safe + * without affecting the user interface. Provide + * mappings from the UNIX thread-safe versions to + * the standard C runtime library calls. + * Only provide function mappings for functions that + * actually exist on WIN32. + */ + +#if !defined(__MINGW32__) +#define strtok_r( _s, _sep, _lasts ) \ + ( *(_lasts) = strtok( (_s), (_sep) ) ) +#endif /* !__MINGW32__ */ + +#define asctime_r( _tm, _buf ) \ + ( strcpy( (_buf), asctime( (_tm) ) ), \ + (_buf) ) + +#define ctime_r( _clock, _buf ) \ + ( strcpy( (_buf), ctime( (_clock) ) ), \ + (_buf) ) + +#define gmtime_r( _clock, _result ) \ + ( *(_result) = *gmtime( (_clock) ), \ + (_result) ) + +#define localtime_r( _clock, _result ) \ + ( *(_result) = *localtime( (_clock) ), \ + (_result) ) + +#define rand_r( _seed ) \ + ( _seed == _seed? rand() : rand() ) + + +/* + * Some compiler environments don't define some things. + */ +#if defined(__BORLANDC__) +# define _ftime ftime +# define _timeb timeb +#endif + +#ifdef __cplusplus + +/* + * Internal exceptions + */ +class ptw32_exception {}; +class ptw32_exception_cancel : public ptw32_exception {}; +class ptw32_exception_exit : public ptw32_exception {}; + +#endif + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* FIXME: This is only required if the library was built using SEH */ +/* + * Get internal SEH tag + */ +PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#ifndef PTW32_BUILD + +#ifdef __CLEANUP_SEH + +/* + * Redefine the SEH __except keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define __except( E ) \ + __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ + ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) + +#endif /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_CXX + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#ifdef _MSC_VER + /* + * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' + * if you want Pthread-Win32 cancelation and pthread_exit to work. + */ + +#ifndef PtW32NoCatchWarn + +#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") +#pragma message("------------------------------------------------------------------") +#pragma message("When compiling applications with MSVC++ and C++ exception handling:") +#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") +#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") +#pragma message(" cancelation and pthread_exit to work. For example:") +#pragma message("") +#pragma message(" #ifdef PtW32CatchAll") +#pragma message(" PtW32CatchAll") +#pragma message(" #else") +#pragma message(" catch(...)") +#pragma message(" #endif") +#pragma message(" {") +#pragma message(" /* Catchall block processing */") +#pragma message(" }") +#pragma message("------------------------------------------------------------------") + +#endif + +#define PtW32CatchAll \ + catch( ptw32_exception & ) { throw; } \ + catch( ... ) + +#else /* _MSC_VER */ + +#define catch( E ) \ + catch( ptw32_exception & ) { throw; } \ + catch( E ) + +#endif /* _MSC_VER */ + +#endif /* __CLEANUP_CXX */ + +#endif /* ! PTW32_BUILD */ + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#ifdef PTW32__HANDLE_DEF +# undef HANDLE +#endif +#ifdef PTW32__DWORD_DEF +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* ! RC_INVOKED */ + +#endif /* PTHREAD_H */ diff --git a/mgizapp/w32/pthread.lib b/mgizapp/w32/pthread.lib Binary files differnew file mode 100644 index 0000000..50d3fc6 --- /dev/null +++ b/mgizapp/w32/pthread.lib diff --git a/mgizapp/w32/pthreadlib.dll b/mgizapp/w32/pthreadlib.dll Binary files differnew file mode 100644 index 0000000..212db2c --- /dev/null +++ b/mgizapp/w32/pthreadlib.dll diff --git a/mgizapp/w32/sched.h b/mgizapp/w32/sched.h new file mode 100644 index 0000000..dfb8e93 --- /dev/null +++ b/mgizapp/w32/sched.h @@ -0,0 +1,178 @@ +/* + * Module: sched.h + * + * Purpose: + * Provides an implementation of POSIX realtime extensions + * as defined in + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ifndef _SCHED_H +#define _SCHED_H + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include <errno.h> +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#if defined(__MINGW32__) || defined(_UWIN) +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +/* For pid_t */ +# include <sys/types.h> +/* Required by Unix 98 */ +# include <time.h> +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ +#else +typedef int pid_t; +#endif + +/* Thread scheduling policies */ + +enum { + SCHED_OTHER = 0, + SCHED_FIFO, + SCHED_RR, + SCHED_MIN = SCHED_OTHER, + SCHED_MAX = SCHED_RR +}; + +struct sched_param { + int sched_priority; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +PTW32_DLLPORT int __cdecl sched_yield (void); + +PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); + +PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); + +PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); + +PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); + +/* + * Note that this macro returns ENOTSUP rather than + * ENOSYS as might be expected. However, returning ENOSYS + * should mean that sched_get_priority_{min,max} are + * not implemented as well as sched_rr_get_interval. + * This is not the case, since we just don't support + * round-robin scheduling. Therefore I have chosen to + * return the same value as sched_setscheduler when + * SCHED_RR is passed to it. + */ +#define sched_rr_get_interval(_pid, _interval) \ + ( errno = ENOTSUP, (int) -1 ) + + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* !_SCHED_H */ + diff --git a/mgizapp/w32/semaphore.h b/mgizapp/w32/semaphore.h new file mode 100644 index 0000000..a3330a6 --- /dev/null +++ b/mgizapp/w32/semaphore.h @@ -0,0 +1,166 @@ +/* + * Module: semaphore.h + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined( SEMAPHORE_H ) +#define SEMAPHORE_H + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +# ifdef PTW32_BUILD +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include <errno.h> +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#define _POSIX_SEMAPHORES + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifndef HAVE_MODE_T +typedef unsigned int mode_t; +#endif + + +typedef struct sem_t_ * sem_t; + +PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, + int pshared, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, + const struct timespec * abstime); + +PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, + int count); + +PTW32_DLLPORT int __cdecl sem_open (const char * name, + int oflag, + mode_t mode, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_unlink (const char * name); + +PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, + int * sval); + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* !SEMAPHORE_H */ |