1------------------------------------------------------------------------------
2--                                                                          --
3--                          GNAT RUN-TIME COMPONENTS                        --
4--                                                                          --
5--                   S Y S T E M . O S _ I N T E R F A C E                  --
6--                                                                          --
7--                                  S p e c                                 --
8--                                                                          --
9--             Copyright (C) 1991-1994, Florida State University            --
10--          Copyright (C) 1995-2011, Free Software Foundation, Inc.         --
11--                                                                          --
12-- GNAT is free software;  you can  redistribute it  and/or modify it under --
13-- terms of the  GNU General Public License as published  by the Free Soft- --
14-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
15-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
16-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
17-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
18--                                                                          --
19-- As a special exception under Section 7 of GPL version 3, you are granted --
20-- additional permissions described in the GCC Runtime Library Exception,   --
21-- version 3.1, as published by the Free Software Foundation.               --
22--                                                                          --
23-- You should have received a copy of the GNU General Public License and    --
24-- a copy of the GCC Runtime Library Exception along with this program;     --
25-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
26-- <http://www.gnu.org/licenses/>.                                          --
27--                                                                          --
28-- GNAT was originally developed  by the GNAT team at  New York University. --
29-- Extensive contributions were provided by Ada Core Technologies Inc.      --
30--                                                                          --
31------------------------------------------------------------------------------
32
33--  This is a LynxOS (Native) version of this package
34
35--  This package encapsulates all direct interfaces to OS services
36--  that are needed by the tasking run-time (libgnarl).
37
38--  PLEASE DO NOT add any with-clauses to this package or remove the pragma
39--  Preelaborate. This package is designed to be a bottom-level (leaf) package.
40
41with Ada.Unchecked_Conversion;
42
43with Interfaces.C;
44
45package System.OS_Interface is
46   pragma Preelaborate;
47
48   pragma Linker_Options ("-mthreads");
49
50   subtype int            is Interfaces.C.int;
51   subtype char           is Interfaces.C.char;
52   subtype short          is Interfaces.C.short;
53   subtype long           is Interfaces.C.long;
54   subtype unsigned       is Interfaces.C.unsigned;
55   subtype unsigned_short is Interfaces.C.unsigned_short;
56   subtype unsigned_long  is Interfaces.C.unsigned_long;
57   subtype unsigned_char  is Interfaces.C.unsigned_char;
58   subtype plain_char     is Interfaces.C.plain_char;
59   subtype size_t         is Interfaces.C.size_t;
60
61   -----------
62   -- Errno --
63   -----------
64
65   function errno return int;
66   pragma Import (C, errno, "__get_errno");
67
68   EAGAIN    : constant := 11;
69   EINTR     : constant := 4;
70   EINVAL    : constant := 22;
71   ENOMEM    : constant := 12;
72   ETIMEDOUT : constant := 60;
73
74   -------------
75   -- Signals --
76   -------------
77
78   Max_Interrupt : constant := 63;
79   type Signal is new int range 0 .. Max_Interrupt;
80   for Signal'Size use int'Size;
81
82   SIGHUP      : constant := 1; --  hangup
83   SIGINT      : constant := 2; --  interrupt (rubout)
84   SIGQUIT     : constant := 3; --  quit (ASCD FS)
85   SIGILL      : constant := 4; --  illegal instruction (not reset)
86   SIGTRAP     : constant := 5; --  trace trap (not reset)
87   SIGBRK      : constant := 6; --  break
88   SIGIOT      : constant := 6; --  IOT instruction
89   SIGABRT     : constant := 6; --  used by abort, replace SIGIOT in the future
90   SIGCORE     : constant := 7; --  kill with core dump
91   SIGEMT      : constant := 7; --  EMT instruction
92   SIGFPE      : constant := 8; --  floating point exception
93   SIGKILL     : constant := 9; --  kill (cannot be caught or ignored)
94   SIGBUS      : constant := 10; --  bus error
95   SIGSEGV     : constant := 11; --  segmentation violation
96   SIGSYS      : constant := 12; --  bad argument to system call
97   SIGPIPE     : constant := 13; --  write on a pipe with no one to read it
98   SIGALRM     : constant := 14; --  alarm clock
99   SIGTERM     : constant := 15; --  software termination signal from kill
100   SIGURG      : constant := 16; --  urgent condition on IO channel
101   SIGSTOP     : constant := 17; --  stop (cannot be caught or ignored)
102   SIGTSTP     : constant := 18; --  user stop requested from tty
103   SIGCONT     : constant := 19; --  stopped process has been continued
104   SIGCLD      : constant := 20; --  alias for SIGCHLD
105   SIGCHLD     : constant := 20; --  child status change
106   SIGTTIN     : constant := 21; --  background tty read attempted
107   SIGTTOU     : constant := 22; --  background tty write attempted
108   SIGIO       : constant := 23; --  I/O possible (Solaris SIGPOLL alias)
109   SIGPOLL     : constant := 23; --  pollable event occurred
110   SIGXCPU     : constant := 24; --  CPU time limit exceeded
111   SIGXFSZ     : constant := 25; --  filesize limit exceeded
112   SIGVTALRM   : constant := 26; --  virtual timer expired
113   SIGPROF     : constant := 27; --  profiling timer expired
114   SIGWINCH    : constant := 28; --  window size change
115   SIGLOST     : constant := 29; --  SUN 4.1 compatibility
116   SIGUSR1     : constant := 30; --  user defined signal 1
117   SIGUSR2     : constant := 31; --  user defined signal 2
118   SIGPRIO     : constant := 32; --  sent to a process with its priority or
119                                 --  group is changed
120
121   SIGADAABORT : constant := SIGABRT;
122   --  Change this if you want to use another signal for task abort.
123   --  SIGTERM might be a good one.
124
125   type Signal_Set is array (Natural range <>) of Signal;
126
127   Unmasked    : constant Signal_Set :=
128     (SIGTRAP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF);
129   Reserved    : constant Signal_Set := (SIGABRT, SIGKILL, SIGSTOP, SIGPRIO);
130
131   type sigset_t is private;
132
133   function sigaddset (set : access sigset_t; sig : Signal) return int;
134   pragma Import (C, sigaddset, "sigaddset");
135
136   function sigdelset (set : access sigset_t; sig : Signal) return int;
137   pragma Import (C, sigdelset, "sigdelset");
138
139   function sigfillset (set : access sigset_t) return int;
140   pragma Import (C, sigfillset, "sigfillset");
141
142   function sigismember (set : access sigset_t; sig : Signal) return int;
143   pragma Import (C, sigismember, "sigismember");
144
145   function sigemptyset (set : access sigset_t) return int;
146   pragma Import (C, sigemptyset, "sigemptyset");
147
148   type struct_sigaction is record
149      sa_handler : System.Address;
150      sa_mask    : sigset_t;
151      sa_flags   : int;
152   end record;
153   pragma Convention (C, struct_sigaction);
154   type struct_sigaction_ptr is access all struct_sigaction;
155
156   SA_SIGINFO  : constant := 16#80#;
157
158   SIG_BLOCK   : constant := 0;
159   SIG_UNBLOCK : constant := 1;
160   SIG_SETMASK : constant := 2;
161
162   SIG_DFL : constant := 0;
163   SIG_IGN : constant := 1;
164
165   function sigaction
166     (sig  : Signal;
167      act  : struct_sigaction_ptr;
168      oact : struct_sigaction_ptr) return int;
169   pragma Import (C, sigaction, "sigaction");
170
171   ----------
172   -- Time --
173   ----------
174
175   Time_Slice_Supported : constant Boolean := True;
176   --  Indicates whether time slicing is supported
177
178   type timespec is private;
179
180   type clockid_t is new int;
181
182   function clock_gettime
183     (clock_id : clockid_t;
184      tp       : access timespec) return int;
185   pragma Inline (clock_gettime);
186   --  LynxOS has non standard clock_gettime
187
188   function To_Duration (TS : timespec) return Duration;
189   pragma Inline (To_Duration);
190
191   function To_Timespec (D : Duration) return timespec;
192   pragma Inline (To_Timespec);
193
194   type struct_timezone is record
195      tz_minuteswest : int;
196      tz_dsttime     : int;
197   end record;
198   pragma Convention (C, struct_timezone);
199   type struct_timezone_ptr is access all struct_timezone;
200
201   -------------------------
202   -- Priority Scheduling --
203   -------------------------
204
205   SCHED_FIFO  : constant := 16#00200000#;
206   SCHED_RR    : constant := 16#00100000#;
207   SCHED_OTHER : constant := 16#00400000#;
208
209   function To_Target_Priority
210     (Prio : System.Any_Priority) return Interfaces.C.int;
211   --  Maps System.Any_Priority to a POSIX priority
212
213   -------------
214   -- Process --
215   -------------
216
217   type pid_t is private;
218
219   function kill (pid : pid_t; sig : Signal) return int;
220   pragma Import (C, kill, "kill");
221
222   function getpid return pid_t;
223   pragma Import (C, getpid, "getpid");
224
225   ---------
226   -- LWP --
227   ---------
228
229   function lwp_self return System.Address;
230   --  lwp_self does not exist on this thread library, revert to pthread_self
231   --  which is the closest approximation (with getpid). This function is
232   --  needed to share 7staprop.adb across POSIX-like targets.
233   pragma Import (C, lwp_self, "pthread_self");
234
235   -------------
236   -- Threads --
237   -------------
238
239   type Thread_Body is access
240     function (arg : System.Address) return System.Address;
241   pragma Convention (C, Thread_Body);
242
243   function Thread_Body_Access is new
244     Ada.Unchecked_Conversion (System.Address, Thread_Body);
245
246   type pthread_t           is private;
247   subtype Thread_Id        is pthread_t;
248
249   type pthread_mutex_t     is limited private;
250   type pthread_cond_t      is limited private;
251   type st_t                is limited private;
252   type pthread_attr_t      is limited private;
253   type pthread_mutexattr_t is limited private;
254   type pthread_condattr_t  is limited private;
255   type pthread_key_t       is private;
256
257   PTHREAD_CREATE_DETACHED : constant := 0;
258
259   PTHREAD_SCOPE_PROCESS : constant := 0;
260   PTHREAD_SCOPE_SYSTEM  : constant := 1;
261
262   -----------
263   -- Stack --
264   -----------
265
266   Alternate_Stack_Size : constant := 0;
267   --  No alternate signal stack is used on this platform
268
269   Stack_Base_Available : constant Boolean := False;
270   --  Indicates whether the stack base is available on this target
271
272   function Get_Stack_Base (thread : pthread_t) return Address;
273   pragma Inline (Get_Stack_Base);
274   --  returns the stack base of the specified thread.
275   --  Only call this function when Stack_Base_Available is True.
276
277   function Get_Page_Size return size_t;
278   function Get_Page_Size return Address;
279   pragma Import (C, Get_Page_Size, "getpagesize");
280   --  returns the size of a page, or 0 if this is not relevant on this
281   --  target
282
283   PROT_NONE  : constant := 0;
284   PROT_READ  : constant := 1;
285   PROT_WRITE : constant := 2;
286   PROT_EXEC  : constant := 4;
287   PROT_USER  : constant := 8;
288   PROT_ALL   : constant := PROT_READ + PROT_WRITE + PROT_EXEC + PROT_USER;
289
290   PROT_ON    : constant := PROT_READ;
291   PROT_OFF   : constant := PROT_ALL;
292
293   function mprotect (addr : Address; len : size_t; prot : int) return int;
294   pragma Import (C, mprotect);
295
296   -------------------------
297   -- POSIX.1c  Section 3 --
298   -------------------------
299
300   function sigwait
301     (set : access sigset_t;
302      sig : access Signal) return int;
303   pragma Inline (sigwait);
304   --  LynxOS has non standard sigwait
305
306   function pthread_kill (thread : pthread_t; sig : Signal) return int;
307   pragma Import (C, pthread_kill, "pthread_kill");
308
309   function pthread_sigmask
310     (how  : int;
311      set  : access sigset_t;
312      oset : access sigset_t) return int;
313   pragma Import (C, pthread_sigmask, "sigprocmask");
314
315   --------------------------
316   -- POSIX.1c  Section 11 --
317   --------------------------
318
319   function pthread_mutexattr_init
320     (attr : access pthread_mutexattr_t) return int;
321   pragma Inline (pthread_mutexattr_init);
322   --  LynxOS has a nonstandard pthread_mutexattr_init
323
324   function pthread_mutexattr_destroy
325     (attr : access pthread_mutexattr_t) return int;
326   pragma Inline (pthread_mutexattr_destroy);
327   --  Lynxos has a nonstandard pthread_mutexattr_destroy
328
329   function pthread_mutex_init
330     (mutex : access pthread_mutex_t;
331      attr  : access pthread_mutexattr_t) return int;
332   pragma Inline (pthread_mutex_init);
333   --  LynxOS has a nonstandard pthread_mutex_init
334
335   function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
336   pragma Inline (pthread_mutex_destroy);
337   --  LynxOS has a nonstandard pthread_mutex_destroy
338
339   function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
340   pragma Inline (pthread_mutex_lock);
341   --  LynxOS has a nonstandard pthread_mutex_lock
342
343   function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
344   pragma Inline (pthread_mutex_unlock);
345   --  LynxOS has a nonstandard pthread_mutex_unlock
346
347   function pthread_condattr_init
348     (attr : access pthread_condattr_t) return int;
349   pragma Inline (pthread_condattr_init);
350   --  LynxOS has a nonstandard pthread_condattr_init
351
352   function pthread_condattr_destroy
353     (attr : access pthread_condattr_t) return int;
354   pragma Inline (pthread_condattr_destroy);
355   --  LynxOS has a nonstandard pthread_condattr_destroy
356
357   function pthread_cond_init
358     (cond : access pthread_cond_t;
359      attr : access pthread_condattr_t) return int;
360   pragma Inline (pthread_cond_init);
361   --  LynxOS has a non standard pthread_cond_init
362
363   function pthread_cond_destroy (cond : access pthread_cond_t) return int;
364   pragma Inline (pthread_cond_destroy);
365   --  LynxOS has a nonstandard pthread_cond_destroy
366
367   function pthread_cond_signal (cond : access pthread_cond_t) return int;
368   pragma Inline (pthread_cond_signal);
369   --  LynxOS has a nonstandard pthread_cond_signal
370
371   function pthread_cond_wait
372     (cond  : access pthread_cond_t;
373      mutex : access pthread_mutex_t) return int;
374   pragma Inline (pthread_cond_wait);
375   --  LynxOS has a nonstandard pthread_cond_wait
376
377   function pthread_cond_timedwait
378     (cond    : access pthread_cond_t;
379      mutex   : access pthread_mutex_t;
380      reltime : access timespec) return int;
381   pragma Inline (pthread_cond_timedwait);
382   --  LynxOS has a nonstandard pthread_cond_timedwait
383
384   Relative_Timed_Wait : constant Boolean := True;
385   --  pthread_cond_timedwait requires a relative delay time
386
387   --------------------------
388   -- POSIX.1c  Section 13 --
389   --------------------------
390
391   PTHREAD_PRIO_NONE    : constant := 0;
392   PTHREAD_PRIO_INHERIT : constant := 0;
393   PTHREAD_PRIO_PROTECT : constant := 0;
394
395   type struct_sched_param is record
396      sched_priority : int;  --  scheduling priority
397   end record;
398
399   function pthread_setschedparam
400     (thread : pthread_t;
401      policy : int;
402      param  : access struct_sched_param) return int;
403   pragma Inline (pthread_setschedparam);
404   --  LynxOS doesn't have pthread_setschedparam.
405   --  Instead, use pthread_setscheduler
406
407   function pthread_mutexattr_setprotocol
408     (attr     : access pthread_mutexattr_t;
409      protocol : int) return int;
410   pragma Inline (pthread_mutexattr_setprotocol);
411   --  LynxOS doesn't have pthread_mutexattr_setprotocol
412
413   function pthread_mutexattr_setprioceiling
414     (attr     : access pthread_mutexattr_t;
415      prioceiling : int) return int;
416   pragma Inline (pthread_mutexattr_setprioceiling);
417   --  LynxOS doesn't have pthread_mutexattr_setprioceiling
418
419   function pthread_attr_setscope
420     (attr            : access pthread_attr_t;
421      contentionscope : int) return int;
422   --  LynxOS doesn't have pthread_attr_setscope: all threads have system scope
423   pragma Inline (pthread_attr_setscope);
424
425   function pthread_attr_setschedpolicy
426     (attr   : access pthread_attr_t;
427      policy : int) return int;
428   pragma Import (C, pthread_attr_setschedpolicy, "pthread_attr_setsched");
429
430   function sched_yield return int;
431   --   pragma Import (C, sched_yield, "sched_yield");
432   pragma Inline (sched_yield);
433
434   ---------------------------
435   -- P1003.1c - Section 16 --
436   ---------------------------
437
438   function pthread_attr_init (attributes : access pthread_attr_t) return int;
439   pragma Import (C, pthread_attr_init, "pthread_attr_create");
440
441   function pthread_attr_destroy
442     (attributes : access pthread_attr_t) return int;
443   pragma Import (C, pthread_attr_destroy, "pthread_attr_delete");
444
445   function pthread_attr_setdetachstate
446     (attr        : access pthread_attr_t;
447      detachstate : int) return int;
448   pragma Inline (pthread_attr_setdetachstate);
449   --  LynxOS doesn't have pthread_attr_setdetachstate
450
451   function pthread_attr_setstacksize
452     (attr      : access pthread_attr_t;
453      stacksize : size_t) return int;
454   pragma Import (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
455
456   function pthread_create
457     (thread        : access pthread_t;
458      attributes    : access pthread_attr_t;
459      start_routine : Thread_Body;
460      arg           : System.Address) return int;
461   pragma Inline (pthread_create);
462   --  LynxOS has a non standard pthread_create
463
464   function pthread_detach (thread : pthread_t) return int;
465   pragma Inline (pthread_detach);
466
467   procedure pthread_exit (status : System.Address);
468   pragma Import (C, pthread_exit, "pthread_exit");
469
470   function pthread_self return pthread_t;
471   pragma Import (C, pthread_self, "pthread_self");
472
473   --------------------------
474   -- POSIX.1c  Section 17 --
475   --------------------------
476
477   function pthread_setspecific
478     (key   : pthread_key_t;
479      value : System.Address) return int;
480   pragma Inline (pthread_setspecific);
481   --  LynxOS has a non standard pthread_setspecific
482
483   function pthread_getspecific (key : pthread_key_t) return System.Address;
484   pragma Inline (pthread_getspecific);
485   --  LynxOS has a non standard pthread_getspecific
486
487   type destructor_pointer is access procedure (arg : System.Address);
488   pragma Convention (C, destructor_pointer);
489
490   function pthread_key_create
491     (key        : access pthread_key_t;
492      destructor : destructor_pointer) return int;
493   pragma Inline (pthread_key_create);
494   --  LynxOS has a non standard pthread_keycreate
495
496   procedure pthread_init;
497   --  This is a dummy procedure to share some GNULLI files
498
499private
500
501   type sigbit_array is array (1 .. 2) of long;
502   type sigset_t is record
503      sa_sigbits : sigbit_array;
504   end record;
505   pragma Convention (C_Pass_By_Copy, sigset_t);
506
507   type pid_t is new long;
508
509   type time_t is new long;
510
511   type timespec is record
512      tv_sec  : time_t;
513      tv_nsec : long;
514   end record;
515   pragma Convention (C, timespec);
516
517   type st_t is record
518      stksize      : int;
519      prio         : int;
520      inheritsched : int;
521      state        : int;
522      sched        : int;
523   end record;
524   pragma Convention (C, st_t);
525
526   type pthread_attr_t is record
527      st                 : st_t;
528      pthread_attr_scope : int;  --  ignored
529   end record;
530   pragma Convention (C, pthread_attr_t);
531
532   type pthread_condattr_t is new int;
533
534   type pthread_mutexattr_t is new int;
535
536   type tid_t is new short;
537   type pthread_t is new tid_t;
538
539   type synch_ptr is access all pthread_mutex_t;
540   type pthread_mutex_t is record
541      w_count   : int;
542      mut_owner : int;
543      id        : unsigned;
544      next      : synch_ptr;
545   end record;
546   pragma Convention (C, pthread_mutex_t);
547
548   type pthread_cond_t is new pthread_mutex_t;
549
550   type pthread_key_t is new int;
551
552end System.OS_Interface;
553