Ver código fonte

* adds support of KSE kernel threads to freeBSD
+ adds ucontext types required
+ adds stack_t to signals include
+ adds kde_ syscalls

git-svn-id: trunk@4850 -

Almindor 19 anos atrás
pai
commit
04ee4375a7
5 arquivos alterados com 236 adições e 4 exclusões
  1. 1 0
      .gitattributes
  2. 137 2
      rtl/freebsd/freebsd.pas
  3. 10 0
      rtl/freebsd/signal.inc
  4. 14 2
      rtl/freebsd/sysnr.inc
  5. 74 0
      rtl/freebsd/ucontexth.inc

+ 1 - 0
.gitattributes

@@ -4174,6 +4174,7 @@ rtl/freebsd/termio.pp svneol=native#text/plain
 rtl/freebsd/termios.inc svneol=native#text/plain
 rtl/freebsd/termiosproc.inc svneol=native#text/plain
 rtl/freebsd/tthread.inc svneol=native#text/plain
+rtl/freebsd/ucontexth.inc -text svneol=unset#plain/text
 rtl/freebsd/unixsock.inc svneol=native#text/plain
 rtl/freebsd/unxconst.inc svneol=native#text/plain
 rtl/freebsd/unxfunc.inc svneol=native#text/plain

+ 137 - 2
rtl/freebsd/freebsd.pas

@@ -30,10 +30,42 @@ Unit FreeBSD;
 interface
 
 uses
-  BaseUnix,Unix;
+  BaseUnix;
 
 const
   SF_NODISKIO = $00000001;  // don't wait for disk IO, similar to non-blocking socket setting
+  
+  // kernel threads
+
+  KSE_VER_0        = 0;
+  KSE_VERSION      = KSE_VER_0;
+
+  {* These flags are kept in km_flags *}
+  KMF_NOUPCALL      = $01;
+  KMF_NOCOMPLETED   = $02;
+  KMF_DONE          = $04;
+  KMF_BOUND         = $08;
+  KMF_WAITSIGEVENT  = $10;
+
+  {* These flags are kept in tm_flags *}
+  TMF_NOUPCALL      = $01;
+
+  {* These flags are kept in tm_dlfags *}
+  TMDF_SSTEP        = $01;
+  TMDF_SUSPEND      = $02;
+
+  {* Flags for kse_switchin *}
+  KSE_SWITCHIN_SETTMBX = $01;
+
+  {* Commands for kse_thr_interrupt *}
+  KSE_INTR_INTERRUPT   = 1;
+  KSE_INTR_RESTART     = 2;
+  KSE_INTR_SENDSIG     = 3;
+  KSE_INTR_SIGEXIT     = 4;
+  KSE_INTR_DBSUSPEND   = 5;
+  KSE_INTR_EXECVE      = 6;
+  
+{$i ucontexth.inc} // required for kse threads
 
 Type  
   SF_HDTR = record
@@ -68,9 +100,67 @@ Type
   pkld_sym_lookup = ^kld_sym_lookup;
   TKldSymLookup = kld_sym_lookup;
   PKldSymLookup = ^kld_sym_lookup;
+  
+  // kernel threads
+
+  pkse_mailbox = ^kse_mailbox;
+  
+  pkse_func_t = ^kse_func_t;
+  kse_func_t = procedure(mbx: pkse_mailbox);
+  TKseFunc = kse_func_t;
+  PKseFunc = pkse_func_t;
+  
+  {*
+   * Thread mailbox.
+   *
+   * This describes a user thread to the kernel scheduler.
+   *}
+  pkse_thr_mailbox = ^kse_thr_mailbox;
+  kse_thr_mailbox = record
+    tm_context: ucontext_t;	  {* User and machine context *}
+    tm_flags: cuint32;            {* Thread flags *}
+    tm_next: pkse_thr_mailbox;    {* Next thread in list *}
+    tm_udata: Pointer;            {* For use by the UTS *}
+    tm_uticks: cuint32;           {* Time in userland *}
+    tm_sticks: cuint32;           {* Time in kernel *}
+    tm_syncsig: siginfo_t;
+    tm_dflags: cuint32;           {* Debug flags *}
+    tm_lwp: lwpid_t;              {* kernel thread UTS runs on *}
+    __spare__: array [0..5] of cuint32;
+  end;
+  TKseThrMailBox = kse_thr_mailbox;
+  PKseThrMailBox = pkse_thr_mailbox;
+
+  
+  {*
+   * KSE mailbox.
+   *
+   * Communication path between the UTS and the kernel scheduler specific to
+   * a single KSE.
+   *}
+   
+  kse_mailbox = record
+    km_version: cuint32;             {* Mailbox version *}
+    km_curthread: pkse_thr_mailbox;  {* Currently running thread *}
+    km_completed: pkse_thr_mailbox;  {* Threads back from kernel *}
+    km_sigscaught: sigset_t;	     {* Caught signals *}
+    km_flags: cuint32;               {* Mailbox flags *}
+    km_func: pkse_func_t;            {* UTS function *}
+    km_stack: stack_t;               {* UTS stack *}
+    km_udata: Pointer;               {* For use by the UTS *}
+    km_timeofday: TTimeSpec;         {* Time of day *}
+    km_quantum: cuint32;             {* Upcall quantum in msecs *}
+    km_lwp: lwpid_t;                 {* kernel thread UTS runs on *}
+    __spare2__: array[0..6] of cuint32
+  end;
+  TKseMailBox = kse_mailbox;
+  PKseMailBox = pkse_mailbox;
+
 
   function sendfile(fd: cint; s: cint; Offset: TOff; nBytes: TSize;
                       HDTR: PSF_HDTR; sBytes: POff; Flags: cint): cint; extdecl;
+                      
+  // Kernel modules support
                     
   function kldload(FileName: pChar): cInt; extdecl;
 
@@ -85,13 +175,22 @@ Type
   function kldfirstmod(fileid: cInt): cInt; extdecl;
 
   function kldsym(fileid: cInt; command: cInt; data: PKldSymLookup): cInt; extdecl;
+  
+  // kernel threads support
+  
+  function kse_exit: cInt; extdecl;
+  function kse_wakeup(mbx: PKseMailBox): cInt; extdecl;
+  function kse_create(mbx: PKseMailBox; newgroup: cInt): cInt; extdecl;
+  function kse_thr_interrupt(tmbx: PKseThrMailBox; cmd: cInt; data: cLong): cInt; extdecl;
+  function kse_release(timeout: PTimeSpec): cInt; extdecl;
+  function kse_switchin(tmbx: PKseThrMailBox; flags: cInt): cInt; extdecl;
 
 implementation
 
 Uses
 {$ifndef FPC_USE_LIBC}  SysCall; {$else} InitC; {$endif}
 
-{$IFNDEF FPC_USE_LIBC}  
+{$IFNDEF FPC_USE_LIBC}
 
 function SendFile(fd: cint; s: cint; Offset: TOff; nBytes: TSize;
                   HDTR: PSF_HDTR; sBytes: POff; Flags: cint): cint;
@@ -109,6 +208,8 @@ begin
     nBytes, TSysParam(HDTR), TSysParam(sBytes), Flags);
 end;
 
+// kernel modules
+
 function kldload(FileName: pChar): cInt;
 begin
   kldload:=do_sysCall(syscall_nr_kldload, TSysParam(FileName));
@@ -146,6 +247,40 @@ begin
                      TSysParam(data));
 end;
 
+// kernel threads
+
+function kse_exit: cInt;
+begin
+  kse_exit:=do_sysCall(TSysParam(syscall_nr_kse_exit));
+end;
+
+function kse_wakeup(mbx: PKseMailBox): cInt;
+begin
+  kse_wakeup:=do_sysCall(syscall_nr_kse_wakeup, TSysParam(mbx));
+end;
+
+function kse_create(mbx: PKseMailBox; newgroup: cInt): cInt;
+begin
+  kse_create:=do_sysCall(syscall_nr_kse_create, TSysParam(mbx),
+                         TSysParam(newgroup));
+end;
+
+function kse_thr_interrupt(tmbx: PKseThrMailBox; cmd: cInt; data: cLong): cInt;
+begin
+  kse_thr_interrupt:=do_SysCall(syscall_nr_kse_thr_interrupt, TSysParam(tmbx),
+                               TSysParam(cmd), TSysParam(data));
+end;
+
+function kse_release(timeout: PTimeSpec): cInt;
+begin
+  kse_release:=do_SysCall(syscall_nr_kse_release, TSysParam(timeout));
+end;
+
+function kse_switchin(tmbx: PKseThrMailBox; flags: cInt): cInt;
+begin
+  kse_switchin:=do_SysCall(syscall_nr_kse_switchin, TSysParam(tmbx), TSysParam(flags));
+end;
+
 {$ENDIF}
 
 end.

+ 10 - 0
rtl/freebsd/signal.inc

@@ -177,6 +177,16 @@ type sigset_t = array[0..3] of Longint;
     Sa_Mask     : TSigSet;
   end;
   PSigActionRec = ^SigActionRec;
+  
+
+  pstack_t = ^stack_t;
+  stack_t = record
+    ss_sp: pChar;                       {* signal stack base *}
+    ss_size: size_t;                    {* signal stack length *}
+    ss_flags: cInt;                     {* SS_DISABLE and/or SS_ONSTACK *}
+  end;
+  TStack = stack_t;
+  PStack = pstack_t;
 
 {
   Change action of process upon receipt of a signal.

+ 14 - 2
rtl/freebsd/sysnr.inc

@@ -13,7 +13,7 @@
  **********************************************************************}
 
 const
-{ Crude converted FreeBSD  4.0-release syscall.h. Copy and paste if you
+{ Crude converted FreeBSD  6.1-release syscall.h. Copy and paste if you
  checked the function.
  syscall_nr_syscall                     =  0;
  syscall_nr_exit                        =  1;
@@ -221,7 +221,12 @@ syscall_nr_getdirentries                =196;
  syscall_nr_aio_waitcomplete            =359;
  syscall_nr_getresuid                   =360;
  syscall_nr_getresgid                   =361;
- syscall_nr_MAXSYSCALL                  =362;
+ syscall_nr_kse_exit                    = 379;
+ syscall_nr_kse_wakeup                  = 380;
+ syscall_nr_kse_create                  = 381;
+ syscall_nr_kse_thr_interrupt           = 382;
+ syscall_nr_kse_release                 = 383;
+ syscall_nr_kse_switchin                = 440;
 
 }
 
@@ -326,4 +331,11 @@ syscall_nr_getdirentries                =196;
  syscall_nr_kldfirstmod                 = 309;
  syscall_nr_kldsym                      = 337;
  syscall_nr_sendfile 			= 393;
+ syscall_nr_kse_exit                    = 379;
+ syscall_nr_kse_wakeup                  = 380;
+ syscall_nr_kse_create                  = 381;
+ syscall_nr_kse_thr_interrupt           = 382;
+ syscall_nr_kse_release                 = 383;
+ syscall_nr_kse_switchin                = 440;
+
 

+ 74 - 0
rtl/freebsd/ucontexth.inc

@@ -0,0 +1,74 @@
+const
+  {* Used by swapcontext(3). *}
+  UCF_SWAPPED      = $00000001;
+  _MC_FPFMT_NODEV  = $10000;     {* device not present or configured *}
+  _MC_FPFMT_387    = $10001;
+  _MC_FPFMT_XMM    = $10002;
+  _MC_FPOWNED_NONE = $20000;     {* FP state not used *}
+  _MC_FPOWNED_FPU  = $20001;     {* FP state came from FPU *}
+  _MC_FPOWNED_PCB  = $20002;     {* FP state came from PCB *}
+
+type
+  plwpid_t = ^lwpid_t;
+  lwpid_t = cint32;
+  TLwPid = lwpid_t;
+  PLwPid = ^lwpid_t;
+
+  {$packrecords 16}
+  TMCFPStateArray = record
+    items: array[0..127] of cInt;
+  end;
+  {$packrecords C}
+
+  mcontext_t = record
+    {*
+     * The first 20 fields must match the definition of
+     * sigcontext. So that we can support sigcontext
+     * and ucontext_t at the same time.
+     *}
+    mc_onstack: cInt;     {* XXX - sigcontext compat. *}
+    mc_gs: cInt;          {* machine state (struct trapframe) *}
+    mc_fs: cInt;
+    mc_es: cInt;
+    mc_ds: cInt;
+    mc_edi: cInt;
+    mc_esi: cInt;
+    mc_ebp: cInt;
+    mc_isp: cInt;
+    mc_ebx: cInt;
+    mc_edx: cInt;
+    mc_ecx: cInt;
+    mc_eax: cInt;
+    mc_trapno: cInt;
+    mc_err: cInt;
+    mc_eip: cInt;
+    mc_cs: cInt;
+    mc_eflags: cInt;
+    mc_esp: cInt;
+    mc_ss: cInt;
+    mc_len: cInt;         {* sizeof(mcontext_t) *}
+    mc_fpformat: cInt;
+    mc_ownedfp: cInt;
+    mc_spare1: array[0..0] of cInt;      {* align next field to 16 bytes *}
+    mc_fpstate: TMCFPStateArray;
+    mc_spare2: array[0..7] of cInt;
+  end;
+
+
+  pucontext_t = ^ucontext_t;
+  ucontext_t = record  // required for kse threads
+    {*
+     * Keep the order of the first two fields. Also,
+     * keep them the first two fields in the structure.
+     * This way we can have a union with struct
+     * sigcontext and ucontext_t. This allows us to
+     * support them both at the same time.
+     * note: the union is not defined, though.
+     *}
+    uc_sigmask: sigset_t;
+    uc_mcontext: mcontext_t;
+    uc_link: pucontext_t;
+    uc_stack: stack_t;
+    uc_flags: cInt;
+    __spare__: array[0..3] of cInt;
+  end;