erzahlung uber: interfacing freepascal code with Oberon (oo2c)

Let’s write a minimal module with one exported function in Oberon:

MODULE m; PROCEDURE add*(a, b : INTEGER): INTEGER; BEGIN RETURN a + b; END add; END m.

We even can compile it now with oo2c

$ oo2c m.Mod

and get directories obj and sym.

We may now compile obj/m.c

and get an object m.o

gcc -Iobj -I/local/oo2c/lib/oo2c/src -I/local/oo2c/lib/oo2c/obj -c obj/m.c

Now we need a pascal wrapper to bind it.

Let’s call it mbind.pas

unit mbind; {$link m.o} (*oo2c objs to link*) {$link RT0.o} {$link Object.o} {$link Exception.o} {$link HashCode.o} {$linklib c} interface uses CTypes; function m__add(a, b : ctypes.cint16) : ctypes.cint16; cdecl; external; (* /local/oo2c/lib/oo2c/obj/C.oh typedef OOC_INT16 C__shortint; *) implementation end.

We need to tell compiler explicitly which object files to link.

m.o is the object file we get by compiling obj/m.c

Other files are the minimal oo2c rtl which needs to be linked.

We also need to link to libc, because oo2c works by compiling via C.

Function name is m__add because oo2c translates m.add to C as m__add

Note, that implementation section is empty, and fpc does not issue an error because the function marked as external.

Eventually, let’s write a main module to call the Oberon function.

program m0; uses mbind; var i : integer; begin i := m__add(20, 3); writeln (i); end.

Neither fpc nor oo2c do not need a make file.

FreePascal compiler, as well as Oberon can itself resolve module dependencies.

For example, I do not need to write a makefile where I compile first mbind.pas and get mbind.o and link it during the next step.

However, in this case I’d like to write a make file.

IPATH = -Iobj -I/local/oo2c/lib/oo2c/src -I/local/oo2c/lib/oo2c/obj LPATH = /local/oo2c/lib/oo2c/obj GCC = /usr/bin/gcc OO2C = /local/oo2c/bin/oo2c FPC = /local/fpc/bin/fpc all: $(OO2C) m.Mod $(GCC) $(IPATH) -c obj/m.c $(FPC) -Fo$(LPATH) -Fo. m0.pas clean: rm *.o rm *.ppu

I usually use custom fpc I compiled from subversion, and I prefer to keep my software in /local

LPATH is the path where oo2c main rtl objects are located, so fpc can find and link RT0.o, Exceptions.o, Object.o and HashCode.o.

So, first oo2c compiles the m module to c.

Then gcc compiles it to object file.

Then fpc compiles the main module.

And now enjoy:

$ ./m0 23

und so weiter

ասք արնետազավրի մասին (մաս 0)

Ես անցնում եմ գործի, ջենթլմեններ, եւ կարծում եմ որ հավես կլինի այդ գործի ընթացքը նկարագրել այստեղ։

Սույն կիսաբազկաթոռով վարպետ Համբսը սկսում է շարք մի պողպատե էակի մասին է, ավելի ճշգրիտ՝ շիկամուկի, ում անունն է՝ Առնետազավր։

Ոչ, ես չեմ վախենում «գողություններից», եւ վստահ եմ որ մտքերը թաքցնելն անիմաստ է, այսպիսով շիկամուկի ստեղծման ընթացքը կլինի բավականին բաց։ Ու այո, այս նյութը ցց է։ Ուրախ կլինեմ, եթե իմ տեքստերը օգտակար կլինեն որեւե մեկին, նույնիսկ մրցակիցների շարքից։

Սակայն, այն հանգամանքը որ իմ սիրելի տեքնոլոգիաները սպեցիֆիկ են, ավաղ, կարող է նվազեցնել այն էակների թիվը ում տեքստը օգտակար կլինի։

Ես օգտագործում եմ իմ ձեւով հավաքած մինիմալիստիկ Ջենթու համակարգ։ Եւ բնականաբար, ինձ պետք է քոմփայլեր։ Այժմ ես մտածում եմ, որ ինձ պետք է avr-gcc-ն։ Ու այն օգտագործելով ես հետագայում կփորձեմ ստանալ Օբերոն քրոսքոմփայլեր եւ գեներացնել avr-libc-ի կապեր Սթյուարթ Գրինհիլլի H2O ծրագրի օգնությամբ։

Սակայն քանի որ avr-gcc-ի ինետում առկա փաթեթները հին են, ու նույնիսկ թե հին չլինեին, ես միեւնույն է նախընտրում եմ հավաքել քոմփայլերի իմ ուզած տարբերակը ինքնուրույն ու իմ իսկ մեքենայի վրա։ Ինձ կօգնի քրոսքոմփայլերներ ստանալու համար նախատեղնված սկրիպտերի հավաքածուն՝ քրոսդեւը՝

# emerge crossdev

Ասենք, ուզում եմ բինուտիլս 2.21 որ ակնարկի Հոլմսին, ու ջիսիսի 4.5.2։

crossdev --binutils 2.21 --gcc 4.5.2 --with-headers --target avr -s3

հիմա մենք ունենք /usr/bin/avr-gcc , ունենք հեդերներ /usr/avr/include-ում, ու լիբեր՝ /usr/avr/lib-ում։

Եթե խնդիր լինի քոմփայլերը օգտագործելու հետ

/usr/libexec/gcc/avr/ld: cannot open linker script file ldscripts/avr5.x: No such file or directory

ապա այն լուծվում է այսպես՝

ln -s /usr/lib/binutils/avr/2.21/ldscripts /usr/avr/lib/ldscripts

Համակարգը տեստավորելու համար քաշում ենք ինետից ցանկացած օրինակ, ասենք վազող լույսերը այստեղից քոմփայլ անում, ու լցնում կոնտրոլերի մեջ։

Երեւի կռահել եք, որ ես խուսափում եմ գրաֆիկական գործիքներ օգտագերծելուց։ Դա արվում է հարմարավետության, մասնավորապես՝ ավտոմատացման հնարավորություն ունենալու համար։ Օրինակ, այդ է պատճառը ինչու ես պատրաստել եմ avrdude-ի հետեւյալ փաթաթանը՝

#cat program.sh
PORT=/dev/ttyUSB0
M=m16
#TYPE=dapa
#TYPE=ponyser
TYPE=siprog

FILE=Running_LEDs.hex

avrdude -p $M -P $PORT -c $TYPE -U flash:w:$FILE

Թայփը սիպրոգ ա, քանի որ Հովիկը հավաքել է սերիալ պորտով աշխատող այսպիսի մի պրոգրամեր։

Լույսերը հիմա, ստորեւ բերված նկարի պես վազվզում են, սակայն ես գիֆ սարքելու զահլա բնավ չունեմ՝

[}}

Այնպես որ զգոն եղեք լույսերի հետ, նրանք կարող են նաեւ վազել։

շարունակելի

ու տենց

ասք ձիետային նստացնելու մասին

փաստորեն, թիմը թույլատրեց c++ կիրառությունը gcc կոդի մեջ։

Սակայն,

For example, I think it goes without question that at this point we are
limiting ourselves to C++98 (plus “long long” so that we have a 64-bit
integer type); C++0x features should not be used. Using multiple
inheritance, templates (other than when using the C++ standard library,
e.g. std::list), or exceptions also seems overly aggressive to me.
We should use features that are relatively easy for C programmers to
understand and relatively hard for new C++ programmers to misuse. (For
example, I think constructors and destructors are pretty easy and hard
to misuse.)

Because C++ is a big language, I think we should try to enumerate what
is OK, rather than what is not OK. But, at the same time, I don’t think
we should try to get overly legalistic about exactly what is in and what
is out. We need information guidelines, not an ISO standard.

որոշված է կիրառել որոշակի անորոշ (դեռ) լեզվի ենթաբազմություն։

Հարց է առաջանում՝ ո՞վ է հետևելու որ կոդը գայդլայններին համապատասխանի։

Ամենալավ լուծումը՝ ավտոմոտացումն է։ Եթե ավտոմատացնել, ապա դա նույնն է ինչ

սահմանել մի ենթաբազմություն ու իրա անունը դնել ասենք c++– կամ –c++, ++c–

կամ +-c-+

Ու էդպիսի ստանդարտ անել դրանով իսկ լուծելով չաղության հարցը։

C-ի դեպքում՝ SafeC-ն նմանատիպ օրինակն է։

Ադաի դեպքում դա արվել է SPARK լեզվի միջոցով։

Այսպիսով, լեզուն ֆսյո-տակի մի տեսակ ակնկարկում ա որ նիհարել ա ուզում։

_ու տենց _

на прошлом м…

на прошлом месте работы я очень рекомендовал использовать скомпилированные с О3 оптимизацией gentoo системы на reiserfs вместо RHEL на ext3

Сделал сетап дженту с скомпиленныйм с О3 mysql так как это их интересовало больше.

А потом уже уйдя с той работы получил результаты их тестов.

меньше – лучше 🙂

blue – my custom Gentoo, Red – RHEL 🙂

gentoo_vs_redhat

мой сетап gentoo против их сетапа RHEL на той же машине

6.53 секунды против 10.74 секунды

21.14 секунды против 32.75 секунды

2 минуты 57.14 сек против 3 минуты, 54.27 секунды

7 минут 44.56 сек против 10 минут 2.54 секунды

P-4 2.4 MHz RAM 512,

Gentoo (kernel 2.6.28.7, FS – reiserfs)

RedHat 4 Enterprice (kernel 2.6.9-5, FS –ext3)

WRITE

Gentoo

41 MB, 387203 record file

LOAD DATA INFILE “04062007” INTO TABLE ulog; Time 6.53 sec

64 MB, 590284 record file

LOAD DATA INFILE “03282007” INTO TABLE ulog; Time 10.74 sec

RH4 EL

41 MB, 387203 record file

LOAD DATA INFILE “04062007” INTO TABLE ulog; Time 21.14 sec

64 MB, 590284 record file

LOAD DATA INFILE “03282007” INTO TABLE ulog; Time 32.75 sec

READ

Gentoo

SELECT COUNT(*) FROM page, page_info WHERE page.page_namespace = 100 AND page.page_id = page_info.page_id; Time 2 min 57.14 sec

SELECT COUNT(*) FROM page WHERE page_title LIKE ‘a’; Time 7 min 44.56 sec

RH

SELECT COUNT(*) FROM page, page_info WHERE page.page_namespace = 100 AND page.page_id = page_info.page_id; Time 3 min 54.27 sec

SELECT COUNT(*) FROM page WHERE page_title LIKE ‘a’; Time 10 min 2.54 sec

новости с http…

новости с http://www.gentoo.org/doc/en/gcc-optimization.xml

# -O3: This is the highest level of optimization possible, and also the riskiest. It will take a longer time to compile your code with this option, and in fact it should not be used system-wide with gcc 4.x. The behavior of gcc has changed significantly since version 3.x. In 3.x, -O3 has been shown to lead to marginally faster execution times over -O2, but this is no longer the case with gcc 4.x. Compiling all your packages with -O3 will result in larger binaries that require more memory, and will significantly increase the odds of compilation failure or unexpected program behavior (including errors). The downsides outweigh the benefits; remember the principle of diminishing returns. Using -O3 is not recommended for gcc 4.x.

Интересно, какая сейчас разница

# gcc -c -Q -O2 –help=optimizers > O2

# gcc -c -Q -O3 –help=optimizers > O3

смотрим

# diff O3 O2

35c35

< -fgcse-after-reload [enabled] -– > -fgcse-after-reload [disabled]

43c43

< -finline-functions [enabled] -– > -finline-functions [disabled]

67c67

< -fpredictive-commoning [enabled] -– > -fpredictive-commoning [disabled]

128c128

< -ftree-vectorize [enabled] -– > -ftree-vectorize [disabled]

135c135

< -funswitch-loops [enabled] -– > -funswitch-loops [disabled]