1------------------------------------------------------------------------------ 2-- -- 3-- GNAT RUN-TIME LIBRARY (GNARL) 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-- GNARL was developed by the GNARL team at Florida State University. -- 29-- Extensive contributions were provided by Ada Core Technologies, Inc. -- 30-- -- 31------------------------------------------------------------------------------ 32 33-- This is a LynxOS (POSIX Threads) 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 -- Selects the POSIX 1.c runtime, rather than the non-threading runtime 50 -- or the deprecated legacy threads library. The -mthreads flag is 51 -- defined in patch.LynxOS and matches the definition for Lynx's gcc. 52 53 subtype int is Interfaces.C.int; 54 subtype short is Interfaces.C.short; 55 subtype long is Interfaces.C.long; 56 subtype unsigned is Interfaces.C.unsigned; 57 subtype unsigned_short is Interfaces.C.unsigned_short; 58 subtype unsigned_long is Interfaces.C.unsigned_long; 59 subtype unsigned_char is Interfaces.C.unsigned_char; 60 subtype plain_char is Interfaces.C.plain_char; 61 subtype size_t is Interfaces.C.size_t; 62 63 ----------- 64 -- Errno -- 65 ----------- 66 67 function errno return int; 68 pragma Import (C, errno, "__get_errno"); 69 70 EAGAIN : constant := 11; 71 EINTR : constant := 4; 72 EINVAL : constant := 22; 73 ENOMEM : constant := 12; 74 ETIMEDOUT : constant := 60; 75 76 ------------- 77 -- Signals -- 78 ------------- 79 80 Max_Interrupt : constant := 63; 81 82 -- Max_Interrupt is the number of OS signals, as defined in: 83 -- 84 -- /usr/include/sys/signal.h 85 -- 86 -- 87 -- The lowest numbered signal is 1, but 0 is a valid argument to some 88 -- library functions, e.g. kill(2). However, 0 is not just another 89 -- signal: For instance 'I in Signal' and similar should be used with 90 -- caution. 91 92 type Signal is new int range 0 .. Max_Interrupt; 93 for Signal'Size use int'Size; 94 95 SIGHUP : constant := 1; -- hangup 96 SIGINT : constant := 2; -- interrupt (rubout) 97 SIGQUIT : constant := 3; -- quit (ASCD FS) 98 SIGILL : constant := 4; -- illegal instruction (not reset) 99 SIGTRAP : constant := 5; -- trace trap (not reset) 100 SIGBRK : constant := 6; -- break 101 SIGIOT : constant := 6; -- IOT instruction 102 SIGABRT : constant := 6; -- used by abort, replace SIGIOT in future 103 SIGCORE : constant := 7; -- kill with core dump 104 SIGEMT : constant := 7; -- EMT instruction 105 SIGFPE : constant := 8; -- floating point exception 106 SIGKILL : constant := 9; -- kill (cannot be caught or ignored) 107 SIGBUS : constant := 10; -- bus error 108 SIGSEGV : constant := 11; -- segmentation violation 109 SIGSYS : constant := 12; -- bad argument to system call 110 SIGPIPE : constant := 13; -- write on a pipe with no one to read it 111 SIGALRM : constant := 14; -- alarm clock 112 SIGTERM : constant := 15; -- software termination signal from kill 113 SIGURG : constant := 16; -- urgent condition on IO channel 114 SIGSTOP : constant := 17; -- stop (cannot be caught or ignored) 115 SIGTSTP : constant := 18; -- user stop requested from tty 116 SIGCONT : constant := 19; -- stopped process has been continued 117 SIGCLD : constant := 20; -- alias for SIGCHLD 118 SIGCHLD : constant := 20; -- child status change 119 SIGTTIN : constant := 21; -- background tty read attempted 120 SIGTTOU : constant := 22; -- background tty write attempted 121 SIGIO : constant := 23; -- I/O possible (Solaris SIGPOLL alias) 122 SIGPOLL : constant := 23; -- pollable event occurred 123 SIGTHREADKILL : constant := 24; -- Reserved by LynxOS runtime 124 SIGXCPU : constant := 24; -- CPU time limit exceeded 125 SIGXFSZ : constant := 25; -- filesize limit exceeded 126 SIGVTALRM : constant := 26; -- virtual timer expired 127 SIGPROF : constant := 27; -- profiling timer expired 128 SIGWINCH : constant := 28; -- window size change 129 SIGLOST : constant := 29; -- SUN 4.1 compatibility 130 SIGUSR1 : constant := 30; -- user defined signal 1 131 SIGUSR2 : constant := 31; -- user defined signal 2 132 133 SIGPRIO : constant := 32; 134 -- sent to a process with its priority or group is changed 135 136 SIGADAABORT : constant := SIGABRT; 137 -- Change this if you want to use another signal for task abort. 138 -- SIGTERM might be a good one. 139 140 type Signal_Set is array (Natural range <>) of Signal; 141 142 Unmasked : constant Signal_Set := 143 (SIGTRAP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF, SIGTHREADKILL); 144 Reserved : constant Signal_Set := (SIGABRT, SIGKILL, SIGSTOP, SIGPRIO); 145 146 type sigset_t is private; 147 148 function sigaddset (set : access sigset_t; sig : Signal) return int; 149 pragma Import (C, sigaddset, "sigaddset"); 150 151 function sigdelset (set : access sigset_t; sig : Signal) return int; 152 pragma Import (C, sigdelset, "sigdelset"); 153 154 function sigfillset (set : access sigset_t) return int; 155 pragma Import (C, sigfillset, "sigfillset"); 156 157 function sigismember (set : access sigset_t; sig : Signal) return int; 158 pragma Import (C, sigismember, "sigismember"); 159 160 function sigemptyset (set : access sigset_t) return int; 161 pragma Import (C, sigemptyset, "sigemptyset"); 162 163 type struct_sigaction is record 164 sa_handler : System.Address; 165 sa_mask : sigset_t; 166 sa_flags : int; 167 end record; 168 pragma Convention (C, struct_sigaction); 169 type struct_sigaction_ptr is access all struct_sigaction; 170 171 SA_SIGINFO : constant := 16#80#; 172 173 SA_ONSTACK : constant := 16#00#; 174 -- SA_ONSTACK is not defined on LynxOS, but it is referred to in the POSIX 175 -- implementation of System.Interrupt_Management. Therefore we define a 176 -- dummy value of zero here so that setting this flag is a nop. 177 178 SIG_BLOCK : constant := 0; 179 SIG_UNBLOCK : constant := 1; 180 SIG_SETMASK : constant := 2; 181 182 SIG_DFL : constant := 0; 183 SIG_IGN : constant := 1; 184 185 function sigaction 186 (sig : Signal; 187 act : struct_sigaction_ptr; 188 oact : struct_sigaction_ptr) return int; 189 pragma Import (C, sigaction, "sigaction"); 190 191 ---------- 192 -- Time -- 193 ---------- 194 195 Time_Slice_Supported : constant Boolean := True; 196 -- Indicates whether time slicing is supported 197 198 type timespec is private; 199 200 type clockid_t is new int; 201 202 function clock_gettime 203 (clock_id : clockid_t; 204 tp : access timespec) return int; 205 pragma Import (C, clock_gettime, "clock_gettime"); 206 207 function clock_getres 208 (clock_id : clockid_t; 209 res : access timespec) return int; 210 pragma Import (C, clock_getres, "clock_getres"); 211 212 function To_Duration (TS : timespec) return Duration; 213 pragma Inline (To_Duration); 214 215 function To_Timespec (D : Duration) return timespec; 216 pragma Inline (To_Timespec); 217 218 type struct_timezone is record 219 tz_minuteswest : int; 220 tz_dsttime : int; 221 end record; 222 pragma Convention (C, struct_timezone); 223 type struct_timezone_ptr is access all struct_timezone; 224 225 ------------------------- 226 -- Priority Scheduling -- 227 ------------------------- 228 229 SCHED_FIFO : constant := 16#200000#; 230 SCHED_RR : constant := 16#100000#; 231 SCHED_OTHER : constant := 16#400000#; 232 233 ------------- 234 -- Process -- 235 ------------- 236 237 type pid_t is private; 238 239 function kill (pid : pid_t; sig : Signal) return int; 240 pragma Import (C, kill, "kill"); 241 242 function getpid return pid_t; 243 pragma Import (C, getpid, "getpid"); 244 245 --------- 246 -- LWP -- 247 --------- 248 249 function lwp_self return System.Address; 250 pragma Import (C, lwp_self, "pthread_self"); 251 252 ------------- 253 -- Threads -- 254 ------------- 255 256 type Thread_Body is access 257 function (arg : System.Address) return System.Address; 258 pragma Convention (C, Thread_Body); 259 260 function Thread_Body_Access is new 261 Ada.Unchecked_Conversion (System.Address, Thread_Body); 262 263 type pthread_t is private; 264 subtype Thread_Id is pthread_t; 265 266 type pthread_mutex_t is limited private; 267 type pthread_cond_t is limited private; 268 type pthread_attr_t is limited private; 269 type pthread_mutexattr_t is limited private; 270 type pthread_condattr_t is limited private; 271 type pthread_key_t is private; 272 273 PTHREAD_CREATE_DETACHED : constant := 1; 274 PTHREAD_CREATE_JOINABLE : constant := 0; 275 276 ----------- 277 -- Stack -- 278 ----------- 279 280 Alternate_Stack_Size : constant := 0; 281 -- No alternate signal stack is used on this platform 282 283 Stack_Base_Available : constant Boolean := False; 284 -- Indicates whether the stack base is available on this target 285 286 function Get_Stack_Base (thread : pthread_t) return Address; 287 pragma Inline (Get_Stack_Base); 288 -- Returns the stack base of the specified thread. 289 -- Only call this function when Stack_Base_Available is True. 290 291 function Get_Page_Size return size_t; 292 function Get_Page_Size return Address; 293 pragma Import (C, Get_Page_Size, "getpagesize"); 294 -- Returns the size of a page, or 0 if this is not relevant on this 295 -- target 296 297 PROT_NONE : constant := 1; 298 PROT_READ : constant := 2; 299 PROT_WRITE : constant := 4; 300 PROT_EXEC : constant := 8; 301 PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC; 302 303 PROT_ON : constant := PROT_READ; 304 PROT_OFF : constant := PROT_ALL; 305 306 function mprotect (addr : Address; len : size_t; prot : int) return int; 307 pragma Import (C, mprotect); 308 309 --------------------------------------- 310 -- Nonstandard Thread Initialization -- 311 --------------------------------------- 312 313 procedure pthread_init; 314 -- This is a dummy procedure to share some GNULLI files 315 316 ------------------------- 317 -- POSIX.1c Section 3 -- 318 ------------------------- 319 320 function sigwait 321 (set : access sigset_t; 322 sig : access Signal) return int; 323 pragma Inline (sigwait); 324 -- LynxOS has non standard sigwait 325 326 function pthread_kill 327 (thread : pthread_t; 328 sig : Signal) return int; 329 pragma Import (C, pthread_kill, "pthread_kill"); 330 331 function pthread_sigmask 332 (how : int; 333 set : access sigset_t; 334 oset : access sigset_t) return int; 335 pragma Import (C, pthread_sigmask, "pthread_sigmask"); 336 -- The behavior of pthread_sigmask on LynxOS requires 337 -- further investigation. 338 339 ---------------------------- 340 -- POSIX.1c Section 11 -- 341 ---------------------------- 342 343 function pthread_mutexattr_init 344 (attr : access pthread_mutexattr_t) return int; 345 pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init"); 346 347 function pthread_mutexattr_destroy 348 (attr : access pthread_mutexattr_t) return int; 349 pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy"); 350 351 function pthread_mutex_init 352 (mutex : access pthread_mutex_t; 353 attr : access pthread_mutexattr_t) return int; 354 pragma Import (C, pthread_mutex_init, "pthread_mutex_init"); 355 356 function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int; 357 pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy"); 358 359 function pthread_mutex_lock (mutex : access pthread_mutex_t) return int; 360 pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock"); 361 362 function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int; 363 pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock"); 364 365 function pthread_condattr_init 366 (attr : access pthread_condattr_t) return int; 367 pragma Import (C, pthread_condattr_init, "pthread_condattr_init"); 368 369 function pthread_condattr_destroy 370 (attr : access pthread_condattr_t) return int; 371 pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy"); 372 373 function pthread_cond_init 374 (cond : access pthread_cond_t; 375 attr : access pthread_condattr_t) return int; 376 pragma Import (C, pthread_cond_init, "pthread_cond_init"); 377 378 function pthread_cond_destroy (cond : access pthread_cond_t) return int; 379 pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy"); 380 381 function pthread_cond_signal (cond : access pthread_cond_t) return int; 382 pragma Import (C, pthread_cond_signal, "pthread_cond_signal"); 383 384 function pthread_cond_wait 385 (cond : access pthread_cond_t; 386 mutex : access pthread_mutex_t) return int; 387 pragma Import (C, pthread_cond_wait, "pthread_cond_wait"); 388 389 function pthread_cond_timedwait 390 (cond : access pthread_cond_t; 391 mutex : access pthread_mutex_t; 392 abstime : access timespec) return int; 393 pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait"); 394 395 Relative_Timed_Wait : constant Boolean := False; 396 -- pthread_cond_timedwait requires an absolute delay time 397 398 -------------------------- 399 -- POSIX.1c Section 13 -- 400 -------------------------- 401 402 PTHREAD_PRIO_NONE : constant := 0; 403 PTHREAD_PRIO_INHERIT : constant := 1; 404 PTHREAD_PRIO_PROTECT : constant := 2; 405 406 function pthread_mutexattr_setprotocol 407 (attr : access pthread_mutexattr_t; 408 protocol : int) return int; 409 pragma Import (C, pthread_mutexattr_setprotocol); 410 411 function pthread_mutexattr_setprioceiling 412 (attr : access pthread_mutexattr_t; 413 prioceiling : int) return int; 414 pragma Import (C, pthread_mutexattr_setprioceiling); 415 416 type struct_sched_param is record 417 sched_priority : int; 418 end record; 419 420 function pthread_setschedparam 421 (thread : pthread_t; 422 policy : int; 423 param : access struct_sched_param) return int; 424 pragma Import (C, pthread_setschedparam, "pthread_setschedparam"); 425 426 function pthread_attr_setscope 427 (attr : access pthread_attr_t; 428 contentionscope : int) return int; 429 pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope"); 430 431 function pthread_attr_setinheritsched 432 (attr : access pthread_attr_t; 433 inheritsched : int) return int; 434 pragma Import (C, pthread_attr_setinheritsched); 435 436 function pthread_attr_setschedpolicy 437 (attr : access pthread_attr_t; 438 policy : int) return int; 439 pragma Import (C, pthread_attr_setschedpolicy); 440 441 function sched_yield return int; 442 pragma Import (C, sched_yield, "sched_yield"); 443 444 -------------------------- 445 -- P1003.1c Section 16 -- 446 -------------------------- 447 448 function pthread_attr_init (attributes : access pthread_attr_t) return int; 449 pragma Import (C, pthread_attr_init, "pthread_attr_init"); 450 451 function pthread_attr_destroy 452 (attributes : access pthread_attr_t) return int; 453 pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy"); 454 455 function pthread_attr_setdetachstate 456 (attr : access pthread_attr_t; 457 detachstate : int) return int; 458 pragma Import (C, pthread_attr_setdetachstate); 459 460 function pthread_attr_setstacksize 461 (attr : access pthread_attr_t; 462 stacksize : size_t) return int; 463 pragma Import (C, pthread_attr_setstacksize); 464 465 function pthread_create 466 (thread : access pthread_t; 467 attributes : access pthread_attr_t; 468 start_routine : Thread_Body; 469 arg : System.Address) return int; 470 pragma Import (C, pthread_create, "pthread_create"); 471 472 procedure pthread_exit (status : System.Address); 473 pragma Import (C, pthread_exit, "pthread_exit"); 474 475 function pthread_self return pthread_t; 476 pragma Import (C, pthread_self, "pthread_self"); 477 478 -------------------------- 479 -- POSIX.1c Section 17 -- 480 -------------------------- 481 482 function st_setspecific 483 (key : pthread_key_t; 484 value : System.Address) return int; 485 pragma Import (C, st_setspecific, "st_setspecific"); 486 487 function st_getspecific 488 (key : pthread_key_t; 489 retval : System.Address) return int; 490 pragma Import (C, st_getspecific, "st_getspecific"); 491 492 type destructor_pointer is access procedure (arg : System.Address); 493 pragma Convention (C, destructor_pointer); 494 495 function st_keycreate 496 (destructor : destructor_pointer; 497 key : access pthread_key_t) return int; 498 pragma Import (C, st_keycreate, "st_keycreate"); 499 500private 501 502 type sigset_t is record 503 X1, X2 : long; 504 end record; 505 pragma Convention (C, 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_attr_t is record 518 stksize : int; 519 prio : int; 520 inheritsched : int; 521 state : int; 522 sched : int; 523 detachstate : int; 524 guardsize : int; 525 end record; 526 pragma Convention (C, st_attr_t); 527 528 type pthread_attr_t is record 529 pthread_attr_magic : unsigned; 530 st : st_attr_t; 531 pthread_attr_scope : int; 532 end record; 533 pragma Convention (C, pthread_attr_t); 534 535 type pthread_condattr_t is record 536 cv_magic : unsigned; 537 cv_pshared : unsigned; 538 end record; 539 pragma Convention (C, pthread_condattr_t); 540 541 type pthread_mutexattr_t is record 542 m_flags : unsigned; 543 m_prio_c : int; 544 m_pshared : int; 545 end record; 546 pragma Convention (C, pthread_mutexattr_t); 547 548 type tid_t is new short; 549 type pthread_t is new tid_t; 550 551 type block_obj_t is new System.Address; 552 -- typedef struct _block_obj_s { 553 -- struct st_entry *b_head; 554 -- } block_obj_t; 555 556 type pthread_mutex_t is record 557 m_flags : unsigned; 558 m_owner : tid_t; 559 m_wait : block_obj_t; 560 m_prio_c : int; 561 m_oldprio : int; 562 m_count : int; 563 m_referenced : int; 564 end record; 565 pragma Convention (C, pthread_mutex_t); 566 type pthread_mutex_t_ptr is access all pthread_mutex_t; 567 568 type pthread_cond_t is record 569 cv_magic : unsigned; 570 cv_wait : block_obj_t; 571 cv_mutex : pthread_mutex_t_ptr; 572 cv_refcnt : int; 573 end record; 574 pragma Convention (C, pthread_cond_t); 575 576 type pthread_key_t is new int; 577 578end System.OS_Interface; 579