현재 시각을 측정하는 손쉬운 방법은 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;
}
'2010/03'에 해당되는 글 3건 |
||
struct timeval & long long :: 2010/03/31 23:56Trackback 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 소스를 추가하고 이를 분석하는 게 정확할 것 같다. <추가 사항>
<참고 사항> opensource 로 소스를 받을 수 있고, ubuntu에서는 apt-get install xtrace 로 설치할 수 있다. http://xtrace.alioth.debian.org/ 를 참고해서 자세한 정보를 얻을 수 있는데, 설치 후 man xtrace 로 옵션에 대한 정보를 볼 수 있다. <추력 정보 설명> 아래 <사용 예>에서 방법을 보도록 하고, 바로 아래 xtrace 의 출력 결과 예를 살펴 보자. 좌측 순으로 시각, 방향(<는 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 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 Trackback Address :: http://www.neodelicious.com/trackback/225
|
||
