"Craig Carey" wrote in message news:501s1voa23mlkfu93dailpb04dh20u7b0n@4ax.com... > > On Thu, 09 Jan 2003 20:46:45 GMT, "James S. Rogers" > wrote: > >The placement of variables in global scope can cause severe problems > >in a concurrent system. Be very careful when not to use global variables > >with tasks. > > > I meant global to each task. I did write that the globals were > parameters. Anyway, the advice has to be ignored... since global > variables that do not change their value, and 'pragma Atomic()' > variables, can be safe to access. Also that strings package I mentioned It is true that global constants are safe to access. pragma Atomic() is not guaranteed to work for all types. Quoting from the Ada Reference Manual, Annex C section 6: Legality Rules It is illegal to apply either an Atomic or Atomic_Components pragma to an object or type if the implementation cannot support the indivisible reads and updates required by the pragma. In general, atomic reads and updates are only possible for objects that fit into a register. Furthermore, pragma Atomic() is really only useful on a uniprocessor system. On multiprocessor systems it makes no difference whether or not a read or update is atomic if there is no memory locking during the operation. You can still have overlapping updates and/or reads instigated from different processors. > labels nodes in a simple global linked list, with Task_Id's which allows > safe erroneous simultaneous traversing and updating of the linked list, > which is faster than using protected objects. I tested the code and it There is no way to check Task_Id's and update or read a linked list element atomically. This entails at least two reads, or a read and a write. The only way to prevent race conditions and contention for resources in this case it to provide a locking or blocking mechanism. This is what protected objects are for. > seems to run OK (and the definition of "erroneous" could be rechecked > at some future date). I recommend you try your tests in a multiprocessor environment. You may be surprised by the results. > > RM 9.10 defines "erroneous": > http://www.adaic.org/standards/95aarm/html/AA-9-10.html Read that definition again. "Erroneous" execution is not a desired behavior. "Erroneous" execution implies that multiple accesses are not sequential. Non-sequential accesses are exposed to race conditions. I do not understand how access can be both safe and erroneous. If you are testing in a uniprocessor environment then the accesses are likely not erroneous because they are occuring in the same task. However, that is much less likely in a multiprocessor environment. From Ada Reference Manual section 9.10: Erroneous Execution Given an action of assigning to an object, and an action of reading or updating a part of the same object (or of a neighboring object if the two are not independently addressable), then the execution of the actions is erroneous unless the actions are sequential. Two actions are sequential if one of the following is true: � One action signals the other; � Both actions occur as part of the execution of the same task; � Both actions occur as part of protected actions on the same protected object, and at most one of the actions is part of a call on a protected function of the protected object. Note that the second bullet is only true if the task performing both operations is not interrupted between the two operations. If it is interrupted there is a very real possibility that another task can change one or more of the objects being "sequentially" accessed by the first task. This will lead to erroneous execution. The way to make all these things happen in the proper (sequential) order is to make the operations be operations on a protected object. Protected operations enforce synchronized access to a protected object. This synchronized access ensures the necessary sequential access to the internals of the protected object. If pragma Atomic() were sufficient there would be no protected objects. Jim Rogers