Hi Przemek,

Here are my 'speedtst --threads=4 --scale' and
'speedtst --threads=4 --scale --exclude=mem' results
respectively (I've used the default DLMALLOC):

Harbour Build Info
---------------------------
Version: Harbour 1.1.0dev (Rev. 9550)
PCode version: 0.2
Compiler: Microsoft Visual C 15.0.26569 (32 bit)
Platform: Windows XP 5.1.2600 Service Pack 3

Built on: Oct  5 2008 19:48:31
Last ChangeLog entry: 2008-10-05 18:46 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
ChangeLog SVN version: ChangeLog 9550 2008-10-05 16:47:14Z vszakats
Extra Harbour compiler switches: -l -gc3
Extra C compiler switches: -DHB_NO_DEBUG -DHB_FM_STATISTICS_OFF
Other build settings: (C mode)

Clipper 5.3b compatible extensions: yes
Clipper 5.2e/5.3b compatible undocumented: yes
Clipper 5.2e/5.3b strict compatibility: no
Xbase++ compatible extensions: yes
FlagShip compatible extensions: yes
Visual Objects compatible extensions: no
FoxPro compatible extensions: no
dBase compatible extensions: no
CLIP compatible extensions: no
Non-portable Harbour extensions: no
Profiler: off
Memory tracing and statistics: off
Maximum symbol name length: 63
---------------------------

10/05/08 21:00:17 Windows XP 5.1.2600 Service Pack 3
Harbour 1.1.0dev (Rev. 9550) (MT)+ Microsoft Visual C 15.0.26569 (32 bit)
THREADS: 4
N_LOOPS: 1000000
1 th. 4 th. factor = = = = ======================================================================== [ T001: x := L_C ]____________________________________ 0.73 0.78 - > 0.94 [ T002: x := L_N ]____________________________________ 0.28 0.50 - > 0.56 [ T003: x := L_D ]____________________________________ 0.30 0.48 - > 0.61 [ T004: x := S_C ]____________________________________ 0.74 0.81 - > 0.91 [ T005: x := S_N ]____________________________________ 0.31 0.56 - > 0.56 [ T006: x := S_D ]____________________________________ 0.31 0.55 - > 0.57 [ T007: x := M_C ]____________________________________ 0.83 0.98 - > 0.84 [ T008: x := M_N ]____________________________________ 0.41 0.74 - > 0.55 [ T009: x := M_D ]____________________________________ 0.42 0.72 - > 0.59 [ T010: x := P_C ]____________________________________ 0.53 0.78 - > 0.68 [ T011: x := P_N ]____________________________________ 0.41 0.72 - > 0.56 [ T012: x := P_D ]____________________________________ 0.42 0.72 - > 0.59 [ T013: x := F_C ]____________________________________ 2.14 2.30 - > 0.93 [ T014: x := F_N ]____________________________________ 1.55 1.72 - > 0.90 [ T015: x := F_D ]____________________________________ 0.89 0.97 - > 0.92 [ T016: x := o:GenCode ]______________________________ 1.47 1.92 - > 0.76 [ T017: x := o[8] ]___________________________________ 1.13 1.22 - > 0.92 [ T018: round( i / 1000, 2 ) ]________________________ 1.36 1.80 - > 0.76 [ T019: str( i / 1000 ) ]_____________________________ 3.80 4.66 - > 0.82 [ T020: val( s ) ]____________________________________ 2.13 2.86 - > 0.74 [ T021: val( a [ i % 16 + 1 ] ) ]_____________________ 4.26 4.24 - > 1.01 [ T022: dtos( d - i % 10000 ) ]_______________________ 3.66 3.73 - > 0.98 [ T023: eval( { || i % 16 } ) ]_______________________ 6.92 12.66 - > 0.55 [ T024: eval( bc := { || i % 16 } ) ]_________________ 2.24 2.63 - > 0.85 [ T025: eval( { |x| x % 16 }, i ) ]___________________ 4.47 11.05 - > 0.40 [ T026: eval( bc := { |x| x % 16 }, i ) ]_____________ 2.25 2.41 - > 0.93 [ T027: eval( { |x| f1( x ) }, i ) ]__________________ 4.72 25.11 - > 0.19 [ T028: eval( bc := { |x| f1( x ) }, i ) ]____________ 2.28 2.69 - > 0.85 [ T029: x := &( "f1(" + str(i) + ")" ) ]______________ 26.72 43.86 - > 0.61 [ T030: bc := &( "{|x|f1(x)}" ); eval( bc, i ) ]______ 32.88 53.64 - > 0.61 [ T031: x := valtype( x ) + valtype( i ) ]___________ 3.86 4.53 - > 0.85 [ T032: x := strzero( i % 100, 2 ) $ a[ i % 16 + 1 ] ] 5.67 6.83 - > 0.83 [ T033: x := a[ i % 16 + 1 ] == s ]___________________ 2.76 2.91 - > 0.95 [ T034: x := a[ i % 16 + 1 ] = s ]____________________ 2.89 3.17 - > 0.91 [ T035: x := a[ i % 16 + 1 ] >= s ]___________________ 2.92 3.17 - > 0.92 [ T036: x := a[ i % 16 + 1 ] <= s ]___________________ 2.89 3.19 - > 0.91 [ T037: x := a[ i % 16 + 1 ] < s ]____________________ 2.92 3.17 - > 0.92 [ T038: x := a[ i % 16 + 1 ] > s ]____________________ 2.88 3.19 - > 0.90 [ T039: ascan( a, i % 16 ) ]__________________________ 2.33 2.84 - > 0.82 [ T040: ascan( a, { |x| x == i % 16 } ) ]_____________ 26.53 29.31 - > 0.91 [ T041: if i%1000==0;a:={};end; aadd(a,{i,1,.T.,s,s2 ] 11.80 28.45 - > 0.41 [ T042: x := a ]______________________________________ 0.75 0.77 - > 0.98 [ T043: x := {} ]_____________________________________ 3.03 35.72 - > 0.08 [ T044: f0() ]________________________________________ 0.59 1.11 - > 0.53 [ T045: f1( i ) ]_____________________________________ 0.80 1.41 - > 0.57 [ T046: f2( c[1...8] ) ]______________________________ 1.14 1.64 - > 0.69 [ T047: f2( c[1...40000] ) ]__________________________ 1.14 1.58 - > 0.72 [ T048: f2( @c[1...40000] ) ]_________________________ 1.14 1.58 - > 0.72 [ T049: f2( @c[1...40000] ), c2 := c ]________________ 1.38 1.88 - > 0.73 [ T050: f3( a, a2, s, i, s2, bc, i, n, x ) ]__________ 3.41 4.06 - > 0.84 [ T051: f2( a ) ]_____________________________________ 1.19 1.61 - > 0.74 [ T052: x := f4() ]___________________________________ 5.94 5.86 - > 1.01 [ T053: x := f5() ]___________________________________ 2.67 3.05 - > 0.88 [ T054: f_prv( c ) ]__________________________________ 5.64 5.22 - > 1.08 = = = = ======================================================================== [ TOTAL ]_________________________________________206.79 344.02 - > 0.60 = = = = ========================================================================
[ total application time: ]...................................829.94
[ total real time: ]..........................................550.83


Harbour Build Info
---------------------------
Version: Harbour 1.1.0dev (Rev. 9550)
PCode version: 0.2
Compiler: Microsoft Visual C 15.0.26569 (32 bit)
Platform: Windows XP 5.1.2600 Service Pack 3

Built on: Oct  5 2008 19:48:31
Last ChangeLog entry: 2008-10-05 18:46 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
ChangeLog SVN version: ChangeLog 9550 2008-10-05 16:47:14Z vszakats
Extra Harbour compiler switches: -l -gc3
Extra C compiler switches: -DHB_NO_DEBUG -DHB_FM_STATISTICS_OFF
Other build settings: (C mode)

Clipper 5.3b compatible extensions: yes
Clipper 5.2e/5.3b compatible undocumented: yes
Clipper 5.2e/5.3b strict compatibility: no
Xbase++ compatible extensions: yes
FlagShip compatible extensions: yes
Visual Objects compatible extensions: no
FoxPro compatible extensions: no
dBase compatible extensions: no
CLIP compatible extensions: no
Non-portable Harbour extensions: no
Profiler: off
Memory tracing and statistics: off
Maximum symbol name length: 63
---------------------------

10/05/08 21:09:28 Windows XP 5.1.2600 Service Pack 3
Harbour 1.1.0dev (Rev. 9550) (MT)+ Microsoft Visual C 15.0.26569 (32 bit)
THREADS: 4
N_LOOPS: 1000000
excluded tests: 029 030 023 025 027 040 041 043 052 053 019 022 031 032
1 th. 4 th. factor = = = = ======================================================================== [ T001: x := L_C ]____________________________________ 0.74 0.78 - > 0.94 [ T002: x := L_N ]____________________________________ 0.30 0.50 - > 0.59 [ T003: x := L_D ]____________________________________ 0.30 0.51 - > 0.58 [ T004: x := S_C ]____________________________________ 0.72 0.81 - > 0.88 [ T005: x := S_N ]____________________________________ 0.31 0.55 - > 0.57 [ T006: x := S_D ]____________________________________ 0.31 0.55 - > 0.57 [ T007: x := M_C ]____________________________________ 0.84 0.98 - > 0.86 [ T008: x := M_N ]____________________________________ 0.41 0.72 - > 0.57 [ T009: x := M_D ]____________________________________ 0.41 0.73 - > 0.55 [ T010: x := P_C ]____________________________________ 0.50 0.78 - > 0.64 [ T011: x := P_N ]____________________________________ 0.41 0.72 - > 0.57 [ T012: x := P_D ]____________________________________ 0.41 0.72 - > 0.57 [ T013: x := F_C ]____________________________________ 2.16 2.36 - > 0.91 [ T014: x := F_N ]____________________________________ 1.56 1.70 - > 0.92 [ T015: x := F_D ]____________________________________ 0.92 0.95 - > 0.97 [ T016: x := o:GenCode ]______________________________ 1.48 1.91 - > 0.78 [ T017: x := o[8] ]___________________________________ 0.95 1.22 - > 0.78 [ T018: round( i / 1000, 2 ) ]________________________ 1.36 1.78 - > 0.76 [ T020: val( s ) ]____________________________________ 2.42 2.73 - > 0.89 [ T021: val( a [ i % 16 + 1 ] ) ]_____________________ 3.56 4.24 - > 0.84 [ T024: eval( bc := { || i % 16 } ) ]_________________ 2.47 2.58 - > 0.96 [ T026: eval( bc := { |x| x % 16 }, i ) ]_____________ 2.22 2.41 - > 0.92 [ T028: eval( bc := { |x| f1( x ) }, i ) ]____________ 2.30 2.63 - > 0.88 [ T033: x := a[ i % 16 + 1 ] == s ]___________________ 2.72 2.89 - > 0.94 [ T034: x := a[ i % 16 + 1 ] = s ]____________________ 2.86 3.17 - > 0.90 [ T035: x := a[ i % 16 + 1 ] >= s ]___________________ 2.86 3.17 - > 0.90 [ T036: x := a[ i % 16 + 1 ] <= s ]___________________ 2.86 3.16 - > 0.91 [ T037: x := a[ i % 16 + 1 ] < s ]____________________ 2.91 3.17 - > 0.92 [ T038: x := a[ i % 16 + 1 ] > s ]____________________ 2.83 3.19 - > 0.89 [ T039: ascan( a, i % 16 ) ]__________________________ 2.28 2.80 - > 0.82 [ T042: x := a ]______________________________________ 0.74 0.80 - > 0.92 [ T044: f0() ]________________________________________ 0.59 1.09 - > 0.54 [ T045: f1( i ) ]_____________________________________ 0.75 1.41 - > 0.53 [ T046: f2( c[1...8] ) ]______________________________ 1.14 1.67 - > 0.68 [ T047: f2( c[1...40000] ) ]__________________________ 1.14 1.58 - > 0.72 [ T048: f2( @c[1...40000] ) ]_________________________ 1.53 1.63 - > 0.94 [ T049: f2( @c[1...40000] ), c2 := c ]________________ 1.63 1.88 - > 0.87 [ T050: f3( a, a2, s, i, s2, bc, i, n, x ) ]__________ 3.42 3.98 - > 0.86 [ T051: f2( a ) ]_____________________________________ 1.17 1.66 - > 0.71 [ T054: f_prv( c ) ]__________________________________ 4.94 5.25 - > 0.94 = = = = ======================================================================== [ TOTAL ]_________________________________________ 63.41 75.34 - > 0.84 = = = = ========================================================================
[ total application time: ]...................................212.88
[ total real time: ]..........................................138.78


Brgds,
Viktor


On 2008.10.05., at 19:27, Przemyslaw Czerpak wrote:

On Sun, 05 Oct 2008, Szak�ts Viktor wrote:

Hi Viktor,

Pls find results attached.
[ Update: I've included tests with "not-yet-released" dlmalloc.
This will give the best results in MT+ mode, but slightly worse
results with MT/ST modes, so I guess its switches would need to
be tweaked for hbvmmt.lib vs hbvm.lib. ]

Thank you very much.
I've just changed speedtst and now it's possible to check scalability
in simple test which should well show poor scalable places.
Because it executes exactly the same loop test simultaneously without
any other code then it should show as performance reduction even empty
mutex calls.
Please try to make test like:
  speedtst --threads=4 --scale
and you will see what is not well scalable.

In my computer for current HVM
  ./speedtst --thread=3 --scale --exclude=mem
gives:

10/05/08 18:47:29 Linux 2.6.25.11-0.1-pae i686
Harbour 1.1.0dev (Rev. 9535) (MT)+ GNU C 4.3.1 (32 bit)
THREADS: 3
N_LOOPS: 1000000
excluded tests: 029 030 023 025 027 040 041 043 052 053 019 022 031 032
                                                 1 th.  3 th.  factor
======================================================================
[ T001: x := L_C ]______________________________  0.27   0.10 ->  2.79
[ T002: x := L_N ]______________________________  0.22   0.07 ->  3.03
[ T003: x := L_D ]______________________________  0.22   0.07 ->  2.97
[ T004: x := S_C ]______________________________  0.32   0.37 ->  0.88
[ T005: x := S_N ]______________________________  0.28   0.09 ->  2.93
[ T006: x := S_D ]______________________________  0.29   0.10 ->  2.97
[ T007: x := M_C ]______________________________  0.37   0.12 ->  2.99
[ T008: x := M_N ]______________________________  0.33   0.11 ->  2.99
[ T009: x := M_D ]______________________________  0.33   0.11 ->  2.96
[ T010: x := P_C ]______________________________  0.37   0.12 ->  3.01
[ T011: x := P_N ]______________________________  0.33   0.12 ->  2.77
[ T012: x := P_D ]______________________________  0.33   0.11 ->  2.97
[ T013: x := F_C ]______________________________  0.73   0.27 ->  2.77
[ T014: x := F_N ]______________________________  0.87   0.34 ->  2.54
[ T015: x := F_D ]______________________________  0.48   0.16 ->  3.01
[ T016: x := o:GenCode ]________________________  0.84   0.27 ->  3.10
[ T017: x := o[8] ]_____________________________  0.51   0.17 ->  3.01
[ T018: round( i / 1000, 2 ) ]__________________  1.03   0.37 ->  2.76
[ T020: val( s ) ]______________________________  1.11   0.37 ->  2.98
[ T021: val( a [ i % 16 + 1 ] ) ]_______________  1.80   0.59 ->  3.05
[ T024: eval( bc := { || i % 16 } ) ]___________  1.21   0.52 ->  2.34
[ T026: eval( bc := { |x| x % 16 }, i ) ]_______  1.23   0.42 ->  2.91
[ T028: eval( bc := { |x| f1( x ) }, i ) ]______  1.51   0.54 ->  2.81
[ T033: x := a[ i % 16 + 1 ] == s ]_____________  1.21   0.45 ->  2.69
[ T034: x := a[ i % 16 + 1 ] = s ]______________  1.34   0.49 ->  2.71
[ T035: x := a[ i % 16 + 1 ] >= s ]_____________  1.36   0.49 ->  2.76
[ T036: x := a[ i % 16 + 1 ] <= s ]_____________  1.35   0.54 ->  2.49
[ T037: x := a[ i % 16 + 1 ] < s ]______________  1.32   0.50 ->  2.62
[ T038: x := a[ i % 16 + 1 ] > s ]______________  1.36   0.46 ->  2.97
[ T039: ascan( a, i % 16 ) ]____________________  1.46   0.49 ->  2.97
[ T042: x := a ]________________________________  0.29   0.10 ->  2.89
[ T044: f0() ]__________________________________  0.55   0.18 ->  3.00
[ T045: f1( i ) ]_______________________________  0.67   0.25 ->  2.63
[ T046: f2( c[1...8] ) ]________________________  0.67   0.23 ->  2.95
[ T047: f2( c[1...40000] ) ]____________________  0.67   0.22 ->  2.97
[ T048: f2( @c[1...40000] ) ]___________________  0.67   0.22 ->  2.97
[ T049: f2( @c[1...40000] ), c2 := c ]__________  0.77   0.26 ->  2.96
[ T050: f3( a, a2, s, i, s2, bc, i, n, x ) ]____  1.61   0.57 ->  2.83
[ T051: f2( a ) ]_______________________________  0.69   0.23 ->  2.95
[ T054: f_prv( c ) ]____________________________  1.86   0.65 ->  2.86
======================================================================
[   TOTAL   ]___________________________________ 32.85  11.89 ->  2.76
======================================================================
[ total application time: ]....................................66.90
[ total real time: ]...........................................44.74

so the results are very close to number of CPUs - I've got 3 ones.
These are very similar results to pure C code I tested.
In this test we use only real time returned by seconds() functions
so we also calculate OS and other process activity reducing the
factor because such overhead is smaller when only one CPU is used
by us and rest can be used for other task.

Please also look at this:

  [ T004: x := S_C ]___________________________  0.32   0.37 ->  0.88

In this test exactly the same reference counter for string in S_C is
increased and decreased by different threads. In my computer when many
threads writes to the same memory cell some serialization action is
automatically executed and it reduces the performance to single thread
level.
After checking results you all sent in last days seems that it's strictly
hardware oriented behavior and in other computers the overhead may be
different. Anyhow this does not effect overall performance and scalability in normal code which makes also sth else then simple coping and releasing
the same string item by different threads.

For me these results are very well.
But the situation is a little bit different when we have to enable tests
which allocates and release memory.
In such case the total speed factor can be reduced by MM and spinlock
inside garbage.c - in my case this is not trivial cost because it's
also simultaneous write to the same memory cell which forces serialization.
This is well seen in this test:
[ T043: x := {} ]_______________________________ 0.67 1.65 -> 0.40 To make it more funny my Linux (SUSE11.0) has very efficient MM in MT mode and in this tests returns new memory block without any internal locks what causes that this is the only one critical places and all threads working in loops are blocked on one spinlock. I'm very interesting how it looks in
other computers.


Here I my detail results with all tests:

10/05/08 19:04:56 Linux 2.6.25.11-0.1-pae i686
Harbour 1.1.0dev (Rev. 9535) (MT)+ GNU C 4.3.1 (32 bit)
THREADS: 3
N_LOOPS: 1000000
1 th. 3 th. factor
======================================================================
[ T001: x := L_C ]______________________________  0.28   0.09 ->  3.07
[ T002: x := L_N ]______________________________  0.22   0.07 ->  2.98
[ T003: x := L_D ]______________________________  0.22   0.07 ->  3.00
[ T004: x := S_C ]______________________________  0.33   0.37 ->  0.89
[ T005: x := S_N ]______________________________  0.28   0.09 ->  2.98
[ T006: x := S_D ]______________________________  0.28   0.10 ->  2.96
[ T007: x := M_C ]______________________________  0.37   0.13 ->  2.96
[ T008: x := M_N ]______________________________  0.33   0.11 ->  2.95
[ T009: x := M_D ]______________________________  0.33   0.12 ->  2.70
[ T010: x := P_C ]______________________________  0.38   0.13 ->  2.87
[ T011: x := P_N ]______________________________  0.33   0.11 ->  2.99
[ T012: x := P_D ]______________________________  0.33   0.11 ->  2.97
[ T013: x := F_C ]______________________________  0.72   0.25 ->  2.88
[ T014: x := F_N ]______________________________  0.87   0.29 ->  2.96
[ T015: x := F_D ]______________________________  0.48   0.17 ->  2.89
[ T016: x := o:GenCode ]________________________  0.84   0.29 ->  2.91
[ T017: x := o[8] ]_____________________________  0.50   0.17 ->  2.98
[ T018: round( i / 1000, 2 ) ]__________________  1.03   0.36 ->  2.90
[ T019: str( i / 1000 ) ]_______________________  2.13   0.73 ->  2.91
[ T020: val( s ) ]______________________________  1.11   0.39 ->  2.89
[ T021: val( a [ i % 16 + 1 ] ) ]_______________  1.79   0.60 ->  2.96
[ T022: dtos( d - i % 10000 ) ]_________________  1.56   0.53 ->  2.92
[ T023: eval( { || i % 16 } ) ]_________________  2.01   2.25 ->  0.89
[ T024: eval( bc := { || i % 16 } ) ]___________  1.25   0.41 ->  3.01
[ T025: eval( { |x| x % 16 }, i ) ]_____________  1.63   2.12 ->  0.77
[ T026: eval( bc := { |x| x % 16 }, i ) ]_______  1.27   0.42 ->  2.99
[ T027: eval( { |x| f1( x ) }, i ) ]____________  1.93   2.28 ->  0.85
[ T028: eval( bc := { |x| f1( x ) }, i ) ]______  1.51   0.53 ->  2.86
[ T029: x := &( "f1(" + str(i) + ")" ) ]________ 11.58   4.56 ->  2.54
[ T030: bc := &( "{|x|f1(x)}" ); eval( bc, i ) _ 13.30   5.57 ->  2.39
[ T031: x := valtype( x ) +  valtype( i ) ]_____  1.67   0.57 ->  2.95
[ T032: x := strzero( i % 100, 2 ) $ a[ i % 16 ]  2.84   1.14 ->  2.50
[ T033: x := a[ i % 16 + 1 ] == s ]_____________  1.22   0.45 ->  2.72
[ T034: x := a[ i % 16 + 1 ] = s ]______________  1.32   0.55 ->  2.39
[ T035: x := a[ i % 16 + 1 ] >= s ]_____________  1.38   0.48 ->  2.87
[ T036: x := a[ i % 16 + 1 ] <= s ]_____________  1.35   0.50 ->  2.67
[ T037: x := a[ i % 16 + 1 ] < s ]______________  1.31   0.48 ->  2.75
[ T038: x := a[ i % 16 + 1 ] > s ]______________  1.36   0.54 ->  2.52
[ T039: ascan( a, i % 16 ) ]____________________  1.51   0.50 ->  3.00
[ T040: ascan( a, { |x| x == i % 16 } ) ]_______ 12.80   5.18 ->  2.47
[ T041: if i%1000==0;a:={};end; aadd(a,{i,1,.T.]  3.52   2.20 ->  1.60
[ T042: x := a ]________________________________  0.30   0.10 ->  2.97
[ T043: x := {} ]_______________________________  0.67   1.65 ->  0.40
[ T044: f0() ]__________________________________  0.56   0.20 ->  2.87
[ T045: f1( i ) ]_______________________________  0.67   0.24 ->  2.76
[ T046: f2( c[1...8] ) ]________________________  0.67   0.23 ->  2.92
[ T047: f2( c[1...40000] ) ]____________________  0.67   0.24 ->  2.74
[ T048: f2( @c[1...40000] ) ]___________________  0.67   0.23 ->  2.94
[ T049: f2( @c[1...40000] ), c2 := c ]__________  0.76   0.26 ->  2.91
[ T050: f3( a, a2, s, i, s2, bc, i, n, x ) ]____  1.63   0.66 ->  2.46
[ T051: f2( a ) ]_______________________________  0.69   0.24 ->  2.94
[ T052: x := f4() ]_____________________________  1.93   0.66 ->  2.93
[ T053: x := f5() ]_____________________________  1.25   0.44 ->  2.84
[ T054: f_prv( c ) ]____________________________  1.84   0.64 ->  2.88
======================================================================
[   TOTAL   ]___________________________________ 91.76  41.80 ->  2.19
======================================================================
[ total application time: ]...................................211.15
[ total real time: ]..........................................133.56

As you can see the total performance were reduced to 2.19.
But this whole test exploits the worst possible cases increasing the
collisions because each thread executed exactly the same code so this
is the worst possible situation and normal user code should be very well
scalable.

best regards,
Przemek
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to