1------------------------------------------------------------------------------ 2-- -- 3-- GNAT RUNTIME COMPONENTS -- 4-- -- 5-- G N A T . T H R E A D S -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 1998-2003 Ada Core Technologies, Inc. -- 10-- -- 11-- GNAT is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 2, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- 17-- for more details. You should have received a copy of the GNU General -- 18-- Public License distributed with GNAT; see file COPYING. If not, write -- 19-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- 20-- MA 02111-1307, USA. -- 21-- -- 22-- As a special exception, if other files instantiate generics from this -- 23-- unit, or you link this unit with other files to produce an executable, -- 24-- this unit does not by itself cause the resulting executable to be -- 25-- covered by the GNU General Public License. This exception does not -- 26-- however invalidate any other reasons why the executable file might be -- 27-- covered by the GNU Public License. -- 28-- -- 29-- GNAT was originally developed by the GNAT team at New York University. -- 30-- Extensive contributions were provided by Ada Core Technologies Inc. -- 31-- -- 32------------------------------------------------------------------------------ 33 34with Ada.Task_Identification; use Ada.Task_Identification; 35with System.Task_Primitives.Operations; 36with System.Tasking; 37with System.Tasking.Stages; use System.Tasking.Stages; 38with System.OS_Interface; use System.OS_Interface; 39with System.Soft_Links; use System.Soft_Links; 40with Unchecked_Conversion; 41 42package body GNAT.Threads is 43 44 use System; 45 46 package STPO renames System.Task_Primitives.Operations; 47 48 type Thread_Id_Ptr is access all Thread_Id; 49 50 function To_Addr is new Unchecked_Conversion (Task_Id, Address); 51 function To_Id is new Unchecked_Conversion (Address, Task_Id); 52 function To_Id is new Unchecked_Conversion (Address, Tasking.Task_ID); 53 function To_Tid is new Unchecked_Conversion 54 (Address, Ada.Task_Identification.Task_Id); 55 function To_Thread is new Unchecked_Conversion (Address, Thread_Id_Ptr); 56 57 type Code_Proc is access procedure (Id : Address; Parm : Void_Ptr); 58 59 task type Thread 60 (Stsz : Natural; 61 Prio : Any_Priority; 62 Parm : Void_Ptr; 63 Code : Code_Proc) 64 is 65 pragma Priority (Prio); 66 pragma Storage_Size (Stsz); 67 end Thread; 68 69 task body Thread is 70 begin 71 Code.all (To_Addr (Current_Task), Parm); 72 end Thread; 73 74 type Tptr is access Thread; 75 76 ------------------- 77 -- Create_Thread -- 78 ------------------- 79 80 function Create_Thread 81 (Code : Address; 82 Parm : Void_Ptr; 83 Size : Natural; 84 Prio : Integer) return System.Address 85 is 86 TP : Tptr; 87 88 function To_CP is new Unchecked_Conversion (Address, Code_Proc); 89 90 begin 91 TP := new Thread (Size, Prio, Parm, To_CP (Code)); 92 return To_Addr (TP'Identity); 93 end Create_Thread; 94 95 --------------------- 96 -- Register_Thread -- 97 --------------------- 98 99 function Register_Thread return System.Address is 100 begin 101 return Task_Primitives.Operations.Register_Foreign_Thread.all'Address; 102 end Register_Thread; 103 104 ----------------------- 105 -- Unregister_Thread -- 106 ----------------------- 107 108 procedure Unregister_Thread is 109 Self_Id : constant Tasking.Task_ID := Task_Primitives.Operations.Self; 110 begin 111 Self_Id.Common.State := Tasking.Terminated; 112 Destroy_TSD (Self_Id.Common.Compiler_Data); 113 Free_Task (Self_Id); 114 end Unregister_Thread; 115 116 -------------------------- 117 -- Unregister_Thread_Id -- 118 -------------------------- 119 120 procedure Unregister_Thread_Id (Thread : System.Address) is 121 Thr : constant Thread_Id := To_Thread (Thread).all; 122 T : Tasking.Task_ID; 123 124 use type Tasking.Task_ID; 125 126 begin 127 STPO.Lock_RTS; 128 129 T := Tasking.All_Tasks_List; 130 loop 131 exit when T = null or else STPO.Get_Thread_Id (T) = Thr; 132 133 T := T.Common.All_Tasks_Link; 134 end loop; 135 136 STPO.Unlock_RTS; 137 138 if T /= null then 139 T.Common.State := Tasking.Terminated; 140 Destroy_TSD (T.Common.Compiler_Data); 141 Free_Task (T); 142 end if; 143 end Unregister_Thread_Id; 144 145 -------------------- 146 -- Destroy_Thread -- 147 -------------------- 148 149 procedure Destroy_Thread (Id : Address) is 150 Tid : constant Task_Id := To_Id (Id); 151 begin 152 Abort_Task (Tid); 153 end Destroy_Thread; 154 155 ---------------- 156 -- Get_Thread -- 157 ---------------- 158 159 procedure Get_Thread (Id : Address; Thread : Address) is 160 use System.OS_Interface; 161 Thr : constant Thread_Id_Ptr := To_Thread (Thread); 162 begin 163 Thr.all := Task_Primitives.Operations.Get_Thread_Id (To_Id (Id)); 164 end Get_Thread; 165 166 ---------------- 167 -- To_Task_Id -- 168 ---------------- 169 170 function To_Task_Id 171 (Id : System.Address) return Ada.Task_Identification.Task_Id 172 is 173 begin 174 return To_Tid (Id); 175 end To_Task_Id; 176 177end GNAT.Threads; 178