<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>リリカル☆Lisp開発日記</title>
	<atom:link href="http://blog.bugyo.tk/lyrical/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.bugyo.tk/lyrical</link>
	<description>リリカルでLispな開発日記</description>
	<lastBuildDate>Tue, 09 Mar 2010 09:58:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>マンガで分かるLisp [その11]</title>
		<link>http://blog.bugyo.tk/lyrical/archives/584</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/584#comments</comments>
		<pubDate>Tue, 09 Mar 2010 09:58:34 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[マンガ]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=584</guid>
		<description><![CDATA[富山に行ってきました。

そこで素敵なお買い物カードを手に入れました。池田市のカードもこれくらい頑張ってほしい。
]]></description>
			<content:encoded><![CDATA[<p>富山に行ってきました。<br />
<a href="http://lambda.bugyo.tk/cdr/mwl20/mwl20.html"><img src="http://lambda.bugyo.tk/cdr/mwl20/mwl_20s.png"alt=""/></a><br />
そこで<a href="http://card.blog.nanto-e.com/detail-30477.html">素敵なお買い物カード</a>を手に入れました。<a href="http://blog.bugyo.tk/lyrical/archives/104">池田市のカード</a>もこれくらい頑張ってほしい。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/584/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>マンガで分かるLisp [Section 3.2]</title>
		<link>http://blog.bugyo.tk/lyrical/archives/580</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/580#comments</comments>
		<pubDate>Sat, 20 Feb 2010 04:40:00 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[マンガ]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=580</guid>
		<description><![CDATA[卒論出した。

あとは発表だけ。
]]></description>
			<content:encoded><![CDATA[<p>卒論出した。<br />
<a href="http://lambda.bugyo.tk/cdr/mwl19/mwl19.html"><img src="http://lambda.bugyo.tk/cdr/mwl19/mwl_19s.png"alt=""></a><br />
あとは発表だけ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/580/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>setjmpとlongjmpでユーザレベルスレッドを作る</title>
		<link>http://blog.bugyo.tk/lyrical/archives/572</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/572#comments</comments>
		<pubDate>Thu, 11 Feb 2010 04:40:10 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=572</guid>
		<description><![CDATA[「C言語のsetjmpとlongjmpがあればスレッドは作れる」
という話を聞いたので実際にやってみました。
まずは、完成品の使用例から。

#include &#60;stdio.h&#62;
#include &#60;s [...]]]></description>
			<content:encoded><![CDATA[<p>「C言語のsetjmpとlongjmpがあればスレッドは作れる」<br />
という話を聞いたので実際にやってみました。<br />
まずは、完成品の使用例から。</p>
<blockquote><pre>
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include "ahothread.h"

void f1(void *args)
{
  int i, j;
  char *str = (char*)args;
  for (i=0; i<3; i++) {
    puts(str);
    for (j=0; j<10000000; j+= 1 + rand()%2);
  }
}

int main(int argc, char **argv)
{
  int t1, t2;
  ahothread_init();
  t1 = ahothread_create(f1, "aho");
  t2 = ahothread_create(f1, "baka");
  ahothread_join(t1);
  ahothread_join(t2);
  return 0;
}
</pre>
</blockquote>
<p>ahoとbakaが交互に出ます。多分。<br />
ループの中でrand()を呼ぶことにより時間稼ぎをしているので、<br />
環境によっては交互じゃない可能性もあります。</p>
<p>次は、スレッドの中身で、もっとも重要な部分。</p>
<blockquote><pre>
int ahothread_create(void (*func)(void*), void *args)
{
  int id = search_free_thread();
  thread_table[id].state = ALIVE;
  if (setjmp(thread_table[current_thread].jb) == 0) {
    if (id > current_thread) {
      alloca((id-current_thread) * FRAME_SIZE);
    }
    else {
      assert(0);
    }
    current_thread = id;
    func(args);
  }
  return id;
}

void ahothread_yield()
{
  if (setjmp(thread_table[current_thread].jb) == 0) {
    int next = search_alive_thread();
    current_thread = next;
    longjmp(thread_table[next].jb, 1);
  }
}
</pre>
</blockquote>
<p>ahothread_createは、setjmpで現在の状態を記憶し、<br />
allocaでスタックポインタを適当に押し上げた後に、(別のスレッドとして)目的の関数を呼びます。<br />
ahothread_yieldは、setjmpで現在の状態を記憶し、<br />
適当な(多くの場合、現在とは別の)スレッドを探し、longjmpで制御を移します。<br />
ahothread_yieldを定期的に呼ぶことにより、実行するスレッドが定期的に切り替わります。</p>
<p>最後に、全部のソースを載せておきますが、<br />
かなりやっつけで作ったのでバグが沢山埋もれている可能性があります。</p>
<blockquote><pre>
#include &lt;stdlib.h&gt;
#include &lt;setjmp.h&gt;
#include &lt;assert.h&gt;
#include &lt;signal.h&gt;
#include &lt;sys/time.h&gt;

#define MAX_THREAD 32
#define FRAME_SIZE 10240

#define DEAD 0
#define ALIVE 1
#define JOIN 2

struct thread_data {
  jmp_buf jb;
  int state;
  int wait;
};

struct thread_data thread_table[MAX_THREAD];
static int current_thread = 0;
static int num_thread = 1;

static int search_alive_thread()
{
  int i;
  for (i=current_thread+1; i&lt;num_thread; i++) {
    if (thread_table[i].state == ALIVE) {
      return i;
    }
  }
  for (i=0; i&lt;=current_thread; i++) {
    if (thread_table[i].state == ALIVE) {
      return i;
    }
  }
  assert(0);
  return -1;
}

static int search_free_thread()
{
  int i = num_thread++;
  assert(i < MAX_THREAD);
  return i;
}

static int search_join_thread(int id)
{
  int i;
  for (i=0; i&lt;num_thread; i++) {
    if (thread_table[i].state == JOIN &#038;&#038;
        thread_table[i].wait == id) {
      return i;
    }
  }
  return -1;
}

void ahothread_yield()
{
  if (setjmp(thread_table[current_thread].jb) == 0) {
    int next = search_alive_thread();
    current_thread = next;
    longjmp(thread_table[next].jb, 1);
  }
}

void ahothread_join(int id)
{
  if (thread_table[id].state != DEAD) {
    thread_table[current_thread].state = JOIN;
    thread_table[current_thread].wait = id;
    ahothread_yield();
  }
}
void ahothread_exit()
{
  int join;
  if (current_thread == 0) {
    exit(0);
  }
  join = search_join_thread(current_thread);
  if (join != -1) {
    thread_table[join].state = ALIVE;
  }
  thread_table[current_thread].state = DEAD;
  ahothread_yield();
}

int ahothread_create(void (*func)(void*), void *args)
{
  int id = search_free_thread();
  thread_table[id].state = ALIVE;
  if (setjmp(thread_table[current_thread].jb) == 0) {
    if (id > current_thread) {
      alloca((id-current_thread) * FRAME_SIZE);
    }
    else {
      assert(0);
    }
    current_thread = id;
    func(args);
  }
  return id;
}

static void ahothread_handler(int sig)
{
  if (num_thread > 1) {
    ahothread_yield();
  }
}

void ahothread_init()
{
  struct sigaction sa = {
    .sa_handler = ahothread_handler,
    .sa_flags = SA_RESTART
  };
  struct itimerval it = {};
  thread_table[0].state = ALIVE;
  it.it_interval.tv_sec = 0;
  it.it_interval.tv_usec = 100000;
  it.it_value = it.it_interval;
  sigemptyset(&#038;sa.sa_mask);
  sigaction(SIGALRM, &#038;sa, NULL);
  setitimer(ITIMER_REAL, &#038;it, 0);
}
</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/572/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>マンガで分かるLisp [その10]</title>
		<link>http://blog.bugyo.tk/lyrical/archives/569</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/569#comments</comments>
		<pubDate>Mon, 01 Feb 2010 03:12:18 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[マンガ]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=569</guid>
		<description><![CDATA[もう2月になってしまった。

卒論の締め切りが迫ってきた。
]]></description>
			<content:encoded><![CDATA[<p>もう2月になってしまった。<br />
<a href="http://lambda.bugyo.tk/cdr/mwl18/mwl18.html"><img src="http://lambda.bugyo.tk/cdr/mwl18/mwl_18s.png"></a><br />
卒論の締め切りが迫ってきた。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/569/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>マンガで分かるLisp [Section 3.1]</title>
		<link>http://blog.bugyo.tk/lyrical/archives/564</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/564#comments</comments>
		<pubDate>Wed, 20 Jan 2010 06:23:39 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[マンガ]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=564</guid>
		<description><![CDATA[お久しぶりです。

もうすぐ、このサイトができてから3年になります。
]]></description>
			<content:encoded><![CDATA[<p>お久しぶりです。<br />
<a href="http://lambda.bugyo.tk/cdr/mwl17/mwl17.html"><img src="http://lambda.bugyo.tk/cdr/mwl17/mwl_17s.png"alt=""></a><br />
もうすぐ、このサイトができてから3年になります。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/564/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>今年1年を振り返る</title>
		<link>http://blog.bugyo.tk/lyrical/archives/558</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/558#comments</comments>
		<pubDate>Thu, 31 Dec 2009 11:16:46 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=558</guid>
		<description><![CDATA[適当に今年の出来事を10個集めてみました。
ポケステでLispが動いた
去年の年末から今年の年始にかけてポケステ向けのLispインタプリタを作りました。
フルマラソン走った
翌日の筋肉痛が凄かったです。タイムが遅かったの [...]]]></description>
			<content:encoded><![CDATA[<p>適当に今年の出来事を10個集めてみました。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/211">ポケステでLispが動いた</a><br />
去年の年末から今年の年始にかけてポケステ向けのLispインタプリタを作りました。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/221">フルマラソン走った</a><br />
翌日の筋肉痛が凄かったです。タイムが遅かったのが残念。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/232">Mac Book買った</a><br />
非常に使いやすいです。いい買い物をした。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/235">自転車で琵琶湖一周</a><br />
大体時速20kmをキープし続けることができました。次走るときはもう少し良い自転車で走りたい。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/category/manga">マンガで分かるLispがたくさん</a><br />
最近停滞気味ですが、最後まで続けたいと思います。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/248">BiwaSchemeでゲーム作った</a><br />
Schemeでブラウザ向けのゲームが作れるというのは面白いですね。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/253">院試受かった</a><br />
院試が近い時期に彦根まで自転車でひこねのよいにゃんこのグッツを買いにいったりしましたが、<br />
試験日やその前日にカツ丼やチキンカツ定食を食べたおかげか無事合格できました。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/259">CLでJavaのアセンブラ/逆アセンブラを作った</a><br />
CLでプログラムを書くのも大分慣れてきたおかげか、比較的楽に書くことができました。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/266">cl-openglで遊んだ</a><br />
こいうプログラムを書くのは楽しいですね。</p>
<p><a href="http://blog.bugyo.tk/lyrical/archives/558">今年1年振り返ってみたけど、ろくなことをやってない</a><br />
特に書くことがなかったので再帰的なリンクを張っておきます。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/558/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Prologでオシオキ</title>
		<link>http://blog.bugyo.tk/lyrical/archives/554</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/554#comments</comments>
		<pubDate>Tue, 01 Dec 2009 10:12:05 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=554</guid>
		<description><![CDATA[メモリたくさん欲しいです(Yet Another Ranha)
を読んで、私もオシオキしてみることにしました。
画像が小さくて良く見えませんが、4人が水泳大会の順位を言っていて、
そのなかで一人だけ嘘をついているのでその [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://d.hatena.ne.jp/ranha/20091201/1259602543">メモリたくさん欲しいです(Yet Another Ranha)</a><br />
を読んで、私もオシオキしてみることにしました。</p>
<p>画像が小さくて良く見えませんが、4人が水泳大会の順位を言っていて、<br />
そのなかで一人だけ嘘をついているのでその人を見つけ出すみたいです。<br />
(順位も求めるみたいですが、誰が嘘をついているか分かれば順位は自明なので、<br />
　順位は表示したりしていません。)</p>
<p>私はranhaさんのように<s>変態</s>紳士では無いので、素直にPrologを使いました。<br />
処理系はSWI-Prolog。</p>
<blockquote><pre>
;; 二つの集合が等しいか
set_eq([], []).
set_eq([X|Xs], Y) :- member(X, Y), delete(Y, X, Z), set_eq(Xs, Z).
;; 4人が別々の順位になるか
rank(X,Y,Z,W) :- set_eq([X,Y,Z,W], [1,2,3,4]).
;; それぞれの言い分
ayu(1).
ayu(2).
suzu(1).
suzu(2).
naru(N, S) :- N < S.
kotori(1).
;; オシオキされる人
oshioki(ayu)   :- suzu(S), kotori(K), rank(_,S,N,K), naru(N, S).
oshioki(suzu)  :- ayu(A), kotori(K), rank(A,S,N,K), naru(N, S).
oshioki(naru)  :- ayu(A), suzu(S), kotori(K), rank(A,S,_,K).
oshioki(kotori):- ayu(A), suzu(S), rank(A,S,N,_), naru(N, S).
</pre>
</blockquote>
<p>で、動かしてみたら、誰をオシオキしたらいいのかすぐに分かります。</p>
<blockquote><pre>
?- oshioki(X).
X = suzu
</pre>
</blockquote>
<p>SWI-Prologのdeleteの引数が想像と逆ですこしハマりました。<br />
それにしてもあまりきれいじゃないですね。<br />
もう少しうまく書けないものか。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/554/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>マンガで分かるLisp [その9]</title>
		<link>http://blog.bugyo.tk/lyrical/archives/551</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/551#comments</comments>
		<pubDate>Wed, 25 Nov 2009 11:29:09 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[マンガ]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=551</guid>
		<description><![CDATA[Movable TypeからWordPressに移行しました。

動作が明らかに速くなって快適です。
]]></description>
			<content:encoded><![CDATA[<p>Movable TypeからWordPressに移行しました。<br />
<a href="http://lambda.bugyo.tk/cdr/mwl16/mwl16.html"><img src="http://lambda.bugyo.tk/cdr/mwl16/mwl_16s.png" alt=""></a><br />
動作が明らかに速くなって快適です。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/551/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>マンガで分かるLisp [Section 2.4]</title>
		<link>http://blog.bugyo.tk/lyrical/archives/267</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/267#comments</comments>
		<pubDate>Tue, 17 Nov 2009 13:18:42 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[マンガ]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=267</guid>
		<description><![CDATA[気がついたらブログを1ヶ月以上放置していた。

なんか色々あった。マンガで分かるLispのトップページに英語訳が付いたり。
]]></description>
			<content:encoded><![CDATA[<p>気がついたらブログを1ヶ月以上放置していた。<br />
<a href="http://lambda.bugyo.tk/cdr/mwl15/mwl15.html"><img src="http://lambda.bugyo.tk/cdr/mwl15/mwl_15s.png" alt=""></a><br />
なんか色々あった。マンガで分かるLispのトップページに英語訳が付いたり。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/267/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>cl-openglで変なもの作った</title>
		<link>http://blog.bugyo.tk/lyrical/archives/266</link>
		<comments>http://blog.bugyo.tk/lyrical/archives/266#comments</comments>
		<pubDate>Mon, 12 Oct 2009 15:31:46 +0000</pubDate>
		<dc:creator>zick</dc:creator>
				<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://blog.bugyo.tk/lyrical/?p=266</guid>
		<description><![CDATA[ものすごく適当に書いてもそれっぽく動く。cl-opengl凄い。
Common Lispでゲームを作るのは案外簡単な気がしてきた。

背景の写真は滋賀県の某所で撮ったものです。
画面のキャプチャにはCopernicusを [...]]]></description>
			<content:encoded><![CDATA[<p>ものすごく適当に書いてもそれっぽく動く。cl-opengl凄い。<br />
Common Lispでゲームを作るのは案外簡単な気がしてきた。<br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/7QEduKeEvPE&#038;hl=ja&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/7QEduKeEvPE&#038;hl=ja&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br />
背景の写真は滋賀県の某所で撮ったものです。<br />
画面のキャプチャには<a href="http://danicsoft.com/projects/copernicus/">Copernicus</a>を使用しました。<br />
ただ、Mac Bookのスペックの問題か、秒間2フレームほどでしか撮影できなかったので、<br />
cl-openglのプログラムの方をゆっくり動かし、撮影した動画をiMovieで早送りしました。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bugyo.tk/lyrical/archives/266/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
