View Issue Details

IDProjectCategoryView StatusLast Update
0037252FPCRTLpublic2020-06-25 13:32
ReporterBi0T1N Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Product Version3.3.1 
Summary0037252: [Patch] Implement thread naming for Darwin
DescriptionThis patch adds support for thread naming (see 0036940) for the Darwin target.
Additional InformationThanks to trev for testing!
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

Bi0T1N

2020-06-24 23:05

reporter  

01-Implement_threadnaming_for_Darwin.patch (1,619 bytes)   
diff --git rtl/darwin/pthread.inc rtl/darwin/pthread.inc
index 910e9b3f6c..3e55f7eb9a 100644
--- rtl/darwin/pthread.inc
+++ rtl/darwin/pthread.inc
@@ -84,3 +84,5 @@ function pthread_mutexattr_destroy(_para1:Ppthread_mutexattr_t):cint;cdecl;exter
 function pthread_mutexattr_gettype(_para1:Ppthread_mutexattr_t; _para2:Pcint):cint;cdecl;external 'c' name 'pthread_mutexattr_gettype';
 function pthread_mutexattr_settype(_para1:Ppthread_mutexattr_t; _para2:cint):cint;cdecl;external 'c' name 'pthread_mutexattr_settype';
 function pthread_cond_timedwait(__cond:ppthread_cond_t; __mutex:ppthread_mutex_t; __abstime:ptimespec):cint; cdecl;external 'c' name 'pthread_cond_timedwait';
+
+function pthread_setname_np(name: PAnsiChar):cint;cdecl;external 'c';
diff --git rtl/unix/cthreads.pp rtl/unix/cthreads.pp
index 08e52dbcb6..31f0002650 100644
--- rtl/unix/cthreads.pp
+++ rtl/unix/cthreads.pp
@@ -511,6 +511,10 @@ Type  PINTRTLEvent = ^TINTRTLEvent;
           pthread_setname_np(pthread_t(threadHandle), @CuttedName[1]);
         end;
       end;
+{$elseif defined(Darwin)}
+      // only allowed to set from within the thread
+      if threadHandle=TThreadID(-1) then
+        pthread_setname_np(@ThreadName[1]);
 {$else}
        {$Warning SetThreadDebugName needs to be implemented}
 {$endif}
@@ -526,6 +530,8 @@ Type  PINTRTLEvent = ^TINTRTLEvent;
       begin
         CSetThreadDebugNameA(threadHandle, AnsiString(ThreadName));
       end;
+{$elseif defined(Darwin)}
+      CSetThreadDebugNameA(threadHandle, AnsiString(ThreadName));
 {$else}
        {$Warning SetThreadDebugName needs to be implemented}
 {$endif}

Bi0T1N

2020-06-24 23:07

reporter   ~0123581

Forgot to mention that it's available since


    __API_AVAILABLE(macos(10.6), ios(3.2))
    int pthread_setname_np(const char*);


according to https://opensource.apple.com/source/libpthread/libpthread-301.30.1/pthread/pthread.h.auto.html

Trevor Roydhouse

2020-06-25 01:19

reporter   ~0123586

Attached namethreads.pas test program slightly changed for macOS from the original in https://bugs.freepascal.org/view.php?id=36941#c122304

Tests were done with:
* macOS 10.14.6 Mojave
* FPC trunk r45683

Note that for macOS, a thread name must be set from within the same thread. This explains why the test program failed to name the "bronze" thread but successfully named the "always number one" main thread in the lldb output below:

(lldb) thread info 1
thread 0000001: tid = 0x17f5, name = always number one, function: __psynch_cvwait , stop reason = signal SIGSTOP
(lldb) thread info 2
thread 0000002: tid = 0x1808, name = 1, function: __semwait_signal
(lldb) thread info 3
thread 0000003: tid = 0x1809, name = 2, function: __semwait_signal
(lldb) thread info 4
thread 0000004: tid = 0x180a, name = 3, function: __semwait_signal
(lldb) thread info 5
thread 0000005: tid = 0x180b, name = 4, function: __semwait_signal
(lldb) thread info 6
thread 0000006: tid = 0x180c, name = 5, function: __semwait_signal
namethreads.pas (1,106 bytes)   
program namethreads;
 
{$mode delphi}

uses
  CThreads, SysUtils, Classes;

type
  TMyThread = class(TThread)
  private
	i: Integer;
  protected
	procedure Execute; override;
	procedure SetNumber(const aNum: Integer);
  end;
 
procedure TMyThread.Execute;
begin
  writeln('hello from thread '+ Integer(ThreadID).ToString);
  NameThreadForDebugging(IntToStr(i));
  sleep(300000);
end;
 
procedure TMyThread.SetNumber(const aNum: Integer);
begin
  i := aNum + 1;
end;

var
  threads: TArray<TMyThread>;
  i: Integer;
  thread: TMyThread;
 
begin
  writeln('start');

  SetLength(threads, 5);
  for i := Low(threads) to High(threads) do
  begin
	threads[i] := TMyThread.Create(True);
	threads[i].SetNumber(i);
  end;
 
  for thread in threads do
  begin
	thread.Start;
  end;
 
  sleep(10000);
 
  TMyThread.NameThreadForDebugging('bronze', threads[2].ThreadID); // third thread
  TMyThread.NameThreadForDebugging('always number one'); // main thread
 
  for thread in threads do
  begin
	thread.WaitFor;
  end;
 
  writeln('done');
  readln;
end.
namethreads.pas (1,106 bytes)   

Sven Barth

2020-06-25 13:32

manager   ~0123592

If pthread_setname_np is only available from 10.6 on then this function needs to be loaded dynamically. For FPC minimum supported version of macOS is 10.4.

Issue History

Date Modified Username Field Change
2020-06-24 23:05 Bi0T1N New Issue
2020-06-24 23:05 Bi0T1N File Added: 01-Implement_threadnaming_for_Darwin.patch
2020-06-24 23:07 Bi0T1N Note Added: 0123581
2020-06-25 01:19 Trevor Roydhouse Note Added: 0123586
2020-06-25 01:19 Trevor Roydhouse File Added: namethreads.pas
2020-06-25 13:32 Sven Barth Note Added: 0123592