16 Temmuz 2018 Pazartesi

fcntl POSIX metodu

Giriş
Şu satırı dahil ederiz.
#include <fcntl.h>
fcntl ile ilgili aldığım bazı notlar aşağıda. fcntl bir POSIX metodu. Burada Posix standardı olan fcntl  ile Unix sistem çağrısı olan ioctl() arasındaki fark anlatılıyor.

fctnl ile dosyanın erişim durumunu almak
Buradaki örnekte gösterildiği gibi O_ACCMODE ile erişim durumu alınabilir.
int fd = fileno(f);
int accmode = fcntl(fd, F_GETFL) & O_ACCMODE;
Çıktı olarak O_RDONLY, O_WRONLY, veya O_RDWR gibi değerler alırız.

fctnl ile non-blocking mode'a geçmek
Örnek
Önce mevcut bitleri alırız.
int flags = fcntl(fd, F_GETFL);
Daha sonra O_NONBLOCK bayrağını kaldırırız.
fcntl(fd, F_SETFL, oldfl | O_NONBLOCK); 
Örnek
Aynı şeyi tek satırda şöyle yaparız.
fcntl(fd, F_SETFL, fcntl(sock_desc, F_GETFL, 0) | O_NONBLOCK);` 
Örnek
Mevcut bitlere dikkat etmeden sadece O_NONBLOCK biti de atanabilir ancak bence yapmamak lazım.
fcntl(fd, F_SETFL, O_NONBLOCK);
Örnek
timeout ile bağlanmak için şöyle yaparız.
typedef enum {
    e_resolve   = -1,
    e_socket    = -2,
    e_sockopt   = -3,
    e_parse     = -4,
    e_timeout   = -5,
    e_io        = -6
} Error;

int main(void) {
...

  sd = connect_to(host, atoi(port));
  ...
  close(sd);
  return 0;
}

int connect_to(char *host, int port) {
  int sd;
  struct sockaddr_in addr;
  fd_set sfds;
  struct timeval tv;

  sd = socket(AF_INET, SOCK_STREAM, 0);
  if (sd == -1) return e_socket;
  if (fcntl(sd, F_SETFL, O_NONBLOCK) == -1) return e_sockopt;
  memset(&addr, 0, sizeof (addr));
  addr.sin_family = AF_INET;
  if (inet_pton(AF_INET, host, &addr.sin_addr) != 1)
    return e_parse;
  addr.sin_port = htons(port);
  connect(sd, (struct sockaddr *) &addr, sizeof (addr));
  FD_ZERO(&sfds);
  FD_SET(sd, &sfds);
  tv.tv_sec = 4;
  tv.tv_usec = 0;
  if (select(sd + 1, NULL, &sfds, NULL, &tv)) return sd;
    return e_timeout;
}
fctnl ile non-blocking mode'dan çıkmak
Şöyle yaparız.
int flags = fcntl(sockfd, F_GETFL);
fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK);
fcntl ile dosya kilitleme
flock ile de dosya kilitlemek mümkün. Açıklaması şöyle
The l_type field can be used to place a read (F_RDLCK) or a write (F_WRLCK) lock on a file. Any number of processes may hold a read lock (shared lock) on a file region, but only one process may hold a write lock (exclusive lock). An exclusive lock excludes all other locks, both shared and exclusive.
Bu konu için Dosya İşlemleri başlıklı yazıya göz atabilirsiniz.

11 Temmuz 2018 Çarşamba

Robustness - Dayanıklılık

Robustness Nedir?
Açıklaması şöyle. Robustness (dayanıklılık) hatalı girdi alsa bile uygulamanın/metodun bu girdi ile başa çıkıp, çalışabilmesi anlamına gelir. 
Robustness denotes the degree to which a system is able to withstand an unexpected internal or external event or change without degradation in system's performance. To put it differently, assuming two systems - A and B - of equal performance, the robustness of system A is greater than that of system B if the same unexpected impact on both systems leaves system A with greater performance than system B.

We stress the word unexpected because the concept of robustness  focuses specifically on performance not only under ordinary, anticipated conditions (which a well designed system should be prepared to withstand) but also under unusual conditions that stress its designers' assumptions. 
Bir başka örnek şöyle.
According to Dr. Woods, "robustness" is the word we most commonly use interchangeably with "resilience." Robustness is about more than our system's ability to rebound from a specific shock; specifically, it's about how our systems absorb a wider and wider range of disturbances without breaking. So when we ask if our systems are "resilient" to particular kinds of failure, we're really asking if they're "robust" enough to handle those failures.

Think of a bridge. A good bridge can withstand stress from wind and weather; it can support constant traffic; it can lose a certain number of supports and still maintain its integrity, say, across a canyon. The builders of the bridge anticipated any number of disturbances and then engineered the system to be able to withstand those disturbances within certain tolerances.
1. Metod Seviyesinde Robustness

Genelde İki Şekilde Olabilir
1.Hatalar emilir ve varsayılan bir davranış gösterilir
2. Hatalı durum karşısında exception fırlatılır ve devam edilmez.

2. Metodlar İçin Testler
Robustness testi için klasik örnekler olarak, null pointer, out of range değerler gibi hatalı girdi örnekleri verilebilir.

Mesajlaşmalar için hatalı CRC kontrolü örneği verilebilir.

Ayrıca kapasite sınırının zorlanması, state transition için müsaade edilmeyen geçişler de test edilebilir.

3. Fail Fast (Hemen Hata Verme) Robustness
Robustness ve Fail Fast yazısına taşıdım

4. Sistem Seviyesinde Robustness
Burada Robustness koddaki metodlar seviyesinde değil, sistem seviyesinde düşünülüyor.

Örnek - Global Exception Handler
Eğer yakalanması unutulan exception varsa, global bir exception handler kullanılarak exception düzgünce gösterilebilir, hatta hatayı otomatik olarak gönderme/paylaşma işlevi bile eklenebilir.

10 Temmuz 2018 Salı

HLA LogicalTimeIntervalFactory Arayüzü - Kullanmayın

Giriş
HLA 1516e (HLA Evolved) ile bu sınıf silinmiş.

HLA MobileFederateServices Sınıfı - Kullanmayın

Giriş
HLA 1516e (HLA Evolved) ile bu sınıf silinmiş. Amacı LogicalTimeFactory ve LogicalTimeIntervalFactory arayüzlerini bir şekilde taşımakmış.

HLA LogicalTimeFactory Arayüzü

Giriş
LogicalTime ve LogicalTimeInterval nesnesi yaratmak için kullanılır.

constructor
Şöyle yaparız
LogicalTimeFactory f = LogicalTimeFactoryFactory.
  .getLogicalTimeFactory (HLAfloat64TimeFactory.NAME);
makeInterval metodu
Sonucu arayüz olarak almak istersek şöyle yaparız.
LogicalTimeInterval interval = timeFactory.makeInterval(1.0);
Sonucu sınıf olarak almak istersek şöyle yaparız.
HLAfloat64Interval interval = timeFactory.makeInterval(1.0);
makeTime metodu
Sonucu arayüz olarak almak istersek şöyle yaparız.
LogicalTime t = timeFactory.makeTime(3.0);
Sonucu sınıf olarak almak istersek şöyle yaparız.
HLAfloat64Time t = timeFactory.makeTime(3.0);

MISRA C

Sürümler
MISRA'nın 1998/2004/2012 gibi sürümleri var. MISRA genellikle "emniyet kritik" gömülü tarzdaki uygulamalarda tercih ediliyor. Eğer MISRA kullanımı zorunlu değilse, CERT C terch edileblir. CERT C için açıklama şöyle
CERT C is specific guidance on writing "secure and resilient software in C and C++". The focus is on language specific advice on what to do and what not to do with what is a very powerful language that assumes you know what you are doing. Note that these languages are often used in writing low level code for infrastructure devices, or for embedded systems, so it is vital that they are well written.
MISRA 2008'den esinlenen AUTOSAR C++ da var.

MISRA Araçları DO-178 ile Kullanılabilir mi ?
Açıklaması şöyle. Eğer MISRA aracı DO-178 kalifikasyonuna sahip olduğunu söylemiyorsa kullanılamaz.
DO-178 tools need to be qualified for DO-178 if you are using them to test your software. I am not aware of anyone successfully using tools qualified for other standards (e.g. MISRA) in avionics

Bazı MISRA Kuralları

Array Bounds
Açıklaması şöyle
In MISRA-C:2012 there is the advisory rule 17.5 which requires that array parameters to functions should have bounds specified, to enable out-of-bounds checking of the array inside that function.
Typecasting a unsigned integer address to a pointer
Kural şunu yapmamamızı istiyor
reinterpret_cast<void*>(0x48036000U),
MISRA C 2012 rule 15.4 - "There should be no more than one break or goto statement used to terminate any iteration statement
Bir döngü içinde iki tane break olmamalı diyor. Bu kural aslında fikir olarak güzel ancak bazen uygulaması zor.
Örnek
Şu kod bu kuralı ihlal eder
do {
  retval = do_smth();
  if (retval != OK) {
    break;
  }

  retval = do_smth2();
  if (retval != OK) {
    break;
  }

  retval = do_smth3();
} while (0u);

Loop - Loop Üst Sınırında Side Effect
Örnek
Şu kod side effect'e sahip bir metod çağırıp döngünün üst sınırını belirlediği için için hata verir.
int foo (int *ptr)
{
  (*ptr)--;
  return *ptr;
}

void main()
{
  int a =20;
  int i;
  for (i=0; i< foo(&a) ; i++)
  {
    /*
      <loop body>
     */       
    }
}
Örnek
Şu kod döngünün üst sınırını belirlediği için için hata verir.
bool_t flag = false;
for ( int16_t i = 0; ( i < 5 ) && !flag; i++ )
{
  if ( C )
  {
    flag = true; /* Compliant - allows early termination of loop */
  }
  i = i + 3; /* Non-compliant - altering the loop counter */
}
If Elseif
Kural şöyle. Bu kural tamamen emniyet amaçlı.
if … else if constructs should be terminated with an else clause
Normalde kodlarken şöyle yaparız
if ( x < 0 )
{
   x = 0;
} /* else not needed */
Kural şöyle yapmamızı istiyor
if ( x < 0 )
{
    x = 0;
}
else if ( y < 0 )
{
    x = 3;
}
else    /* this else clause is required, even if the */
{       /* programmer expects this will never be reached */
        /* no change in value of x */
}