Is it the good marker or not Ada95? [closed] - multitasking

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Consider the following controller (protected object) in Ada95 to adapt that a Task calls Waiting() this one its not going to be put on waiting if the waiting marker (Marker) corresponds already on the marker of selection (Selecting_Marker) only naturally before it's initialization:
protected type Controller is
entry Waiting(Marker : in Marker_Type);
procedure WakeUp(Marker : in Marker_Type);
private
Tentative_Count : Natural := 0;
Selecting_Marker : Marker_Type;
end Controller;
protected body Controller is
entry Waiting (Marker : in Marker_Type) when Tentative_Count > 0 is
begin
Tentative_Count := Tentative_Count - 1;
if Selecting_Marker /= Marker then
requeue Waiting;
end if;
end Waiting;
procedure WakeUp (Marker : in Marker_Type) is
begin
Selecting_Marker := Marker;
Tentative_Count := Waiting'Count;
end WakeUp;
end Controller;

The object is to alter the behavior of the protected object, likely the following line:
entry Waiting (Marker : in Marker_Type) when Tentative_Count > 0 is
I'm not well-versed in protected objects, so won't offer any more than that except to say you'd probably be better off a) rereading the book's chapter on protected objects; and b) understanding what the objective of the code is and what the teacher/book is asking.
Part b is especially important, as in real life you need to be able to translate specifications into an implementation; and oftentimes the exact-wording is at odds with the examples and/or the example/reasoning.
Additional resources:
Ada 95 Rationale: II.9 Protected Types
Ada 95 Rationale: 9.1 Protected Types

Related

performance of functional architecture with modules vs. class types, in F#

I understand that functional architecture is encouraged in F#, but I'm hitting a performance wall that doesn't exist with class types.
I have a state type with a bunch of fields in it and it is passed around a series of functions through the code pipeline.
At every state, when some transformation occurs, a new object is created.
Some example is this:
match ChefHelpers.evaluateOpening t brain with
| Some openOrder ->
info $"open order received: {openOrder.Side}"
match! ExchangeBus.submitOneOrderRetryAsync brain.Exchange openOrder with
| Ok _->
{brain.CookOrder.Instrument.PriceToString openOrder.Price} / sl.{stopLossOrder.Side.Letter} at {brain.CookOrder.Instrument.PriceToString stopLossOrder.Price}"
let m = $"{t.Timestamp.Format}: send open order {openOrder.Side}, last price was {brain.CookOrder.Instrument.PriceToString brain.Analysis.LastPrice}"
return Message m, ({ brain.WithStatus (Cooking MonitorForClose) with OpenOrder = Some openOrder })
| Error e ->
let m = $"{t.Timestamp}: couldn't open position:\n{e.Describe()}"
return! ChefHelpers.cancelAllOrdersAsync brain (ChefError m) (ExchangeError (Other (e.Describe())))
| None ->
return NoMessage, brain
Where the object 'brain' that holds all the states will get passed around, updated, etc
And this works very well when run live since everything may get executed a 2-3 times per second at most.
When I want to run the same code on static data to check behavior, etc, this is a different story because I'm running it millions of times while I'm waiting for it to finish.
All this code is dealing with small lists, doing basic comparisons, arithmetic, etc so the the cost of rebuilding the main object sticks out and becomes painfully apparent.
I tried to rebuild some of that logic as an object type where the state is a bunch of mutable variables and the performance difference is dramatic.
I have a lot of code like this:
type A = { }
let a : A = ...
let a = doSomething1 a
let a = doSomething2 a
let a =
match x with
| true -> doSomething3 a
| false -> a
etc
I'd say the whole tool architecture is built with code that looks like that.
and there is a lot of these:
let a = { a with X = 3 }
but there is no concurrency in the pipeline and it is very linear, so in the case of the last line, if I had a way to tell the compiler: it's the same object, it is not used anywhere else, edit it in place, then the performance would be a lot better.
What could be strategies I could use to keep the code readable, but minimize that issue?
Is the problem the actual data copying? the main object has 18 fields, so I can't imagine it being larger than 200 bytes, allocating space for it? or does it create a lot of garbage collection?
It's not something straightforward to profile since it's a cost that's everywhere and inside dotnet.
Any feedback / ideas would be great, especially "you're doing it wrong, do X instead" :)
From a design perspective, 18 fields is actually a fairly large record, in my opinion. Perhaps you could factor that into sub-records, so you're not constantly re-allocating the entire thing? So instead of this:
type A =
{
X : int
Field1 : int
Field2 : int
...
Field18 : int
}
You could have this instead:
type Sub1 =
{
Field1 : int
...
Field9 : int
}
type Sub2 =
{
Field10 : int
...
Field18 : int
}
type A =
{
X : int
Sub1 : Sub1
Sub2 : Sub2
}
Then the performance cost of let a = { a with X = 3 } would presumably be less.
Bonus idea: You might also want to emulate the cool Haskell kids, and look into lenses, which are designed specifically for reading and updating parts of immutable data.

Dining Philosopher problem Ada- Implementing ID Dispenser

I have the following code, related to the dining philosopher problem. I am very new to Ada so am not sure about how to implement the Id_Dispenser package.
with Ada.Text_IO; use Ada.Text_IO;
with Id_Dispenser;
with Semaphores; use Semaphores;
procedure Philos is
No_of_Philos : constant Positive := 5; -- Number of philosophers
Meditation : constant Duration := 0.0;
type Table_Ix is mod No_of_Philos;
Forks : array (Table_Ix) of Binary_Semaphore (Initially_Available => True);
package Index_Dispenser is new Id_Dispenser (Element => Table_Ix);
use Index_Dispenser;
task type Philo;
task body Philo is
Philo_Nr : Table_Ix; -- Philisopher number
begin
Dispenser.Draw_Id (Id => Philo_Nr);
Put_Line ("Philosopher" & Table_Ix'Image (Philo_Nr) & " looks for forks.");
Forks (Philo_Nr).Wait; delay Meditation; Forks (Philo_Nr + 1).Wait;
Put_Line ("Philosopher" & Table_Ix'Image (Philo_Nr) & " eats.");
Forks (Philo_Nr).Signal; Forks (Philo_Nr + 1).Signal;
Put_Line ("Philosopher" & Table_Ix'Image (Philo_Nr) & " dropped forks.");
end Philo;
Table : array (Table_Ix) of Philo; pragma Unreferenced (Table);
begin
null;
end Philos;
I have implemented the following semaphore, which I think should be correct
package body semaphores is
protected body Binary_Semaphore is
entry Wait when Count > 0 is
begin
Count := Count - 1;
end Wait;
entry Release when Count < 1 is
begin
Count := Count + 1;
end Signal
end Binary_Semaphore;
end semaphores;
What does the Id_Dispenser need?
Looking at your code,
type Table_Ix is mod No_of_Philos;
...
package Index_Dispenser is new Id_Dispenser (Element => Table_Ix);
we can tell that Id_Dispenser is a generic package with a formal type named Element, and that the formal type is modular:
generic
type Element is mod <>;
package Id_Dispenser is
This
Philo_Nr : Table_Ix; -- Philisopher number
begin
Dispenser.Draw_Id (Id => Philo_Nr);
tells us that Id_Dispenser has some sort of component called Dispenser with a subprogram Draw_Id with an out parameter named Id which returns an Element.
Now, since this is a concurrent program, I'm going to guess that Dispenser is a protected object:
protected Dispenser is
procedure Draw_Id (Id : out Element);
private
...
end Dispenser;
The private part could simply be an array of Boolean indexed by Element,
Available : array (Element) of Boolean := (others => True);
but unfortunately you can't have an anonymous array as a component, so you need a proper type, giving
generic
type Element is mod <>;
package Id_Dispenser is
type Availability is array (Element) of Boolean;
protected Dispenser is
procedure Draw_Id (Id : out Element);
private
Available : Availability := (others => True);
end Dispenser;
end Id_Dispenser;
I'm not happy that the type Availability is visible, but the package now just needs implementing (!)
We could make Availability invisible by making Id_Dispenser.Dispenser a package, with Availability and the actual PO declared in the body. But that may be getting a little too purist for Ben’s context.
Firstly, you shouldn't really shorten identifiers, so you should have task type Philosophers... You can always use a renaming later on.
Shouldn't you model the forks and the philosophers? Each Philosopher as a task (hint array of task types).
Look at protected objects to model the forks.
Id_dispenser needs to implement a Draw_ID method.
Since the Dispenser variable is not declared here, it must presumably be declared in Id_dispenser. This hidden declaration is not very good style, as you can see it causes confusion; I would use a qualified name to make it obvious where it came from, as Index_Dispenser.Dispenser (which can then be renamed to reduce clutter in the rest of the code).
Id_dispenser may also need to provide an object factory method to initialise the Dispenser variable at its declaration.
Or, the intent may be that Dispenser will be the only one of its type, in which case you can treat Id_dispenser as a singleton package with Dispenser as the only object.

Passing strings as task creation discriminants in Ada

I'm moving my first steps with Ada, and I'm finding that I struggle to understand how to do common, even banal, operations that in other languages would be immediate.
In this case, I defined the following task type (and access type so I can create new instances):
task type Passenger(
Name : String_Ref;
Workplace_Station : String_Ref;
Home_Station : String_Ref
);
type Passenger_Ref is access all Passenger;
As you can see, it's a simple task that has 3 discriminants that can be passed to it when creating an instance. String_Ref is defined as:
type String_Ref is access all String;
and I use it because apparently you cannot use "normal" types as task discriminants, only references or primitive types.
So I want to create an instance of such a task, but whatever I do, I get an error. I cannot pass the strings directly by simply doing:
Passenger1 := new Passenger(Name => "foo", Workplace_Station => "man", Home_Station => "bar");
Because those are strings and not references to strings, fair enough.
So I tried:
task body Some_Task_That_Tries_To_Use_Passenger is
Passenger1 : Passenger_Ref;
Name1 : aliased String := "Foo";
Home1 : aliased String := "Man";
Work1 : aliased String := "Bar";
begin
Passenger1 := new Passenger(Name => Name1'Access, Workplace_Station => Work1'Access, Home_Station => Home1'Access);
But this doesn't work either, as, from what I understand, the Home1/Name1/Work1 variables are local to task Some_Task_That_Tries_To_Use_Passenger and so cannot be used by Passenger's "constructor".
I don't understand how I have to do it to be honest. I've used several programming languages in the past, but I never had so much trouble passing a simple String to a constructor, I feel like a total idiot but I don't understand why such a common operation would be so complicated, I'm sure I'm approaching the problem incorrectly, please enlighten me and show me the proper way to do this, because I'm going crazy :D
Yes, I agree it is a serious problem with the language that discriminates of task and record types have to be discrete. Fortunately there is a simple solution for task types -- the data can be passed via an "entry" point.
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure Main is
task type Task_Passenger is
entry Construct(Name, Workplace, Home : in String);
end Passenger;
task body Task_Passenger is
N, W, H : Unbounded_String;
begin
accept Construct(Name, Workplace, Home : in String) do
N := To_Unbounded_String(Name);
W := To_Unbounded_String(Workplace);
H := To_Unbounded_String(Home);
end Construct;
--...
end Passenger;
Passenger : Task_Passenger;
begin
Passenger.Construct("Any", "length", "strings!");
--...
end Main;
Ada doesn't really have constructors. In other languages, a constructor is, in essence, a method that takes parameters and has a body that does stuff with those parameters. Trying to get discriminants to serve as a constructor doesn't work well, since there's no subprogram body to do anything with the discriminants. Maybe it looks like it should, because the syntax involves a type followed by a list of discriminant values in parentheses and separated by commas. But that's a superficial similarity. The purpose of discriminants isn't to emulate constructors.
For a "normal" record type, the best substitute for a constructor is a function that returns an object of the type. (Think of this as similar to using a static "factory method" instead of a constructor in a language like Java.) The function can take String parameters or parameters of any other type.
For a task type, it's a little trickier, but you can write a function that returns an access to a task.
type Passenger_Acc is access all Passenger;
function Make_Passenger (Name : String;
Workplace_Station : String;
Home_Station : String) return Passenger_Acc;
To implement it, you'll need to define an entry in the Passenger task (see Roger Wilco's answer), and then you can use it in the body:
function Make_Passenger (Name : String;
Workplace_Station : String;
Home_Station : String) return Passenger_Acc is
Result : Passenger_Acc;
begin
Result := new Passenger;
Result.Construct (Name, Workplace_Station, Home_Station);
return Result;
end Make_Passenger;
(You have to do this by returning a task access. I don't think you can get the function to return a task itself, because you'd have to use an extended return to set up the task object and the task object isn't activated until after the function returns and thus can't accept an entry.)
You say
"I don't understand how I have to do it to be honest. I've used several programming languages in the past, but I never had so much trouble passing a simple String to a constructor, I feel like a total idiot but I don't understand why such a common operation would be so complicated, I'm sure I'm approaching the problem incorrectly, please enlighten me and show me the proper way to do this, because I'm going crazy :D"
Ada's access types are often a source of confusion. The main issue is that Ada doesn't have automatic garbage collection, and wants to ensure you can't suffer from the problem of returning pointers to local variables. The combination of these two results in a curious set of rules that force you to design your solution carefully.
If you are sure your code is good, then you can always used 'Unrestricted_Access on an aliased String. This puts all the responsibility on you to ensure the accessed variable won't disappear from underneath the task though.
It doesn't have to be all that complicated. You can use an anonymous access type and allocate the strings on demand, but please consider if you really want the strings to be discriminants.
Here is a complete, working example:
with Ada.Text_IO;
procedure String_Discriminants is
task type Demo (Name : not null access String);
task body Demo is
begin
Ada.Text_IO.Put_Line ("Demo task named """ & Name.all & """.");
exception
when others =>
Ada.Text_IO.Put_Line ("Demo task terminated by an exception.");
end Demo;
Run_Demo : Demo (new String'("example 1"));
Second_Demo : Demo (new String'("example 2"));
begin
null;
end String_Discriminants;
Another option is to declare the strings as aliased constants in a library level package, but then you are quite close to just having an enumerated discriminant, and should consider that option carefully before discarding it.
I think another solution would be the following:
task body Some_Task_That_Tries_To_Use_Passenger is
Name1 : aliased String := "Foo";
Home1 : aliased String := "Man";
Work1 : aliased String := "Bar";
Passenger1 : aliased Passenger(
Name => Name1'Access,
Workplace_Station => Work1'Access,
Home_Station => Home1'Access
);
begin
--...

Ada actual for "S" must be a variable

So here is a piece of my body file. I am getting the error "words.adb:75:42: actual for "S" must be a variable".
procedure Remove_Character(S : in out Ustring; C : in Character; Successful : out Boolean) is
begin
for I in 1..length(S) loop
if Element(S, I) = C then
Delete(S, I, I);
Successful := true;
return;
end if;
end loop;
Successful := false;
end Remove_Character;
function Is_Subset(Subset : Ustring; S : Ustring) return Boolean is
Could_Remove : Boolean;
begin
for I in 1..length(Subset) loop
Remove_Character(S , Element(Subset, I), Could_Remove);
if Could_Remove = false then
return false;
end if;
end loop;
return True;
end Is_Subset;
I understand where my error is coming from. Remove_Character uses S : in out Ustring while function Is_Subset uses S : in Ustring.
My question is how do I change the variable from Remove_Character into only an in Ustring?
Sorry if this is a tad jumbled, I'm fairly new to both programming and the site.
You can't, at least not directly.
I don't know what a UString is, but I presume the Delete procedure modifies it. If you changed the declaration of S in Remove_Character to S: in Ustring, you'd presumably get an error on the call to Delete.
The simplest approach I can think of would be to make a copy of S in Is_Subset:
Copy_Of_S: UString := S;
and then pass the (modifiable) copy to Remove_Character.
By "simplest", I mean it makes the smallest change to your existing code. But you should probably consider reorganizing it. Determining whether one UString is a subset of another by modifying one of the strings doesn't seem like the best approach; I'm sure there's a more efficient way to do it.
A minor and irrelevant point: this:
if Could_Remove = false then
is better written as:
if not Could_Remove then

Calculating next date in Turbo Pascal [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
program date;
uses wincrt;
var
m,ch,ch1,ch2,ch3: string ;
mois,j,a,b: integer ;
begin
write('a');read(a);
write('j');read(j);
write('mois');read(mois);
case mois of
1,3,5,7,8,10: if j<31 then
begin
b:=j+1;
m:=str(b,ch)+'/'+str(mois,ch2)+'/'+str(a,ch3);
else if j=31then
b:=1;
s:=mois+1;
m:=concat(str(b,ch),'/',str(s,ch2),'/',str(a,ch3));
end
else m:='erreur';
4,6,9,11:if j<30 then
begin
b:=j+1;
m:=concat(str(b,ch),'/',str(mois,ch2),'/',str(a,ch3));
end
else j=30 then
begin
b:=1;
s:=mois+1;
m:=concat(str(b,ch),'/',str(mois,ch2),'/',str(a,ch3));
end
else m:='erreur';
2:if j<28 then
begin
b:=j+1;
m:=concat(str(b,ch),'/',str(mois,ch2),'/',str(a,ch3));
end
else if j=28 then
begin
b:=1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(a,ch3));
end
else if((a mod 4=0)AND (a mod 100<>0)) or ((a mod 100=0)and(a mod 400=0)) then
if j<29 then
begin
b:=j+1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(a,ch3));
end
else if j=29 then
begin
b:=1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(a,ch3));
end
else m:='erreur';
12:if j<31 then
begin
b:=j+1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(a,ch3));
end
else if j=31 then
begin
b:=1;
s:=a+1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(s,ch3));
end;
writeln(m);
end.
this is my program i hope you be able to help me
It may be a good idea to indent the code according to the begin/end-blocks. This make it very easy to spot unpaired begin/end statements.
m:=str(b,ch)+'/'+str(mois,ch2)+'/'+str(a,ch3);
It is a long time since i did something with Turbo Pascal, but if i remember correctly, str is a procedure. So it does not return anything.
In order to simplify your program, it may be a good idea, to only calculate the new variables "b", "mois" and "a" inside the case block. And then do the transformation to a string once after the case-block.
str(b, ch);
str(mois, ch2);
str(a, ch3);
m := ch + '/' + ch2 + '/' + ch3;

Resources