mirror of git://gcc.gnu.org/git/gcc.git
a-numaux-vms.ads, [...]: New files.
2011-12-15 Arnaud Charlet <charlet@adacore.com>
* a-numaux-vms.ads, s-asthan-vms-ia64.adb, s-auxdec-vms-ia64.adb,
s-memory-vms_64.adb, s-memory-vms_64.ads, s-osinte-vms-ia64.adb,
s-osinte-vms-ia64.ads, s-tasdeb-vms.adb: New files.
From-SVN: r182374
This commit is contained in:
parent
0c5c7b003e
commit
90376fadb8
|
|
@ -1,3 +1,9 @@
|
|||
2011-12-15 Arnaud Charlet <charlet@adacore.com>
|
||||
|
||||
* a-numaux-vms.ads, s-asthan-vms-ia64.adb, s-auxdec-vms-ia64.adb,
|
||||
s-memory-vms_64.adb, s-memory-vms_64.ads, s-osinte-vms-ia64.adb,
|
||||
s-osinte-vms-ia64.ads, s-tasdeb-vms.adb: New files.
|
||||
|
||||
2011-12-15 Vincent Pucci <pucci@adacore.com>
|
||||
|
||||
* aspects.adb, aspects.ads Aspect_Dimension and
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT RUN-TIME COMPONENTS --
|
||||
-- --
|
||||
-- A D A . N U M E R I C S . A U X --
|
||||
-- --
|
||||
-- S p e c --
|
||||
-- (VMS Version) --
|
||||
-- --
|
||||
-- Copyright (C) 2003-2010, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNAT was originally developed by the GNAT team at New York University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- This package provides the basic computational interface for the generic
|
||||
-- elementary functions. The C library version interfaces with the routines
|
||||
-- in the C mathematical library, and is thus quite portable, although it may
|
||||
-- not necessarily meet the requirements for accuracy in the numerics annex.
|
||||
|
||||
-- This is the VMS version
|
||||
|
||||
package Ada.Numerics.Aux is
|
||||
pragma Pure;
|
||||
|
||||
type Double is digits 15;
|
||||
pragma Float_Representation (IEEE_Float, Double);
|
||||
-- Type Double is the type used to call the C routines. Note that this
|
||||
-- is IEEE format even when running on VMS with VAX_Native representation
|
||||
-- since we use the IEEE version of the C library with VMS.
|
||||
|
||||
-- We import these functions directly from C. Note that we label them
|
||||
-- all as pure functions, because indeed all of them are in fact pure!
|
||||
|
||||
function Sin (X : Double) return Double;
|
||||
pragma Import (C, Sin, "MATH$SIN_T");
|
||||
pragma Pure_Function (Sin);
|
||||
|
||||
function Cos (X : Double) return Double;
|
||||
pragma Import (C, Cos, "MATH$COS_T");
|
||||
pragma Pure_Function (Cos);
|
||||
|
||||
function Tan (X : Double) return Double;
|
||||
pragma Import (C, Tan, "MATH$TAN_T");
|
||||
pragma Pure_Function (Tan);
|
||||
|
||||
function Exp (X : Double) return Double;
|
||||
pragma Import (C, Exp, "MATH$EXP_T");
|
||||
pragma Pure_Function (Exp);
|
||||
|
||||
function Sqrt (X : Double) return Double;
|
||||
pragma Import (C, Sqrt, "MATH$SQRT_T");
|
||||
pragma Pure_Function (Sqrt);
|
||||
|
||||
function Log (X : Double) return Double;
|
||||
pragma Import (C, Log, "DECC$TLOG_2");
|
||||
pragma Pure_Function (Log);
|
||||
|
||||
function Acos (X : Double) return Double;
|
||||
pragma Import (C, Acos, "MATH$ACOS_T");
|
||||
pragma Pure_Function (Acos);
|
||||
|
||||
function Asin (X : Double) return Double;
|
||||
pragma Import (C, Asin, "MATH$ASIN_T");
|
||||
pragma Pure_Function (Asin);
|
||||
|
||||
function Atan (X : Double) return Double;
|
||||
pragma Import (C, Atan, "MATH$ATAN_T");
|
||||
pragma Pure_Function (Atan);
|
||||
|
||||
function Sinh (X : Double) return Double;
|
||||
pragma Import (C, Sinh, "MATH$SINH_T");
|
||||
pragma Pure_Function (Sinh);
|
||||
|
||||
function Cosh (X : Double) return Double;
|
||||
pragma Import (C, Cosh, "MATH$COSH_T");
|
||||
pragma Pure_Function (Cosh);
|
||||
|
||||
function Tanh (X : Double) return Double;
|
||||
pragma Import (C, Tanh, "MATH$TANH_T");
|
||||
pragma Pure_Function (Tanh);
|
||||
|
||||
function Pow (X, Y : Double) return Double;
|
||||
pragma Import (C, Pow, "DECC$TPOW_2");
|
||||
pragma Pure_Function (Pow);
|
||||
|
||||
end Ada.Numerics.Aux;
|
||||
|
|
@ -0,0 +1,608 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT RUN-TIME COMPONENTS --
|
||||
-- --
|
||||
-- S Y S T E M . A S T _ H A N D L I N G --
|
||||
-- --
|
||||
-- B o d y --
|
||||
-- --
|
||||
-- Copyright (C) 1996-2010, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNAT was originally developed by the GNAT team at New York University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- This is the OpenVMS/IA64 version
|
||||
|
||||
with System; use System;
|
||||
|
||||
with System.IO;
|
||||
|
||||
with System.Machine_Code;
|
||||
with System.Parameters;
|
||||
|
||||
with System.Tasking;
|
||||
with System.Tasking.Rendezvous;
|
||||
with System.Tasking.Initialization;
|
||||
with System.Tasking.Utilities;
|
||||
|
||||
with System.Task_Primitives;
|
||||
with System.Task_Primitives.Operations;
|
||||
with System.Task_Primitives.Operations.DEC;
|
||||
|
||||
with Ada.Finalization;
|
||||
with Ada.Task_Attributes;
|
||||
|
||||
with Ada.Exceptions; use Ada.Exceptions;
|
||||
|
||||
with Ada.Unchecked_Conversion;
|
||||
with Ada.Unchecked_Deallocation;
|
||||
|
||||
package body System.AST_Handling is
|
||||
|
||||
package ATID renames Ada.Task_Identification;
|
||||
|
||||
package SP renames System.Parameters;
|
||||
package ST renames System.Tasking;
|
||||
package STR renames System.Tasking.Rendezvous;
|
||||
package STI renames System.Tasking.Initialization;
|
||||
package STU renames System.Tasking.Utilities;
|
||||
|
||||
package STPO renames System.Task_Primitives.Operations;
|
||||
package STPOD renames System.Task_Primitives.Operations.DEC;
|
||||
|
||||
AST_Lock : aliased System.Task_Primitives.RTS_Lock;
|
||||
-- This is a global lock; it is used to execute in mutual exclusion
|
||||
-- from all other AST tasks. It is only used by Lock_AST and
|
||||
-- Unlock_AST.
|
||||
|
||||
procedure Lock_AST (Self_ID : ST.Task_Id);
|
||||
-- Locks out other AST tasks. Preceding a section of code by Lock_AST and
|
||||
-- following it by Unlock_AST creates a critical region.
|
||||
|
||||
procedure Unlock_AST (Self_ID : ST.Task_Id);
|
||||
-- Releases lock previously set by call to Lock_AST.
|
||||
-- All nested locks must be released before other tasks competing for the
|
||||
-- tasking lock are released.
|
||||
|
||||
--------------
|
||||
-- Lock_AST --
|
||||
--------------
|
||||
|
||||
procedure Lock_AST (Self_ID : ST.Task_Id) is
|
||||
begin
|
||||
STI.Defer_Abort_Nestable (Self_ID);
|
||||
STPO.Write_Lock (AST_Lock'Access, Global_Lock => True);
|
||||
end Lock_AST;
|
||||
|
||||
----------------
|
||||
-- Unlock_AST --
|
||||
----------------
|
||||
|
||||
procedure Unlock_AST (Self_ID : ST.Task_Id) is
|
||||
begin
|
||||
STPO.Unlock (AST_Lock'Access, Global_Lock => True);
|
||||
STI.Undefer_Abort_Nestable (Self_ID);
|
||||
end Unlock_AST;
|
||||
|
||||
---------------------------------
|
||||
-- AST_Handler Data Structures --
|
||||
---------------------------------
|
||||
|
||||
-- As noted in the private part of the spec of System.Aux_DEC, the
|
||||
-- AST_Handler type is simply a pointer to a procedure that takes
|
||||
-- a single 64bit parameter. The following is a local copy
|
||||
-- of that definition.
|
||||
|
||||
-- We need our own copy because we need to get our hands on this
|
||||
-- and we cannot see the private part of System.Aux_DEC. We don't
|
||||
-- want to be a child of Aux_Dec because of complications resulting
|
||||
-- from the use of pragma Extend_System. We will use unchecked
|
||||
-- conversions between the two versions of the declarations.
|
||||
|
||||
type AST_Handler is access procedure (Param : Long_Integer);
|
||||
|
||||
-- However, this declaration is somewhat misleading, since the values
|
||||
-- referenced by AST_Handler values (all produced in this package by
|
||||
-- calls to Create_AST_Handler) are highly stylized.
|
||||
|
||||
-- The first point is that in VMS/I64, procedure pointers do not in
|
||||
-- fact point to code, but rather to a procedure descriptor.
|
||||
-- So a value of type AST_Handler is in fact a pointer to one of
|
||||
-- descriptors.
|
||||
|
||||
type Descriptor_Type is
|
||||
record
|
||||
Entry_Point : System.Address;
|
||||
GP_Value : System.Address;
|
||||
end record;
|
||||
for Descriptor_Type'Alignment use Standard'Maximum_Alignment;
|
||||
-- pragma Warnings (Off, Descriptor_Type);
|
||||
-- Suppress harmless warnings about alignment.
|
||||
-- Should explain why this warning is harmless ???
|
||||
|
||||
type Descriptor_Ref is access all Descriptor_Type;
|
||||
|
||||
-- Normally, there is only one such descriptor for a given procedure, but
|
||||
-- it works fine to make a copy of the single allocated descriptor, and
|
||||
-- use the copy itself, and we take advantage of this in the design here.
|
||||
-- The idea is that AST_Handler values will all point to a record with the
|
||||
-- following structure:
|
||||
|
||||
-- Note: When we say it works fine, there is one delicate point, which
|
||||
-- is that the code for the AST procedure itself requires the original
|
||||
-- descriptor address. We handle this by saving the orignal descriptor
|
||||
-- address in this structure and restoring in Process_AST.
|
||||
|
||||
type AST_Handler_Data is record
|
||||
Descriptor : Descriptor_Type;
|
||||
Original_Descriptor_Ref : Descriptor_Ref;
|
||||
Taskid : ATID.Task_Id;
|
||||
Entryno : Natural;
|
||||
end record;
|
||||
|
||||
type AST_Handler_Data_Ref is access all AST_Handler_Data;
|
||||
|
||||
function To_AST_Handler is new Ada.Unchecked_Conversion
|
||||
(AST_Handler_Data_Ref, System.Aux_DEC.AST_Handler);
|
||||
|
||||
-- Each time Create_AST_Handler is called, a new value of this record
|
||||
-- type is created, containing a copy of the procedure descriptor for
|
||||
-- the routine used to handle all AST's (Process_AST), and the Task_Id
|
||||
-- and entry number parameters identifying the task entry involved.
|
||||
|
||||
-- The AST_Handler value returned is a pointer to this record. Since
|
||||
-- the record starts with the procedure descriptor, it can be used
|
||||
-- by the system in the normal way to call the procedure. But now
|
||||
-- when the procedure gets control, it can determine the address of
|
||||
-- the procedure descriptor used to call it (since the ABI specifies
|
||||
-- that this is left sitting in register r27 on entry), and then use
|
||||
-- that address to retrieve the Task_Id and entry number so that it
|
||||
-- knows on which entry to queue the AST request.
|
||||
|
||||
-- The next issue is where are these records placed. Since we intend
|
||||
-- to pass pointers to these records to asynchronous system service
|
||||
-- routines, they have to be on the heap, which means we have to worry
|
||||
-- about when to allocate them and deallocate them.
|
||||
|
||||
-- We solve this problem by introducing a task attribute that points to
|
||||
-- a vector, indexed by the entry number, of AST_Handler_Data records
|
||||
-- for a given task. The pointer itself is a controlled object allowing
|
||||
-- us to write a finalization routine that frees the referenced vector.
|
||||
|
||||
-- An entry in this vector is either initialized (Entryno non-zero) and
|
||||
-- can be used for any subsequent reference to the same entry, or it is
|
||||
-- unused, marked by the Entryno value being zero.
|
||||
|
||||
type AST_Handler_Vector is array (Natural range <>) of AST_Handler_Data;
|
||||
type AST_Handler_Vector_Ref is access all AST_Handler_Vector;
|
||||
|
||||
type AST_Vector_Ptr is new Ada.Finalization.Controlled with record
|
||||
Vector : AST_Handler_Vector_Ref;
|
||||
end record;
|
||||
|
||||
procedure Finalize (Obj : in out AST_Vector_Ptr);
|
||||
-- Override Finalize so that the AST Vector gets freed.
|
||||
|
||||
procedure Finalize (Obj : in out AST_Vector_Ptr) is
|
||||
procedure Free is new
|
||||
Ada.Unchecked_Deallocation (AST_Handler_Vector, AST_Handler_Vector_Ref);
|
||||
begin
|
||||
if Obj.Vector /= null then
|
||||
Free (Obj.Vector);
|
||||
end if;
|
||||
end Finalize;
|
||||
|
||||
AST_Vector_Init : AST_Vector_Ptr;
|
||||
-- Initial value, treated as constant, Vector will be null
|
||||
|
||||
package AST_Attribute is new Ada.Task_Attributes
|
||||
(Attribute => AST_Vector_Ptr,
|
||||
Initial_Value => AST_Vector_Init);
|
||||
|
||||
use AST_Attribute;
|
||||
|
||||
-----------------------
|
||||
-- AST Service Queue --
|
||||
-----------------------
|
||||
|
||||
-- The following global data structures are used to queue pending
|
||||
-- AST requests. When an AST is signalled, the AST service routine
|
||||
-- Process_AST is called, and it makes an entry in this structure.
|
||||
|
||||
type AST_Instance is record
|
||||
Taskid : ATID.Task_Id;
|
||||
Entryno : Natural;
|
||||
Param : Long_Integer;
|
||||
end record;
|
||||
-- The Taskid and Entryno indicate the entry on which this AST is to
|
||||
-- be queued, and Param is the parameter provided from the AST itself.
|
||||
|
||||
AST_Service_Queue_Size : constant := 256;
|
||||
AST_Service_Queue_Limit : constant := 250;
|
||||
type AST_Service_Queue_Index is mod AST_Service_Queue_Size;
|
||||
-- Index used to refer to entries in the circular buffer which holds
|
||||
-- active AST_Instance values. The upper bound reflects the maximum
|
||||
-- number of AST instances that can be stored in the buffer. Since
|
||||
-- these entries are immediately serviced by the high priority server
|
||||
-- task that does the actual entry queuing, it is very unusual to have
|
||||
-- any significant number of entries simulaneously queued.
|
||||
|
||||
AST_Service_Queue : array (AST_Service_Queue_Index) of AST_Instance;
|
||||
pragma Volatile_Components (AST_Service_Queue);
|
||||
-- The circular buffer used to store active AST requests
|
||||
|
||||
AST_Service_Queue_Put : AST_Service_Queue_Index := 0;
|
||||
AST_Service_Queue_Get : AST_Service_Queue_Index := 0;
|
||||
pragma Atomic (AST_Service_Queue_Put);
|
||||
pragma Atomic (AST_Service_Queue_Get);
|
||||
-- These two variables point to the next slots in the AST_Service_Queue
|
||||
-- to be used for putting a new entry in and taking an entry out. This
|
||||
-- is a circular buffer, so these pointers wrap around. If the two values
|
||||
-- are equal the buffer is currently empty. The pointers are atomic to
|
||||
-- ensure proper synchronization between the single producer (namely the
|
||||
-- Process_AST procedure), and the single consumer (the AST_Service_Task).
|
||||
|
||||
--------------------------------
|
||||
-- AST Server Task Structures --
|
||||
--------------------------------
|
||||
|
||||
-- The basic approach is that when an AST comes in, a call is made to
|
||||
-- the Process_AST procedure. It queues the request in the service queue
|
||||
-- and then wakes up an AST server task to perform the actual call to the
|
||||
-- required entry. We use this intermediate server task, since the AST
|
||||
-- procedure itself cannot wait to return, and we need some caller for
|
||||
-- the rendezvous so that we can use the normal rendezvous mechanism.
|
||||
|
||||
-- It would work to have only one AST server task, but then we would lose
|
||||
-- all overlap in AST processing, and furthermore, we could get priority
|
||||
-- inversion effects resulting in starvation of AST requests.
|
||||
|
||||
-- We therefore maintain a small pool of AST server tasks. We adjust
|
||||
-- the size of the pool dynamically to reflect traffic, so that we have
|
||||
-- a sufficient number of server tasks to avoid starvation.
|
||||
|
||||
Max_AST_Servers : constant Natural := 16;
|
||||
-- Maximum number of AST server tasks that can be allocated
|
||||
|
||||
Num_AST_Servers : Natural := 0;
|
||||
-- Number of AST server tasks currently active
|
||||
|
||||
Num_Waiting_AST_Servers : Natural := 0;
|
||||
-- This is the number of AST server tasks that are either waiting for
|
||||
-- work, or just about to go to sleep and wait for work.
|
||||
|
||||
Is_Waiting : array (1 .. Max_AST_Servers) of Boolean := (others => False);
|
||||
-- An array of flags showing which AST server tasks are currently waiting
|
||||
|
||||
AST_Task_Ids : array (1 .. Max_AST_Servers) of ST.Task_Id;
|
||||
-- Task Id's of allocated AST server tasks
|
||||
|
||||
task type AST_Server_Task (Num : Natural) is
|
||||
pragma Priority (Priority'Last);
|
||||
end AST_Server_Task;
|
||||
-- Declaration for AST server task. This task has no entries, it is
|
||||
-- controlled by sleep and wakeup calls at the task primitives level.
|
||||
|
||||
type AST_Server_Task_Ptr is access all AST_Server_Task;
|
||||
-- Type used to allocate server tasks
|
||||
|
||||
-----------------------
|
||||
-- Local Subprograms --
|
||||
-----------------------
|
||||
|
||||
procedure Allocate_New_AST_Server;
|
||||
-- Allocate an additional AST server task
|
||||
|
||||
procedure Process_AST (Param : Long_Integer);
|
||||
-- This is the central routine for processing all AST's, it is referenced
|
||||
-- as the code address of all created AST_Handler values. See detailed
|
||||
-- description in body to understand how it works to have a single such
|
||||
-- procedure for all AST's even though it does not get any indication of
|
||||
-- the entry involved passed as an explicit parameter. The single explicit
|
||||
-- parameter Param is the parameter passed by the system with the AST.
|
||||
|
||||
-----------------------------
|
||||
-- Allocate_New_AST_Server --
|
||||
-----------------------------
|
||||
|
||||
procedure Allocate_New_AST_Server is
|
||||
Dummy : AST_Server_Task_Ptr;
|
||||
pragma Unreferenced (Dummy);
|
||||
|
||||
begin
|
||||
if Num_AST_Servers = Max_AST_Servers then
|
||||
return;
|
||||
|
||||
else
|
||||
-- Note: it is safe to increment Num_AST_Servers immediately, since
|
||||
-- no one will try to activate this task until it indicates that it
|
||||
-- is sleeping by setting its entry in Is_Waiting to True.
|
||||
|
||||
Num_AST_Servers := Num_AST_Servers + 1;
|
||||
Dummy := new AST_Server_Task (Num_AST_Servers);
|
||||
end if;
|
||||
end Allocate_New_AST_Server;
|
||||
|
||||
---------------------
|
||||
-- AST_Server_Task --
|
||||
---------------------
|
||||
|
||||
task body AST_Server_Task is
|
||||
Taskid : ATID.Task_Id;
|
||||
Entryno : Natural;
|
||||
Param : aliased Long_Integer;
|
||||
Self_Id : constant ST.Task_Id := ST.Self;
|
||||
|
||||
pragma Volatile (Param);
|
||||
|
||||
begin
|
||||
-- By making this task independent of master, when the environment
|
||||
-- task is finalizing, the AST_Server_Task will be notified that it
|
||||
-- should terminate.
|
||||
|
||||
STU.Make_Independent;
|
||||
|
||||
-- Record our task Id for access by Process_AST
|
||||
|
||||
AST_Task_Ids (Num) := Self_Id;
|
||||
|
||||
-- Note: this entire task operates with the main task lock set, except
|
||||
-- when it is sleeping waiting for work, or busy doing a rendezvous
|
||||
-- with an AST server. This lock protects the data structures that
|
||||
-- are shared by multiple instances of the server task.
|
||||
|
||||
Lock_AST (Self_Id);
|
||||
|
||||
-- This is the main infinite loop of the task. We go to sleep and
|
||||
-- wait to be woken up by Process_AST when there is some work to do.
|
||||
|
||||
loop
|
||||
Num_Waiting_AST_Servers := Num_Waiting_AST_Servers + 1;
|
||||
|
||||
Unlock_AST (Self_Id);
|
||||
|
||||
STI.Defer_Abort (Self_Id);
|
||||
|
||||
if SP.Single_Lock then
|
||||
STPO.Lock_RTS;
|
||||
end if;
|
||||
|
||||
STPO.Write_Lock (Self_Id);
|
||||
|
||||
Is_Waiting (Num) := True;
|
||||
|
||||
Self_Id.Common.State := ST.AST_Server_Sleep;
|
||||
STPO.Sleep (Self_Id, ST.AST_Server_Sleep);
|
||||
Self_Id.Common.State := ST.Runnable;
|
||||
|
||||
STPO.Unlock (Self_Id);
|
||||
|
||||
if SP.Single_Lock then
|
||||
STPO.Unlock_RTS;
|
||||
end if;
|
||||
|
||||
-- If the process is finalizing, Undefer_Abort will simply end
|
||||
-- this task.
|
||||
|
||||
STI.Undefer_Abort (Self_Id);
|
||||
|
||||
-- We are awake, there is something to do!
|
||||
|
||||
Lock_AST (Self_Id);
|
||||
Num_Waiting_AST_Servers := Num_Waiting_AST_Servers - 1;
|
||||
|
||||
-- Loop here to service outstanding requests. We are always
|
||||
-- locked on entry to this loop.
|
||||
|
||||
while AST_Service_Queue_Get /= AST_Service_Queue_Put loop
|
||||
Taskid := AST_Service_Queue (AST_Service_Queue_Get).Taskid;
|
||||
Entryno := AST_Service_Queue (AST_Service_Queue_Get).Entryno;
|
||||
Param := AST_Service_Queue (AST_Service_Queue_Get).Param;
|
||||
|
||||
AST_Service_Queue_Get := AST_Service_Queue_Get + 1;
|
||||
|
||||
-- This is a manual expansion of the normal call simple code
|
||||
|
||||
declare
|
||||
type AA is access all Long_Integer;
|
||||
P : AA := Param'Unrestricted_Access;
|
||||
|
||||
function To_ST_Task_Id is new Ada.Unchecked_Conversion
|
||||
(ATID.Task_Id, ST.Task_Id);
|
||||
|
||||
begin
|
||||
Unlock_AST (Self_Id);
|
||||
STR.Call_Simple
|
||||
(Acceptor => To_ST_Task_Id (Taskid),
|
||||
E => ST.Task_Entry_Index (Entryno),
|
||||
Uninterpreted_Data => P'Address);
|
||||
|
||||
exception
|
||||
when E : others =>
|
||||
System.IO.Put_Line ("%Debugging event");
|
||||
System.IO.Put_Line (Exception_Name (E) &
|
||||
" raised when trying to deliver an AST.");
|
||||
|
||||
if Exception_Message (E)'Length /= 0 then
|
||||
System.IO.Put_Line (Exception_Message (E));
|
||||
end if;
|
||||
|
||||
System.IO.Put_Line ("Task type is " & "Receiver_Type");
|
||||
System.IO.Put_Line ("Task id is " & ATID.Image (Taskid));
|
||||
end;
|
||||
|
||||
Lock_AST (Self_Id);
|
||||
end loop;
|
||||
end loop;
|
||||
end AST_Server_Task;
|
||||
|
||||
------------------------
|
||||
-- Create_AST_Handler --
|
||||
------------------------
|
||||
|
||||
function Create_AST_Handler
|
||||
(Taskid : ATID.Task_Id;
|
||||
Entryno : Natural) return System.Aux_DEC.AST_Handler
|
||||
is
|
||||
Attr_Ref : Attribute_Handle;
|
||||
|
||||
Process_AST_Ptr : constant AST_Handler := Process_AST'Access;
|
||||
-- Reference to standard procedure descriptor for Process_AST
|
||||
|
||||
function To_Descriptor_Ref is new Ada.Unchecked_Conversion
|
||||
(AST_Handler, Descriptor_Ref);
|
||||
|
||||
Original_Descriptor_Ref : constant Descriptor_Ref :=
|
||||
To_Descriptor_Ref (Process_AST_Ptr);
|
||||
|
||||
begin
|
||||
if ATID.Is_Terminated (Taskid) then
|
||||
raise Program_Error;
|
||||
end if;
|
||||
|
||||
Attr_Ref := Reference (Taskid);
|
||||
|
||||
-- Allocate another server if supply is getting low
|
||||
|
||||
if Num_Waiting_AST_Servers < 2 then
|
||||
Allocate_New_AST_Server;
|
||||
end if;
|
||||
|
||||
-- No point in creating more if we have zillions waiting to
|
||||
-- be serviced.
|
||||
|
||||
while AST_Service_Queue_Put - AST_Service_Queue_Get
|
||||
> AST_Service_Queue_Limit
|
||||
loop
|
||||
delay 0.01;
|
||||
end loop;
|
||||
|
||||
-- If no AST vector allocated, or the one we have is too short, then
|
||||
-- allocate one of right size and initialize all entries except the
|
||||
-- one we will use to unused. Note that the assignment automatically
|
||||
-- frees the old allocated table if there is one.
|
||||
|
||||
if Attr_Ref.Vector = null
|
||||
or else Attr_Ref.Vector'Length < Entryno
|
||||
then
|
||||
Attr_Ref.Vector := new AST_Handler_Vector (1 .. Entryno);
|
||||
|
||||
for E in 1 .. Entryno loop
|
||||
Attr_Ref.Vector (E).Descriptor.Entry_Point :=
|
||||
Original_Descriptor_Ref.Entry_Point;
|
||||
Attr_Ref.Vector (E).Descriptor.GP_Value :=
|
||||
Attr_Ref.Vector (E)'Address;
|
||||
Attr_Ref.Vector (E).Original_Descriptor_Ref :=
|
||||
Original_Descriptor_Ref;
|
||||
Attr_Ref.Vector (E).Taskid := Taskid;
|
||||
Attr_Ref.Vector (E).Entryno := E;
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
return To_AST_Handler (Attr_Ref.Vector (Entryno)'Unrestricted_Access);
|
||||
end Create_AST_Handler;
|
||||
|
||||
----------------------------
|
||||
-- Expand_AST_Packet_Pool --
|
||||
----------------------------
|
||||
|
||||
procedure Expand_AST_Packet_Pool
|
||||
(Requested_Packets : Natural;
|
||||
Actual_Number : out Natural;
|
||||
Total_Number : out Natural)
|
||||
is
|
||||
pragma Unreferenced (Requested_Packets);
|
||||
begin
|
||||
-- The AST implementation of GNAT does not permit dynamic expansion
|
||||
-- of the pool, so we simply add no entries and return the total. If
|
||||
-- it is necessary to expand the allocation, then this package body
|
||||
-- must be recompiled with a larger value for AST_Service_Queue_Size.
|
||||
|
||||
Actual_Number := 0;
|
||||
Total_Number := AST_Service_Queue_Size;
|
||||
end Expand_AST_Packet_Pool;
|
||||
|
||||
-----------------
|
||||
-- Process_AST --
|
||||
-----------------
|
||||
|
||||
procedure Process_AST (Param : Long_Integer) is
|
||||
|
||||
Handler_Data_Ptr : AST_Handler_Data_Ref;
|
||||
-- This variable is set to the address of the descriptor through
|
||||
-- which Process_AST is called. Since the descriptor is part of
|
||||
-- an AST_Handler value, this is also the address of this value,
|
||||
-- from which we can obtain the task and entry number information.
|
||||
|
||||
function To_Address is new Ada.Unchecked_Conversion
|
||||
(ST.Task_Id, System.Task_Primitives.Task_Address);
|
||||
|
||||
begin
|
||||
-- Move the contrived GP into place so Taskid and Entryno
|
||||
-- become available, then restore the true GP.
|
||||
|
||||
System.Machine_Code.Asm
|
||||
(Template => "mov %0 = r1",
|
||||
Outputs => AST_Handler_Data_Ref'Asm_Output
|
||||
("=r", Handler_Data_Ptr),
|
||||
Volatile => True);
|
||||
|
||||
System.Machine_Code.Asm
|
||||
(Template => "ld8 r1 = %0;;",
|
||||
Inputs => System.Address'Asm_Input
|
||||
("m", Handler_Data_Ptr.Original_Descriptor_Ref.GP_Value),
|
||||
Volatile => True);
|
||||
|
||||
AST_Service_Queue (AST_Service_Queue_Put) := AST_Instance'
|
||||
(Taskid => Handler_Data_Ptr.Taskid,
|
||||
Entryno => Handler_Data_Ptr.Entryno,
|
||||
Param => Param);
|
||||
|
||||
-- OpenVMS Programming Concepts manual, chapter 8.2.3:
|
||||
-- "Implicit synchronization can be achieved for data that is shared
|
||||
-- for write by using only AST routines to write the data, since only
|
||||
-- one AST can be running at any one time."
|
||||
|
||||
-- This subprogram runs at AST level so is guaranteed to be
|
||||
-- called sequentially at a given access level.
|
||||
|
||||
AST_Service_Queue_Put := AST_Service_Queue_Put + 1;
|
||||
|
||||
-- Need to wake up processing task. If there is no waiting server
|
||||
-- then we have temporarily run out, but things should still be
|
||||
-- OK, since one of the active ones will eventually pick up the
|
||||
-- service request queued in the AST_Service_Queue.
|
||||
|
||||
for J in 1 .. Num_AST_Servers loop
|
||||
if Is_Waiting (J) then
|
||||
Is_Waiting (J) := False;
|
||||
|
||||
-- Sleeps are handled by ASTs on VMS, so don't call Wakeup
|
||||
|
||||
STPOD.Interrupt_AST_Handler (To_Address (AST_Task_Ids (J)));
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
end Process_AST;
|
||||
|
||||
begin
|
||||
STPO.Initialize_Lock (AST_Lock'Access, STPO.Global_Task_Level);
|
||||
end System.AST_Handling;
|
||||
|
|
@ -0,0 +1,576 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT COMPILER COMPONENTS --
|
||||
-- --
|
||||
-- S Y S T E M . A U X _ D E C --
|
||||
-- --
|
||||
-- B o d y --
|
||||
-- --
|
||||
-- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNAT was originally developed by the GNAT team at New York University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- This is the Itanium/VMS version.
|
||||
|
||||
-- The Add,Clear_Interlocked subprograms are dubiously implmented due to
|
||||
-- the lack of a single bit sync_lock_test_and_set builtin.
|
||||
|
||||
-- The "Retry" parameter is ignored due to the lack of retry builtins making
|
||||
-- the subprograms identical to the non-retry versions.
|
||||
|
||||
pragma Style_Checks (All_Checks);
|
||||
-- Turn off alpha ordering check on subprograms, this unit is laid
|
||||
-- out to correspond to the declarations in the DEC 83 System unit.
|
||||
|
||||
with Interfaces;
|
||||
package body System.Aux_DEC is
|
||||
|
||||
use type Interfaces.Unsigned_8;
|
||||
|
||||
------------------------
|
||||
-- Fetch_From_Address --
|
||||
------------------------
|
||||
|
||||
function Fetch_From_Address (A : Address) return Target is
|
||||
type T_Ptr is access all Target;
|
||||
function To_T_Ptr is new Ada.Unchecked_Conversion (Address, T_Ptr);
|
||||
Ptr : constant T_Ptr := To_T_Ptr (A);
|
||||
begin
|
||||
return Ptr.all;
|
||||
end Fetch_From_Address;
|
||||
|
||||
-----------------------
|
||||
-- Assign_To_Address --
|
||||
-----------------------
|
||||
|
||||
procedure Assign_To_Address (A : Address; T : Target) is
|
||||
type T_Ptr is access all Target;
|
||||
function To_T_Ptr is new Ada.Unchecked_Conversion (Address, T_Ptr);
|
||||
Ptr : constant T_Ptr := To_T_Ptr (A);
|
||||
begin
|
||||
Ptr.all := T;
|
||||
end Assign_To_Address;
|
||||
|
||||
-----------------------
|
||||
-- Clear_Interlocked --
|
||||
-----------------------
|
||||
|
||||
procedure Clear_Interlocked
|
||||
(Bit : in out Boolean;
|
||||
Old_Value : out Boolean)
|
||||
is
|
||||
Clr_Bit : Boolean := Bit;
|
||||
Old_Uns : Interfaces.Unsigned_8;
|
||||
|
||||
function Sync_Lock_Test_And_Set
|
||||
(Ptr : Address;
|
||||
Value : Interfaces.Unsigned_8) return Interfaces.Unsigned_8;
|
||||
pragma Import (Intrinsic, Sync_Lock_Test_And_Set,
|
||||
"__sync_lock_test_and_set_1");
|
||||
|
||||
begin
|
||||
Old_Uns := Sync_Lock_Test_And_Set (Clr_Bit'Address, 0);
|
||||
Bit := Clr_Bit;
|
||||
Old_Value := Old_Uns /= 0;
|
||||
end Clear_Interlocked;
|
||||
|
||||
procedure Clear_Interlocked
|
||||
(Bit : in out Boolean;
|
||||
Old_Value : out Boolean;
|
||||
Retry_Count : Natural;
|
||||
Success_Flag : out Boolean)
|
||||
is
|
||||
pragma Unreferenced (Retry_Count);
|
||||
|
||||
Clr_Bit : Boolean := Bit;
|
||||
Old_Uns : Interfaces.Unsigned_8;
|
||||
|
||||
function Sync_Lock_Test_And_Set
|
||||
(Ptr : Address;
|
||||
Value : Interfaces.Unsigned_8) return Interfaces.Unsigned_8;
|
||||
pragma Import (Intrinsic, Sync_Lock_Test_And_Set,
|
||||
"__sync_lock_test_and_set_1");
|
||||
|
||||
begin
|
||||
Old_Uns := Sync_Lock_Test_And_Set (Clr_Bit'Address, 0);
|
||||
Bit := Clr_Bit;
|
||||
Old_Value := Old_Uns /= 0;
|
||||
Success_Flag := True;
|
||||
end Clear_Interlocked;
|
||||
|
||||
---------------------
|
||||
-- Set_Interlocked --
|
||||
---------------------
|
||||
|
||||
procedure Set_Interlocked
|
||||
(Bit : in out Boolean;
|
||||
Old_Value : out Boolean)
|
||||
is
|
||||
Set_Bit : Boolean := Bit;
|
||||
Old_Uns : Interfaces.Unsigned_8;
|
||||
|
||||
function Sync_Lock_Test_And_Set
|
||||
(Ptr : Address;
|
||||
Value : Interfaces.Unsigned_8) return Interfaces.Unsigned_8;
|
||||
pragma Import (Intrinsic, Sync_Lock_Test_And_Set,
|
||||
"__sync_lock_test_and_set_1");
|
||||
|
||||
begin
|
||||
Old_Uns := Sync_Lock_Test_And_Set (Set_Bit'Address, 1);
|
||||
Bit := Set_Bit;
|
||||
Old_Value := Old_Uns /= 0;
|
||||
end Set_Interlocked;
|
||||
|
||||
procedure Set_Interlocked
|
||||
(Bit : in out Boolean;
|
||||
Old_Value : out Boolean;
|
||||
Retry_Count : Natural;
|
||||
Success_Flag : out Boolean)
|
||||
is
|
||||
pragma Unreferenced (Retry_Count);
|
||||
|
||||
Set_Bit : Boolean := Bit;
|
||||
Old_Uns : Interfaces.Unsigned_8;
|
||||
|
||||
function Sync_Lock_Test_And_Set
|
||||
(Ptr : Address;
|
||||
Value : Interfaces.Unsigned_8) return Interfaces.Unsigned_8;
|
||||
pragma Import (Intrinsic, Sync_Lock_Test_And_Set,
|
||||
"__sync_lock_test_and_set_1");
|
||||
begin
|
||||
Old_Uns := Sync_Lock_Test_And_Set (Set_Bit'Address, 1);
|
||||
Bit := Set_Bit;
|
||||
Old_Value := Old_Uns /= 0;
|
||||
Success_Flag := True;
|
||||
end Set_Interlocked;
|
||||
|
||||
---------------------
|
||||
-- Add_Interlocked --
|
||||
---------------------
|
||||
|
||||
procedure Add_Interlocked
|
||||
(Addend : Short_Integer;
|
||||
Augend : in out Aligned_Word;
|
||||
Sign : out Integer)
|
||||
is
|
||||
Overflowed : Boolean := False;
|
||||
Former : Aligned_Word;
|
||||
|
||||
function Sync_Fetch_And_Add
|
||||
(Ptr : Address;
|
||||
Value : Short_Integer) return Short_Integer;
|
||||
pragma Import (Intrinsic, Sync_Fetch_And_Add, "__sync_fetch_and_add_2");
|
||||
|
||||
begin
|
||||
Former.Value := Sync_Fetch_And_Add (Augend.Value'Address, Addend);
|
||||
|
||||
if Augend.Value < 0 then
|
||||
Sign := -1;
|
||||
elsif Augend.Value > 0 then
|
||||
Sign := 1;
|
||||
else
|
||||
Sign := 0;
|
||||
end if;
|
||||
|
||||
if Former.Value > 0 and then Augend.Value <= 0 then
|
||||
Overflowed := True;
|
||||
end if;
|
||||
|
||||
if Overflowed then
|
||||
raise Constraint_Error;
|
||||
end if;
|
||||
end Add_Interlocked;
|
||||
|
||||
----------------
|
||||
-- Add_Atomic --
|
||||
----------------
|
||||
|
||||
procedure Add_Atomic
|
||||
(To : in out Aligned_Integer;
|
||||
Amount : Integer)
|
||||
is
|
||||
procedure Sync_Add_And_Fetch
|
||||
(Ptr : Address;
|
||||
Value : Integer);
|
||||
pragma Import (Intrinsic, Sync_Add_And_Fetch, "__sync_add_and_fetch_4");
|
||||
begin
|
||||
Sync_Add_And_Fetch (To.Value'Address, Amount);
|
||||
end Add_Atomic;
|
||||
|
||||
procedure Add_Atomic
|
||||
(To : in out Aligned_Integer;
|
||||
Amount : Integer;
|
||||
Retry_Count : Natural;
|
||||
Old_Value : out Integer;
|
||||
Success_Flag : out Boolean)
|
||||
is
|
||||
pragma Unreferenced (Retry_Count);
|
||||
|
||||
function Sync_Fetch_And_Add
|
||||
(Ptr : Address;
|
||||
Value : Integer) return Integer;
|
||||
pragma Import (Intrinsic, Sync_Fetch_And_Add, "__sync_fetch_and_add_4");
|
||||
|
||||
begin
|
||||
Old_Value := Sync_Fetch_And_Add (To.Value'Address, Amount);
|
||||
Success_Flag := True;
|
||||
end Add_Atomic;
|
||||
|
||||
procedure Add_Atomic
|
||||
(To : in out Aligned_Long_Integer;
|
||||
Amount : Long_Integer)
|
||||
is
|
||||
procedure Sync_Add_And_Fetch
|
||||
(Ptr : Address;
|
||||
Value : Long_Integer);
|
||||
pragma Import (Intrinsic, Sync_Add_And_Fetch, "__sync_add_and_fetch_8");
|
||||
begin
|
||||
Sync_Add_And_Fetch (To.Value'Address, Amount);
|
||||
end Add_Atomic;
|
||||
|
||||
procedure Add_Atomic
|
||||
(To : in out Aligned_Long_Integer;
|
||||
Amount : Long_Integer;
|
||||
Retry_Count : Natural;
|
||||
Old_Value : out Long_Integer;
|
||||
Success_Flag : out Boolean)
|
||||
is
|
||||
pragma Unreferenced (Retry_Count);
|
||||
|
||||
function Sync_Fetch_And_Add
|
||||
(Ptr : Address;
|
||||
Value : Long_Integer) return Long_Integer;
|
||||
pragma Import (Intrinsic, Sync_Fetch_And_Add, "__sync_fetch_and_add_8");
|
||||
-- Why do we keep importing this over and over again???
|
||||
|
||||
begin
|
||||
Old_Value := Sync_Fetch_And_Add (To.Value'Address, Amount);
|
||||
Success_Flag := True;
|
||||
end Add_Atomic;
|
||||
|
||||
----------------
|
||||
-- And_Atomic --
|
||||
----------------
|
||||
|
||||
procedure And_Atomic
|
||||
(To : in out Aligned_Integer;
|
||||
From : Integer)
|
||||
is
|
||||
procedure Sync_And_And_Fetch
|
||||
(Ptr : Address;
|
||||
Value : Integer);
|
||||
pragma Import (Intrinsic, Sync_And_And_Fetch, "__sync_and_and_fetch_4");
|
||||
begin
|
||||
Sync_And_And_Fetch (To.Value'Address, From);
|
||||
end And_Atomic;
|
||||
|
||||
procedure And_Atomic
|
||||
(To : in out Aligned_Integer;
|
||||
From : Integer;
|
||||
Retry_Count : Natural;
|
||||
Old_Value : out Integer;
|
||||
Success_Flag : out Boolean)
|
||||
is
|
||||
pragma Unreferenced (Retry_Count);
|
||||
|
||||
function Sync_Fetch_And_And
|
||||
(Ptr : Address;
|
||||
Value : Integer) return Integer;
|
||||
pragma Import (Intrinsic, Sync_Fetch_And_And, "__sync_fetch_and_and_4");
|
||||
|
||||
begin
|
||||
Old_Value := Sync_Fetch_And_And (To.Value'Address, From);
|
||||
Success_Flag := True;
|
||||
end And_Atomic;
|
||||
|
||||
procedure And_Atomic
|
||||
(To : in out Aligned_Long_Integer;
|
||||
From : Long_Integer)
|
||||
is
|
||||
procedure Sync_And_And_Fetch
|
||||
(Ptr : Address;
|
||||
Value : Long_Integer);
|
||||
pragma Import (Intrinsic, Sync_And_And_Fetch, "__sync_and_and_fetch_8");
|
||||
begin
|
||||
Sync_And_And_Fetch (To.Value'Address, From);
|
||||
end And_Atomic;
|
||||
|
||||
procedure And_Atomic
|
||||
(To : in out Aligned_Long_Integer;
|
||||
From : Long_Integer;
|
||||
Retry_Count : Natural;
|
||||
Old_Value : out Long_Integer;
|
||||
Success_Flag : out Boolean)
|
||||
is
|
||||
pragma Unreferenced (Retry_Count);
|
||||
|
||||
function Sync_Fetch_And_And
|
||||
(Ptr : Address;
|
||||
Value : Long_Integer) return Long_Integer;
|
||||
pragma Import (Intrinsic, Sync_Fetch_And_And, "__sync_fetch_and_and_8");
|
||||
|
||||
begin
|
||||
Old_Value := Sync_Fetch_And_And (To.Value'Address, From);
|
||||
Success_Flag := True;
|
||||
end And_Atomic;
|
||||
|
||||
---------------
|
||||
-- Or_Atomic --
|
||||
---------------
|
||||
|
||||
procedure Or_Atomic
|
||||
(To : in out Aligned_Integer;
|
||||
From : Integer)
|
||||
is
|
||||
procedure Sync_Or_And_Fetch
|
||||
(Ptr : Address;
|
||||
Value : Integer);
|
||||
pragma Import (Intrinsic, Sync_Or_And_Fetch, "__sync_or_and_fetch_4");
|
||||
|
||||
begin
|
||||
Sync_Or_And_Fetch (To.Value'Address, From);
|
||||
end Or_Atomic;
|
||||
|
||||
procedure Or_Atomic
|
||||
(To : in out Aligned_Integer;
|
||||
From : Integer;
|
||||
Retry_Count : Natural;
|
||||
Old_Value : out Integer;
|
||||
Success_Flag : out Boolean)
|
||||
is
|
||||
pragma Unreferenced (Retry_Count);
|
||||
|
||||
function Sync_Fetch_And_Or
|
||||
(Ptr : Address;
|
||||
Value : Integer) return Integer;
|
||||
pragma Import (Intrinsic, Sync_Fetch_And_Or, "__sync_fetch_and_or_4");
|
||||
|
||||
begin
|
||||
Old_Value := Sync_Fetch_And_Or (To.Value'Address, From);
|
||||
Success_Flag := True;
|
||||
end Or_Atomic;
|
||||
|
||||
procedure Or_Atomic
|
||||
(To : in out Aligned_Long_Integer;
|
||||
From : Long_Integer)
|
||||
is
|
||||
procedure Sync_Or_And_Fetch
|
||||
(Ptr : Address;
|
||||
Value : Long_Integer);
|
||||
pragma Import (Intrinsic, Sync_Or_And_Fetch, "__sync_or_and_fetch_8");
|
||||
begin
|
||||
Sync_Or_And_Fetch (To.Value'Address, From);
|
||||
end Or_Atomic;
|
||||
|
||||
procedure Or_Atomic
|
||||
(To : in out Aligned_Long_Integer;
|
||||
From : Long_Integer;
|
||||
Retry_Count : Natural;
|
||||
Old_Value : out Long_Integer;
|
||||
Success_Flag : out Boolean)
|
||||
is
|
||||
pragma Unreferenced (Retry_Count);
|
||||
|
||||
function Sync_Fetch_And_Or
|
||||
(Ptr : Address;
|
||||
Value : Long_Integer) return Long_Integer;
|
||||
pragma Import (Intrinsic, Sync_Fetch_And_Or, "__sync_fetch_and_or_8");
|
||||
|
||||
begin
|
||||
Old_Value := Sync_Fetch_And_Or (To.Value'Address, From);
|
||||
Success_Flag := True;
|
||||
end Or_Atomic;
|
||||
|
||||
------------
|
||||
-- Insqhi --
|
||||
------------
|
||||
|
||||
procedure Insqhi
|
||||
(Item : Address;
|
||||
Header : Address;
|
||||
Status : out Insq_Status) is
|
||||
|
||||
procedure SYS_PAL_INSQHIL
|
||||
(STATUS : out Integer; Header : Address; ITEM : Address);
|
||||
pragma Interface (External, SYS_PAL_INSQHIL);
|
||||
pragma Import_Valued_Procedure (SYS_PAL_INSQHIL, "SYS$PAL_INSQHIL",
|
||||
(Integer, Address, Address),
|
||||
(Value, Value, Value));
|
||||
|
||||
Istat : Integer;
|
||||
|
||||
begin
|
||||
SYS_PAL_INSQHIL (Istat, Header, Item);
|
||||
|
||||
if Istat = 0 then
|
||||
Status := OK_Not_First;
|
||||
elsif Istat = 1 then
|
||||
Status := OK_First;
|
||||
|
||||
else
|
||||
-- This status is never returned on IVMS
|
||||
|
||||
Status := Fail_No_Lock;
|
||||
end if;
|
||||
end Insqhi;
|
||||
|
||||
------------
|
||||
-- Remqhi --
|
||||
------------
|
||||
|
||||
procedure Remqhi
|
||||
(Header : Address;
|
||||
Item : out Address;
|
||||
Status : out Remq_Status)
|
||||
is
|
||||
-- The removed item is returned in the second function return register,
|
||||
-- R9 on IVMS. The VMS ABI calls for "small" records to be returned in
|
||||
-- these registers, so inventing this odd looking record type makes that
|
||||
-- all work.
|
||||
|
||||
type Remq is record
|
||||
Status : Long_Integer;
|
||||
Item : Address;
|
||||
end record;
|
||||
|
||||
procedure SYS_PAL_REMQHIL
|
||||
(Remret : out Remq; Header : Address);
|
||||
pragma Interface (External, SYS_PAL_REMQHIL);
|
||||
pragma Import_Valued_Procedure
|
||||
(SYS_PAL_REMQHIL, "SYS$PAL_REMQHIL",
|
||||
(Remq, Address),
|
||||
(Value, Value));
|
||||
|
||||
-- Following variables need documentation???
|
||||
|
||||
Rstat : Long_Integer;
|
||||
Remret : Remq;
|
||||
|
||||
begin
|
||||
SYS_PAL_REMQHIL (Remret, Header);
|
||||
|
||||
Rstat := Remret.Status;
|
||||
Item := Remret.Item;
|
||||
|
||||
if Rstat = 0 then
|
||||
Status := Fail_Was_Empty;
|
||||
|
||||
elsif Rstat = 1 then
|
||||
Status := OK_Not_Empty;
|
||||
|
||||
elsif Rstat = 2 then
|
||||
Status := OK_Empty;
|
||||
|
||||
else
|
||||
-- This status is never returned on IVMS
|
||||
|
||||
Status := Fail_No_Lock;
|
||||
end if;
|
||||
|
||||
end Remqhi;
|
||||
|
||||
------------
|
||||
-- Insqti --
|
||||
------------
|
||||
|
||||
procedure Insqti
|
||||
(Item : Address;
|
||||
Header : Address;
|
||||
Status : out Insq_Status) is
|
||||
|
||||
procedure SYS_PAL_INSQTIL
|
||||
(STATUS : out Integer; Header : Address; ITEM : Address);
|
||||
pragma Interface (External, SYS_PAL_INSQTIL);
|
||||
pragma Import_Valued_Procedure (SYS_PAL_INSQTIL, "SYS$PAL_INSQTIL",
|
||||
(Integer, Address, Address),
|
||||
(Value, Value, Value));
|
||||
|
||||
Istat : Integer;
|
||||
|
||||
begin
|
||||
SYS_PAL_INSQTIL (Istat, Header, Item);
|
||||
|
||||
if Istat = 0 then
|
||||
Status := OK_Not_First;
|
||||
|
||||
elsif Istat = 1 then
|
||||
Status := OK_First;
|
||||
|
||||
else
|
||||
-- This status is never returned on IVMS
|
||||
|
||||
Status := Fail_No_Lock;
|
||||
end if;
|
||||
end Insqti;
|
||||
|
||||
------------
|
||||
-- Remqti --
|
||||
------------
|
||||
|
||||
procedure Remqti
|
||||
(Header : Address;
|
||||
Item : out Address;
|
||||
Status : out Remq_Status)
|
||||
is
|
||||
-- The removed item is returned in the second function return register,
|
||||
-- R9 on IVMS. The VMS ABI calls for "small" records to be returned in
|
||||
-- these registers, so inventing (where is rest of this comment???)
|
||||
|
||||
type Remq is record
|
||||
Status : Long_Integer;
|
||||
Item : Address;
|
||||
end record;
|
||||
|
||||
procedure SYS_PAL_REMQTIL
|
||||
(Remret : out Remq; Header : Address);
|
||||
pragma Interface (External, SYS_PAL_REMQTIL);
|
||||
pragma Import_Valued_Procedure (SYS_PAL_REMQTIL, "SYS$PAL_REMQTIL",
|
||||
(Remq, Address),
|
||||
(Value, Value));
|
||||
|
||||
Rstat : Long_Integer;
|
||||
Remret : Remq;
|
||||
|
||||
begin
|
||||
SYS_PAL_REMQTIL (Remret, Header);
|
||||
|
||||
Rstat := Remret.Status;
|
||||
Item := Remret.Item;
|
||||
|
||||
-- Wouldn't case be nicer here, and in previous similar cases ???
|
||||
|
||||
if Rstat = 0 then
|
||||
Status := Fail_Was_Empty;
|
||||
|
||||
elsif Rstat = 1 then
|
||||
Status := OK_Not_Empty;
|
||||
|
||||
elsif Rstat = 2 then
|
||||
Status := OK_Empty;
|
||||
else
|
||||
-- This status is never returned on IVMS
|
||||
|
||||
Status := Fail_No_Lock;
|
||||
end if;
|
||||
end Remqti;
|
||||
|
||||
end System.Aux_DEC;
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT RUN-TIME COMPONENTS --
|
||||
-- --
|
||||
-- S Y S T E M . M E M O R Y --
|
||||
-- --
|
||||
-- B o d y --
|
||||
-- --
|
||||
-- Copyright (C) 2001-2010, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNAT was originally developed by the GNAT team at New York University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- This is the VMS 64 bit implementation of this package
|
||||
|
||||
-- This implementation assumes that the underlying malloc/free/realloc
|
||||
-- implementation is thread safe, and thus, no additional lock is required.
|
||||
-- Note that we still need to defer abort because on most systems, an
|
||||
-- asynchronous signal (as used for implementing asynchronous abort of
|
||||
-- task) cannot safely be handled while malloc is executing.
|
||||
|
||||
-- If you are not using Ada constructs containing the "abort" keyword, then
|
||||
-- you can remove the calls to Abort_Defer.all and Abort_Undefer.all from
|
||||
-- this unit.
|
||||
|
||||
pragma Compiler_Unit;
|
||||
|
||||
with Ada.Exceptions;
|
||||
with System.Soft_Links;
|
||||
with System.Parameters;
|
||||
with System.CRTL;
|
||||
|
||||
package body System.Memory is
|
||||
|
||||
use Ada.Exceptions;
|
||||
use System.Soft_Links;
|
||||
|
||||
function c_malloc (Size : System.CRTL.size_t) return System.Address
|
||||
renames System.CRTL.malloc;
|
||||
|
||||
procedure c_free (Ptr : System.Address)
|
||||
renames System.CRTL.free;
|
||||
|
||||
function c_realloc
|
||||
(Ptr : System.Address; Size : System.CRTL.size_t) return System.Address
|
||||
renames System.CRTL.realloc;
|
||||
|
||||
Gnat_Heap_Size : Integer;
|
||||
pragma Import (C, Gnat_Heap_Size, "__gl_heap_size");
|
||||
-- Set by Feature logical GNAT$NO_MALLOC_64 and/or Binder switch -Hnn
|
||||
|
||||
-----------
|
||||
-- Alloc --
|
||||
-----------
|
||||
|
||||
function Alloc (Size : size_t) return System.Address is
|
||||
Result : System.Address;
|
||||
Actual_Size : size_t := Size;
|
||||
|
||||
begin
|
||||
if Gnat_Heap_Size = 32 then
|
||||
return Alloc32 (Size);
|
||||
end if;
|
||||
|
||||
if Size = size_t'Last then
|
||||
Raise_Exception (Storage_Error'Identity, "object too large");
|
||||
end if;
|
||||
|
||||
-- Change size from zero to non-zero. We still want a proper pointer
|
||||
-- for the zero case because pointers to zero length objects have to
|
||||
-- be distinct, but we can't just go ahead and allocate zero bytes,
|
||||
-- since some malloc's return zero for a zero argument.
|
||||
|
||||
if Size = 0 then
|
||||
Actual_Size := 1;
|
||||
end if;
|
||||
|
||||
if Parameters.No_Abort then
|
||||
Result := c_malloc (System.CRTL.size_t (Actual_Size));
|
||||
else
|
||||
Abort_Defer.all;
|
||||
Result := c_malloc (System.CRTL.size_t (Actual_Size));
|
||||
Abort_Undefer.all;
|
||||
end if;
|
||||
|
||||
if Result = System.Null_Address then
|
||||
Raise_Exception (Storage_Error'Identity, "heap exhausted");
|
||||
end if;
|
||||
|
||||
return Result;
|
||||
end Alloc;
|
||||
|
||||
-------------
|
||||
-- Alloc32 --
|
||||
-------------
|
||||
|
||||
function Alloc32 (Size : size_t) return System.Address is
|
||||
Result : System.Address;
|
||||
Actual_Size : size_t := Size;
|
||||
|
||||
begin
|
||||
if Size = size_t'Last then
|
||||
Raise_Exception (Storage_Error'Identity, "object too large");
|
||||
end if;
|
||||
|
||||
-- Change size from zero to non-zero. We still want a proper pointer
|
||||
-- for the zero case because pointers to zero length objects have to
|
||||
-- be distinct, but we can't just go ahead and allocate zero bytes,
|
||||
-- since some malloc's return zero for a zero argument.
|
||||
|
||||
if Size = 0 then
|
||||
Actual_Size := 1;
|
||||
end if;
|
||||
|
||||
if Parameters.No_Abort then
|
||||
Result := C_malloc32 (Actual_Size);
|
||||
else
|
||||
Abort_Defer.all;
|
||||
Result := C_malloc32 (Actual_Size);
|
||||
Abort_Undefer.all;
|
||||
end if;
|
||||
|
||||
if Result = System.Null_Address then
|
||||
Raise_Exception (Storage_Error'Identity, "heap exhausted");
|
||||
end if;
|
||||
|
||||
return Result;
|
||||
end Alloc32;
|
||||
|
||||
----------
|
||||
-- Free --
|
||||
----------
|
||||
|
||||
procedure Free (Ptr : System.Address) is
|
||||
begin
|
||||
if Parameters.No_Abort then
|
||||
c_free (Ptr);
|
||||
else
|
||||
Abort_Defer.all;
|
||||
c_free (Ptr);
|
||||
Abort_Undefer.all;
|
||||
end if;
|
||||
end Free;
|
||||
|
||||
-------------
|
||||
-- Realloc --
|
||||
-------------
|
||||
|
||||
function Realloc
|
||||
(Ptr : System.Address;
|
||||
Size : size_t)
|
||||
return System.Address
|
||||
is
|
||||
Result : System.Address;
|
||||
Actual_Size : constant size_t := Size;
|
||||
|
||||
begin
|
||||
if Gnat_Heap_Size = 32 then
|
||||
return Realloc32 (Ptr, Size);
|
||||
end if;
|
||||
|
||||
if Size = size_t'Last then
|
||||
Raise_Exception (Storage_Error'Identity, "object too large");
|
||||
end if;
|
||||
|
||||
if Parameters.No_Abort then
|
||||
Result := c_realloc (Ptr, System.CRTL.size_t (Actual_Size));
|
||||
else
|
||||
Abort_Defer.all;
|
||||
Result := c_realloc (Ptr, System.CRTL.size_t (Actual_Size));
|
||||
Abort_Undefer.all;
|
||||
end if;
|
||||
|
||||
if Result = System.Null_Address then
|
||||
Raise_Exception (Storage_Error'Identity, "heap exhausted");
|
||||
end if;
|
||||
|
||||
return Result;
|
||||
end Realloc;
|
||||
|
||||
---------------
|
||||
-- Realloc32 --
|
||||
---------------
|
||||
|
||||
function Realloc32
|
||||
(Ptr : System.Address;
|
||||
Size : size_t)
|
||||
return System.Address
|
||||
is
|
||||
Result : System.Address;
|
||||
Actual_Size : constant size_t := Size;
|
||||
|
||||
begin
|
||||
if Size = size_t'Last then
|
||||
Raise_Exception (Storage_Error'Identity, "object too large");
|
||||
end if;
|
||||
|
||||
if Parameters.No_Abort then
|
||||
Result := C_realloc32 (Ptr, Actual_Size);
|
||||
else
|
||||
Abort_Defer.all;
|
||||
Result := C_realloc32 (Ptr, Actual_Size);
|
||||
Abort_Undefer.all;
|
||||
end if;
|
||||
|
||||
if Result = System.Null_Address then
|
||||
Raise_Exception (Storage_Error'Identity, "heap exhausted");
|
||||
end if;
|
||||
|
||||
return Result;
|
||||
end Realloc32;
|
||||
end System.Memory;
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT RUN-TIME COMPONENTS --
|
||||
-- --
|
||||
-- S Y S T E M . M E M O R Y --
|
||||
-- --
|
||||
-- S p e c --
|
||||
-- --
|
||||
-- Copyright (C) 2001-2010, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNAT was originally developed by the GNAT team at New York University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- This package provides the low level memory allocation/deallocation
|
||||
-- mechanisms used by GNAT for VMS 64 bit.
|
||||
|
||||
-- To provide an alternate implementation, simply recompile the modified
|
||||
-- body of this package with gnatmake -u -a -g s-memory.adb and make sure
|
||||
-- that the ali and object files for this unit are found in the object
|
||||
-- search path.
|
||||
|
||||
-- This unit may be used directly from an application program by providing
|
||||
-- an appropriate WITH, and the interface can be expected to remain stable.
|
||||
|
||||
pragma Compiler_Unit;
|
||||
|
||||
package System.Memory is
|
||||
pragma Elaborate_Body;
|
||||
|
||||
type size_t is mod 2 ** Standard'Address_Size;
|
||||
-- Note: the reason we redefine this here instead of using the
|
||||
-- definition in Interfaces.C is that we do not want to drag in
|
||||
-- all of Interfaces.C just because System.Memory is used.
|
||||
|
||||
function Alloc (Size : size_t) return System.Address;
|
||||
-- This is the low level allocation routine. Given a size in storage
|
||||
-- units, it returns the address of a maximally aligned block of
|
||||
-- memory. The implementation of this routine is guaranteed to be
|
||||
-- task safe, and also aborts are deferred if necessary.
|
||||
--
|
||||
-- If size_t is set to size_t'Last on entry, then a Storage_Error
|
||||
-- exception is raised with a message "object too large".
|
||||
--
|
||||
-- If size_t is set to zero on entry, then a minimal (but non-zero)
|
||||
-- size block is allocated.
|
||||
--
|
||||
-- Note: this is roughly equivalent to the standard C malloc call
|
||||
-- with the additional semantics as described above.
|
||||
|
||||
function Alloc32 (Size : size_t) return System.Address;
|
||||
-- Equivalent to Alloc except on VMS 64 bit where it invokes
|
||||
-- 32 bit malloc.
|
||||
|
||||
procedure Free (Ptr : System.Address);
|
||||
-- This is the low level free routine. It frees a block previously
|
||||
-- allocated with a call to Alloc. As in the case of Alloc, this
|
||||
-- call is guaranteed task safe, and aborts are deferred.
|
||||
--
|
||||
-- Note: this is roughly equivalent to the standard C free call
|
||||
-- with the additional semantics as described above.
|
||||
|
||||
function Realloc
|
||||
(Ptr : System.Address;
|
||||
Size : size_t) return System.Address;
|
||||
-- This is the low level reallocation routine. It takes an existing
|
||||
-- block address returned by a previous call to Alloc or Realloc,
|
||||
-- and reallocates the block. The size can either be increased or
|
||||
-- decreased. If possible the reallocation is done in place, so that
|
||||
-- the returned result is the same as the value of Ptr on entry.
|
||||
-- However, it may be necessary to relocate the block to another
|
||||
-- address, in which case the information is copied to the new
|
||||
-- block, and the old block is freed. The implementation of this
|
||||
-- routine is guaranteed to be task safe, and also aborts are
|
||||
-- deferred as necessary.
|
||||
--
|
||||
-- If size_t is set to size_t'Last on entry, then a Storage_Error
|
||||
-- exception is raised with a message "object too large".
|
||||
--
|
||||
-- If size_t is set to zero on entry, then a minimal (but non-zero)
|
||||
-- size block is allocated.
|
||||
--
|
||||
-- Note: this is roughly equivalent to the standard C realloc call
|
||||
-- with the additional semantics as described above.
|
||||
|
||||
function Realloc32
|
||||
(Ptr : System.Address;
|
||||
Size : size_t) return System.Address;
|
||||
-- Equivalent to Realloc except on VMS 64 bit where it invokes
|
||||
-- 32 bit realloc.
|
||||
|
||||
private
|
||||
|
||||
-- The following names are used from the generated compiler code
|
||||
|
||||
pragma Export (C, Alloc, "__gnat_malloc");
|
||||
pragma Export (C, Alloc32, "__gnat_malloc32");
|
||||
pragma Export (C, Free, "__gnat_free");
|
||||
pragma Export (C, Realloc, "__gnat_realloc");
|
||||
pragma Export (C, Realloc32, "__gnat_realloc32");
|
||||
|
||||
function C_malloc32 (Size : size_t) return System.Address;
|
||||
pragma Import (C, C_malloc32, "_malloc32");
|
||||
-- An alias for malloc for allocating 32bit memory on 64bit VMS
|
||||
|
||||
function C_realloc32
|
||||
(Ptr : System.Address;
|
||||
Size : size_t) return System.Address;
|
||||
pragma Import (C, C_realloc32, "_realloc32");
|
||||
-- An alias for realloc for allocating 32bit memory on 64bit VMS
|
||||
|
||||
end System.Memory;
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
|
||||
-- --
|
||||
-- S Y S T E M . O S _ I N T E R F A C E --
|
||||
-- --
|
||||
-- B o d y --
|
||||
-- --
|
||||
-- Copyright (C) 2003-2010, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNARL was developed by the GNARL team at Florida State University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies, Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- This is a OpenVMS/IA64 version of this package
|
||||
|
||||
-- This package encapsulates all direct interfaces to OS services
|
||||
-- that are needed by children of System.
|
||||
|
||||
pragma Polling (Off);
|
||||
-- Turn off polling, we do not want ATC polling to take place during
|
||||
-- tasking operations. It causes infinite loops and other problems.
|
||||
|
||||
with Interfaces.C; use Interfaces.C;
|
||||
|
||||
package body System.OS_Interface is
|
||||
|
||||
-----------------
|
||||
-- sched_yield --
|
||||
-----------------
|
||||
|
||||
function sched_yield return int is
|
||||
procedure sched_yield_base;
|
||||
pragma Import (C, sched_yield_base, "PTHREAD_YIELD_NP");
|
||||
|
||||
begin
|
||||
sched_yield_base;
|
||||
return 0;
|
||||
end sched_yield;
|
||||
|
||||
end System.OS_Interface;
|
||||
|
|
@ -0,0 +1,652 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
|
||||
-- --
|
||||
-- S Y S T E M . O S _ I N T E R F A C E --
|
||||
-- --
|
||||
-- S p e c --
|
||||
-- --
|
||||
-- Copyright (C) 1991-1994, Florida State University --
|
||||
-- Copyright (C) 1995-2010, Free Software Foundation, Inc. --
|
||||
-- --
|
||||
-- GNAT is free software; you can redistribute it and/or modify it under --
|
||||
-- terms of the GNU General Public License as published by the Free Soft- --
|
||||
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
||||
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
||||
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. --
|
||||
-- --
|
||||
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
||||
-- additional permissions described in the GCC Runtime Library Exception, --
|
||||
-- version 3.1, as published by the Free Software Foundation. --
|
||||
-- --
|
||||
-- You should have received a copy of the GNU General Public License and --
|
||||
-- a copy of the GCC Runtime Library Exception along with this program; --
|
||||
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
||||
-- <http://www.gnu.org/licenses/>. --
|
||||
-- --
|
||||
-- GNARL was developed by the GNARL team at Florida State University. --
|
||||
-- Extensive contributions were provided by Ada Core Technologies, Inc. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- This is a OpenVMS/IA64 version of this package
|
||||
|
||||
-- This package encapsulates all direct interfaces to OS services
|
||||
-- that are needed by the tasking run-time (libgnarl).
|
||||
|
||||
-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
|
||||
-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
|
||||
|
||||
with Interfaces.C;
|
||||
|
||||
with Ada.Unchecked_Conversion;
|
||||
|
||||
with System.Aux_DEC;
|
||||
|
||||
package System.OS_Interface is
|
||||
pragma Preelaborate;
|
||||
|
||||
pragma Linker_Options ("--for-linker=ia64$library:pthread$rtl.exe");
|
||||
-- Link in the DEC threads library
|
||||
|
||||
-- pragma Linker_Options ("--for-linker=/threads_enable");
|
||||
-- Enable upcalls and multiple kernel threads.
|
||||
|
||||
subtype int is Interfaces.C.int;
|
||||
subtype short is Interfaces.C.short;
|
||||
subtype long is Interfaces.C.long;
|
||||
subtype unsigned is Interfaces.C.unsigned;
|
||||
subtype unsigned_short is Interfaces.C.unsigned_short;
|
||||
subtype unsigned_long is Interfaces.C.unsigned_long;
|
||||
subtype unsigned_char is Interfaces.C.unsigned_char;
|
||||
subtype plain_char is Interfaces.C.plain_char;
|
||||
subtype size_t is Interfaces.C.size_t;
|
||||
|
||||
-----------------------------
|
||||
-- Signals (Interrupt IDs) --
|
||||
-----------------------------
|
||||
|
||||
-- Type signal has an arbitrary limit of 31
|
||||
|
||||
Max_Interrupt : constant := 31;
|
||||
type Signal is new unsigned range 0 .. Max_Interrupt;
|
||||
for Signal'Size use unsigned'Size;
|
||||
|
||||
type sigset_t is array (Signal) of Boolean;
|
||||
pragma Pack (sigset_t);
|
||||
|
||||
-- Interrupt_Number_Type
|
||||
-- Unsigned long integer denoting the number of an interrupt
|
||||
|
||||
subtype Interrupt_Number_Type is unsigned_long;
|
||||
|
||||
-- OpenVMS system services return values of type Cond_Value_Type
|
||||
|
||||
subtype Cond_Value_Type is unsigned_long;
|
||||
subtype Short_Cond_Value_Type is unsigned_short;
|
||||
|
||||
type IO_Status_Block_Type is record
|
||||
Status : Short_Cond_Value_Type;
|
||||
Count : unsigned_short;
|
||||
Dev_Info : unsigned_long;
|
||||
end record;
|
||||
|
||||
type AST_Handler is access procedure (Param : Address);
|
||||
pragma Convention (C, AST_Handler);
|
||||
No_AST_Handler : constant AST_Handler := null;
|
||||
|
||||
CMB_M_READONLY : constant := 16#00000001#;
|
||||
CMB_M_WRITEONLY : constant := 16#00000002#;
|
||||
AGN_M_READONLY : constant := 16#00000001#;
|
||||
AGN_M_WRITEONLY : constant := 16#00000002#;
|
||||
|
||||
IO_WRITEVBLK : constant := 48; -- WRITE VIRTUAL BLOCK
|
||||
IO_READVBLK : constant := 49; -- READ VIRTUAL BLOCK
|
||||
|
||||
----------------
|
||||
-- Sys_Assign --
|
||||
----------------
|
||||
--
|
||||
-- Assign I/O Channel
|
||||
--
|
||||
-- Status = returned status
|
||||
-- Devnam = address of device name or logical name string
|
||||
-- descriptor
|
||||
-- Chan = address of word to receive channel number assigned
|
||||
-- Acmode = access mode associated with channel
|
||||
-- Mbxnam = address of mailbox logical name string descriptor, if
|
||||
-- mailbox associated with device
|
||||
-- Flags = optional channel flags longword for specifying options
|
||||
-- for the $ASSIGN operation
|
||||
--
|
||||
|
||||
procedure Sys_Assign
|
||||
(Status : out Cond_Value_Type;
|
||||
Devnam : String;
|
||||
Chan : out unsigned_short;
|
||||
Acmode : unsigned_short := 0;
|
||||
Mbxnam : String := String'Null_Parameter;
|
||||
Flags : unsigned_long := 0);
|
||||
pragma Interface (External, Sys_Assign);
|
||||
pragma Import_Valued_Procedure
|
||||
(Sys_Assign, "SYS$ASSIGN",
|
||||
(Cond_Value_Type, String, unsigned_short,
|
||||
unsigned_short, String, unsigned_long),
|
||||
(Value, Descriptor (s), Reference,
|
||||
Value, Descriptor (s), Value),
|
||||
Flags);
|
||||
|
||||
----------------
|
||||
-- Sys_Cantim --
|
||||
----------------
|
||||
--
|
||||
-- Cancel Timer
|
||||
--
|
||||
-- Status = returned status
|
||||
-- Reqidt = ID of timer to be cancelled
|
||||
-- Acmode = Access mode
|
||||
--
|
||||
procedure Sys_Cantim
|
||||
(Status : out Cond_Value_Type;
|
||||
Reqidt : Address;
|
||||
Acmode : unsigned);
|
||||
pragma Interface (External, Sys_Cantim);
|
||||
pragma Import_Valued_Procedure
|
||||
(Sys_Cantim, "SYS$CANTIM",
|
||||
(Cond_Value_Type, Address, unsigned),
|
||||
(Value, Value, Value));
|
||||
|
||||
----------------
|
||||
-- Sys_Crembx --
|
||||
----------------
|
||||
--
|
||||
-- Create mailbox
|
||||
--
|
||||
-- Status = returned status
|
||||
-- Prmflg = permanent flag
|
||||
-- Chan = channel
|
||||
-- Maxmsg = maximum message
|
||||
-- Bufquo = buufer quote
|
||||
-- Promsk = protection mast
|
||||
-- Acmode = access mode
|
||||
-- Lognam = logical name
|
||||
-- Flags = flags
|
||||
--
|
||||
procedure Sys_Crembx
|
||||
(Status : out Cond_Value_Type;
|
||||
Prmflg : unsigned_char;
|
||||
Chan : out unsigned_short;
|
||||
Maxmsg : unsigned_long := 0;
|
||||
Bufquo : unsigned_long := 0;
|
||||
Promsk : unsigned_short := 0;
|
||||
Acmode : unsigned_short := 0;
|
||||
Lognam : String;
|
||||
Flags : unsigned_long := 0);
|
||||
pragma Interface (External, Sys_Crembx);
|
||||
pragma Import_Valued_Procedure
|
||||
(Sys_Crembx, "SYS$CREMBX",
|
||||
(Cond_Value_Type, unsigned_char, unsigned_short,
|
||||
unsigned_long, unsigned_long, unsigned_short,
|
||||
unsigned_short, String, unsigned_long),
|
||||
(Value, Value, Reference,
|
||||
Value, Value, Value,
|
||||
Value, Descriptor (s), Value));
|
||||
|
||||
-------------
|
||||
-- Sys_QIO --
|
||||
-------------
|
||||
--
|
||||
-- Queue I/O
|
||||
--
|
||||
-- Status = Returned status of call
|
||||
-- EFN = event flag to be set when I/O completes
|
||||
-- Chan = channel
|
||||
-- Func = function
|
||||
-- Iosb = I/O status block
|
||||
-- Astadr = system trap to be generated when I/O completes
|
||||
-- Astprm = AST parameter
|
||||
-- P1-6 = optional parameters
|
||||
|
||||
procedure Sys_QIO
|
||||
(Status : out Cond_Value_Type;
|
||||
EFN : unsigned_long := 0;
|
||||
Chan : unsigned_short;
|
||||
Func : unsigned_long := 0;
|
||||
Iosb : out IO_Status_Block_Type;
|
||||
Astadr : AST_Handler := No_AST_Handler;
|
||||
Astprm : Address := Null_Address;
|
||||
P1 : unsigned_long := 0;
|
||||
P2 : unsigned_long := 0;
|
||||
P3 : unsigned_long := 0;
|
||||
P4 : unsigned_long := 0;
|
||||
P5 : unsigned_long := 0;
|
||||
P6 : unsigned_long := 0);
|
||||
|
||||
procedure Sys_QIO
|
||||
(Status : out Cond_Value_Type;
|
||||
EFN : unsigned_long := 0;
|
||||
Chan : unsigned_short;
|
||||
Func : unsigned_long := 0;
|
||||
Iosb : Address := Null_Address;
|
||||
Astadr : AST_Handler := No_AST_Handler;
|
||||
Astprm : Address := Null_Address;
|
||||
P1 : unsigned_long := 0;
|
||||
P2 : unsigned_long := 0;
|
||||
P3 : unsigned_long := 0;
|
||||
P4 : unsigned_long := 0;
|
||||
P5 : unsigned_long := 0;
|
||||
P6 : unsigned_long := 0);
|
||||
|
||||
pragma Interface (External, Sys_QIO);
|
||||
pragma Import_Valued_Procedure
|
||||
(Sys_QIO, "SYS$QIO",
|
||||
(Cond_Value_Type, unsigned_long, unsigned_short, unsigned_long,
|
||||
IO_Status_Block_Type, AST_Handler, Address,
|
||||
unsigned_long, unsigned_long, unsigned_long,
|
||||
unsigned_long, unsigned_long, unsigned_long),
|
||||
(Value, Value, Value, Value,
|
||||
Reference, Value, Value,
|
||||
Value, Value, Value,
|
||||
Value, Value, Value));
|
||||
|
||||
pragma Import_Valued_Procedure
|
||||
(Sys_QIO, "SYS$QIO",
|
||||
(Cond_Value_Type, unsigned_long, unsigned_short, unsigned_long,
|
||||
Address, AST_Handler, Address,
|
||||
unsigned_long, unsigned_long, unsigned_long,
|
||||
unsigned_long, unsigned_long, unsigned_long),
|
||||
(Value, Value, Value, Value,
|
||||
Value, Value, Value,
|
||||
Value, Value, Value,
|
||||
Value, Value, Value));
|
||||
|
||||
----------------
|
||||
-- Sys_Setimr --
|
||||
----------------
|
||||
--
|
||||
-- Set Timer
|
||||
--
|
||||
-- Status = Returned status of call
|
||||
-- EFN = event flag to be set when timer expires
|
||||
-- Tim = expiration time
|
||||
-- AST = system trap to be generated when timer expires
|
||||
-- Redidt = returned ID of timer (e.g. to cancel timer)
|
||||
-- Flags = flags
|
||||
--
|
||||
procedure Sys_Setimr
|
||||
(Status : out Cond_Value_Type;
|
||||
EFN : unsigned_long;
|
||||
Tim : Long_Integer;
|
||||
AST : AST_Handler;
|
||||
Reqidt : Address;
|
||||
Flags : unsigned_long);
|
||||
pragma Interface (External, Sys_Setimr);
|
||||
pragma Import_Valued_Procedure
|
||||
(Sys_Setimr, "SYS$SETIMR",
|
||||
(Cond_Value_Type, unsigned_long, Long_Integer,
|
||||
AST_Handler, Address, unsigned_long),
|
||||
(Value, Value, Reference,
|
||||
Value, Value, Value));
|
||||
|
||||
Interrupt_ID_0 : constant := 0;
|
||||
Interrupt_ID_1 : constant := 1;
|
||||
Interrupt_ID_2 : constant := 2;
|
||||
Interrupt_ID_3 : constant := 3;
|
||||
Interrupt_ID_4 : constant := 4;
|
||||
Interrupt_ID_5 : constant := 5;
|
||||
Interrupt_ID_6 : constant := 6;
|
||||
Interrupt_ID_7 : constant := 7;
|
||||
Interrupt_ID_8 : constant := 8;
|
||||
Interrupt_ID_9 : constant := 9;
|
||||
Interrupt_ID_10 : constant := 10;
|
||||
Interrupt_ID_11 : constant := 11;
|
||||
Interrupt_ID_12 : constant := 12;
|
||||
Interrupt_ID_13 : constant := 13;
|
||||
Interrupt_ID_14 : constant := 14;
|
||||
Interrupt_ID_15 : constant := 15;
|
||||
Interrupt_ID_16 : constant := 16;
|
||||
Interrupt_ID_17 : constant := 17;
|
||||
Interrupt_ID_18 : constant := 18;
|
||||
Interrupt_ID_19 : constant := 19;
|
||||
Interrupt_ID_20 : constant := 20;
|
||||
Interrupt_ID_21 : constant := 21;
|
||||
Interrupt_ID_22 : constant := 22;
|
||||
Interrupt_ID_23 : constant := 23;
|
||||
Interrupt_ID_24 : constant := 24;
|
||||
Interrupt_ID_25 : constant := 25;
|
||||
Interrupt_ID_26 : constant := 26;
|
||||
Interrupt_ID_27 : constant := 27;
|
||||
Interrupt_ID_28 : constant := 28;
|
||||
Interrupt_ID_29 : constant := 29;
|
||||
Interrupt_ID_30 : constant := 30;
|
||||
Interrupt_ID_31 : constant := 31;
|
||||
|
||||
-----------
|
||||
-- Errno --
|
||||
-----------
|
||||
|
||||
function errno return int;
|
||||
pragma Import (C, errno, "__get_errno");
|
||||
|
||||
EINTR : constant := 4; -- Interrupted system call
|
||||
EAGAIN : constant := 11; -- No more processes
|
||||
ENOMEM : constant := 12; -- Not enough core
|
||||
|
||||
-------------------------
|
||||
-- Priority Scheduling --
|
||||
-------------------------
|
||||
|
||||
SCHED_FIFO : constant := 1;
|
||||
SCHED_RR : constant := 2;
|
||||
SCHED_OTHER : constant := 3;
|
||||
SCHED_BG : constant := 4;
|
||||
SCHED_LFI : constant := 5;
|
||||
SCHED_LRR : constant := 6;
|
||||
|
||||
-------------
|
||||
-- Process --
|
||||
-------------
|
||||
|
||||
type pid_t is private;
|
||||
|
||||
function kill (pid : pid_t; sig : Signal) return int;
|
||||
pragma Import (C, kill);
|
||||
|
||||
function getpid return pid_t;
|
||||
pragma Import (C, getpid);
|
||||
|
||||
-------------
|
||||
-- Threads --
|
||||
-------------
|
||||
|
||||
type Thread_Body is access
|
||||
function (arg : System.Address) return System.Address;
|
||||
pragma Convention (C, Thread_Body);
|
||||
|
||||
function Thread_Body_Access is new
|
||||
Ada.Unchecked_Conversion (System.Aux_DEC.Short_Address, Thread_Body);
|
||||
|
||||
type pthread_t is private;
|
||||
subtype Thread_Id is pthread_t;
|
||||
|
||||
type pthread_mutex_t is limited private;
|
||||
type pthread_cond_t is limited private;
|
||||
type pthread_attr_t is limited private;
|
||||
type pthread_mutexattr_t is limited private;
|
||||
type pthread_condattr_t is limited private;
|
||||
type pthread_key_t is private;
|
||||
|
||||
PTHREAD_CREATE_JOINABLE : constant := 0;
|
||||
PTHREAD_CREATE_DETACHED : constant := 1;
|
||||
|
||||
PTHREAD_CANCEL_DISABLE : constant := 0;
|
||||
PTHREAD_CANCEL_ENABLE : constant := 1;
|
||||
|
||||
PTHREAD_CANCEL_DEFERRED : constant := 0;
|
||||
PTHREAD_CANCEL_ASYNCHRONOUS : constant := 1;
|
||||
|
||||
-- Don't use ERRORCHECK mutexes, they don't work when a thread is not
|
||||
-- the owner. AST's, at least, unlock others threads mutexes. Even
|
||||
-- if the error is ignored, they don't work.
|
||||
PTHREAD_MUTEX_NORMAL_NP : constant := 0;
|
||||
PTHREAD_MUTEX_RECURSIVE_NP : constant := 1;
|
||||
PTHREAD_MUTEX_ERRORCHECK_NP : constant := 2;
|
||||
|
||||
PTHREAD_INHERIT_SCHED : constant := 0;
|
||||
PTHREAD_EXPLICIT_SCHED : constant := 1;
|
||||
|
||||
function pthread_cancel (thread : pthread_t) return int;
|
||||
pragma Import (C, pthread_cancel, "PTHREAD_CANCEL");
|
||||
|
||||
procedure pthread_testcancel;
|
||||
pragma Import (C, pthread_testcancel, "PTHREAD_TESTCANCEL");
|
||||
|
||||
function pthread_setcancelstate
|
||||
(newstate : int; oldstate : access int) return int;
|
||||
pragma Import (C, pthread_setcancelstate, "PTHREAD_SETCANCELSTATE");
|
||||
|
||||
function pthread_setcanceltype
|
||||
(newtype : int; oldtype : access int) return int;
|
||||
pragma Import (C, pthread_setcanceltype, "PTHREAD_SETCANCELTYPE");
|
||||
|
||||
-------------------------
|
||||
-- POSIX.1c Section 3 --
|
||||
-------------------------
|
||||
|
||||
function pthread_lock_global_np return int;
|
||||
pragma Import (C, pthread_lock_global_np, "PTHREAD_LOCK_GLOBAL_NP");
|
||||
|
||||
function pthread_unlock_global_np return int;
|
||||
pragma Import (C, pthread_unlock_global_np, "PTHREAD_UNLOCK_GLOBAL_NP");
|
||||
|
||||
--------------------------
|
||||
-- POSIX.1c Section 11 --
|
||||
--------------------------
|
||||
|
||||
function pthread_mutexattr_init
|
||||
(attr : access pthread_mutexattr_t) return int;
|
||||
pragma Import (C, pthread_mutexattr_init, "PTHREAD_MUTEXATTR_INIT");
|
||||
|
||||
function pthread_mutexattr_destroy
|
||||
(attr : access pthread_mutexattr_t) return int;
|
||||
pragma Import (C, pthread_mutexattr_destroy, "PTHREAD_MUTEXATTR_DESTROY");
|
||||
|
||||
function pthread_mutexattr_settype_np
|
||||
(attr : access pthread_mutexattr_t;
|
||||
mutextype : int) return int;
|
||||
pragma Import (C, pthread_mutexattr_settype_np,
|
||||
"PTHREAD_MUTEXATTR_SETTYPE_NP");
|
||||
|
||||
function pthread_mutex_init
|
||||
(mutex : access pthread_mutex_t;
|
||||
attr : access pthread_mutexattr_t) return int;
|
||||
pragma Import (C, pthread_mutex_init, "PTHREAD_MUTEX_INIT");
|
||||
|
||||
function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
|
||||
pragma Import (C, pthread_mutex_destroy, "PTHREAD_MUTEX_DESTROY");
|
||||
|
||||
function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
|
||||
pragma Import (C, pthread_mutex_lock, "PTHREAD_MUTEX_LOCK");
|
||||
|
||||
function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
|
||||
pragma Import (C, pthread_mutex_unlock, "PTHREAD_MUTEX_UNLOCK");
|
||||
|
||||
function pthread_condattr_init
|
||||
(attr : access pthread_condattr_t) return int;
|
||||
pragma Import (C, pthread_condattr_init, "PTHREAD_CONDATTR_INIT");
|
||||
|
||||
function pthread_condattr_destroy
|
||||
(attr : access pthread_condattr_t) return int;
|
||||
pragma Import (C, pthread_condattr_destroy, "PTHREAD_CONDATTR_DESTROY");
|
||||
|
||||
function pthread_cond_init
|
||||
(cond : access pthread_cond_t;
|
||||
attr : access pthread_condattr_t) return int;
|
||||
pragma Import (C, pthread_cond_init, "PTHREAD_COND_INIT");
|
||||
|
||||
function pthread_cond_destroy (cond : access pthread_cond_t) return int;
|
||||
pragma Import (C, pthread_cond_destroy, "PTHREAD_COND_DESTROY");
|
||||
|
||||
function pthread_cond_signal (cond : access pthread_cond_t) return int;
|
||||
pragma Import (C, pthread_cond_signal, "PTHREAD_COND_SIGNAL");
|
||||
|
||||
function pthread_cond_signal_int_np
|
||||
(cond : access pthread_cond_t) return int;
|
||||
pragma Import (C, pthread_cond_signal_int_np,
|
||||
"PTHREAD_COND_SIGNAL_INT_NP");
|
||||
|
||||
function pthread_cond_wait
|
||||
(cond : access pthread_cond_t;
|
||||
mutex : access pthread_mutex_t) return int;
|
||||
pragma Import (C, pthread_cond_wait, "PTHREAD_COND_WAIT");
|
||||
|
||||
--------------------------
|
||||
-- POSIX.1c Section 13 --
|
||||
--------------------------
|
||||
|
||||
function pthread_mutexattr_setprotocol
|
||||
(attr : access pthread_mutexattr_t; protocol : int) return int;
|
||||
pragma Import (C, pthread_mutexattr_setprotocol,
|
||||
"PTHREAD_MUTEXATTR_SETPROTOCOL");
|
||||
|
||||
type struct_sched_param is record
|
||||
sched_priority : int; -- scheduling priority
|
||||
end record;
|
||||
for struct_sched_param'Size use 8*4;
|
||||
pragma Convention (C, struct_sched_param);
|
||||
|
||||
function pthread_setschedparam
|
||||
(thread : pthread_t;
|
||||
policy : int;
|
||||
param : access struct_sched_param) return int;
|
||||
pragma Import (C, pthread_setschedparam, "PTHREAD_SETSCHEDPARAM");
|
||||
|
||||
function pthread_attr_setscope
|
||||
(attr : access pthread_attr_t;
|
||||
contentionscope : int) return int;
|
||||
pragma Import (C, pthread_attr_setscope, "PTHREAD_ATTR_SETSCOPE");
|
||||
|
||||
function pthread_attr_setinheritsched
|
||||
(attr : access pthread_attr_t;
|
||||
inheritsched : int) return int;
|
||||
pragma Import (C, pthread_attr_setinheritsched,
|
||||
"PTHREAD_ATTR_SETINHERITSCHED");
|
||||
|
||||
function pthread_attr_setschedpolicy
|
||||
(attr : access pthread_attr_t; policy : int) return int;
|
||||
pragma Import (C, pthread_attr_setschedpolicy,
|
||||
"PTHREAD_ATTR_SETSCHEDPOLICY");
|
||||
|
||||
function pthread_attr_setschedparam
|
||||
(attr : access pthread_attr_t;
|
||||
sched_param : int) return int;
|
||||
pragma Import (C, pthread_attr_setschedparam, "PTHREAD_ATTR_SETSCHEDPARAM");
|
||||
|
||||
function sched_yield return int;
|
||||
|
||||
--------------------------
|
||||
-- P1003.1c Section 16 --
|
||||
--------------------------
|
||||
|
||||
function pthread_attr_init (attributes : access pthread_attr_t) return int;
|
||||
pragma Import (C, pthread_attr_init, "PTHREAD_ATTR_INIT");
|
||||
|
||||
function pthread_attr_destroy
|
||||
(attributes : access pthread_attr_t) return int;
|
||||
pragma Import (C, pthread_attr_destroy, "PTHREAD_ATTR_DESTROY");
|
||||
|
||||
function pthread_attr_setdetachstate
|
||||
(attr : access pthread_attr_t;
|
||||
detachstate : int) return int;
|
||||
pragma Import (C, pthread_attr_setdetachstate,
|
||||
"PTHREAD_ATTR_SETDETACHSTATE");
|
||||
|
||||
function pthread_attr_setstacksize
|
||||
(attr : access pthread_attr_t;
|
||||
stacksize : size_t) return int;
|
||||
pragma Import (C, pthread_attr_setstacksize, "PTHREAD_ATTR_SETSTACKSIZE");
|
||||
|
||||
function pthread_create
|
||||
(thread : access pthread_t;
|
||||
attributes : access pthread_attr_t;
|
||||
start_routine : Thread_Body;
|
||||
arg : System.Address) return int;
|
||||
pragma Import (C, pthread_create, "PTHREAD_CREATE");
|
||||
|
||||
procedure pthread_exit (status : System.Address);
|
||||
pragma Import (C, pthread_exit, "PTHREAD_EXIT");
|
||||
|
||||
function pthread_self return pthread_t;
|
||||
pragma Import (C, pthread_self, "PTHREAD_SELF");
|
||||
-- ??? This can be inlined, see pthread.h
|
||||
|
||||
--------------------------
|
||||
-- POSIX.1c Section 17 --
|
||||
--------------------------
|
||||
|
||||
function pthread_setspecific
|
||||
(key : pthread_key_t;
|
||||
value : System.Address) return int;
|
||||
pragma Import (C, pthread_setspecific, "PTHREAD_SETSPECIFIC");
|
||||
|
||||
function pthread_getspecific (key : pthread_key_t) return System.Address;
|
||||
pragma Import (C, pthread_getspecific, "PTHREAD_GETSPECIFIC");
|
||||
|
||||
type destructor_pointer is access procedure (arg : System.Address);
|
||||
pragma Convention (C, destructor_pointer);
|
||||
|
||||
function pthread_key_create
|
||||
(key : access pthread_key_t;
|
||||
destructor : destructor_pointer) return int;
|
||||
pragma Import (C, pthread_key_create, "PTHREAD_KEY_CREATE");
|
||||
|
||||
private
|
||||
|
||||
type pid_t is new int;
|
||||
|
||||
type pthreadLongAddr_p is mod 2 ** Long_Integer'Size;
|
||||
|
||||
type pthreadLongAddr_t is mod 2 ** Long_Integer'Size;
|
||||
type pthreadLongAddr_t_ptr is mod 2 ** Long_Integer'Size;
|
||||
|
||||
type pthreadLongString_t is mod 2 ** Long_Integer'Size;
|
||||
|
||||
type pthreadLongUint_t is mod 2 ** Long_Integer'Size;
|
||||
type pthreadLongUint_array is array (Natural range <>)
|
||||
of pthreadLongUint_t;
|
||||
|
||||
type pthread_t is mod 2 ** Long_Integer'Size;
|
||||
|
||||
type pthread_cond_t is record
|
||||
state : unsigned;
|
||||
valid : unsigned;
|
||||
name : pthreadLongString_t;
|
||||
arg : unsigned;
|
||||
sequence : unsigned;
|
||||
block : pthreadLongAddr_t_ptr;
|
||||
end record;
|
||||
for pthread_cond_t'Size use 8*32;
|
||||
pragma Convention (C, pthread_cond_t);
|
||||
|
||||
type pthread_attr_t is record
|
||||
valid : long;
|
||||
name : pthreadLongString_t;
|
||||
arg : pthreadLongUint_t;
|
||||
reserved : pthreadLongUint_array (0 .. 18);
|
||||
end record;
|
||||
for pthread_attr_t'Size use 8*176;
|
||||
pragma Convention (C, pthread_attr_t);
|
||||
|
||||
type pthread_mutex_t is record
|
||||
lock : unsigned;
|
||||
valid : unsigned;
|
||||
name : pthreadLongString_t;
|
||||
arg : unsigned;
|
||||
sequence : unsigned;
|
||||
block : pthreadLongAddr_p;
|
||||
owner : unsigned;
|
||||
depth : unsigned;
|
||||
end record;
|
||||
for pthread_mutex_t'Size use 8*40;
|
||||
pragma Convention (C, pthread_mutex_t);
|
||||
|
||||
type pthread_mutexattr_t is record
|
||||
valid : long;
|
||||
reserved : pthreadLongUint_array (0 .. 14);
|
||||
end record;
|
||||
for pthread_mutexattr_t'Size use 8*128;
|
||||
pragma Convention (C, pthread_mutexattr_t);
|
||||
|
||||
type pthread_condattr_t is record
|
||||
valid : long;
|
||||
reserved : pthreadLongUint_array (0 .. 12);
|
||||
end record;
|
||||
for pthread_condattr_t'Size use 8*112;
|
||||
pragma Convention (C, pthread_condattr_t);
|
||||
|
||||
type pthread_key_t is new unsigned;
|
||||
|
||||
pragma Inline (pthread_self);
|
||||
|
||||
end System.OS_Interface;
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue