'2010/03'에 해당되는 글 3건

< PREV #1  | NEXT >

struct timeval & long long :: 2010/03/31 23:56

현재 시각을 측정하는 손쉬운 방법은 gettimeofday()를 이용하는 것으로,
이때 struct timeval 구조체를 이용하게 된다.

<API>
int gettimeofday(struct timeval *tv, struct timezone *tz);

<example>
struct timeval tv;
if (!gettimeofday(&tv, NULL)) fprintf(stderr, "%s error at %d\n", __FUNCTION__, __LINE__);


그리고 /usr/include/sys/time.h 파일을 보면 다음과 같은 편리한 macro를 제공함을 알 수 있다.
__USE_BSD 가 언제 #define 되는지 모르겟지만 이용 할 수 있었다.
stuct timeval 에 sec 부분과 usec 부분으로 분리되어 있는데 아래 3개 macro는 유용할 것이다.
timercmp(a, b, CMP)
timeradd(a, b, result)
timersub(a, b, result)
예를 들어 현재 시각을 매번 측정하여 그 차이를 위의 timersub를 통해 손쉽게 계산할 수 있고,
그 차이를 timeradd를 통해 손쉽게 계속 더해갈 수 있다.

#ifdef __USE_BSD
/* Convenience macros for operations on timevals.
   NOTE: `timercmp' does not work for >= or <=.  */
# define timerisset(tvp)        ((tvp)->tv_sec || (tvp)->tv_usec)
# define timerclear(tvp)        ((tvp)->tv_sec = (tvp)->tv_usec = 0)
# define timercmp(a, b, CMP)                                                  \
  (((a)->tv_sec == (b)->tv_sec) ?                                             \
   ((a)->tv_usec CMP (b)->tv_usec) :                                          \
   ((a)->tv_sec CMP (b)->tv_sec))
# define timeradd(a, b, result)                                               \
  do {                                                                        \
    (result)->tv_sec = (a)->tv_sec + (b)->tv_sec;                             \
    (result)->tv_usec = (a)->tv_usec + (b)->tv_usec;                          \
    if ((result)->tv_usec >= 1000000)                                         \
      {                                                                       \
        ++(result)->tv_sec;                                                   \
        (result)->tv_usec -= 1000000;                                         \
      }                                                                       \
  } while (0)
# define timersub(a, b, result)                                               \
  do {                                                                        \
    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                             \
    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;                          \
    if ((result)->tv_usec < 0) {                                              \
      --(result)->tv_sec;                                                     \
      (result)->tv_usec += 1000000;                                           \
    }                                                                         \
  } while (0)
#endif  /* BSD */

그런데 struct timeval 을 그대로 이용할 때는 불편할 때가 있다.
예를 들어 sec을 일부와 usec의 일부만을 출력하거나
다른 일반 int type으로 저장한 시간과 비교할 때가 그럴 수 있을 것이다.

(어디까지나 선택사항이지만) 이때는 struct timeval 을 long long 으로 변환해서 저장하는 것이 편하다.
아래와 같이 long long time 에 저장하는 것이다.
time = tv.tv_sec * 1000000LL + tv.tv_usec;

참고적으로 혹시 전환 과정에서 data 손실을 우려할 수 있으나 그렇지 않다.
long long type이 보통 8byte 이고, struct timeval의 tv_sec 과 tv_usec 이 각각 4byte 인데,
실제로는 tv_usec의 값은 최대 10^6 - 1 로서, 이는 2진수 값으로 20bit 이하이다.
따라서 20bit 인 2.5byte를 shift 하더라도 데이터 손실이 없는 것이다.

아래는 관련해서 테스트한 소스 코드이며,
struct timeval : 1270047284.534099
long long      : 1270047284534099
실행결과 바로 위와 같이 두 값이 같음을 알 수 있다.

#include <stdio.h>
#include <sys/time.h>

int main(int argc, char *argv[])
{
        struct timeval tv;
        long long time;

        if (gettimeofday(&tv, NULL)) fprintf(stderr, "%s error at %d\n", __FUNCTION__, __LINE__);
        time = tv.tv_sec * 1000000LL + tv.tv_usec;

        printf("struct timeval : %d.%-6d\n", (int)tv.tv_sec, (int)tv.tv_usec);
        printf("long long      : %lld\n", time);

        return 0;
}

크리에이티브 커먼즈 라이센스
Creative Commons License
2010/03/31 23:56 2010/03/31 23:56
Trackback Address :: http://www.neodelicious.com/trackback/227

xtrace - Xclient program이 사용하는 xlib API를 보자 :: 2010/03/06 09:42

<배경>

strace를 사용하고자 했는데, 어쩌다 xtrace가 있더라.
혹시 Xserver와 관련해서 뭔가 trace 하는가 했는데, 예감이 맞았다.


<결론>

결론부터 얘기하면, Xclient와 Xserver 사이의 X11 Protocol 상의 정보를 훔쳐볼 수 있다.

즉, Xlib을 사용하는 Xclient 프로그램 혹은 Xlib를 backend로 사용하는 GTK 프로그램 등의 프로그램의 소스를 보지 않아도 내부적으로 사용하는 Xlib API의 이름을 알 수 있다.

또한 해당 API를 통해 Xserver 와 주고받는 정보도 볼 수 있는데 어느 정도까지 제공해주는지는 확인해봐야 할 것 같다. 기본 Xlib API는 되는듯 한데, 다른 X extension상의  API는 대부분 어느 API인지 그 이름조차 안 나오는 것 같다. 그래도 특정 Xclient에서 어떤 Xlib API를 사용하는지 살펴보는 용도로는 사용할 수 있을 것 같다.

그밖에 옵션을 통해 시각을 출력할 수 있는데, 이를 통해 특정 Xclient 프로그램의 Xserver 이용 비중을 측정한다거나, 특정 Xlib API에 대한 이용 비중을 측정하는 것은 좀 무리가 있어 보인다.

정확하게 하려면 역시 Xserver 내에 logging 소스를 추가하고 이를 분석하는 게 정확할 것 같다.


<추가 사항>
  1. 다양한 옵션을 제공하는데, 이중 일부를 소개한다.
  2. -D [name] : 가상으로 사용할 display 값으로,  '-D :9' 처럼 쓰면 되고 기본 적으로 :9 로 되어 있다.
  3. -d [name] : 기본 Xserver의 display 값으로 안 쓰면 기본값을 사용한다.
  4. -k : 더 이상 Xclient 가 없어도 xtrace를 종료하지 않는다.
  5. -i : Xclient가 Xserver에 보내는 매 request를 보낼지 선택할 수 있다.
  6. -o [filename] : stdout 대신에 특정 파일에 출력한다.
  7. --timestamps : 매 정보에 대한 시각을 출력한다.
  8. --relative-timestamps : 매 정보에 대한 시각을 출력하되, 첫 연결을 기준으로 상대적 시각을 출력한다.

<참고 사항>

opensource 로 소스를 받을 수 있고,
ubuntu에서는 apt-get install xtrace 로 설치할 수 있다.
http://xtrace.alioth.debian.org/ 를 참고해서 자세한 정보를 얻을 수 있는데, 설치 후 man xtrace 로 옵션에 대한 정보를 볼 수 있다.


<추력 정보 설명>

아래  <사용 예>에서 방법을 보도록 하고, 바로 아래 xtrace 의 출력 결과 예를 살펴 보자.

0.  1 000:<:0001: 20: Request(98): QueryExtension  name='BIG-REQUESTS'
0.  1 000:>:0001:32: Reply to QueryExtension: present=true(0x01) major-opcode=142 first-event=0 first-error=0


좌측 순으로 시각, 방향(<는 Xserver로, > Xclient로), data size(?) 이고, 그 이후는 해당 정보이다.
X11 protocol에는 Xclient가 보내는 request와 Xserver가 보내는 reply, error, event 가 있는데 이에 대한 정보를 보여준다. 특히 request는 어떤 request 인지 major, minor 번호와 해당 API 이름와 정보를 출력한다.

아래는 xtrace 참고 웹 페이지에서 가져온 것으로,
xtrace에서 keyboard extension에 대한 정보를 갖고 있지 않아서 152번 Major에 대한 request가 무엇인지 알 수 없어 'unknown'으로 보여주고 있다.

000:>:0x0004:32: Reply to BigReqEnable: maximum-request-length=1048575
000:<:0005: 20: Request(98): QueryExtension name='XKEYBOARD'
000:>:0x0005:32: Reply to QueryExtension: present=true(0x01) major-opcode=152 first-event=111 first-error=178
000:<:0006: 8: Request(152): unknown


<사용 예>

$ xtrace --relative-timestamps &
No display name to create specified, trying :9
$ DISPLAY=:9 xdpyinfo
Got connection from unknown(local)
0.  0 000:<: am lsb-first want 11:0 authorising with 'MIT-MAGIC-COOKIE-1' of length 16
0.  1 000:>: Success, version is 11:0-52704.
0.  1 000:<:0001: 20: Request(98): QueryExtension  name='BIG-REQUESTS'
0.  1 000:>:0001:32: Reply to QueryExtension: present=true(0x01) major-opcode=142 first-event=0 first-error=0
0.  1 000:<:0002:  4: BIG-REQUESTS-Request(142,0): BigReqEnable
0.  2 000:>:0002:32: Reply to BigReqEnable: maximum-request-length=4194303
0.  2 000:<:0003: 20: Request(55): CreateGC cid=0x04a00000 drawable=0x000000fa  values={background=0x00ffffff}
0.  2 000:<:0004: 24: Request(20): GetProperty delete=false(0x00) window=0x000000fa property=0x17("RESOURCE_MANAGER") type=0x1f("STRING") long-offset=0x00000000 long-length=0x05f5e100
0.  2 000:>:0004:208: Reply to GetProperty:  type=0x1f("STRING") bytes-after=0x00000000   data='Xcursor.size:\t18\nXcursor.theme:\tHuman\nXcursor.theme_core:\ttrue\nXft.antialias:\t1\nXft.dpi:\t96\nXft.hinting:\t1\nXft.hintstyle:\thintslight\nXft.lcdfilter:\tlcddefault\nXft.rgba:\trgb\n'
0.  2 000:<:0005: 20: Request(98): QueryExtension  name='XKEYBOARD'
0.  3 000:>:0005:32: Reply to QueryExtension: present=true(0x01) major-opcode=144 first-event=96 first-error=153
0.  3 000:<:0006:  8: XKEYBOARD-Request(144,0): UseExtension major=1 minor=0
0.  3 000:>:0006:32: Reply to UseExtension: major=1 minor=0
0.  4 000:<:0007:  4: Request(43): GetInputFocus
0.  4 000:>:0007:32: Reply to GetInputFocus: revert-to=Parent(0x02) focus=0x04600005
0.  4 000:<:0008:  4: Request(99): ListExtensions
0.  4 000:>:0008:300: Reply to ListExtensions: number of STRs in names=0x1b names={ s='MIT-SCREEN-SAVER'},{ s='XFree86-VidModeExtension'},{ s='XFree86-DGA'},{ s='DPMS'},{ s='XVideo'},{ s='X-Resource'},{ s='DOUBLE-BUFFER'},{ s='RECORD'},{ s='DRI2'},{ s='Generic Event Extension'},{ s='SHAPE'},{ s='MIT-SHM'},{ s='XInputExtension'},{ s='XTEST'},{ s='BIG-REQUESTS'},{ s='SYNC'},{ s='XKEYBOARD'},{ s='XC-MISC'},{ s='SECURITY'},{ s='XFIXES'},{ s='RENDER'},{ s='RANDR'},{ s='XINERAMA'},{ s='Composite'},{ s='DAMAGE'},{ s='GLX'},{ s='SGI-GLX'},{ s=''},{ s=''};
0.  6 000:<:0009: 12: Request(97): QueryBestSize class=Cursor(0x00) drawable=0x000000fa width=65535 height=65535
0.  6 000:>:0009:32: Reply to QueryBestSize: width=64 height=64
0. 59 000:<:000a:  8: Request(60): FreeGC gc=0x04a00000
0. 59 000:<:000b:  4: Request(43): GetInputFocus
0. 59 000:>:000b:32: Reply to GetInputFocus: revert-to=Parent(0x02) focus=0x04600005

크리에이티브 커먼즈 라이센스
Creative Commons License
2010/03/06 09:42 2010/03/06 09:42
Trackback Address :: http://www.neodelicious.com/trackback/226

홈페이지 텍스트큐브로 전환 :: 2010/03/03 00:17

<배경>
기존 테터툴즈 프로그램에서 잘 쓰던 파일 업로드 기능이 안 되어서 해결 방법을 알아보던 중
텍스트큐브라는 이름의 테터툴즈 차기 버전으로 업그레이트 하면 해결된다고 한다.

이 와중에서 기존 mireene 호스팅 서버의 PHP 버전이 낮아서 서버 이전을 요청한 후 확인하니,
서버 이전은 되었는데 mysql 복구가 제대로 안 되어 있었다.
이를 해결하려고 mysql 전혀 몰라서 mysql 명령어도 찾아보고
별 짓을 다 해서 거의 6시간 이상 낑낑대어서 해결했다.

참고적으로 테터툴즈에서 기존에 사용하던 tt_ 접두사의 DB를 그대로 사용하면서 할 수도 있는 것 같은데,
기존의 것과 중복되는 것 같아 적당히 되는 것 같은(?) 확인만 했다.
아무튼 아래와 같이 해결했다.

<자료 복구>
우선 기존 서버에 있는 html 이하의 디렉토리를 모두 새 서버로 복사했고,
sql data 가 없어서 실제로 블로그가 정상 동작하지 않음을 확인했다.
그래서 우선 기존 서버의 mysql에서 다음과 같이 sql data를 파일로 추출했다.
mysqldump -u delicious -p delicious > dump_100228.sql
그리고 이 파일을 새 서버로 다음과 같이 sql에 적용하려 하니,
mysql -u delicious -p delicous < dump_10228.sql
적용된 것은 같은데 중복되는 값이 있다는 에러가 났다.
여튼 그래서 한참 찾다가 아래 주소를 통해 호스팅 업체에서
www.neodelicious.com/mysql
mysql를 편하게 이용할 수 있는 기능을 제공하고 있었다.
여기에서 기존에 delicious database의 잘못된 data를 모두 삭제(drop)하고,
또한 위에서 만든 dump_10228.sql 파일을 에러 없이 적용(sql > Location of the textfile)했다.

<텍스트큐브 설정>
다음과 같이 먼저 준비하고,
tar xvzf ./etc/textcube-1.8.2-expansion.tar.gz
mv ./tc/ ./html
chmod 757 ./html ./html/skin/blog/
아래 1~7단계를 모두 한 후에
아래와 같이 권한 설정을 복구했다.
chmod 755 ./html ./html/skin/blog/

1 단계
http://www.neodelicious.com/setup.php
2 단계
'새로운 텍스트큐브를 설정합니다'
3 단계
데이터베이스 관리 시스템 : MySQL
데이터베이스 서버 : localhost
데이터베이스 포트 : 3306
데이터베이스 이름 : delicious
데이터베이스 사용자명 : delicious
데이터베이스 암호 : **********
테이블 식별자 : tc_
4 단계
$ chmod 777 ./html ./html/skin/blog/
5 단계
단일 사용자 : 단일 블로그
6 단계
이메일 : kjwdelicious@naver.com
비밀번호 : *******
블로그 식별자 : delicious
필명 : delicious
7 이후 단계
'텍스트큐브 관리 툴'로 로그린 하신 후 필요사항을 수정하십니오
http://www.neodelicious.com/owner
그리고 아래 주소에 가서
http://www.neodelicious.com
설정 > 데이터 관리 > 데이터를 복원합니다.
$ cp ./Tattertools-Backup-20100228.xml ./html
웹에서 파일 가져오기
백업파일 URL : http://www.neodelicious.com/Tattertools-Backup-20100228.xml
크리에이티브 커먼즈 라이센스
Creative Commons License
2010/03/03 00:17 2010/03/03 00:17
Trackback Address :: http://www.neodelicious.com/trackback/225
< PREV #1  | NEXT >