void pinnedGarbageCollect() { for(mem_iter iter = pinned_maps.begin(); iter != pinned_maps.end(); ++iter) { if ((iter->second).is_free) { pinnedFreeWrapper(iter->first); } } mem_iter memory_curr = pinned_maps.begin(); mem_iter memory_end = pinned_maps.end(); while(memory_curr != memory_end) { if (memory_curr->second.is_free) { pinned_maps.erase(memory_curr++); } else { ++memory_curr; } } }
T* pinnedAlloc(const size_t &elements) { managerInit(); T* ptr = NULL; // Allocate the higher megabyte. Overhead of creating pinned memory is // more so we want more resuable memory. size_t alloc_bytes = divup(sizeof(T) * elements, 1048576) * 1048576; if (elements > 0) { // FIXME: Add better checks for garbage collection // Perhaps look at total memory available as a metric if (pinned_maps.size() >= MAX_BUFFERS || pinned_used_bytes >= MAX_BYTES) { pinnedGarbageCollect(); } for(mem_iter iter = pinned_maps.begin(); iter != pinned_maps.end(); ++iter) { mem_info info = iter->second; if (info.is_free && info.bytes == alloc_bytes) { iter->second.is_free = false; pinned_used_bytes += alloc_bytes; return (T *)iter->first; } } // Perform garbage collection if memory can not be allocated if (cudaMallocHost((void **)&ptr, alloc_bytes) != cudaSuccess) { pinnedGarbageCollect(); CUDA_CHECK(cudaMallocHost((void **)(&ptr), alloc_bytes)); } mem_info info = {false, false, alloc_bytes}; pinned_maps[ptr] = info; pinned_used_bytes += alloc_bytes; } return (T*)ptr; }
bool exec( int instruction ) { // printf( "EXEC: %d\n", instruction ); switch( instruction ) { // moo case 0: { if( prog_pos == program.begin() ) quit( true ); prog_pos--; // skip previous command. int level = 1; while( level > 0 ) { if( prog_pos == program.begin() ) break; prog_pos--; if( (*prog_pos) == 0 ) level++; else if( (*prog_pos) == 7 ) // look for MOO level--; } if( level != 0 ) quit(true); return exec( *prog_pos ); } // mOo case 1: if( mem_poses[stomach] == memory[stomach].begin() ) quit( true ); else mem_poses[stomach]--; break; // moO case 2: mem_poses[stomach]++; if( mem_poses[stomach] == memory[stomach].end() ) { memory[stomach].push_back(0); mem_poses[stomach] = memory[stomach].end(); mem_poses[stomach]--; } break; // mOO case 3: if( (*mem_poses[stomach]) == 3 ) quit( false ); return exec(*mem_poses[stomach]); // Moo case 4: if( (*mem_poses[stomach]) != 0 ) printf( "%c", *mem_poses[stomach] ); else { (*mem_poses[stomach]) = getchar(); while( getchar() != '\n' ); } break; // MOo case 5: (*mem_poses[stomach])--; break; // MoO case 6: (*mem_poses[stomach])++; break; // MOO case 7: if( (*mem_poses[stomach]) == 0 ) { int level = 1; int prev = 0; prog_pos++; // have to skip past next command when looking for next moo. if( prog_pos == program.end() ) break; while( level > 0 ) { prev = *prog_pos; prog_pos++; if( prog_pos == program.end() ) break; if( (*prog_pos) == 7 ) level++; else if( (*prog_pos) == 0 ) // look for moo command. { level--; if( prev == 7 ) level--; } } if( level != 0 ) quit( true ); } break; // OOO case 8: (*mem_poses[stomach]) = 0; break; // MMM case 9: if( has_register_val ) (*mem_poses[stomach]) = register_val; else register_val = (*mem_poses[stomach]); has_register_val = !has_register_val; break; // OOM case 10: printf( "%d\n", *mem_poses[stomach] ); break; // oom case 11: { char buf[100]; unsigned int c = 0; while( c < sizeof(buf)-1 ) { buf[c] = getchar(); c++; buf[c] = 0; if( buf[c-1] == '\n' ) break; } // swallow, just in case. if( c == sizeof(buf) ) while( getchar() != '\n' ); (*mem_poses[stomach]) = atoi( buf ); break; } // MMm case 12: { stomach--; if(stomach < 0) stomach += num_stomachs; break; } // MmM case 13: { stomach++; if(stomach >= num_stomachs) stomach -= num_stomachs; break; } // Oom case 14: { for( int i=0; i<num_stomachs; ++i ) { if( mem_poses[i] == memory[i].begin() ) quit( true ); else mem_poses[i]--; } break; } // oOm case 15: { for( int i=0; i<num_stomachs; ++i ) { mem_poses[i]++; if( mem_poses[i] == memory[i].end() ) { memory[i].push_back(0); mem_poses[i] = memory[i].end(); mem_poses[i]--; } } break; } // OoM case 16: { for( int i=0; i<num_stomachs; ++i ) { (*mem_poses[i])--; } break; } // oOM case 17: { for( int i=0; i<num_stomachs; ++i) { (*mem_poses[i])++; } break; } // ooo case 18: { for( int i=0; i<num_stomachs; ++i) { (*mem_poses[i]) = 0; } break; } // mmm case 19: { if( has_register_val ) { int weight = 0; for( int i=0; i<num_stomachs; ++i) { if( *mem_poses[i] > 0 ) weight += *mem_poses[i]; } if( weight == 0 ) { for( int i=0; i<num_stomachs; ++i ) { *mem_poses[i] = register_val; } } else { int div = register_val / weight; int mod = register_val - div * weight; for( int i=0; i<num_stomachs; ++i ) { if( *mem_poses[i] > 0 ) *mem_poses[i] = *mem_poses[i] * div; else if( *mem_poses[i] < 0 ) *mem_poses[i] = mod * -*mem_poses[i]; else *mem_poses[i] = 0; } } } else { int sum = 0; for( int i=0; i<num_stomachs; ++i) { sum += *mem_poses[i]; } register_val = sum; } has_register_val = !has_register_val; break; } // bad stuff default: quit( false ); }; prog_pos++; return true; }
int main( int argc, char** argv ) { if( argc < 2 ) { printf( "Usage: %s program.cow\n\n", argv[0] ); exit( 1 ); } FILE* f = fopen( argv[1], "rb" ); if( f == NULL ) { printf( "Cannot open source file [%s].\n", argv[1] ); exit( 1 ); } char buf[3]; memset( buf, 0, 3 ); //int pos = 0; // tola: unused? while( !feof(f) ) { int found = 0; buf[2] = fgetc( f ); if(( found = !strncmp( "moo", buf, 3 ) )) program.push_back( 0 ); else if(( found = !strncmp( "mOo", buf, 3 ) )) program.push_back( 1 ); else if(( found = !strncmp( "moO", buf, 3 ) )) program.push_back( 2 ); else if(( found = !strncmp( "mOO", buf, 3 ) )) program.push_back( 3 ); else if(( found = !strncmp( "Moo", buf, 3 ) )) program.push_back( 4 ); else if(( found = !strncmp( "MOo", buf, 3 ) )) program.push_back( 5 ); else if(( found = !strncmp( "MoO", buf, 3 ) )) program.push_back( 6 ); else if(( found = !strncmp( "MOO", buf, 3 ) )) program.push_back( 7 ); else if(( found = !strncmp( "OOO", buf, 3 ) )) program.push_back( 8 ); else if(( found = !strncmp( "MMM", buf, 3 ) )) program.push_back( 9 ); else if(( found = !strncmp( "OOM", buf, 3 ) )) program.push_back( 10 ); else if(( found = !strncmp( "oom", buf, 3 ) )) program.push_back( 11 ); // from here down, distributed digestion specific calls else if(( found = !strncmp( "MMm", buf, 3 ) )) program.push_back( 12 ); else if(( found = !strncmp( "MmM", buf, 3 ) )) program.push_back( 13 ); else if(( found = !strncmp( "Oom", buf, 3 ) )) program.push_back( 14 ); else if(( found = !strncmp( "oOm", buf, 3 ) )) program.push_back( 15 ); else if(( found = !strncmp( "OoM", buf, 3 ) )) program.push_back( 16 ); else if(( found = !strncmp( "oOM", buf, 3 ) )) program.push_back( 17 ); else if(( found = !strncmp( "ooo", buf, 3 ) )) program.push_back( 18 ); else if(( found = !strncmp( "mmm", buf, 3 ) )) program.push_back( 19 ); if( found ) { memset( buf, 0, 3 ); } else { buf[0] = buf[1]; buf[1] = buf[2]; buf[2] = 0; } } fclose( f ); printf( "Welcome to COW!\n\nExecuting [%s]...\n\n", argv[1] ); // init main memory. for(int i=0; i<num_stomachs; ++i) { memory[i].push_back(0); mem_poses[i] = memory[i].begin(); } stomach = 0; prog_pos = program.begin(); while( prog_pos != program.end() ) if( !exec( *prog_pos ) ) break; quit( false ); return 0; }
bool compile( int instruction, bool advance ) { switch( instruction ) { // moo case 0: { int level = 1; int num = MOOcount + 1; mem_t::iterator t = prog_pos; t--; // skip past previous command when searching for MOO. if( t != program.begin() ) { if((*t) == 7 ) num--; while( level > 0 ) { if( t == program.begin() ) break; t--; if( (*t) == 0 ) level++; else if( (*t) == 7 ) // look for MOO { level--; num--; } } } if( level != 0 && advance ) quit(); else if( level != 0 ) { fprintf( output, "rterr();" ); break; } moocount++; fprintf( output, "goto M%d;", num ); fprintf( output, "m%d:", moocount ); PRETTY( "moo" ); } break; // mOo case 1: fprintf( output, "if(p==m.begin()){rterr();}else{p--;}" ); PRETTY( "mOo" ); break; // moO case 2: fprintf( output, "p++; if(p==m.end()){m.push_back(0);p=m.end();p--;}" ); PRETTY( "moO" ); break; // mOO case 3: // I think it should be possible to build a switch statement here and then // use the compile function itself to fill in the possibilities. // printf( "NOT IMPLEMENTED: mOO\n\n" ); // quit(); fprintf( output, "switch(*p){" ); fprintf( output, "case 0:{" ); compile( 0, false ); fprintf( output, "}break;" ); fprintf( output, "case 1:{" ); compile( 1, false ); fprintf( output, "}break;" ); fprintf( output, "case 2:{" ); compile( 2, false ); fprintf( output, "}break;" ); fprintf( output, "case 4:{" ); compile( 4, false ); fprintf( output, "}break;" ); fprintf( output, "case 5:{" ); compile( 5, false ); fprintf( output, "}break;" ); fprintf( output, "case 6:{" ); compile( 6, false ); fprintf( output, "}break;" ); fprintf( output, "case 7:{" ); compile( 7, false ); fprintf( output, "}break;" ); fprintf( output, "case 8:{" ); compile( 8, false ); fprintf( output, "}break;" ); fprintf( output, "case 9:{" ); compile( 9, false ); fprintf( output, "}break;" ); fprintf( output, "case 10:{" ); compile( 10, false ); fprintf( output, "}break;" ); fprintf( output, "case 11:{" ); compile( 11, false ); fprintf( output, "}break;" ); fprintf( output, "default:{goto x;}};" ); PRETTY( "mOO" ); break; // Moo case 4: fprintf( output, "if((*p)!=0){putchar(*p);}else{(*p)=getchar();while(getchar()!='\\n');}" ); PRETTY( "Moo" ); break; // MOo case 5: fprintf( output, "(*p)--;" ); PRETTY( "MOo" ); break; // MoO case 6: fprintf( output, "(*p)++;" ); PRETTY( "MoO" ); break; // MOO case 7: { int level = 1; int num = moocount; int prev = 0; mem_t::iterator t = prog_pos; t++; // have to skip past next command when looking for next moo. if( t != program.end() ) { if( (*t) == 0 ) num++; while( level > 0 ) { prev = *t; t++; if( t == program.end() ) break; if( (*t) == 7 ) // look for MOO command. level++; else if( (*t) == 0 ) // look for moo command. { if( prev == 7 ) level--; level--; num++; } if( level == 0 ) break; } } if( advance && level != 0 ) quit(); else if( level != 0 ) { fprintf( output, "rterr();" ); break; } MOOcount++; fprintf( output, "M%d:", MOOcount ); fprintf( output, "if(!(*p))goto m%d;", num ); PRETTY( "MOO" ); } break; // OOO case 8: fprintf( output, "(*p)=0;" ); PRETTY( "OOO" ); break; // MMM case 9: fprintf( output, "if(h){(*p)=r;}else{r=(*p);}h=!h;" ); PRETTY( "MMM" ); break; // OOM case 10: fprintf( output, "printf(\"%%d\\n\",*p);" ); PRETTY( "OOM" ); break; // oom case 11: fprintf( output, "char b[100];int c=0;" ); fprintf( output, "while(c<sizeof(b)-1){b[c]=getchar();c++;b[c]=0;if(b[c-1]=='\\n')break;}" ); fprintf( output, "if(c==sizeof(b))while(getchar()!='\\n');(*p)=atoi(b);" ); PRETTY( "oom" ); break; // bad stuff default: return false; }; if( advance ) prog_pos++; return true; }
int main( int argc, char** argv ) { if( argc < 2 ) { printf( "Usage: %s program.cow\n\n", argv[0] ); exit( 1 ); } FILE* f = fopen( argv[1], "rb" ); if( f == NULL ) { printf( "Cannot open source file [%s].\n", argv[1] ); exit( 1 ); } char buf[3]; memset( buf, 0, 3 ); int pos = 0; while( !feof(f) ) { int found = 0; buf[2] = fgetc( f ); if( found = !strncmp( "moo", buf, 3 ) ) program.push_back( 0 ); else if( found = !strncmp( "mOo", buf, 3 ) ) program.push_back( 1 ); else if( found = !strncmp( "moO", buf, 3 ) ) program.push_back( 2 ); else if( found = !strncmp( "mOO", buf, 3 ) ) program.push_back( 3 ); else if( found = !strncmp( "Moo", buf, 3 ) ) program.push_back( 4 ); else if( found = !strncmp( "MOo", buf, 3 ) ) program.push_back( 5 ); else if( found = !strncmp( "MoO", buf, 3 ) ) program.push_back( 6 ); else if( found = !strncmp( "MOO", buf, 3 ) ) program.push_back( 7 ); else if( found = !strncmp( "OOO", buf, 3 ) ) program.push_back( 8 ); else if( found = !strncmp( "MMM", buf, 3 ) ) program.push_back( 9 ); else if( found = !strncmp( "OOM", buf, 3 ) ) program.push_back( 10 ); else if( found = !strncmp( "oom", buf, 3 ) ) program.push_back( 11 ); if( found ) { memset( buf, 0, 3 ); } else { buf[0] = buf[1]; buf[1] = buf[2]; buf[2] = 0; } } fclose( f ); printf( "Compiling [%s]...\n", argv[1] ); // init main memory. /* memory.push_back( 0 ); mem_pos = memory.begin(); */ output = fopen( "cow.out.cpp", "wb" ); fprintf( output, "#include <stdio.h>\n" ); fprintf( output, "#include <vector>\n" ); fprintf( output, "typedef std::vector<int> t_;t_ m;t_::iterator p;\n" ); fprintf( output, "bool h;int r;\n" ); fprintf( output, "void rterr(){puts(\"Runtime error.\\n\");}\n" ); fprintf( output, "int main(int a,char** v){\n" ); fprintf( output, "m.push_back(0);p=m.begin();h=false;\n" ); prog_pos = program.begin(); while( prog_pos != program.end() ) if( !compile( *prog_pos, true ) ) { printf( "ERROR!\n" ); break; } fprintf( output, "x:return(0);}\n" ); fclose( output ); printf( "C++ source code: cow.out.cpp\n" ); #ifdef COMPILER std::string path( (const char*)COMPILER ); path.append( " " ); path.append( (const char*)NAME_FLAG ); path.append( " " ); path.append( (const char*)OUTPUT_EXEC ); path.append( " " ); path.append( (const char*)FLAGS ); path.append( " " ); path.append( (const char*)OUTPUT_CPP ); if( system( path.c_str() ) ) printf( "\n\nCould not compile. Possible causes: C++ compiler is not installed, not in path, or not named '%s' or there is a bug in this compiler.\n\n", COMPILER ); else printf( "Executable created: cow.out\n" ); #endif return 0; }
bool op_ring::execute() { if( pos != 0 ) switch( pos ) { // One case 2: value=1; break; // Zero case 3: value=0; break; // Load case 4: value=*mem_pos; break; // Store case 5: *mem_pos = value; break; // DAdd case 7: { int t = mem_pos - memory.begin(); t += value; if( t < 0 ) return false; // out of bounds! if( t < memory.size() ) mem_pos = memory.begin() + t; else { while( memory.size() <= t ) memory.push_back(0); mem_pos = memory.begin() + t; } } break; // Logic case 8: if( *mem_pos != 0 ) value = value && 1; else value = 0; break; // If case 9: if( *mem_pos == 0 ) break; // else fall through! // PAdd case 6: { int t = prog_pos - program.begin(); t += value; if( t < 0 || t >= program.size() ) return false; // out of bounds! prog_pos = program.begin() + t; next_instruction = false; } break; // IntIO case 10: if( value == 0 ) { // read integer char buf[100]; int c = 0; while( c < sizeof(buf)-1 ) { buf[c] = getchar(); c++; buf[c] = 0; if( buf[c-1] == '\n' ) break; } // swallow, just in case. if( c == sizeof(buf) ) while( getchar() != '\n' ); (*mem_pos) = atoi( buf ); } else printf( "%d", *mem_pos ); break; // AscIO case 11: if( value == 0 ) { // read character (*mem_pos) = getchar(); while( getchar() != '\n' ); } else printf( "%c", *mem_pos ); break; // Exit case 1: default: return false; } return true; }
int main( int argc, char** argv ) { if( argc < 2 ) { printf( "Usage: %s program.wrl\n\n", argv[0] ); exit( 1 ); } FILE* f = fopen( argv[1], "rb" ); if( f == NULL ) { printf( "Cannot open source file [%s].\n", argv[1] ); exit( 1 ); } while( !feof(f) ) { char buf = fgetc( f ); if( buf == '1' ) program.push_back( true ); else if( buf == '0' ) program.push_back( false ); } fclose( f ); printf( "Welcome to Whirl!\n\nExecuting [%s]...\n\n", argv[1] ); // init main memory. memory.push_back( 0 ); mem_pos = memory.begin(); prog_pos = program.begin(); bool execute = false; while( prog_pos != program.end() ) { next_instruction = true; if( *prog_pos ) { cur->rotate(); execute = false; } else { cur->switch_dir(); if( execute ) { if( !cur->execute() ) return 0; (cur == &ops)? cur = &math: cur = &ops; execute = false; } else execute = true; } if( next_instruction ) prog_pos++; } printf( "\n" ); return 0; }