瀏覽代碼

# revisions: 45460,45481

git-svn-id: tags/release_3_2_0@45532 -
marco 5 年之前
父節點
當前提交
322509bd4e
共有 3 個文件被更改,包括 112 次插入21 次删除
  1. 25 14
      installer/install.dat
  2. 3 0
      rtl/linux/pthread.inc
  3. 84 7
      rtl/unix/cthreads.pp

+ 25 - 14
installer/install.dat

@@ -146,6 +146,8 @@ package=utils-dxegendos.zip[dxegdos.zip],Generation of D~X~E modules loadable at
 package=ufcl-pdfdos.zip[ufcpddos.zip],PDF generating and TTF file info library
 package=ufcl-pdfdos.zip[ufcpddos.zip],PDF generating and TTF file info library
 # Dos-2 25
 # Dos-2 25
 package=urtl-genericsdos.zip[urtlgdos.zip],RTL-generic collection library
 package=urtl-genericsdos.zip[urtlgdos.zip],RTL-generic collection library
+# Dos-2 26
+package=units-webidldos.zip[uwidldos.zip],Web IDL parser and converter to Object Pascal classes
 
 
 #
 #
 # Win32 packages
 # Win32 packages
@@ -369,8 +371,6 @@ package=utils-pas2fpmos2.zip[p2fmos2.zip],Generate fpmake.pp for Pascal source
 package=utils-pas2jnios2.zip[p2jnos2.zip],Generate JNI bridge for Pascal code
 package=utils-pas2jnios2.zip[p2jnos2.zip],Generate JNI bridge for Pascal code
 # OS/2 31
 # OS/2 31
 package=utils-pas2utos2.zip[p2utos2.zip],Pascal source to FPC Unit test generator
 package=utils-pas2utos2.zip[p2utos2.zip],Pascal source to FPC Unit test generator
-# OS/2 32
-package=ufcl-pdfos2.zip[ufcpdos2.zip],PDF generating and TTF file info library
 
 
 #
 #
 # OS/2 packages 2nd part
 # OS/2 packages 2nd part
@@ -449,10 +449,6 @@ package=utils-rmwaitos2.zip[rmwos2.zip],Remove (delete) file(s) with optional re
 package=utils-lexyaccos2.zip[tplyos2.zip],Compiler generator for TP and compatibles
 package=utils-lexyaccos2.zip[tplyos2.zip],Compiler generator for TP and compatibles
 # OS/2-2 31
 # OS/2-2 31
 package=utils-fpcmos2.zip[fpcmos2.zip],Generate Makefiles out of Makefile.fpc files
 package=utils-fpcmos2.zip[fpcmos2.zip],Generate Makefiles out of Makefile.fpc files
-# OS/2-2 32
-package=utils-unicodeos2.zip[ucodeos2.zip],Transformation of Unicode consortium data for FPC
-
-
 
 
 
 
 #
 #
@@ -462,6 +458,15 @@ pack=OS/2-3
 filecheck=*os2.zip
 filecheck=*os2.zip
 # OS/2-3 1
 # OS/2-3 1
 package=urtl-genericsos2.zip[urtlgos2.zip],RTL-generic collection library
 package=urtl-genericsos2.zip[urtlgos2.zip],RTL-generic collection library
+# OS/2-3 3
+package=units-webidlos2.zip[uwidlos2.zip],Web IDL parser and converter to Object Pascal classes
+# OS/2-3 4
+package=utils-json2pasos2.zip[jsnpos2.zip],Create Object Pascal classes from JSON files
+# OS/2-3 5
+package=ufcl-pdfos2.zip[ufcpdos2.zip],PDF generating and TTF file info library
+# OS/2-3 6
+package=utils-unicodeos2.zip[ucodeos2.zip],Transformation of Unicode consortium data for FPC
+
 
 
 #
 #
 # EMX packages
 # EMX packages
@@ -541,8 +546,6 @@ package=utils-pas2fpmemx.zip[p2fmemx.zip],Generate fpmake.pp for Pascal source
 package=utils-pas2jniemx.zip[p2jnemx.zip],Generate JNI bridge for Pascal code
 package=utils-pas2jniemx.zip[p2jnemx.zip],Generate JNI bridge for Pascal code
 # EMX 31
 # EMX 31
 package=utils-pas2utemx.zip[p2utemx.zip],Pascal source to FPC Unit test generator
 package=utils-pas2utemx.zip[p2utemx.zip],Pascal source to FPC Unit test generator
-# EMX 32
-package=ufcl-pdfemx.zip[ufcpdemx.zip],PDF generating and TTF file info library
 
 
 #
 #
 # EMX packages 2nd part
 # EMX packages 2nd part
@@ -621,8 +624,6 @@ package=utils-rmwaitemx.zip[rmwemx.zip],Remove (delete) file(s) with optional re
 package=utils-lexyaccemx.zip[tplyemx.zip],Compiler generator for TP and compatibles
 package=utils-lexyaccemx.zip[tplyemx.zip],Compiler generator for TP and compatibles
 # EMX-2 31
 # EMX-2 31
 package=utils-fpcmemx.zip[fpcmemx.zip],Generate Makefiles out of Makefile.fpc files
 package=utils-fpcmemx.zip[fpcmemx.zip],Generate Makefiles out of Makefile.fpc files
-# EMX-3 32
-package=utils-unicodeemx.zip[ucodeemx.zip],Transformation of Unicode consortium data for FPC
 
 
 
 
 #
 #
@@ -632,6 +633,14 @@ pack=EMX-3
 filecheck=*emx.zip
 filecheck=*emx.zip
 # EMX-3 1
 # EMX-3 1
 package=urtl-genericsemx.zip[urtlgemx.zip],RTL-generic collection library
 package=urtl-genericsemx.zip[urtlgemx.zip],RTL-generic collection library
+# EMX-3 3
+package=units-webidlemx.zip[uwidlemx.zip],Web IDL parser and converter to Object Pascal classes
+# EMX-3 4
+package=utils-json2pasemx.zip[jsnemx2.zip],Create Object Pascal classes from JSON files
+# EMX-3 5
+package=ufcl-pdfemx.zip[ufcpdemx.zip],PDF generating and TTF file info library
+# EMX-3 6
+package=utils-unicodeemx.zip[ucodeemx.zip],Transformation of Unicode consortium data for FPC
 
 
 
 
 #
 #
@@ -764,11 +773,11 @@ package=units-sqlite.source.zip[usqltsrc.zip],SQLite interface units sources
 # Source-2 16
 # Source-2 16
 package=units-fpmkunit.source.zip[ufpmksrc.zip],Units required for building fpmake.exe
 package=units-fpmkunit.source.zip[ufpmksrc.zip],Units required for building fpmake.exe
 # Source-2 17
 # Source-2 17
-package=fcl-json.source.zip[ufcljsrc.zip],Free Component Library (FCL)-JSON interface
+package=units-fcl-json.source.zip[ufcljsrc.zip],Free Component Library (FCL)-JSON interface
 # Source-2 18
 # Source-2 18
-package=fcl-async.source.zip[ufclasrc.zip],Free Component Library (FCL)-asynchronous events
+package=units-fcl-async.source.zip[ufclasrc.zip],Free Component Library (FCL)-asynchronous events
 # Source-2 19
 # Source-2 19
-package=fcl-process.source.zip[ufclpsrc.zip],Free Component Library (FCL)-process management
+package=units-fcl-process.source.zip[ufclpsrc.zip],Free Component Library (FCL)-process management
 # Source-2 20
 # Source-2 20
 package=units-chm.source.zip[uchmsrc.zip],Support for .chm files handling
 package=units-chm.source.zip[uchmsrc.zip],Support for .chm files handling
 # Source-2 21
 # Source-2 21
@@ -780,7 +789,7 @@ package=units-fcl-res.source.zip[ufclesrc.zip],Free Component Library (FCL)-reso
 # Source-2 24
 # Source-2 24
 package=units-bzip2.source.zip[ubz2src.zip],Units for bzip2 decompression
 package=units-bzip2.source.zip[ubz2src.zip],Units for bzip2 decompression
 # Source-2 25
 # Source-2 25
-package=fcl-js.source.zip[ufcjssrc.zip],Free Component Library (FCL)-Javascript support
+package=units-fcl-js.source.zip[ufcjssrc.zip],Free Component Library (FCL)-Javascript support
 # Source-2 26
 # Source-2 26
 package=units-ptc.source.zip[uptcsrc.zip],Free portable framebuffer library
 package=units-ptc.source.zip[uptcsrc.zip],Free portable framebuffer library
 # Source-2 27
 # Source-2 27
@@ -857,6 +866,8 @@ package=units-rtl-objpas.source.zip[urtlosrc.zip],RTL-Object Pascal units (e.g.
 package=units-rtl-unicode.source.zip[urtlusrc.zip],RTL-miscellaneous Unicode support units
 package=units-rtl-unicode.source.zip[urtlusrc.zip],RTL-miscellaneous Unicode support units
 # Source-3 30
 # Source-3 30
 package=units-rtl-generics.source.zip[urtlgsrc.zip],RTL-generic collection library
 package=units-rtl-generics.source.zip[urtlgsrc.zip],RTL-generic collection library
+# Source-3 31
+package=utils-json2pas.source.zip[jsnpsrc.zip],Create Object Pascal classes from JSON files
 
 
 
 
 defaultcfg=
 defaultcfg=

+ 3 - 0
rtl/linux/pthread.inc

@@ -153,6 +153,7 @@ Type
     function pthread_cond_timedwait(__cond:ppthread_cond_t; __mutex:ppthread_mutex_t; __abstime:ptimespec):longint;cdecl;external;
     function pthread_cond_timedwait(__cond:ppthread_cond_t; __mutex:ppthread_mutex_t; __abstime:ptimespec):longint;cdecl;external;
     function pthread_condattr_init(__attr:ppthread_condattr_t):longint;cdecl;external;
     function pthread_condattr_init(__attr:ppthread_condattr_t):longint;cdecl;external;
     function pthread_condattr_destroy(__attr:ppthread_condattr_t):longint;cdecl;external;
     function pthread_condattr_destroy(__attr:ppthread_condattr_t):longint;cdecl;external;
+    function pthread_condattr_setclock(__attr:ppthread_condattr_t; __clock_id: longint):longint;cdecl;external;
     function pthread_key_create(__key:ppthread_key_t; __destr_function:__destr_function_t):longint;cdecl;external;
     function pthread_key_create(__key:ppthread_key_t; __destr_function:__destr_function_t):longint;cdecl;external;
     function pthread_key_delete(__key:pthread_key_t):longint;cdecl;external;
     function pthread_key_delete(__key:pthread_key_t):longint;cdecl;external;
     function pthread_setspecific(__key:pthread_key_t; __pointer:pointer):longint;cdecl;external;
     function pthread_setspecific(__key:pthread_key_t; __pointer:pointer):longint;cdecl;external;
@@ -228,6 +229,7 @@ Var
 {$ifndef ANDROID}
 {$ifndef ANDROID}
     pthread_condattr_init : Function(__attr:ppthread_condattr_t):longint;cdecl;
     pthread_condattr_init : Function(__attr:ppthread_condattr_t):longint;cdecl;
     pthread_condattr_destroy : Function(__attr:ppthread_condattr_t):longint;cdecl;
     pthread_condattr_destroy : Function(__attr:ppthread_condattr_t):longint;cdecl;
+    pthread_condattr_setclock: Function(__attr:ppthread_condattr_t; __clock_id: longint):longint;cdecl;
 {$endif}
 {$endif}
     pthread_key_create : Function(__key:ppthread_key_t; __destr_function:__destr_function_t):longint;cdecl;
     pthread_key_create : Function(__key:ppthread_key_t; __destr_function:__destr_function_t):longint;cdecl;
     pthread_key_delete : Function(__key:pthread_key_t):longint;cdecl;
     pthread_key_delete : Function(__key:pthread_key_t):longint;cdecl;
@@ -321,6 +323,7 @@ begin
 {$ifndef ANDROID}
 {$ifndef ANDROID}
   Pointer(pthread_condattr_init) := dlsym(PthreadDLL,'pthread_condattr_init');
   Pointer(pthread_condattr_init) := dlsym(PthreadDLL,'pthread_condattr_init');
   Pointer(pthread_condattr_destroy) := dlsym(PthreadDLL,'pthread_condattr_destroy');
   Pointer(pthread_condattr_destroy) := dlsym(PthreadDLL,'pthread_condattr_destroy');
+  Pointer(pthread_condattr_setclock) := dlsym(PthreadDLL,'pthread_condattr_setclock');
 {$endif}
 {$endif}
   Pointer(pthread_key_create) := dlsym(PthreadDLL,'pthread_key_create');
   Pointer(pthread_key_create) := dlsym(PthreadDLL,'pthread_key_create');
   Pointer(pthread_key_delete) := dlsym(PthreadDLL,'pthread_key_delete');
   Pointer(pthread_key_delete) := dlsym(PthreadDLL,'pthread_key_delete');

+ 84 - 7
rtl/unix/cthreads.pp

@@ -67,6 +67,9 @@ Procedure SetCThreadManager;
 implementation
 implementation
 
 
 Uses
 Uses
+{$if defined(Linux) and not defined(Android)}
+  Linux,
+{$endif}
   BaseUnix,
   BaseUnix,
   unix,
   unix,
   unixtype,
   unixtype,
@@ -547,6 +550,10 @@ type
      TPthreadMutex = pthread_mutex_t;
      TPthreadMutex = pthread_mutex_t;
      Tbasiceventstate=record
      Tbasiceventstate=record
          FCondVar: TPthreadCondition;
          FCondVar: TPthreadCondition;
+{$if defined(Linux) and not defined(Android)}         
+         FAttr: pthread_condattr_t;
+         FClockID: longint;
+{$ifend}        
          FEventSection: TPthreadMutex;
          FEventSection: TPthreadMutex;
          FWaiters: longint;
          FWaiters: longint;
          FIsSet,
          FIsSet,
@@ -565,19 +572,67 @@ Const
 function IntBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
 function IntBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
 var
 var
   MAttr : pthread_mutexattr_t;
   MAttr : pthread_mutexattr_t;
-  res   : cint;
+  res   : cint;  
+{$if defined(Linux) and not defined(Android)}  
+  timespec: ttimespec;
+{$ifend}  
 begin
 begin
   new(plocaleventstate(result));
   new(plocaleventstate(result));
   plocaleventstate(result)^.FManualReset:=AManualReset;
   plocaleventstate(result)^.FManualReset:=AManualReset;
   plocaleventstate(result)^.FWaiters:=0;
   plocaleventstate(result)^.FWaiters:=0;
   plocaleventstate(result)^.FDestroying:=False;
   plocaleventstate(result)^.FDestroying:=False;
   plocaleventstate(result)^.FIsSet:=InitialState;
   plocaleventstate(result)^.FIsSet:=InitialState;
-  res := pthread_cond_init(@plocaleventstate(result)^.FCondVar, nil);
+{$if defined(Linux) and not defined(Android)}  
+  res := pthread_condattr_init(@plocaleventstate(result)^.FAttr);
+  if (res <> 0) then
+  begin
+    FreeMem(result);
+    fpc_threaderror;  
+  end;
+  
+  if clock_gettime(CLOCK_MONOTONIC_RAW, @timespec) = 0 then
+  begin
+    res := pthread_condattr_setclock(@plocaleventstate(result)^.FAttr, CLOCK_MONOTONIC_RAW);
+  end
+  else
+  begin
+    res := -1; // No support for CLOCK_MONOTONIC_RAW   
+  end;
+  
+  if (res = 0) then
+  begin
+    plocaleventstate(result)^.FClockID := CLOCK_MONOTONIC_RAW;
+  end
+  else
+  begin
+    res := pthread_condattr_setclock(@plocaleventstate(result)^.FAttr, CLOCK_MONOTONIC);
+    if (res = 0) then
+    begin
+      plocaleventstate(result)^.FClockID := CLOCK_MONOTONIC;
+    end
+    else
+    begin
+      pthread_condattr_destroy(@plocaleventstate(result)^.FAttr);
+      FreeMem(result);
+      fpc_threaderror;  
+    end;    
+  end;  
+
+  res := pthread_cond_init(@plocaleventstate(result)^.FCondVar, @plocaleventstate(result)^.FAttr);
   if (res <> 0) then
   if (res <> 0) then
   begin
   begin
+    pthread_condattr_destroy(@plocaleventstate(result)^.FAttr);  
     FreeMem(result);
     FreeMem(result);
     fpc_threaderror;
     fpc_threaderror;
   end;
   end;
+{$else}
+  res := pthread_cond_init(@plocaleventstate(result)^.FCondVar, nil);
+  if (res <> 0) then
+  begin
+    FreeMem(result);
+    fpc_threaderror;
+  end; 
+{$ifend} 
 
 
   res:=pthread_mutexattr_init(@MAttr);
   res:=pthread_mutexattr_init(@MAttr);
   if res=0 then
   if res=0 then
@@ -595,6 +650,9 @@ begin
   if res <> 0 then
   if res <> 0 then
     begin
     begin
       pthread_cond_destroy(@plocaleventstate(result)^.FCondVar);
       pthread_cond_destroy(@plocaleventstate(result)^.FCondVar);
+{$if defined(Linux) and not defined(Android)}  
+      pthread_condattr_destroy(@plocaleventstate(result)^.FAttr);	
+{$ifend}      
       FreeMem(result);
       FreeMem(result);
       fpc_threaderror;
       fpc_threaderror;
     end;
     end;
@@ -616,6 +674,9 @@ begin
 
 
   { and clean up }
   { and clean up }
   pthread_cond_destroy(@plocaleventstate(state)^.Fcondvar);
   pthread_cond_destroy(@plocaleventstate(state)^.Fcondvar);
+{$if defined(Linux) and not defined(Android)}  
+  pthread_condattr_destroy(@plocaleventstate(state)^.FAttr);	
+{$ifend}  
   pthread_mutex_destroy(@plocaleventstate(state)^.FEventSection);
   pthread_mutex_destroy(@plocaleventstate(state)^.FEventSection);
   dispose(plocaleventstate(state));
   dispose(plocaleventstate(state));
 end;
 end;
@@ -646,6 +707,7 @@ var
   isset: boolean;
   isset: boolean;
   tnow : timeval;
   tnow : timeval;
 begin
 begin
+
   { safely check whether we are being destroyed, if so immediately return. }
   { safely check whether we are being destroyed, if so immediately return. }
   { otherwise (under the same mutex) increase the number of waiters        }
   { otherwise (under the same mutex) increase the number of waiters        }
   pthread_mutex_lock(@plocaleventstate(state)^.feventsection);
   pthread_mutex_lock(@plocaleventstate(state)^.feventsection);
@@ -668,17 +730,32 @@ begin
   else
   else
     begin
     begin
       //Wait with timeout using pthread_cond_timedwait
       //Wait with timeout using pthread_cond_timedwait
-      fpgettimeofday(@tnow,nil);
+{$if defined(Linux) and not defined(Android)}
+      if clock_gettime(plocaleventstate(state)^.FClockID, @timespec) <> 0 then
+      begin
+        Result := Ord(wrError);
+        Exit;
+      end;
+      timespec.tv_sec  := timespec.tv_sec + (clong(timeout) div 1000);
+      timespec.tv_nsec := ((clong(timeout) mod 1000) * 1000000) + (timespec.tv_nsec);
+{$else}
+      // TODO: FIX-ME: Also use monotonic clock for other *nix targets
+      fpgettimeofday(@tnow, nil);
       timespec.tv_sec  := tnow.tv_sec + (clong(timeout) div 1000);
       timespec.tv_sec  := tnow.tv_sec + (clong(timeout) div 1000);
-      timespec.tv_nsec := (clong(timeout) mod 1000)*1000000 + tnow.tv_usec*1000;
+      timespec.tv_nsec := ((clong(timeout) mod 1000) * 1000000) + (tnow.tv_usec * 1000);
+{$ifend}
       if timespec.tv_nsec >= 1000000000 then
       if timespec.tv_nsec >= 1000000000 then
         begin
         begin
           inc(timespec.tv_sec);
           inc(timespec.tv_sec);
           dec(timespec.tv_nsec, 1000000000);
           dec(timespec.tv_nsec, 1000000000);
         end;
         end;
-      errres:=0;
-      while (not plocaleventstate(state)^.FDestroying) and (not plocaleventstate(state)^.FIsSet) and (errres<>ESysETIMEDOUT) do
-        errres:=pthread_cond_timedwait(@plocaleventstate(state)^.Fcondvar, @plocaleventstate(state)^.feventsection, @timespec);
+      errres := 0;
+      while (not plocaleventstate(state)^.FDestroying) and
+            (not plocaleventstate(state)^.FIsSet) and 
+            (errres<>ESysETIMEDOUT) do
+        errres := pthread_cond_timedwait(@plocaleventstate(state)^.Fcondvar,
+                                         @plocaleventstate(state)^.feventsection, 
+                                         @timespec);
     end;
     end;
 
 
   isset := plocaleventstate(state)^.FIsSet;
   isset := plocaleventstate(state)^.FIsSet;