Pages

Sunday, December 07, 2014

wxWidgets - Build - Linux

cd <WXWIDGETS_SRC_DIR>
mkdir trunk; mkdir build
svn checkout https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk trunk
cd build
../trunk/configure --prefix=<WXWIDGETS_SRC_DIR>/dist \ --enable-static --disable-shared --with-libpng --with-libjpeg --without-libtiff \ --with-libxm --with-libiconv --with-regex=builtin --disable-stc --enable-htmlhelp \ --enable-aui --enable-grid --enable-timer --enable-dynlib --enable-dynamicloader \ --with-gtk=3 --enable-debug --enable-debug_gdb
make
make install

Sunday, May 11, 2014

wxWidgets - Windows - MinGW

SET PATH=%PATH%;C:\MinGW\bin cd <wxWidgets_SOURCE_DIR>\build\msw mingw32-make -f makefile.gcc USE_XRC=1 SHARED=0 MONOLITHIC=0 BUILD=release UNICODE=1

wxWidgets files to be able to compile a wxWidgets application are in directories:

- <wxWidgets_SOURCE_DIR>\include
- <wxWidgets_SOURCE_DIR>\lib\gcc_lib.

Saturday, April 26, 2014

C++ / C / Queue

queue.cpp:
#include <stdio.h> #include <stdlib.h> #include "queue.h" /** * Queue item creation. */ void queue_item_create(QueueItem_t **queue_item) { DEBUG("queue_item_create()\n"); *queue_item = (QueueItem_t *) malloc(sizeof(QueueItem_t)); (*queue_item)->data = NULL; // Initially a isolated item (*queue_item)->next = NULL; } void queue_item_set_data(QueueItem_t *queue_item, UserData_t data) { DEBUG("queue_item_set_data()\n"); queue_item->data = (UserData_t) data; } /** * Queue item destruction. */ void queue_item_destroy(QueueItem_t *queue_item) { DEBUG("queue_item_destroy()\n"); if (!queue_item) { return; } if (queue_item->data) { free(queue_item->data); } free(queue_item); } /** * Queue creation. */ void queue_create(Queue_t **my_queue) { DEBUG("queue_create()\n"); *my_queue = (Queue_t *) malloc(sizeof(Queue_t)); (*my_queue)->root = NULL; (*my_queue)->last = NULL; (*my_queue)->count = 0; } /** * Remove first item from queue. */ bool queue_pop_item(Queue_t **my_queue) { if (*my_queue == NULL) { return false; } if ((*my_queue)->root == NULL) { return false; } DEBUG("queue_pop_item()\n"); // First item QueueItem_t *item = (*my_queue)->root; DEBUG("item: %p\n", item); // Point to the next item if ((*my_queue)->root->next) { DEBUG("There is a next item.\n"); (*my_queue)->root = (*my_queue)->root->next; } // List empty else { DEBUG("There is no more items.\n"); (*my_queue)->root = NULL; (*my_queue)->last = NULL; } DEBUG("root: %p\n", (*my_queue)->root); // Free memory used by the first item queue_item_destroy(item); return true; } /** * Add a item at the end of the queue. */ void queue_push(Queue_t **my_queue, QueueItem_t *item) { if (*my_queue == NULL || item == NULL) { return; } DEBUG("queue_push()\n"); // Current root will be the second item from queue if ((*my_queue)->last) { (*my_queue)->last->next = item; (*my_queue)->last = (*my_queue)->last->next; } else { (*my_queue)->last = item; (*my_queue)->root = (*my_queue)->last; } (*my_queue)->count++; } QueueItem_t *queue_get_first(Queue_t *my_queue) { if (my_queue == NULL) { return NULL; } if (my_queue->root == NULL) { return NULL; } return my_queue->root; } /** * Destroy the queue. */ void queue_destroy(Queue_t **my_queue) { if (*my_queue == NULL) { return; } DEBUG("queue_destroy()\n"); if ((*my_queue)->root != NULL) { int count = 0; while ((*my_queue)->root) { ++count; DEBUG("item %d: %p\n", count, (*my_queue)->root); queue_pop_item(my_queue); } } free(*my_queue); } /** * Dump the queue. */ void queue_dump(Queue_t *my_queue) { DEBUG("queue_dump()\n"); if (my_queue->root == NULL) { DEBUG("No items on queue.\n"); return; } QueueItem_t *root = my_queue->root; unsigned int item_index = 0; while (root) { ++item_index; DEBUG("item %d: %p\n", item_index, root); if (root->data) { DEBUG("item data %d: %d\n", item_index, *((int *)root->data)); } if (!root->next) { break; } root = root->next; } }

queue.h:
#ifndef QUEUE_H #define QUEUE_H #define DEBUG printf /** * Queue item */ typedef struct QueueItem_st { void *data; /**< User data. */ struct QueueItem_st *next; /**< Location of the next item from queue. */ } QueueItem_t; typedef struct Queue_st { struct QueueItem_st *root; /**< Location of the next item from queue. */ struct QueueItem_st *last; /**< Location of the next item from queue. */ unsigned int count; } Queue_t; typedef void * UserData_t; void queue_item_create(QueueItem_t **queue_item); void queue_item_set_data(QueueItem_t *queue_item, UserData_t data); /** * Queue item destruction. */ void queue_item_destroy(QueueItem_t *queue_item); /** * Queue creation. */ void queue_create(Queue_t **my_queue); /** * Remove first item from queue. */ bool queue_pop_item(Queue_t **my_queue); /** * Add a item at the end of the queue. */ void queue_push(Queue_t **my_queue, QueueItem_t *item); QueueItem_t *queue_get_first(Queue_t *my_queue); /** * Destroy the queue. */ void queue_destroy(Queue_t **my_queue); /** * Dump the queue. */ void queue_dump(Queue_t *my_queue); #endif /* QUEUE_H */

queue-test.cpp:
#include <stdio.h> #include <stdlib.h> #include "queue.h" /** * Test program. */ int main(int argc, char *argv[]) { DEBUG("\nCreate a queue\n"); Queue_t *queue_1; queue_create(&queue_1); DEBUG("queue address: %p\n", queue_1); for (int item_index = 0; item_index < 5; item_index++) { DEBUG("\nCreate a queue item\n"); QueueItem_t *item_1; queue_item_create(&item_1); DEBUG("item address: %p\n", item_1); DEBUG("\nQueue item data\n"); int *data = (int *) malloc(sizeof(int)); *data = item_index; queue_item_set_data(item_1, (UserData_t) data); //item_1->data = (UserData_t) data; DEBUG("\nAdd a item to the queue\n"); queue_push(&queue_1, item_1); } DEBUG("\nDump queue content\n"); queue_dump(queue_1); DEBUG("\nConsuming queue content\n"); do { QueueItem_t *item = queue_get_first(queue_1); if (!item) { printf("There is no more items to consume\n"); break; } printf("Item consumed..\n"); } while (queue_pop_item(&queue_1)); DEBUG("\nDestroy the queue\n"); queue_destroy(&queue_1); return 0; }

Makefile:
CPPFLAGS=-Wall -g all: queue-test queue queue-test: queue queue-test.o $(CXX) $(CPPFLAGS) -c queue-test.cpp -o queue-test.o $(CXX) queue-test.o queue.o -o queue-test queue: queue.o $(CXX) $(CPPFLAGS) -c queue.cpp -o queue.o clean: rm -f *.o rm -f queue-test

Build:
$ make $ valgrind --leak-check=full ./queue-test

Monday, April 14, 2014

PThreads - Simple alignment and synchronization with a base thread

thread.c file:
#include <pthread.h> #include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <math.h> #define THREADS_COUNT 7 #define NITER 10000000 int count = 0; sem_t mutex; int threads_count = THREADS_COUNT; int iterations_count = NITER; pthread_t thread_first_id; short thread_first_started = 0; void *thread_function(void *data) { int i, tmp; int processed_count = 0; pid_t pid = getpid(); int *id = data; pthread_t self = pthread_self(); long thread_id = (long) self; printf("process %ld, thread %ld entering. id=%d\n", pid, thread_id, *id); if (thread_id == thread_first_id) { thread_first_started = 1; printf("Thead 1 started. Sleeping. id=%d\n", *id); usleep(2000); printf("Thead 1 started. Awaking. id=%d\n", *id); } else { while (!thread_first_started) { printf("process %ld, thread %ld waiting.\n", pid, thread_id); usleep(100); } } while (count < NITER) { sem_wait(&mutex); ++count; if (count > iterations_count) { sem_post(&mutex); break; } double x = pow(i, i); double s = sqrt(x); double c = cbrt(x); double l = log(x); double l10 = log10(x); double e = exp(x); ++processed_count; //printf("%ld - %d\n", thread_id, count); sem_post(&mutex); } printf("process %ld, thread %ld exiting. Processed items = %d, %.2f%% of total.\n", pid, thread_id, processed_count, 100.0 * processed_count / (double) iterations_count); pthread_exit(NULL); } int main(int argc, char *argv[]) { if (argc > 1) { iterations_count = atoi(argv[1]); } if (argc > 2) { threads_count = atoi(argv[2]); } printf("iterations = %d\n", iterations_count); printf("threads = %d\n", threads_count); pthread_t threads[threads_count]; int i; int *data; // Initializing unamed semaphore sem_init(&mutex, 0, 1); // Starting threads for (i = 0; i < threads_count; i++) { data = (int *) malloc(sizeof(int)); *data = i; printf("Creating thread %d with data=%d\n", i, *data); if (pthread_create(&threads[i], NULL, thread_function, (void *) data)) { printf("ERROR creating thread %d\n", i + 1); exit(1); } if (i == 0) { thread_first_id = threads[i]; } } // Waiting threads to finish for (i = 0; i < threads_count; i++) { if (pthread_join(threads[i], NULL)) { printf("\n ERROR joining thread"); exit(1); } } pthread_exit(NULL); }
Build:
gcc thread.c -lpthread -lrt -lm
Run: a.out <ITERATIONS> <THREADS COUNT>
time ./a.out 10000000 7

Tuesday, January 21, 2014

JS / CSS - Bar that stays on top of the page

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <style> html, body { height: 100%; } body { padding: 0; padding-top: 30px; margin: 0; } #topbar { position: absolute; top: 0; left: 0; height: 30px; background-color: #ccc; display: block; width: 100%; } </style> <script type="text/javascript"> function onScroll() { if (window.pageYOffset > 0) document.getElementById('topbar').style.position = 'fixed'; else document.getElementById('topbar').style.position = 'absolute'; } function onLoad() { var str = ""; for (var i = 0; i < 300; i++) { str += "Test<br/>"; } document.getElementsByTagName('body')[0].innerHTML += str; window.onscroll = onScroll; } </script> </head> <body onload="onLoad()"> <div id="topbar">Fixed bar</div> </body> </html>