(extendsfdf2): Add pattern accidentally deleted when cirrus instructions were
[official-gcc.git] / gcc / ada / 5gtaprop.adb
blob96098f514f494479d0a1de727b694d159cafd4e7
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
4 -- --
5 -- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
6 -- --
7 -- B o d y --
8 -- --
9 -- --
10 -- Copyright (C) 1992-2001, Free Software Foundation, Inc. --
11 -- --
12 -- GNARL is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNARL; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
22 -- --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
29 -- --
30 -- GNARL was developed by the GNARL team at Florida State University. --
31 -- Extensive contributions were provided by Ada Core Technologies, Inc. --
32 -- --
33 ------------------------------------------------------------------------------
35 -- This is an Irix (old athread library) version of this package
37 -- This package contains all the GNULL primitives that interface directly
38 -- with the underlying OS.
40 pragma Polling (Off);
41 -- Turn off polling, we do not want ATC polling to take place during
42 -- tasking operations. It causes infinite loops and other problems.
44 with Interfaces.C;
45 -- used for int
46 -- size_t
48 with System.Tasking.Debug;
49 -- used for Known_Tasks
51 with System.Task_Info;
53 with System.Interrupt_Management;
54 -- used for Keep_Unmasked
55 -- Abort_Task_Interrupt
56 -- Interrupt_ID
58 with System.Parameters;
59 -- used for Size_Type
61 with System.Tasking;
62 -- used for Ada_Task_Control_Block
63 -- Task_ID
65 with System.Program_Info;
66 -- used for Default_Task_Stack
67 -- Default_Time_Slice
68 -- Stack_Guard_Pages
69 -- Pthread_Sched_Signal
70 -- Pthread_Arena_Size
72 with System.Soft_Links;
73 -- used for Defer/Undefer_Abort
75 -- Note that we do not use System.Tasking.Initialization directly since
76 -- this is a higher level package that we shouldn't depend on. For example
77 -- when using the restricted run time, it is replaced by
78 -- System.Tasking.Restricted.Initialization
80 with System.OS_Primitives;
81 -- used for Delay_Modes
83 with System.Storage_Elements;
84 -- used for To_Address
86 with Unchecked_Conversion;
87 with Unchecked_Deallocation;
89 package body System.Task_Primitives.Operations is
91 use System.Tasking.Debug;
92 use System.Tasking;
93 use Interfaces.C;
94 use System.OS_Interface;
95 use System.Parameters;
96 use System.OS_Primitives;
98 package SSL renames System.Soft_Links;
100 ------------------
101 -- Local Data --
102 ------------------
104 -- The followings are logically constants, but need to be initialized
105 -- at run time.
107 Single_RTS_Lock : aliased RTS_Lock;
108 -- This is a lock to allow only one thread of control in the RTS at
109 -- a time; it is used to execute in mutual exclusion from all other tasks.
110 -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
112 Environment_Task_ID : Task_ID;
113 -- A variable to hold Task_ID for the environment task.
115 Locking_Policy : Character;
116 pragma Import (C, Locking_Policy, "__gl_locking_policy");
118 Clock_Address : constant System.Address :=
119 System.Storage_Elements.To_Address (16#200F90#);
121 RT_Clock_Id : clockid_t;
122 for RT_Clock_Id'Address use Clock_Address;
124 -----------------------
125 -- Local Subprograms --
126 -----------------------
128 procedure Initialize_Athread_Library;
130 function To_Task_ID is new Unchecked_Conversion (System.Address, Task_ID);
132 function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
134 -------------------
135 -- Stack_Guard --
136 -------------------
138 -- The underlying thread system sets a guard page at the
139 -- bottom of a thread stack, so nothing is needed.
140 -- ??? Check the comment above
142 procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
143 begin
144 null;
145 end Stack_Guard;
147 --------------------
148 -- Get_Thread_Id --
149 --------------------
151 function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
152 begin
153 return T.Common.LL.Thread;
154 end Get_Thread_Id;
156 ----------
157 -- Self --
158 ----------
160 function Self return Task_ID is
161 begin
162 return To_Task_ID (pthread_get_current_ada_tcb);
163 end Self;
165 ---------------------
166 -- Initialize_Lock --
167 ---------------------
169 -- Note: mutexes and cond_variables needed per-task basis are
170 -- initialized in Initialize_TCB and the Storage_Error is
171 -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
172 -- used in RTS is initialized before any status change of RTS.
173 -- Therefore rasing Storage_Error in the following routines
174 -- should be able to be handled safely.
176 procedure Initialize_Lock
177 (Prio : System.Any_Priority;
178 L : access Lock)
180 Attributes : aliased pthread_mutexattr_t;
181 Result : Interfaces.C.int;
183 begin
184 Result := pthread_mutexattr_init (Attributes'Access);
186 if Result = FUNC_ERR then
187 raise Storage_Error;
188 end if;
190 if Locking_Policy = 'C' then
192 Result := pthread_mutexattr_setqueueorder
193 (Attributes'Access, MUTEX_PRIORITY_CEILING);
195 pragma Assert (Result /= FUNC_ERR);
197 Result := pthread_mutexattr_setceilingprio
198 (Attributes'Access, Interfaces.C.int (Prio));
200 pragma Assert (Result /= FUNC_ERR);
201 end if;
203 Result := pthread_mutex_init (L, Attributes'Access);
205 if Result = FUNC_ERR then
206 Result := pthread_mutexattr_destroy (Attributes'Access);
207 raise Storage_Error;
208 end if;
210 Result := pthread_mutexattr_destroy (Attributes'Access);
211 end Initialize_Lock;
213 procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
214 Attributes : aliased pthread_mutexattr_t;
215 Result : Interfaces.C.int;
216 begin
217 Result := pthread_mutexattr_init (Attributes'Access);
219 if Result = FUNC_ERR then
220 raise Storage_Error;
221 end if;
223 if Locking_Policy = 'C' then
224 Result := pthread_mutexattr_setqueueorder
225 (Attributes'Access, MUTEX_PRIORITY_CEILING);
226 pragma Assert (Result /= FUNC_ERR);
228 Result := pthread_mutexattr_setceilingprio
229 (Attributes'Access, Interfaces.C.int (System.Any_Priority'Last));
230 pragma Assert (Result /= FUNC_ERR);
231 end if;
233 Result := pthread_mutex_init (L, Attributes'Access);
235 if Result = FUNC_ERR then
236 Result := pthread_mutexattr_destroy (Attributes'Access);
237 raise Storage_Error;
238 end if;
240 Result := pthread_mutexattr_destroy (Attributes'Access);
241 end Initialize_Lock;
243 -------------------
244 -- Finalize_Lock --
245 -------------------
247 procedure Finalize_Lock (L : access Lock) is
248 Result : Interfaces.C.int;
250 begin
251 Result := pthread_mutex_destroy (L);
252 pragma Assert (Result = 0);
253 end Finalize_Lock;
255 procedure Finalize_Lock (L : access RTS_Lock) is
256 Result : Interfaces.C.int;
258 begin
259 Result := pthread_mutex_destroy (L);
260 pragma Assert (Result = 0);
261 end Finalize_Lock;
263 ----------------
264 -- Write_Lock --
265 ----------------
267 procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
268 Result : Interfaces.C.int;
269 begin
270 Result := pthread_mutex_lock (L);
272 Ceiling_Violation := Result = FUNC_ERR and then errno = EINVAL;
273 pragma Assert (Result /= FUNC_ERR);
274 end Write_Lock;
276 procedure Write_Lock
277 (L : access RTS_Lock; Global_Lock : Boolean := False)
279 Result : Interfaces.C.int;
280 begin
281 if not Single_Lock or else Global_Lock then
282 Result := pthread_mutex_lock (L);
283 pragma Assert (Result = 0);
284 end if;
285 end Write_Lock;
287 procedure Write_Lock (T : Task_ID) is
288 Result : Interfaces.C.int;
289 begin
290 if not Single_Lock then
291 Result := pthread_mutex_lock (T.Common.LL.L'Access);
292 pragma Assert (Result = 0);
293 end if;
294 end Write_Lock;
296 ---------------
297 -- Read_Lock --
298 ---------------
300 procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
301 begin
302 Write_Lock (L, Ceiling_Violation);
303 end Read_Lock;
305 ------------
306 -- Unlock --
307 ------------
309 procedure Unlock (L : access Lock) is
310 Result : Interfaces.C.int;
311 begin
312 Result := pthread_mutex_unlock (L);
313 pragma Assert (Result = 0);
314 end Unlock;
316 procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
317 Result : Interfaces.C.int;
318 begin
319 if not Single_Lock or else Global_Lock then
320 Result := pthread_mutex_unlock (L);
321 pragma Assert (Result = 0);
322 end if;
323 end Unlock;
325 procedure Unlock (T : Task_ID) is
326 Result : Interfaces.C.int;
327 begin
328 if not Single_Lock then
329 Result := pthread_mutex_unlock (T.Common.LL.L'Access);
330 pragma Assert (Result = 0);
331 end if;
332 end Unlock;
334 -----------
335 -- Sleep --
336 -----------
338 procedure Sleep
339 (Self_ID : ST.Task_ID;
340 Reason : System.Tasking.Task_States)
342 Result : Interfaces.C.int;
343 begin
344 if Single_Lock then
345 Result := pthread_cond_wait
346 (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access);
347 else
348 Result := pthread_cond_wait
349 (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access);
350 end if;
352 -- EINTR is not considered a failure.
353 pragma Assert (Result = 0 or else Result = EINTR);
354 end Sleep;
356 -----------------
357 -- Timed_Sleep --
358 -----------------
360 procedure Timed_Sleep
361 (Self_ID : Task_ID;
362 Time : Duration;
363 Mode : ST.Delay_Modes;
364 Reason : System.Tasking.Task_States;
365 Timedout : out Boolean;
366 Yielded : out Boolean)
368 Check_Time : constant Duration := Monotonic_Clock;
369 Abs_Time : Duration;
370 Request : aliased struct_timeval;
371 Result : Interfaces.C.int;
372 begin
373 Timedout := True;
374 Yielded := False;
376 if Mode = Relative then
377 Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
378 else
379 Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
380 end if;
382 if Abs_Time > Check_Time then
383 Request := To_Timeval (Abs_Time);
385 loop
386 exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
387 or else Self_ID.Pending_Priority_Change;
389 if Single_Lock then
390 Result := pthread_cond_timedwait
391 (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access,
392 Request'Access);
394 else
395 Result := pthread_cond_timedwait
396 (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access,
397 Request'Access);
398 end if;
400 exit when Abs_Time <= Monotonic_Clock;
402 if Result = 0 or Result = EINTR then
403 -- somebody may have called Wakeup for us
404 Timedout := False;
405 exit;
406 end if;
408 pragma Assert (Result = ETIMEDOUT
409 or else (Result = -1 and then errno = EAGAIN));
410 end loop;
411 end if;
412 end Timed_Sleep;
414 -----------------
415 -- Timed_Delay --
416 -----------------
418 procedure Timed_Delay
419 (Self_ID : Task_ID;
420 Time : Duration;
421 Mode : ST.Delay_Modes)
423 Check_Time : constant Duration := Monotonic_Clock;
424 Abs_Time : Duration;
425 Request : aliased struct_timeval;
426 Result : Interfaces.C.int;
428 begin
429 -- Only the little window between deferring abort and
430 -- locking Self_ID is the reason we need to
431 -- check for pending abort and priority change below! :(
433 SSL.Abort_Defer.all;
435 if Single_Lock then
436 Lock_RTS;
437 end if;
439 Write_Lock (Self_ID);
441 if Mode = Relative then
442 Abs_Time := Time + Check_Time;
443 else
444 Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
445 end if;
447 if Abs_Time > Check_Time then
448 Request := To_Timeval (Abs_Time);
449 Self_ID.Common.State := Delay_Sleep;
451 loop
452 if Self_ID.Pending_Priority_Change then
453 Self_ID.Pending_Priority_Change := False;
454 Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
455 Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
456 end if;
458 exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
460 if Single_Lock then
461 Result := pthread_cond_timedwait (Self_ID.Common.LL.CV'Access,
462 Single_RTS_Lock'Access, Request'Access);
463 else
464 Result := pthread_cond_timedwait (Self_ID.Common.LL.CV'Access,
465 Self_ID.Common.LL.L'Access, Request'Access);
466 end if;
468 exit when Abs_Time <= Monotonic_Clock;
470 pragma Assert (Result = 0 or else
471 Result = ETIMEDOUT or else
472 (Result = -1 and then errno = EAGAIN) or else
473 Result = EINTR);
474 end loop;
476 Self_ID.Common.State := Runnable;
477 end if;
479 Unlock (Self_ID);
481 if Single_Lock then
482 Unlock_RTS;
483 end if;
485 pthread_yield;
486 SSL.Abort_Undefer.all;
487 end Timed_Delay;
489 ---------------------
490 -- Monotonic_Clock --
491 ---------------------
493 function Monotonic_Clock return Duration is
494 type timeval is record
495 tv_sec : Integer;
496 tv_usec : Integer;
497 end record;
498 pragma Convention (C, timeval);
500 tv : aliased timeval;
502 procedure gettimeofday (tp : access timeval);
503 pragma Import (C, gettimeofday, "gettimeofday", "gettimeofday");
505 begin
506 gettimeofday (tv'Access);
507 return Duration (tv.tv_sec) + Duration (tv.tv_usec) / 1_000_000.0;
508 end Monotonic_Clock;
510 -------------------
511 -- RT_Resolution --
512 -------------------
514 function RT_Resolution return Duration is
515 begin
516 return 10#1.0#E-6;
517 end RT_Resolution;
519 ------------
520 -- Wakeup --
521 ------------
523 procedure Wakeup
524 (T : ST.Task_ID;
525 Reason : System.Tasking.Task_States)
527 Result : Interfaces.C.int;
528 begin
529 Result := pthread_cond_signal (T.Common.LL.CV'Access);
530 pragma Assert (Result = 0);
531 end Wakeup;
533 -----------
534 -- Yield --
535 -----------
537 procedure Yield (Do_Yield : Boolean := True) is
538 begin
539 if Do_Yield then
540 pthread_yield;
541 end if;
542 end Yield;
544 ------------------
545 -- Set_Priority --
546 ------------------
548 procedure Set_Priority
549 (T : Task_ID;
550 Prio : System.Any_Priority;
551 Loss_Of_Inheritance : Boolean := False)
553 Result : Interfaces.C.int;
554 begin
555 T.Common.Current_Priority := Prio;
556 Result := pthread_setprio (T.Common.LL.Thread, Interfaces.C.int (Prio));
557 pragma Assert (Result /= FUNC_ERR);
559 end Set_Priority;
561 ------------------
562 -- Get_Priority --
563 ------------------
565 function Get_Priority (T : Task_ID) return System.Any_Priority is
566 begin
567 return T.Common.Current_Priority;
568 end Get_Priority;
570 ----------------
571 -- Enter_Task --
572 ----------------
574 procedure Enter_Task (Self_ID : Task_ID) is
575 Result : Interfaces.C.int;
576 begin
577 Self_ID.Common.LL.Thread := pthread_self;
578 Self_ID.Common.LL.LWP := sproc_self;
580 Result :=
581 pthread_set_ada_tcb (Self_ID.Common.LL.Thread, To_Address (Self_ID));
583 pragma Assert (Result = 0);
585 Lock_RTS;
587 for J in Known_Tasks'Range loop
588 if Known_Tasks (J) = null then
589 Known_Tasks (J) := Self_ID;
590 Self_ID.Known_Tasks_Index := J;
591 exit;
592 end if;
593 end loop;
595 Unlock_RTS;
596 end Enter_Task;
598 --------------
599 -- New_ATCB --
600 --------------
602 function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
603 begin
604 return new Ada_Task_Control_Block (Entry_Num);
605 end New_ATCB;
607 ----------------------
608 -- Initialize_TCB --
609 ----------------------
611 procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
612 Result : Interfaces.C.int;
613 Cond_Attr : aliased pthread_condattr_t;
615 begin
616 if not Single_Lock then
617 Initialize_Lock (Self_ID.Common.LL.L'Access, ATCB_Level);
618 end if;
620 Result := pthread_condattr_init (Cond_Attr'Access);
621 pragma Assert (Result = 0 or else Result = ENOMEM);
623 if Result = 0 then
624 Result := pthread_cond_init (Self_ID.Common.LL.CV'Access,
625 Cond_Attr'Access);
626 pragma Assert (Result = 0 or else Result = ENOMEM);
627 end if;
629 if Result = 0 then
630 Succeeded := True;
631 else
632 if not Single_Lock then
633 Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
634 pragma Assert (Result = 0);
635 end if;
637 Succeeded := False;
638 end if;
640 Result := pthread_condattr_destroy (Cond_Attr'Access);
641 pragma Assert (Result = 0);
642 end Initialize_TCB;
644 -----------------
645 -- Create_Task --
646 -----------------
648 procedure Create_Task
649 (T : Task_ID;
650 Wrapper : System.Address;
651 Stack_Size : System.Parameters.Size_Type;
652 Priority : System.Any_Priority;
653 Succeeded : out Boolean)
655 Attributes : aliased pthread_attr_t;
656 Adjusted_Stack_Size : Interfaces.C.size_t;
657 Result : Interfaces.C.int;
659 function Thread_Body_Access is new
660 Unchecked_Conversion (System.Address, start_addr);
662 function To_Resource_T is new Unchecked_Conversion
663 (System.Task_Info.Resource_Vector_T, System.OS_Interface.resource_t);
665 use System.Task_Info;
667 begin
668 if Stack_Size = Unspecified_Size then
669 Adjusted_Stack_Size :=
670 Interfaces.C.size_t (System.Program_Info.Default_Task_Stack);
672 elsif Stack_Size < Minimum_Stack_Size then
673 Adjusted_Stack_Size := Interfaces.C.size_t (Minimum_Stack_Size);
675 else
676 Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
677 end if;
679 Result := pthread_attr_init (Attributes'Access);
680 pragma Assert (Result = 0 or else Result = ENOMEM);
682 if Result /= 0 then
683 Succeeded := False;
684 return;
685 end if;
687 Result := pthread_attr_setdetachstate (Attributes'Access, 1);
688 pragma Assert (Result = 0);
690 Result := pthread_attr_setstacksize
691 (Attributes'Access, Adjusted_Stack_Size);
692 pragma Assert (Result = 0);
694 if T.Common.Task_Info /= null then
695 Result := pthread_attr_setresources
696 (Attributes'Access,
697 To_Resource_T (T.Common.Task_Info.Thread_Resources));
698 pragma Assert (Result /= FUNC_ERR);
700 if T.Common.Task_Info.Thread_Timeslice /= 0.0 then
701 declare
702 use System.OS_Interface;
704 Tv : aliased struct_timeval := To_Timeval
705 (T.Common.Task_Info.Thread_Timeslice);
706 begin
707 Result := pthread_attr_set_tslice
708 (Attributes'Access, Tv'Access);
709 end;
710 end if;
712 if T.Common.Task_Info.Bound_To_Sproc then
713 Result := pthread_attr_set_boundtosproc
714 (Attributes'Access, PTHREAD_BOUND);
715 Result := pthread_attr_set_bsproc
716 (Attributes'Access, T.Common.Task_Info.Sproc);
717 end if;
719 end if;
721 -- Since the initial signal mask of a thread is inherited from the
722 -- creator, and the Environment task has all its signals masked, we
723 -- do not need to manipulate caller's signal mask at this point.
724 -- All tasks in RTS will have All_Tasks_Mask initially.
726 Result := pthread_create
727 (T.Common.LL.Thread'Access,
728 Attributes'Access,
729 Thread_Body_Access (Wrapper),
730 To_Address (T));
731 pragma Assert (Result = 0 or else Result = EAGAIN);
733 Succeeded := Result = 0;
735 Set_Priority (T, Priority);
737 Result := pthread_attr_destroy (Attributes'Access);
738 pragma Assert (Result /= FUNC_ERR);
739 end Create_Task;
741 ------------------
742 -- Finalize_TCB --
743 ------------------
745 procedure Finalize_TCB (T : Task_ID) is
746 procedure Free is new
747 Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
749 Result : Interfaces.C.int;
750 Tmp : Task_ID := T;
752 begin
753 if not Single_Lock then
754 Result := pthread_mutex_destroy (T.Common.LL.L'Access);
755 pragma Assert (Result = 0);
756 end if;
758 Result := pthread_cond_destroy (T.Common.LL.CV'Access);
759 pragma Assert (Result = 0);
761 if T.Known_Tasks_Index /= -1 then
762 Known_Tasks (T.Known_Tasks_Index) := null;
763 end if;
765 Free (Tmp);
766 end Finalize_TCB;
768 ---------------
769 -- Exit_Task --
770 ---------------
772 procedure Exit_Task is
773 begin
774 pthread_exit (System.Null_Address);
775 end Exit_Task;
777 ----------------
778 -- Abort_Task --
779 ----------------
781 procedure Abort_Task (T : Task_ID) is
782 Result : Interfaces.C.int;
783 begin
784 Result := pthread_kill (T.Common.LL.Thread,
785 Interfaces.C.int (System.Interrupt_Management.Abort_Task_Interrupt));
786 pragma Assert (Result = 0);
787 end Abort_Task;
789 ----------------
790 -- Check_Exit --
791 ----------------
793 -- Dummy versions. The only currently working versions is for solaris
794 -- (native).
796 function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
797 begin
798 return True;
799 end Check_Exit;
801 --------------------
802 -- Check_No_Locks --
803 --------------------
805 function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
806 begin
807 return True;
808 end Check_No_Locks;
810 ----------------------
811 -- Environment_Task --
812 ----------------------
814 function Environment_Task return Task_ID is
815 begin
816 return Environment_Task_ID;
817 end Environment_Task;
819 --------------
820 -- Lock_RTS --
821 --------------
823 procedure Lock_RTS is
824 begin
825 Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
826 end Lock_RTS;
828 ----------------
829 -- Unlock_RTS --
830 ----------------
832 procedure Unlock_RTS is
833 begin
834 Unlock (Single_RTS_Lock'Access, Global_Lock => True);
835 end Unlock_RTS;
837 ------------------
838 -- Suspend_Task --
839 ------------------
841 function Suspend_Task
842 (T : ST.Task_ID;
843 Thread_Self : Thread_Id) return Boolean is
844 begin
845 if T.Common.LL.Thread /= Thread_Self then
846 return pthread_suspend (T.Common.LL.Thread) = 0;
847 else
848 return True;
849 end if;
850 end Suspend_Task;
852 -----------------
853 -- Resume_Task --
854 -----------------
856 function Resume_Task
857 (T : ST.Task_ID;
858 Thread_Self : Thread_Id) return Boolean is
859 begin
860 if T.Common.LL.Thread /= Thread_Self then
861 return pthread_resume (T.Common.LL.Thread) = 0;
862 else
863 return True;
864 end if;
865 end Resume_Task;
867 ----------------
868 -- Initialize --
869 ----------------
871 procedure Initialize (Environment_Task : Task_ID) is
872 begin
873 Environment_Task_ID := Environment_Task;
875 Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
876 -- Initialize the lock used to synchronize chain of all ATCBs.
878 Enter_Task (Environment_Task);
880 Set_Priority (Environment_Task,
881 Environment_Task.Common.Current_Priority);
882 end Initialize;
884 procedure Initialize_Athread_Library is
885 Result : Interfaces.C.int;
886 Init : aliased pthread_init_struct;
888 package PINF renames System.Program_Info;
889 package C renames Interfaces.C;
891 begin
892 Init.conf_initsize := C.int (PINF.Pthread_Arena_Size);
893 Init.max_sproc_count := C.int (PINF.Max_Sproc_Count);
894 Init.sproc_stack_size := C.size_t (PINF.Sproc_Stack_Size);
895 Init.os_default_priority := C.int (PINF.Os_Default_Priority);
896 Init.os_sched_signal := C.int (PINF.Pthread_Sched_Signal);
897 Init.guard_pages := C.int (PINF.Stack_Guard_Pages);
898 Init.init_sproc_count := C.int (PINF.Initial_Sproc_Count);
900 Result := pthread_exec_begin (Init'Access);
901 pragma Assert (Result /= FUNC_ERR);
903 if Result = FUNC_ERR then
904 raise Storage_Error; -- Insufficient resources.
905 end if;
907 end Initialize_Athread_Library;
909 begin
910 Initialize_Athread_Library;
911 end System.Task_Primitives.Operations;