void lwp_stop() { SAVE_STATE(); if (lwp_procs) { GetSP(lwp_ptable[lwp_running].sp); } else { /* oops no more procs */ RESTORE_STATE(); } /* get back to "system" stack */ SetSP(original_stack_pointer); RESTORE_STATE(); return; }
///Rectangle generator GridItemPtr Grid::rectangle_generator::operator()() { //Generator preamble BEGIN_RESTORE_STATE; RESTORE_STATE(state1); END_RESTORE_STATE; //Generator body BEGIN_GENERATOR; ix0 = limit( (int)floor(x0*grid->cellScale.x), 0, grid->numCols ); iy0 = limit( (int)floor(y0*grid->cellScale.y), 0, grid->numRows ); ix1 = limit( (int)ceil(x1*grid->cellScale.x), 0, grid->numCols ); iy1 = limit( (int)ceil(y1*grid->cellScale.y), 0, grid->numRows ); //note that local variable are not used, because we are inside pseudo-gnerator for (y=iy0; y<=iy1;++y){ for (x=ix0; x<=ix1;++x){ cur_cell = &(grid->cellRef(x,y)); i = cur_cell->items.begin(); while ( i!=cur_cell->items.end() ){ if ( in_rect((*i)->getPos(), x0, y0, x1, y1) ){ YIELD( *i, state1 ); } ++i; } } } END_GENERATOR; return GridItemPtr(); //dummy return, just to exit the generator }
void lwp_start() { SAVE_STATE(); GetSP(original_stack_pointer); /* make sure we have threads to run */ if (lwp_procs == 0) { SetSP(original_stack_pointer); RESTORE_STATE(); /* dont do anything if we have no jobs */ return; } /* pick a proc */ setRunning(); /* switch to new stack */ SetSP(lwp_ptable[lwp_running].sp); RESTORE_STATE(); return; }
void lwp_yield() { /* push everything onto our stack */ SAVE_STATE(); /* save our stack pointer in our process table */ GetSP(lwp_ptable[lwp_running].sp); /* now we grab the new process */ setRunning(); SetSP(lwp_ptable[lwp_running].sp); RESTORE_STATE(); return; }
GridItemPtr Grid::items_generator::operator()() { BEGIN_RESTORE_STATE; RESTORE_STATE( state1 ); RESTORE_STATE( state2 ); END_RESTORE_STATE; BEGIN_GENERATOR; for( i=0; i<grid->numRows*grid->numCols; ++i){ curCell = &(grid->cells[i]); for( iItem = curCell->items.begin(); iItem != curCell->items.end(); ++iItem){ YIELD( *iItem, state1 ); } } curCell = &(grid->unallocated); for( iItem = curCell->items.begin(); iItem != curCell->items.end(); ++iItem){ YIELD( *iItem, state2 ); } END_GENERATOR; return GridItemPtr(); }
//Circular generator GridItemPtr Grid::circular_generator::operator()() { //TODO Possible optimization: instead of skipping the cells that are too far, // enumerate only cells that are near enough. This would require more // computations though. BEGIN_RESTORE_STATE; RESTORE_STATE( state1 ); END_RESTORE_STATE; BEGIN_GENERATOR; //first determine rectangle, where to search for ix0 = limit( (int)floor((center.x-r)*grid->cellScale.x), 0, grid->numCols ); iy0 = limit( (int)floor((center.y-r)*grid->cellScale.y), 0, grid->numRows ); ix1 = limit( (int)ceil((center.x+r)*grid->cellScale.x), 0, grid->numCols ); iy1 = limit( (int)ceil((center.y+r)*grid->cellScale.y), 0, grid->numRows ); max_cell_radius = grid->cellSize.norm()*0.5; //maxi //now enumerate all cells inside this rectangular area for ( iy = iy0; iy<iy1; ++iy ){ for ( ix = ix0; ix < ix1; ++ix ){ //determine, whether this cell can be displayed at all { vec2 c((ix+ftype(0.5))*grid->cellSize.x, (iy+ftype(0.5))*grid->cellSize.y); //distance from the cell center to the circle center ftype d = (c - center).norm(); if ( d > r + max_cell_radius ) continue;//skip this cell - it is too far from center. } //iterate items inside cell curCell = &(grid->cellRef( ix, iy )); iItem = curCell->items.begin(); iItemEnd = curCell->items.end(); while (iItem != iItemEnd){ // for ( iItem = curCell->items.begin(); iItem != curCell->items.end(); ++iItem){ //determine, whether this located item lays inside the circle if ( dist((*iItem)->getPos(), center) <= r ){ YIELD( *iItem, state1 ); } ++iItem; } } } END_GENERATOR; return GridItemPtr();//Dummy }
/* * lwp_exit * * we build */ void lwp_exit() { lwp_procs--; /* saved into global so we can access after sp changes */ stackToFree = lwp_ptable[lwp_running].stack; if (lwp_procs == 0) { SetSP(original_stack_pointer); /* free the stack of the last lwp */ freeStack(); lwp_stop(); } /* cleanup sets new running proc */ /* and it accounts for the missing proc */ cleanup(); /*SetSP(original_stack_pointer);*/ freeStack(); SetSP(lwp_ptable[lwp_running].sp); RESTORE_STATE(); return; }