Der tolle Supermarkt nahkauf betreibt auf seinen Kassenrechnern Linux :D Ein Phoenix BIOS mit LILO Bootloader. Heute zufällig gesehen, als sie die Kiste neu gestartet hatten.
LILO.. das Zeug muss uralt sein. Oder hat jemand in den letzten 10 Jahren LILO installiert? :D :D :D
18.02.2016
Nahkauf + Linux
17.02.2016
Fortran: Detect 64bit 32bit
Ein möglicher Weg zu erkennen ob auf einer 64bit oder 32bit Maschine compiliert wird ist mit Hilfe
von macros. Die üblichen macros wie __amd64, __amd64__, __x86_64 __x86_64__ funktionieren unter gfortran (nicht) mehr, da sie nur zeigen ob eine 64Bit Prozessor zur Verfügung steht. Und nicht, ob man
auch wirklich für 64bit compiliert. [1]
Es ist natürlich möglich untr 64bit OS für 32bit zu compilieren, wenn zum Beispiel nur ein 32bit Compiler zur Verfügung steht. Oder zu Testzwecken
Laut doku [2] steht zu diesem Zwecke das macro __LP64__ zur Verfügung.
__LP64__
_LP64
These macros are defined, with value 1, if (and only if) the compilation is for a target where long int and pointer both use 64-bits and int uses 32-bit.
Pointer ist 64bit und integer ist 32bit. So ist es richtig. Alle anderen (M$) machen es falsch.
Nun gibt es leider Compiler, die kein Preprocessing beherrschen. Zum Glück gibt es Fortran 2003
mit dem neuen iso_c_binding Modul. Das Symbol C_INTPTR_T repräsentiert die Größe eines
Pointers und kann als KIND parameter benutzt werden.
program main
use, intrinsic :: iso_c_binding
implicit none
integer(kind=C_INTPTR_T) :: sizeofapointer
!__LP64__
!_LP64
! These macros are defined, with value 1, if (and only if) the compilation is for a target where long int and pointer both use 64-bits and int uses 32-bit.
#ifdef __LP64__
write(*,*) "64bit detected by macro"
#else
write(*,*) "32bit detected by macro"
#endif
write(*,*) "C_INTPTR_T", C_INTPTR_T
end program
PS: Es ist möglich mit gfortran für 32bit zu compilieren. Einfach gfortran-multilib installieren
und dem Compiler -m32 geben.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47175
[2] https://gcc.gnu.org/onlinedocs/gcc-4.2.1/cpp/Common-Predefined-Macros.html
12.02.2016
/proc status
Code snipped to read /proc status with fortran.
E.g. used memory and so...
! original: http://hiliev.eu/posts/recipe-obtaining-peak-vm-memory-size-in-pure-fortran.html
module ProcStatus
contains
!---------------------------------------------------------------!
! Returns current process virtual memory size !
! Requires Linux procfs mounted at /proc !
!---------------------------------------------------------------!
! Output: vmsize - vmsize VM size in kB !
!---------------------------------------------------------------!
function getVmSize() result(vmsize)
implicit none
integer :: vmsize
character(len=80) :: stat_key, stat_value
!
vmsize = 0
open(unit=1000, file="/proc/self/status", status='old', err=99)
do while (.true.)
read(unit=1000, fmt=*, err=88) stat_key, stat_value
if (stat_key == 'VmSize:') then
read(stat_value, *) vmsize
exit
end if
end do
88 close(unit=1000)
if (vmsize == 0) goto 99
return
!
99 print *, 'ERROR: procfs not mounted or not compatible'
vmsize = -1
end function getVmSize
end module ProcStatus
program test
use ProcStatus
implicit none
integer :: vmsize
integer, allocatable :: arr(:)
allocate(arr(10000000)) ! ~ 40MB
arr(:) = 0
vmsize = getVmSize()
print *, 'VM size: ', vmsize, ' kB'
end program test
02.02.2016
C gecaste (Bug of the day 10)
Ist nicht direkt ein Bug, aber kann ganz leicht zu einem werden. Vorallem stört das rum-gecaste und Pointer auf locale Variablen. Hier ein Stück Code, wo ich erst drei mal hinschauen musste
typedef struct s_rocsmq_message {
...
} t_rocsmq_message, *p_rocsmq_message;
void func() {
t_rocsmq_message message;
rocsmq_recv(..., (p_rocsmq_message) & message, ROCSMQ_POLL)
}
Aber, ich sollte weniger mich beschweren, ehr Hilfe leisten.
Hier eine sehr einfache C++ version ohne Extras:
namespace rocs{
struct mqMessage {
...
};
}
using namespace rocs;
void func() {
mqMessage message = mqRecv(...);
}
Keine Pointer, kein gecaste. Lokale Variable dann declariert und gleich initialisiert, wenn man sie braucht.
Projektname "rocs" aus den Datentypen und Funktionsnamen entfernt und in ein namespace ausgelagert. Verständlicher,
weniger Code, weniger Fehler.