/** * Checks in the message. If the message was checked out for * writing, the buffer will be committed and returned to the * object_allocator if allow_simultaneous_rw is not set, the * buffer will be committing regardless of whether there is an * existing reader. If it is set, the thread will wait until * there are no readers before committing the buffer. Returns the * norm of the change of value. (using the norm() function) if its * a write checkin. Returns 0 otherwise. * * \warning writes may block for extended periods if there are * readers */ double checkin(object_allocator_tls<F> &pool, const F *msg, const factor_norm<F>& norm, const bool allow_simultaneous_rw) { double residual = -1; lock.lock(); // if it matches message address, this was a read request if (msg == &message) { assert(readercount > 0); readercount--; } //this was a write request else if (msg == writebuffer) { //Optional: Wait for readers to complete if (!allow_simultaneous_rw) { while(readercount > 0) { lock.unlock(); sched_yield(); lock.lock(); } } // compute the delta residual = norm(message , *(writebuffer)); message = *(writebuffer); pool.checkin(writebuffer); writebuffer = NULL; lastresidual = residual; } else { //Erroneous message! assert(0); } lock.unlock(); return residual; }
// kfree - free memory block // This function frees a block of memory given by kmalloc(), allowing other kernel tasks to use it. void kfree(char* ptr) { // given a pointer to a block of memory: // find the header for that block of memory // set the free bit // compress the list k_heap_blk *header_ptr = (k_heap_blk*)((size_t)(ptr-sizeof(k_heap_blk)-1)); __dynmem_lock.lock(); #ifdef DYNMEM_CHECK_FREE_CALLS if(header_ptr->magic == HEAP_MAGIC_NUMBER) { #endif header_ptr->used = false; if(header_ptr->prev != NULL) { if( !(header_ptr->prev->used) ) { // Just delete this block. k_heap_delete(header_ptr); } } if(header_ptr->next != NULL) { if( !(header_ptr->next->used) ) { // Delete header_ptr->next. k_heap_blk *next = header_ptr->next; k_heap_delete(next); } } //k_heap_compress(); #ifdef DYNMEM_CHECK_FREE_CALLS } else { // We're freeing an invalid pointer. panic("dynmem: bad free() call -- could not find magic number\ndynmem: Pointer points to: 0x%x.\n", (unsigned long long int)((size_t)ptr) ); } #endif __dynmem_lock.unlock(); }
char* kmalloc(size_t size) { // iterate over every block in the heap list except for the last one // and look for a block where the space between the block and the next in the list is at least size bytes... // if we can't find one, extend the heap. int n_blks = (size / HEAP_BLK_SIZE)+1; char* ptr = NULL; k_heap_blk* blk = heap.start; __dynmem_lock.lock(); while(blk->next != NULL) { if(!blk->used) { int blk_sz = ((size_t)blk->next - (size_t)blk); if( blk_sz-sizeof(k_heap_blk) >= size ) { blk->used = true; char* ptr = NULL; if( (blk_sz / HEAP_BLK_SIZE) > n_blks ) { k_heap_add_at_offset(blk, n_blks); blk->next->used = false; ptr = (char*)((size_t)blk+sizeof(k_heap_blk)+1); } else { ptr = (char*)((size_t)blk+sizeof(k_heap_blk)+1); } break; } } blk = blk->next; } if(ptr == NULL) { // if we still haven't allocated memory, then make a new block. k_heap_add_at_offset(heap.end, n_blks); heap.end->prev->used = true; ptr = (char*)((size_t)(heap.end->prev)+sizeof(k_heap_blk)+1); } __dynmem_lock.unlock(); return ptr; }
// terminal_writestring - print a string to screen // this function prints a line of text to screen, wrapping and scrolling if necessary. void terminal_writestring(char* data) { __vga_write_lock.lock(); size_t datalen = strlen(data); for ( size_t i = 0; i < datalen; i++ ) { terminal_putchar(data[i]); } __vga_write_lock.unlock(); }
/** * Checks the message. If its a write request, a buffer will be * taken from the object_allocator */ F *checkout(object_allocator_tls<F> &pool, const ReadWrite rw) { if (rw == Reading) { lock.lock(); readercount++; lock.unlock(); return &message; } else { lock.lock(); // we only support 1 writer. assert(writebuffer == NULL); writebuffer = pool.checkout(); lock.unlock(); (*writebuffer) = message; return writebuffer; } }
virtual void invoke() { #ifdef DEBUG s_locker.lock(); s_fibers.remove(&m_fb->m_link); s_locker.unlock(); #endif m_fb->m_joins.set(); m_fb->Unref(); }
void terminal_backspace() { __vga_write_lock.lock(); if(--terminal_column > VGA_WIDTH) { if(--terminal_row > VGA_HEIGHT) { terminal_scroll(-1); terminal_row = 0; } } terminal_putentryat(' ', terminal_color, terminal_column, terminal_row); __vga_write_lock.unlock(); }
bool find(data item) { size_t bucket = hashfn(item) % buckets.size(); lock.lock(); for (auto it = buckets[bucket].begin(); it != buckets[bucket].end(); it++) { if (*it == item) { lock.unlock(); return true; } } lock.unlock(); return false; }
void Service::Create(fiber_func func, void *data, int32_t stacksize, const char* name, Fiber** retVal) { Fiber *fb; void **stack; stacksize = (stacksize + FB_STK_ALIGN - 1) & ~(FB_STK_ALIGN - 1); #ifdef WIN32 fb = (Fiber *) VirtualAlloc(NULL, stacksize, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); #else fb = (Fiber *) malloc(stacksize); #endif if (fb == NULL) return; stack = (void **) fb + stacksize / sizeof(void *) - 5; new(fb) Fiber(s_service, data); fb->m_cntxt.ip = (intptr_t) fiber_proc; fb->m_cntxt.sp = (intptr_t) stack; #if defined(x64) #ifdef _WIN32 fb->m_cntxt.Rcx = (intptr_t) func; fb->m_cntxt.Rdx = (intptr_t) fb; #else fb->m_cntxt.Rdi = (intptr_t) func; fb->m_cntxt.Rsi = (intptr_t) fb; #endif #elif defined(I386) stack[1] = (void *)func; stack[2] = fb; #elif defined(arm) fb->m_cntxt.r0 = (intptr_t) func; fb->m_cntxt.r1 = (intptr_t) fb; #endif #ifdef DEBUG s_locker.lock(); s_fibers.putTail(&fb->m_link); s_locker.unlock(); #endif if (retVal) { *retVal = fb; fb->Ref(); } fb->Ref(); fb->resume(); }
void Service::forEach(void (*func)(Fiber*)) { s_locker.lock(); linkitem* p = s_fibers.head(); while (p) { Fiber* zfb = 0; func((Fiber*)((intptr_t)p - (intptr_t)(&zfb->m_link))); p = s_fibers.next(p); } s_locker.unlock(); }
/** * Checks the message. If its a write request, a buffer will be * taken from the object_allocator. If the object is currently * allocated for writing then this function will return NULL */ F *trycheckout(object_allocator_tls<F> &pool, const ReadWrite rw) { if (rw == Reading) { return checkout(pool,rw); } else { lock.lock(); if (writebuffer != NULL) { lock.unlock(); return NULL; } writebuffer = pool.checkout(); lock.unlock(); (*writebuffer) = message; return writebuffer; } }
void notify_all() const { spinlock_.lock(); broadcasting_ = waiters_ > 0; if ( broadcasting_ ) { ZI_VERIFY( win32::ReleaseSemaphore( semaphore_, waiters_, 0 ) ); spinlock_.unlock(); ZI_VERIFY_0( win32::WaitForSingleObject( last_event_, win32::forever ) ); broadcasting_ = 0; } else { spinlock_.unlock(); } }
// terminal_scroll - scroll the console // Positive values scroll down (adding new lines to the bottom); negative values do the inverse. void terminal_scroll(int num_rows) { __vga_write_lock.lock(); if(num_rows > 0) { // scroll down for(size_t y=0;y<VGA_HEIGHT-1;y++) for(size_t x=0;x<VGA_WIDTH;x++) terminal_buffer[y*VGA_WIDTH+x] = terminal_buffer[(y+1)*VGA_WIDTH+x]; for(size_t x=0;x<VGA_WIDTH;x++) terminal_buffer[(VGA_HEIGHT-1)*VGA_WIDTH+x] = make_vgaentry(' ', make_color(COLOR_LIGHT_GREY, COLOR_BLACK)); } else if(num_rows < 0) { // scroll up for(size_t y=VGA_HEIGHT-1;y>0;y--) for(size_t x=0;x<VGA_WIDTH;x++) terminal_buffer[y*VGA_WIDTH+x] = terminal_buffer[(y-1)*VGA_WIDTH+x]; for(size_t x=0;x<VGA_WIDTH;x++) terminal_buffer[x] = make_vgaentry(' ', make_color(COLOR_LIGHT_GREY, COLOR_BLACK)); } __vga_write_lock.unlock(); }
// terminal_putchar - write a single character to screen // This function prints a character to screen in a manner similar to "terminal_writestring" (see below). // '\n' characters are automatically used to scroll and start new lines. void terminal_putchar(char c) { __vga_write_lock.lock(); if(c=='\n') { terminal_column = 0; if ( ++terminal_row == VGA_HEIGHT ) { terminal_scroll(1); terminal_row = VGA_HEIGHT-1; } __vga_write_lock.unlock(); return; } terminal_putentryat(c, terminal_color, terminal_column, terminal_row); if ( ++terminal_column == VGA_WIDTH ) { terminal_column = 0; if ( ++terminal_row == VGA_HEIGHT ) { terminal_scroll(1); terminal_row = VGA_HEIGHT-1; } } __vga_write_lock.unlock(); }
explicit scoped_lock( spinlock & sp ): sp_( sp ) { sp.lock(); }
void insert(data item) { size_t bucket = hashfn(item) % buckets.size(); lock.lock(); buckets[bucket].push_back(item); lock.unlock(); }