/* * sleep with timeout in milliseconds */ void minithread_sleep_with_timeout(int delay) { interrupt_level_t l = set_interrupt_level(DISABLED); register_alarm(delay, get_new_alarm_handler(), minithread_self()); set_interrupt_level(l); minithread_stop(); }
/* * semaphore_P(semaphore_t sem) * Wait on the semaphore. */ void semaphore_P(semaphore_t sem) { while(atomic_test_and_set(&(sem->mutex))); if (--sem->limit < 0) { queue_append(sem->waiting, minithread_self()); sem->mutex = 0; minithread_stop(); } else { sem->mutex = 0; } }
/* * semaphore_P(semaphore_t sem) * P on the sempahore. */ void semaphore_P(semaphore_t sem) { /* while (1 == atomic_test_and_set(&(sem->lock))) ; */ if (0 > --(sem->count)) { queue_append(sem->wait, minithread_self()); /* atomic_clear(&(sem->lock)); */ minithread_stop(); } /* else { atomic_clear(&(sem->lock)); } */ }
/* Final proc of all newly created minithreads. Will never terminate and threads add * themselves to the cleanup_queue and then context switch to the reaper thread to perform * all the necesary cleanup steps to dispose of the thread properly and safely. */ int minithread_cleanup(int* id) { minithread_t* mini = minithread_self(); mini->status = ZOMBIE; interrupt_level_t old_level = set_interrupt_level(DISABLED); queue_append(schedule_data->cleanup_queue, mini); set_interrupt_level(old_level); // notify reaper thread and let it run semaphore_V(reaper_sema); minithread_stop(); return 0; }
/* * semaphore_P(semaphore_t sem) * P on the sempahore. */ void semaphore_P(semaphore_t sem) { //Loop until we succeed semaphore_spinlock(&(sem->lock)); while (sem->count == 0) { queue_append(sem->thread_queue, minithread_self()); atomic_clear(&(sem->lock)); minithread_stop(); semaphore_spinlock(&(sem->lock)); } //Got the semaphore. Decrement and break sem->count--; atomic_clear(&(sem->lock)); }
void semaphore_P(semaphore_t *sem) { //Validate input arguments, abort if invalid argument is seen AbortOnCondition(sem == NULL, "Null argument sem in semaphore_P()"); assert(sem->semaWaitQ != NULL); //sanity check interrupt_level_t old_level = set_interrupt_level(DISABLED); //disable interrupts //critical section if (sem->count > 0) sem->count--; else { minithread_t* currThread = minithread_self(); //get the calling thread AbortOnCondition(currThread == NULL, "Failed in minithread_self() method in semaphore_P()"); queue_append(sem->semaWaitQ, currThread); //put thread onto semaphore's wait queue minithread_stop(); //block calling thread, yield processor } set_interrupt_level(old_level); //restore interrupt level }
/* Given a path, find the inode it refers to (either file or dir) */ int _find_path_inode(char* path) { int i, x; minifile_t inode; block_t data_block; char** path_parts; int path_part_ct = 0; int found_inode = 1; minithread_t running = minithread_self(); superblock_t superblock; int block_id; int path_parts_size = _find_path_len(path); if (strcmp(path, "/") == 0) { superblock = (superblock_t) _retrieve_block(0); block_id = superblock->u.data.root_dir_block_id; return block_id; } // Split up path by "/"s path_parts = _parse_path(path, path_parts_size); // Is this a relative or absolute path? if (path[0] == '/') { /* TODO: MUST PUT THIS BACK IN superblock = (superblock_t) _retrieve_block(0); inode = (minifile_t) _retrieve_block(superblock->u.data.root_dir_block_id); */ inode = (minifile_t) _retrieve_block(1); path_part_ct++; } else { inode = (minifile_t) _retrieve_block(running->dir_block_id); } while (found_inode == 1 && path_part_ct < path_parts_size) { found_inode = 0; // Go through all the data blocks for (i = 0; i < inode->u.data.num_data_blocks; i++) { if (found_inode == 1) break; data_block = _retrieve_block(_inode_get_data_block_id(inode, i)); // Go through the listing for (x = 0; x < MAX_DIR_DATA_BLOCK_ENTRIES; x++) { if (data_block->type.dir_data_block.entries[x].inode_block_id == 0) { continue; } if (strcmp(data_block->type.dir_data_block.entries[x].name, path_parts[path_part_ct]) == 0) { // We found it block_id = data_block->type.dir_data_block.entries[x].inode_block_id; _release_block((block_t) inode); inode = (minifile_t) _retrieve_block(data_block->type.dir_data_block.entries[x].inode_block_id); found_inode = 1; path_part_ct++; break; } } } } _release_block((block_t) inode); if (found_inode == 1) { return block_id; } return -1; }