Monday, December 14, 2009

Barrier mechanism

While we make threads and make it work, sometime we want to make them stop at a certain point of work flow. Barrier can be used to make them wait till the other threads end their jobs. Here is an example. 5th thread will sleep 5 seconds and the other threads will wait with pthread_barrier_wait().

#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

#define THREADNUM 5

pthread_barrier_t barrier;

struct thread_ctx {
    pthread_t tid;
    int idx;
} thr_ctx[THREADNUM];

void *start_thread(void *);
void clean_thread();
void exit_w_err(const char *);

int main()
{
    int i;

    pthread_barrier_init(&barrier, NULL, THREADNUM);

    for(i = 0; i < THREADNUM; i++) {
        thr_ctx[i].idx = i;
        if (pthread_create(&thr_ctx[i].tid, NULL,
            start_thread, (void *)&thr_ctx[i])) {
            exit_w_err("thread_create");
        }
    }
    clean_thread();
}

void *start_thread(void *in_ctx)
{
    int res;
    struct thread_ctx *ctx;

    ctx = (struct thread_ctx *)in_ctx;

    /*
     * thread will wait with barrier
     */
    if (ctx->idx == THREADNUM - 1) {
        sleep(5);
        printf("thread (%d) arrived\n", ctx->idx);
    }
    else 
        printf("thread (%d) started to wait\n", ctx->idx);

    if ((res = pthread_barrier_wait(&barrier)) == EINVAL)
    {
        printf("\t errno : %d\n", res);
        return NULL;
    }

    return in_ctx;
}

void clean_thread(void)
{
    int i;
    void *res; // dummy pointer.

    for (i = 0; i < THREADNUM; i++) {
        pthread_join(thr_ctx[i].tid, &res);
    }

    return;
}

void exit_w_err(const char *msg)
{
    fprintf(stderr, "[ERROR] %s\n", msg);
    exit(0);
}

Thursday, December 10, 2009

13 ways to make your web page faster.

1. Remove trivial text - comment, tab, space, etc.
2. Cache ajax data if it's possible.
3. Set your css, javascript out of the page and include them. So that it would be cached.
4. Script, css optimization.
5. Adjust ETags.
6. Trim meta data of your img files. If you want resize it, send them as resized.
7. Use gzip compression option so that compressed data will be transmitted.
8. Javascript DOM Access is slow. Cache them if it's possible.
9. Set your css on the top so that browser can render your page as it gets data.
10. Browser can't download javascript in parallel way. Put them on the bottom.
11. Don't use css expression, filter.
12. Set cache in response header field.
13. Note that some mobile devices cache only page smaller than 25kb.

Wednesday, October 28, 2009

Sample thread code using mutex

For your education.


#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#define THREAD_NUM 5
#define MUTEX_ENABLED 0

struct thread_ctx
{
    int id;
    pthread_t tid;
} ctx_arr[THREAD_NUM];

int fd;
pthread_mutex_t *mtx;
pthread_mutexattr_t *mtxattr;

void * t_worker(void *arg)
{
    int i;
    char buf[10];

    struct thread_ctx *ctx = (struct thread_ctx *)arg;
    sprintf(buf, "%d\n", ctx->id);

    if (MUTEX_ENABLED)
        pthread_mutex_lock(mtx);

    // critical section
    for (i = 0; i < 4; i++)
    {  
        write(fd, buf, strlen(buf));
        usleep(100);
    }

    if (MUTEX_ENABLED)
        pthread_mutex_unlock(mtx);

    return (void *)ctx;
}

int main()
{
    int i;
    void *res;

    // open file
    fd = open("result.dat", O_CREAT|O_RDWR);
    if (fd < 0)
    {  
        printf("[ERROR] file open failure - %s.\n", strerror(fd));
        return -1;
    }

    // init mutex
    mtx = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
    mtxattr = (pthread_mutexattr_t *)malloc(sizeof(pthread_mutexattr_t));
    pthread_mutexattr_init(mtxattr);
    pthread_mutexattr_settype(mtxattr, PTHREAD_MUTEX_TIMED_NP);
    pthread_mutex_init(mtx, mtxattr);

    for (i = 0; i < THREAD_NUM; i++)
    {  
        ctx_arr[i].id = i;
        if (pthread_create(&ctx_arr[i].tid, NULL, t_worker,
                (void *)(ctx_arr + i)) != 0)
        {  
            printf("[ERROR] pthread_create failure\n");
        }
    }

    // To join all threads.
    for (i = 0; i < THREAD_NUM; i++)
    {  
        pthread_join(ctx_arr[i].tid, &res);
    }
    printf("[MSG] All threads are joined.\n");

    close(fd);
    free(mtx);
    free(mtxattr);

    return 0;
}


result :

cat result.dat # mutex off
2
1
0
1
0
1
3
0
1
2
3
4
4
4
4
3
4
4
4
4
cat result.dat # mutex on
1
1
1
1
0
0
0
0
2
2
2
2
3
3
3
3
4
4
4
4

Wednesday, October 21, 2009

installing posix man pages

For example, if you can't get man pages for pthread_create,

(Some blogs recommend you to install glibc-doc, but it wouldn't work.)

just do 'sudo apt-get install manpages-posix-dev'

Tuesday, August 18, 2009

Using autocomplete plugin of jQuery with django

1. Download jQuery auto complete plugin here.

2. Unzip it.

3. Copy below files from the unzipped onto your javascript directory.
  • jquery.autocomplete.css
  • jquery.autocomplete.js
  • jquery.bgiframes.min.js
  • jquery.dimensions.js (from jquery.com)
4. Include them.

5. If you want to activate auto complete onto the html tag with id 'qwerty', add following code onto your js code area.

$(document).ready(function(){
  $("#qwerty").autocomplete{
    '/ajax/autocomplete',
    {multiple: true, multipleSeparator: ', '}
  );
});

6. Setup urls.py so that it can handle '/ajax/autocomplete' with ajax_autocomplete module.

7. in views.py, make ajax_autocomplete module like,

def ajax_autocomplete(request):
  if request.GET.has_key('q'):
    # Write your code here (search dictionary or db, etc..)
    # And put it onto res (separated with '\n').
    return HttpResponse(res)
  return HttpResponse()

8. Done. Have fun :)

Tuesday, August 4, 2009

MSN proxy with ssh using Pidgin

If your company blocked MSN port and you have accessable server out of your company, use it as a proxy with ssh -D option.

Set tunnel with '>ssh -D 1234 yourserveraddress.com'.
(You can use any port number instead of 1234.)

Set proxy option in your pidgin.
Host : localhost
Port : 1234

That's all. Have fun.

Monday, August 3, 2009

Using django - Accounts

Django auth system is in django.contrib.auth.
(Included in INSTALLED_APPS as a default)

Login page
You can use default django login handler.

<urls.py>
urlpatterns = patterns('',
  ...
  (r'^login/$', 'django.contrib.auth.views.login')
<eof>

You need to make a template for login page.

<templates/registration/login.html>
 <form methos='post' action='.'>
  <label for='id_username'>Username : </label>
  {{ form.username }}
  <br>
  <label for='id_password'>Password : </label>
  {{ form.password }}
  <br>
  <input type='hidden' name='next' value='/'/>
  <input type='submit' value='Login'/>
 </form>
<eof>

User objects methods

  • is_authenticated()

  • get_full_name()

  • email_user(subject, message, from_email=None)

  • set_password(raw_password)

  • check_password(raw_password)



Logout
<views.py>
from django.http import HttpResponseRedirect
from django.contrib.auth import logout

def logout_page(request):
  logout(request)
  return HttpResponseRedirect('/')
<eof>

<urls.py>
  ...
  (r'^logout/$', logout_page),
  ...
<eof>