UMIX OS
大した理由も無いが、2年前(1年半前)に参加したICFP2006(http://icfpcontest.org/)のUMIX動作をするコードを置いてみる。そこそこ探して公開されてるルーチンを漁ったが、ベンチマークでは一応一番速く動いてくれる。なので今更やってみたいなんて人がいるんならUMIXを作った後の状態からどーぞ。
メモリ管理についてはNULLアドレス以外では
- 本来の容量+1をアロケートする
- サイズを0番目に記入
- +1したアドレスを返すことで普通に使える
という処理をしている。もちろんfreeするときにはアドレスを-1する必要がある。
……という点まで含めてどこかの誰か(海外)のパクり。
ちなみに、ログインのためのユーザーとかパスワードなんて知ったこっちゃない。そこは自分で探しておくれ。
※追記で注意…64bit OSだと動かないですよ。ポインタとplatter(32bit unsigned int)を相互変換してるんで。
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef unsigned int uint; typedef unsigned char uchar; uint* prog = NULL; uint r[] = {0, 0, 0, 0, 0, 0, 0, 0}; uint pc = 0; uint* alloc(uint size) { uint* p = (uint*)calloc(size + 1, sizeof(uint)); p[0] = size; return (p + 1); } int init(int argc, char* argv[]) { uint zsize, size, dsize, i; FILE* fp; if( (fp = fopen((argc > 1) ? argv[1] : "sandmark.umz", "rb")) == NULL ) return 1; fseek(fp, 0, SEEK_END); zsize = ftell(fp); rewind(fp); printf("Program size = %d Byte\n", zsize); zsize *= 2; prog = (uint*)malloc(zsize); size = dsize = 0; do { size += dsize; dsize = fread(prog + size, 1, zsize - size, fp); } while( dsize > 0 ); fclose(fp); size /= sizeof(uint); /* LE -> BE */ for( i = 0 ; i < size ; i++ ) { uchar *t = (uchar*)&prog[i]; prog[i] = ((((((uint)t[0] << 8) | t[1]) << 8) | t[2]) << 8) | t[3]; } return 0; } int main(int argc, char* argv[]) { uint a, b, c, code, ope; if( init(argc, argv) ) { free(prog); return 1; } while( 1 ) { code = prog[pc++]; ope = (code >> 28) & 15; if( ope == 13 ) { a = (code >> 25) & 7; r[a] = code & 0x1ffffff; continue; } if( ope < 7 ) { a = (code >> 6) & 7; b = (code >> 3) & 7; c = code & 7; switch( ope ) { case 0: if( r[c] ) r[a] = r[b]; break; case 1: if( r[b] ) r[a] = ((uint*)r[b])[r[c]]; else r[a] = prog[r[c]]; break; case 2: if( r[a] ) ((uint*)r[a])[r[b]] = r[c]; else prog[r[b]] = r[c]; break; case 3: r[a] = r[b] + r[c]; break; case 4: r[a] = r[b] * r[c]; break; case 5: r[a] = r[b] / r[c]; break; case 6: r[a] = ~(r[b] & r[c]); break; } continue; } switch( ope ) { case 7: goto HALT; case 8: r[(code >> 3) & 7] = (uint)alloc(r[code & 7]); break; case 9: free((uint*)r[code & 7] - 1); break; case 10: putchar(r[code & 7]); fflush(stdout); break; case 11: r[code & 7] = getchar(); break; case 12: b = (code >> 3) & 7; if( r[b] ) { int size = *((uint*)r[b] - 1); prog = (uint*)realloc((void*)prog, size * sizeof(uint)); memcpy(prog, (void*)r[b], size * sizeof(uint)); } pc = r[code & 7]; break; default: printf("Unknown operation %u\n", ope); goto HALT; } } HALT: return 0; }