Recent

Recent Posts

Pages: [1] 2 3 ... 10
1
General / Re: Multithreading - synchronize or not?
« Last post by Martin_fr on Today at 01:08:18 pm »
https://en.wikipedia.org/wiki/Memory_barrier

So between modifying the data in "aEven" and setting "EvenFlag" for the other thread you need a barrier. (write barrier).

After checking the flag, and before reading the data, you need a readbarrier.



Assuming ONLY ONE thread each:

Code: Pascal  [Select][+][-]
  1.           if FlagEven = 0 then  // this can be a dirty read, no problem
  2.           begin
  3. //               FlagEven:=1; // not needed
  4. ReadWriteBarrier; // Don't read the below data before FlagEven really is 0
  5.        // Don't write it either....
  6.                for k:=0 to cBigSize-1 do aEven[k]:=EvenVal;
  7. // If I am correct then the other thread won't access them due to FlagEven => so "inc" is ok, no InterlockedIncrement needed)
  8.                inc(EvenVal);
  9.                inc(CountOutData);
  10. WriteBarrier; // Don't write the below, before all the above has been written
  11.                FlagEven:=2; //-- send data
  12.           end;


You still need InterlockedIncrement for the Counter that is not protected by any flags.
2
General / Re: Multithreading - synchronize or not?
« Last post by Martin_fr on Today at 01:06:32 pm »
"Counter" is member of thread class. It is local to thread, there is no conflict.

aEven, aOdd is global array, that one thread writes and other reads. Flag indicates when to read when to write.

So 2 threads total only?

Then why set               
Code: Pascal  [Select][+][-]
  1. FlagEven:=1;
There is no thread checking for that. The thread that wanted it 0 is in the "if" block, the other one will wait till it is 2. So you could leave it 0?


Quote
Interlocked, does include the needed barriers.

"Interlocked" you mean:
lock cmpxchg [mem], reg
or
lock xadd [mem], reg ?

Both of them include (afaik) all the read/write barriers that you need. Any InterLocked... (or asm lock ...) should do that.
3
General / Re: Multithreading - synchronize or not?
« Last post by mika on Today at 12:55:41 pm »
"Counter" is member of thread class. It is local to thread, there is no conflict.

aEven, aOdd is global array, that one thread writes and other reads. Flag indicates when to read when to write.

If there is ONLY ONE thread of each then... Well, afaik technically you need Read/Write barriers in some cases. But it may work without. Though, I would put a "WriteBarrier;" in front of the assignments setting it to 2 or 0 (before the "end" of the "if"'s begin/end block). 
yes it is  "ONLY ONE thread of each" and ONLY ONE at a time.

Interlocked, does include the needed barriers.

"Interlocked" you mean:
lock cmpxchg [mem], reg
or
lock xadd [mem], reg ?

4
Unix / Re: A fairly simple sound solution? [SOLVED]
« Last post by VisualLab on Today at 12:48:08 pm »
Hi!   8-)

Is there any fairly simple sound solution, one can use at a (rather simple) Pascal program?

Beep and Sound didn't work for me and I found other suggestions, but they're way too old (and irrelevant), for today's Linux standards, or much complicated (eg. using sophisticated C routines etc).

Please keep in mind, that Pascal (amongst many other things) is also an educational tool and I'm in need of a rather simple solution (like the above mentioned-but no working commands Beep and Sound) and not for excellent but sophisticated C or Java like code, which are all good and well, but I'll have a really hard time, trying to demonstrate them to novice learners.

This is an operating system modeled on the old OS designed for mainframe machines. It is constantly being developed mainly to support networks, servers, etc. solutions. And it works well there. Unfortunately, Linux is not suitable for teaching or presenting multimedia solutions (audio, video, animations, fancy graphics, etc.). Yes, there are attempts to use Linux for specific multimedia applications (e.g. video editing -> DaVinci), but they are not suitable for programming education.

Please don't take this as an insult or a malicious comment. This is simply the architecture of Linux and this is how its programmers want to develop it (like many other open source projects). And users can use what is available or they can look for a different solution.

Besides, Windows multimedia solutions are not that simple either (although much better designed and operated). Unfortunately, multimedia support requires knowledge of API and/or external libraries. There are no shortcuts here.
5
General / Re: Multithreading - synchronize or not?
« Last post by Martin_fr on Today at 12:41:07 pm »
Quote
Code: Pascal  [Select][+][-]
  1. FlagEven
That should work...

Well, depends: Is there exactly ONE even thread, and exactly ONE odd thread? => Or are there several of at least one of them.

If there are several, then it is a problem.
If there are several then you need (iirc)
Code: Pascal  [Select][+][-]
  1. InterlockedCompareExchange(FlagEven, 1, 0)
Set it to 1, but only if it really still is 0. (Because, otherwise 2 threads can set it to 1.)
And use the result of that for the "if" condition

If there is ONLY ONE thread of each then... Well, afaik technically you need Read/Write barriers in some cases. But it may work without. Though, I would put a "WriteBarrier;" in front of the assignments setting it to 2 or 0 (before the "end" of the "if"'s begin/end block). 

Interlocked, does include the needed barriers.



--- EDIT:

Well actually, if you have ONLY ONE of each thread. You may need ReadWriteBarrier after entering each if block.
6
Graphics / Re: May be useful to somebody
« Last post by KodeZwerg on Today at 12:38:22 pm »
Good one Handoko, I was not aware about yours and started my own, basics are same I think.
My thingy aint perfect nor ready, just some basics prepared to make it better.
Button1 initiate the action on Panel2.
2 checkboxes and a TEdit is used.
As of right now my way does write only to the width, height/wordwrap is not teached yet but you can call method seperate with proper coordinate.

TODO:
better color managment, currently it is fixed to black background and white text.
boundschecking if written text is inside rect, wordwrap etc

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  9.   Spin;
  10.  
  11. type
  12.   TTextStyle = (tsNone, tsSuper, tsSub);
  13.   TOneLine = packed record
  14.     X, Y: Integer;
  15.     TextStyle: TTextStyle;
  16.     Line: string;
  17.   end;
  18.   TAllLines = array of TOneLine;
  19.  
  20. type
  21.  
  22.   { TForm1 }
  23.  
  24.   TForm1 = class(TForm)
  25.     Button1: TButton;
  26.     cbSub: TCheckBox;
  27.     cbSuper: TCheckBox;
  28.     Edit1: TEdit;
  29.     Label1: TLabel;
  30.     Panel1: TPanel;
  31.     Panel2: TPanel;
  32.     SpinEdit1: TSpinEdit;
  33.     procedure Button1Click(Sender: TObject);
  34.     procedure cbSuperChange(Sender: TObject);
  35.     procedure cbSubChange(Sender: TObject);
  36.     procedure FormCreate(Sender: TObject);
  37.   strict private
  38.     FBMP: TBitmap;
  39.     Lines: TAllLines;
  40.   strict private
  41.     procedure AddLine(const ABitmap: TBitmap; const AFont: TFont;
  42.       const AText: string; const AStyle: TTextStyle = tsNone;
  43.       const X: Integer = -1; const Y: Integer = -1);
  44.   private
  45.  
  46.   public
  47.  
  48.   end;
  49.  
  50. var
  51.   Form1: TForm1;
  52.  
  53. implementation
  54.  
  55. {$R *.lfm}
  56.  
  57. { TForm1 }
  58.  
  59. procedure TForm1.FormCreate(Sender: TObject);
  60. begin
  61.   FBMP := TBitmap.Create;
  62.   FBMP.SetSize(Panel2.ClientRect.Width, Panel2.ClientRect.Height);
  63. end;
  64.  
  65. procedure TForm1.AddLine(const ABitmap: TBitmap; const AFont: TFont;
  66.   const AText: string; const AStyle: TTextStyle = tsNone;
  67.   const X: Integer = -1; const Y: Integer = -1);
  68. var
  69.   LX, LY: Integer;
  70.   i: Integer;
  71.   FontSize: Integer;
  72. begin
  73.   // sanity check
  74.   if AText = '' then
  75.     Exit;
  76.   ABitmap.Canvas.Brush.Style := bsClear;
  77.   ABitmap.Canvas.Font := AFont;
  78.   ABitmap.Canvas.Font.Color := clWhite;
  79.   // precheck X/Y
  80.   if (X = -1) and (Length(Lines) = 0) then
  81.     LX := 0;
  82.   if (Y = -1) and (Length(Lines) = 0) then
  83.     LY := 0;
  84.   if (X = -1) and (Length(Lines) > 0) then
  85.     LX := Lines[High(Lines)].X + ABitmap.Canvas.TextWidth(Lines[High(Lines)].Line);
  86.   if (Y = -1) and (Length(Lines) > 0) then
  87.     LY := Lines[High(Lines)].Y;
  88.   i := Length(Lines);
  89.   SetLength(Lines, Succ(i));
  90.   Lines[i].Line := AText;
  91.   Lines[i].X := LX;
  92.   Lines[i].Y := LY;
  93.   Lines[i].TextStyle := AStyle;
  94.   case AStyle of
  95.     tsNone:  ABitmap.Canvas.TextOut(Lines[i].X, Lines[i].Y, Lines[i].Line);
  96.     tsSuper: begin
  97.                if ABitmap.Canvas.Font.Size = 0 then
  98.                  FontSize := (9 * 2) div 3
  99.                else
  100.                  FontSize := (ABitmap.Canvas.Font.Size * 2) div 3
  101.                ABitmap.Canvas.Font.Size := FontSize;
  102.                ABitmap.Canvas.TextOut(Lines[i].X, Lines[i].Y - FontSize, Lines[i].Line);
  103.              end;
  104.     tsSub:   begin
  105.                if ABitmap.Canvas.Font.Size = 0 then
  106.                  FontSize := (9 * 2) div 3
  107.                else
  108.                  FontSize := (ABitmap.Canvas.Font.Size * 2) div 3
  109.                ABitmap.Canvas.Font.Size := FontSize;
  110.                ABitmap.Canvas.TextOut(Lines[i].X, Lines[i].Y + FontSize, Lines[i].Line);
  111.              end;
  112.   end;
  113. end;
  114.  
  115. procedure TForm1.Button1Click(Sender: TObject);
  116. begin
  117.   if ((not cbSuper.Checked) and (not cbSub.Checked)) then
  118.     AddLine(FBMP, Self.Font, Edit1.Text);
  119.   if (cbSuper.Checked and (not cbSub.Checked)) then
  120.     AddLine(FBMP, Self.Font, Edit1.Text, tsSuper);
  121.   if ((not cbSuper.Checked) and cbSub.Checked) then
  122.     AddLine(FBMP, Self.Font, Edit1.Text, tsSub);
  123.   Panel2.Canvas.Draw(0, 0, FBMP);
  124. end;
  125.  
  126. procedure TForm1.cbSuperChange(Sender: TObject);
  127. begin
  128.   if cbSuper.Checked then
  129.     cbSub.Checked := False;
  130. end;
  131.  
  132. procedure TForm1.cbSubChange(Sender: TObject);
  133. begin
  134.   if cbSub.Checked then
  135.     cbSuper.Checked := False;
  136. end;
  137.  
  138. end.
7
General / Re: Multithreading - synchronize or not?
« Last post by Martin_fr on Today at 12:31:38 pm »
Well, only looking at the extract in the post...

The global counters have a risk of going wrong. (race condition).

You should at least use
Code: Pascal  [Select][+][-]
  1. InterlockedIncrement(Counter)
And similar for other counters.


I don't know if "aEven" is shared with something?
8
Beginners / Re: Can function be used for change event
« Last post by VisualLab on Today at 12:18:23 pm »
Has anyone ever tried using a function with boolean result for a change event?
Currently I use procedure change_event (sender:tobject);

Sometimes change events get activated when no change actually occurred such as when a tedit loses focus.

Specific events are used to handle such situations. In case of loss of focus, handling the OnExit event helps. There is no need to come up with an unusual solution.
9
General / Multithreading - synchronize or not?
« Last post by mika on Today at 12:08:20 pm »
I created this example based of my multithreading app.

How to do synchronization in this? I kinda works with no syncronization at all...

relevant snipet from attached example:
Code: Pascal  [Select][+][-]
  1. procedure TThreadEven.Execute;
  2. var cur : qword;
  3.     k: longword;
  4.     OddVal : qword;
  5.     EvenVal : qword;
  6.     er : longword;
  7. begin
  8.      OddVal:= 1;
  9.      EvenVal:=1;
  10.      while (not Terminated)  do
  11.      begin
  12.           inc(Counter); //-- spin count
  13.  
  14.           if FlagEven = 0 then
  15.           begin
  16.                FlagEven:=1;
  17.                for k:=0 to cBigSize-1 do aEven[k]:=EvenVal;
  18.                inc(EvenVal);
  19.                inc(CountOutData);
  20.                FlagEven:=2; //-- send data
  21.           end;
  22.  
  23.           if FlagOdd = 2 then //-- incoming data from "Odd" thread
  24.           begin
  25.                er:=0;
  26.                FlagOdd:=3;
  27.                for k:=0 to cSize-1 do if aOdd[k]<>OddVal then inc(er);
  28.                inc(OddVal);
  29.                inc(CountInData);
  30.                if er<>0 then inc(CountErData);
  31.                FlagOdd:=0; //-- data recived and processed, ready for new
  32.           end;
  33.      end;
  34. end;
  35.  
  36.  
  37. procedure TThreadOdd.Execute;
  38. var cur : qword;
  39.     k: longword;
  40.     OddVal : qword;
  41.     EvenVal : qword;
  42.     er : longword;
  43.  
  44. begin
  45.      OddVal:= 1;
  46.      EvenVal:=1;
  47.      while (not Terminated)  do
  48.      begin
  49.           inc(Counter); //-- spin count
  50.  
  51.           if FlagOdd = 0 then
  52.           begin
  53.                FlagOdd:=1;
  54.                for k:=0 to cSize-1 do aOdd[k]:=OddVal;
  55.                inc(OddVal);
  56.                inc(CountOutData);
  57.                FlagOdd:=2; //-- send data
  58.           end;
  59.  
  60.           if FlagEven = 2 then //-- incoming data from "Even" thread
  61.           begin
  62.                er:=0;
  63.                FlagEven:=3;
  64.                for k:=0 to cBigSize-1 do if aEven[k]<>EvenVal then inc(er);
  65.                inc(EvenVal);
  66.                inc(CountInData);
  67.                if er<>0 then inc(CountErData);
  68.                FlagEven:=0; //-- data recived and processed, ready for new
  69.           end;
  70.  
  71.      end;
  72. end;
10
Unix / Re: A fairly simple sound solution?
« Last post by Giorgos on Today at 11:45:19 am »
I found a simple solution, based on executing shell programs.
(In this case, a console media player).

Code: Pascal  [Select][+][-]
  1. program sound;
  2.  
  3. uses Unix;
  4.  
  5. begin
  6.   fpSystem('play -q ~/TEMPG/SAMPLE.WAV');
  7. end.

A short WAV file, somewhere in the filesystem will do.
I used play, but also aplay, paplay or any console media player will do.

PS. It written ages ago. Today's FPC, throughs a warning (although the program compiles and run flawlessly).

Code: Pascal  [Select][+][-]
  1. >fpc PLAY.PAS
  2. Free Pascal Compiler version 3.0.4+dfsg-22 [2019/01/24] for x86_64
  3. Copyright (c) 1993-2017 by Florian Klaempfl and others
  4. Target OS: Linux for x86-64
  5. Compiling PLAY.PAS
  6. PLAY.PAS(6,7) Warning: Symbol "fpSystem" is deprecated: "use ansistring version"
  7. Linking PLAY
  8. /usr/bin/ld.bfd: warning: link.res contains output sections; did you forget -T?
  9. 7 lines compiled, 0.2 sec
  10. 1 warning(s) issued
  11. >
Pages: [1] 2 3 ... 10

TinyPortal © 2005-2018