07 April, 2012

LG optimus P500 and no caller ID problem

LG optimus P500 strangely doesn't show caller's photo (really some weird issue). I've updated all software and didn't get any fix for this. Full screen caller ID (full/light) doesn't work either.
Curious thing happens when you install HD Caller ID: default calling application starts using photos set by this application, but HD Caller ID doesn't work itself. At least it solves problem with default app, though you need to set all photos via HD Caller ID and not using address/contact book.

18 June, 2011

Easy way to merge (put together) several pdf files into single one in Linux

I've noticed, that convert utility from ImageMagick is a great tool to union PDF's into single one:
convert 1.pdf 2.pdf 3.pdf single.pdf

08 June, 2011

Using fsync and fsync_range with directories

There is a non-obvious difference between possible fd argument for fsync() and fsync_range(). In Linux and NetBSD you can use fsync() to sync directory. In NetBSD there is also fsync_range() which can't be used for directories, because it expects writable fd. Originally I thought that if fsync_range() can't, then fsync() can't too, but it can.

Example below shows how to obtain file descriptor for directory to use it with fsync:
#include <stdio.h>
#include <stdlib.h>

#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>


int main() {
    int fd;
    DIR *dirp;
    int error;
    char path[] = "test_dir";

    if ((dirp = opendir(path)) == 0) {
        printf("Failed to open dir: %d\n", errno);
        return -1;
    }
    fd = dirfd(dirp);
    if (fd == -1) {
        printf("Failed to open: %d\n", errno);
        return -1;
    }

    if (fsync(fd) == -1) {
        printf("fsync failed: %d\n", errno);
        return -1;
    }
    return 0;
}

02 June, 2011

On the transparent conversion of Indirect (mutual) recursion to "no nested calls"

In a previous post I've shown how to implement functions in recursion-like style without nested call (real recursion). Implementing algorithms this way helps to save some memory (stack).
It made me wonder if we can convert/optimize mutual recursion in a way transparent to users. As basic example I chose following code:
int even(int n)
{
    if (n == 0)
        return 1;
    else
        return odd(abs(n) - 1);
}

int odd(int n)
{
    if (n == 0)
        return 0;
    else
        return even(abs(n) - 1);
}

Like in previous example I decided to use context manipulations plus function wrappers for even() and odd().
Unfortunately there is no way to wrap functions (symbols) referenced in same file as the symbol (check this). It gives some limitations: in our case even() and odd() should be separated into different source files. In common case our approach will not work with normal recursion (a()->a()) without source modification (not just recompiling with wrapper library as I wanted). Note, that if even() and odd() are in the shared library (most likely), then you can use LD_PRELOAD to wrap these functions and it will work just fine.

even.c:
int odd(int);

int even(int n)
{
    if (n == 0)
        return 1;
    else
        return odd(abs(n) - 1);
}

odd.c:
int even(int);

int odd(int n)
{
    if (n == 0)
        return 0;
    else
        return even(abs(n) - 1);
}


wrapped.c:
int __real_even(int n);
int __real_odd(int n);

volatile int even_odd_arg;
int (*volatile fp)(int);
volatile int even_odd_res;


void dispatch(ucontext_t *_return_context) {
    static ucontext_t *return_context = 0;
    if (return_context == NULL) {
        return_context = _return_context;
    }
    even_odd_res = fp(even_odd_arg);

    setcontext(return_context);
}

ucontext_t* get_dispatcher_context(ucontext_t* return_context)
{
    static ucontext_t dispatcher_context;
    static char iterator_stack[SIGSTKSZ];
    static initialized = 0;

    if (initialized)
        return &dispatcher_context;

    dispatcher_context.uc_stack.ss_sp   = iterator_stack;
    dispatcher_context.uc_stack.ss_size = sizeof(iterator_stack);
    getcontext(&dispatcher_context);

    makecontext(&dispatcher_context, (void (*)(void)) dispatch,
                1, return_context);

    return &dispatcher_context;
}

int __wrap_even(int n) {
    ucontext_t this_context;
    even_odd_arg = n;
    fp = __real_even;
    swapcontext(&this_context, get_dispatcher_context(&this_context));

    return even_odd_res;
}


int __wrap_odd(int n) {
    ucontext_t this_context;
    even_odd_arg = n;
    fp = __real_odd;
    swapcontext(&this_context, get_dispatcher_context(&this_context));
    return even_odd_res;
}


main.c:
int even(int);

int main()
{
    int i;
    for (i = 0; i <= 10; i++) {
        int is_even = even(i);
        if (is_even)
            printf("%d is even\n", i);
        else
            printf("%d is odd\n", i);
    }
    return 0;
}

To compile use "gcc -c -O0 *.c; gcc *.o -Wl,-wrap,even -Wl,-wrap,odd -o test_mut_rec".

Mutual recursion without nested function calls in C

My friend Ryukzak has implemented mutual recursion library to use it without nested calls and thus memory overhead (stack). I decided I can do the same using ucontext. Here is a prototype (not generic) to calculate factorial:

struct Fac_state {
    int n;
    int acc;
};

void fac_times2(ucontext_t *other_context, ucontext_t *this_context,
               struct Fac_state *fstate)
{
    while (1) {
        fstate->acc *= fstate->n;
        fstate->n--;
        swapcontext(this_context, other_context);
    }
}


int factorial(int n)
{
    char iterator_stack[SIGSTKSZ];
    struct Fac_state fstate = {n, 1};

    ucontext_t this_context, other_context;

    other_context.uc_stack.ss_sp   = iterator_stack;
    other_context.uc_stack.ss_size = sizeof(iterator_stack);
    getcontext(&other_context);

    makecontext(&other_context, (void (*)(void)) fac_times2,
                3, &this_context, &other_context, &fstate);

    while (1) {
        if (fstate.n == 0)
            break;
        swapcontext(&this_context, &other_context);
    }
    return fstate.acc;
}

One more example in my next post.

27 May, 2011

How to wrap/overwrite/override function in C (gcc and clang)

Today I was tinkering with executing some code right before main() in C. I found a good description in this post. Here is some code similar to the code in that post:
__attribute__((constructor)) void before() {
    printf("Before main\n");
}

int main() {
    printf("Main\n");
    return 0;
}

Another task was to access to the argc and argv outside main(). The reason is that I reimplement some library and can't modify its users. With wrap option available both in gcc and clang I can at first execute my version of main (which can store argc and argv somewhere) and then call real main. Code below can be compiled with "clang sample.c -Wl,-wrap,main" or "gcc sample.c -Wl,-wrap,main":
int __real_main(int argc, char* argv[]);

int __wrap_main(int argc, char* argv[])
{
    printf("Wrapped main\n");
    return __real_main(argc, argv);
}

int main(int argc, char* argv[])
{
    printf("Main\n");
    return 0;
}

A good addition to the "LD_PRELOAD" trick with shared libraries.

15 January, 2011

CGA programming in C

CGA (Color Graphics Adapter) is an ancient graphical adapter from IBM introduced in 1981. It was IBM's first color graphical card and supported several graphical modes. I will describe programming in 640x200 black/white (monochrome) mode.

Each pixel can be accessed independently (but you still can address just bytes, so each time you can modify 8 pixels).
All lines divided into even and odd. Memory of even lines located at 0xB8000. 80 bytes used for each line, thus you need 8000 bytes for each bank of lines.
Because of performance extra 192 bytes added to each bank (8192 is a power of 2), so odd lines start at 0xBA000.
The code below used to put/clear pixel from the sceen:
#define EVEN_LINES 0xB8000
#define ODD_LINES 0xBA000

unsigned char *mem[] = {(unsigned char*) EVEN_LINES,
                        (unsigned char*) ODD_LINES};

static void drv_put_pixel(int x, int y, unsigned int color)
{
    unsigned char mask = 0x80 >> (x % 8);
    int offset = y/2 * 640/8 + x/8;
    if (color)
        *(mem[y % 2] + offset) |= mask;
    else
        *(mem[y % 2] + offset) &= ~mask;
}
Before you put any pixel you should activate this video mode (BIOS interrupt 10 to set video mode 6):
int video_init()
{
    __asm__("\
                mov $0, %ah;\
                mov $6, %al;\
                int $0x10;\
            ");
}
In this graphical mode pixel aspect ratio of 1:2.4, so if you just plot pixels as you always do with any high level drawing library you might get following picture:


To fix this issue you can use framebuffer to plot pixels in application's memory:
#define FB_LENGTH       (SCREEN_WIDTH*SCREEN_HEIGHT)
#define DRAW_PIXEL(x, y, colour) frame_buffer[(y)*SCREEN_WIDTH + (x)] =\
                                                                    (colour)
color_t frame_buffer[FB_LENGTH];

Then use following code to copy from framebuffer to video memory:
void fb_to_screen() {
    int x, y, Yfb;

    for (y = 0, Yfb = 0; Yfb < SCREEN_HEIGHT; y++, Yfb += 2) {
        for (x = 0; x < SCREEN_WIDTH; x++) {
            color_t pixel1 = frame_buffer[Yfb * SCREEN_WIDTH + x];
            if (Yfb != 0) {
                color_t pixel0 = frame_buffer[(Yfb - 1) * SCREEN_WIDTH + x];
                color_t pixel2 = frame_buffer[(Yfb + 1) * SCREEN_WIDTH + x];
                if (pixel0 == pixel2 && pixel0 != pixel1) {
                        drv_put_pixel(x, y, pixel1);
                } else {
                        /* "Merge" line1 and line2 */
                        drv_put_pixel(x, y, pixel2);
                }
            } else {
                drv_put_pixel(x, y, pixel1);
            }
        }
    }
}
It might be a good idea to optimize routine above, e.g. to sync only modified sections of the screen (or at least just modified lines). Now the picture looks fine (for algorithm you may refer to the code). and also you got some extra drawing space (not shown on the picture) because of scaling:
The problem with CGA programming is that int 10h is forbidden in modern operating systems (like access to the video memory). AFAIK it can be done in MS-DOS only (that nifty real mode applications), thus you need to compile the code into 16-byte dos application and run it under dos, or in windows dos compatible mode or in DOSBox (recommended). Following excellent VGA-programming tutorial is based on DJGPP 2.0 or Borland C, Turbo C. I failed to execute in Windows XP their binary produced by DJPP, but it worked fine in DOSBox with csdpmi5b unpacked to the app directory. In next article I will shortly describe running 32-bit windows applications in DOS. If you write in ASM you can use tasm and probably masm. To learn how to draw primiteves I recommend David Brackeen's "256-Color VGA Programming in C" mentined earlier.