Beispiel #1
0
void
test_or ()
{
  v = 0;
  count = 1;

  atomic_fetch_or (&v, count);
  if (v != 1)
    abort ();

  count *= 2;
  atomic_fetch_or_explicit (&v, count, memory_order_consume);
  if (v != 3)
    abort ();

  count *= 2;
  atomic_fetch_or (&v, 4);
  if (v != 7)
    abort ();

  count *= 2;
  atomic_fetch_or_explicit (&v, 8, memory_order_release);
  if (v != 15)
    abort ();

  count *= 2;
  atomic_fetch_or (&v, count);
  if (v != 31)
    abort ();

  count *= 2;
  atomic_fetch_or_explicit (&v, count, memory_order_seq_cst);
  if (v != 63)
    abort ();
}
Beispiel #2
0
static ssize_t __block_write(struct file *file, off_t posit, uint8_t *buf, size_t count)
{
	struct blockdev *bd = file->inode->devdata;
	int blk_size = bd->ctl->blocksize;
	unsigned pos = posit;

	// If we are offset in a block, we dont wanna overwrite stuff.
	if(pos % blk_size)
	{
		struct ioreq *req = ioreq_create(bd, READ, pos / blk_size, 1);
		struct buffer *br = block_cache_get_first_buffer(req);
		ioreq_put(req);
		if(!br)
			return 0;
		// If count is less than whats remaining, just use count.
		int write = (blk_size-(pos % blk_size));
		if(count < (unsigned)write)
			write=count;
		memcpy(br->data+(pos % blk_size), buf, write);
		atomic_fetch_or(&br->flags, BUFFER_DIRTY);
		buffer_put(br);
		buf += write;
		count -= write;
		pos += write;
	}
	while(count >= (unsigned int)blk_size)
	{
		ASSERT((pos & ~(blk_size - 1)) == pos);

		struct buffer *entry = dm_block_cache_get(bd, pos / blk_size);
		if(!entry) {
			entry = buffer_create(bd, pos / blk_size, BUFFER_DIRTY, buf);
			memcpy(entry->data, buf, blk_size);
			dm_block_cache_insert(bd, pos/blk_size, entry, BLOCK_CACHE_OVERWRITE);
		} else {
			memcpy(entry->data, buf, blk_size);
			atomic_fetch_or(&entry->flags, BUFFER_DIRTY);
		}
		buffer_put(entry);
		count -= blk_size;
		pos += blk_size;
		buf += blk_size;
	}
	// Anything left over?
	if(count > 0)
	{
		struct ioreq *req = ioreq_create(bd, READ, pos/blk_size, 1);
		struct buffer *br = block_cache_get_first_buffer(req);
		ioreq_put(req);
		if(!br)
			return 0;
		memcpy(br->data, buf, count);
		atomic_fetch_or(&br->flags, BUFFER_DIRTY);
		buffer_put(br);
		pos+=count;
	}
	return pos-posit;
}
Beispiel #3
0
void
test_fetch_or ()
{
  v = 0;
  count = 1;

  if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0)
    abort ();

  count *= 2;
  if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1)
    abort ();

  count *= 2;
  if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3)
    abort ();

  count *= 2;
  if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7)
    abort ();

  count *= 2;
  if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15)
    abort ();

  count *= 2;
  if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31)
    abort ();

  count *= 2;
  if (atomic_fetch_or (&v, count) != 63)
    abort ();
}
Beispiel #4
0
/* indicates that the inode needs to be written back to the filesystem */
void vfs_inode_set_dirty(struct inode *node)
{
	assert(!(node->flags & INODE_NEEDREAD));
	if(!(atomic_fetch_or(&node->flags, INODE_DIRTY) & INODE_DIRTY)) {
		linkedlist_insert(ic_dirty, &node->dirty_item, node);
	}
}
Beispiel #5
0
__attribute__((noinline)) static void tm_process_exit(int code)
{
	spinlock_acquire(&current_thread->status_lock);
	if(code != -9) 
		current_process->exit_reason.cause = __EXIT;
	current_process->exit_reason.ret = code;
	current_process->exit_reason.pid = current_process->pid;
	spinlock_release(&current_thread->status_lock);

	/* update times */
	if(current_process->parent) {
		time_t total_utime = current_process->utime + current_process->cutime;
		time_t total_stime = current_process->stime + current_process->cstime;
		atomic_fetch_add_explicit(&current_process->parent->cutime,
				total_utime, memory_order_relaxed);
		atomic_fetch_add_explicit(&current_process->parent->cstime,
				total_stime, memory_order_relaxed);
	}
	file_close_all();
	if(current_process->root)
		vfs_icache_put(current_process->root);
	if(current_process->cwd)
		vfs_icache_put(current_process->cwd);
	mutex_destroy(&current_process->fdlock);
	mm_destroy_all_mappings(current_process);
	linkedlist_destroy(&(current_process->mappings));
	valloc_destroy(&current_process->mmf_valloc);

	/* this is done before SIGCHILD is sent out */
	atomic_fetch_or(&current_process->flags, PROCESS_EXITED);
	if(current_process->parent) {
		struct process *init = tm_process_get(0);
		assert(init);
		
		__linkedlist_lock(process_list);
		struct process *child;
		struct linkedentry *node;
		for(node = linkedlist_iter_start(process_list);
				node != linkedlist_iter_end(process_list);
				node = linkedlist_iter_next(node)) {
			child = linkedentry_obj(node);
			if(child->parent == current_process) {
				tm_process_inc_reference(init);
				child->parent = init;
				tm_process_put(current_process);
			}
		}
		__linkedlist_unlock(process_list);
		tm_signal_send_process(current_process->parent, SIGCHILD);
		tm_blocklist_wakeall(&current_process->waitlist);
		tm_process_put(init);
	}
	tm_process_put(current_process); /* fork starts us out at refs = 1 */
}
Beispiel #6
0
void tm_process_wait_cleanup(struct process *proc)
{
	assert(proc != current_process);
	/* prevent this process from being "cleaned up" multiple times */
	if(!(atomic_fetch_or(&proc->flags, PROCESS_CLEANED) & PROCESS_CLEANED)) {
		assert(proc->thread_count == 0);
		linkedlist_remove(process_list, &proc->listnode);
		mutex_destroy(&proc->map_lock);
		if(proc->parent)
			tm_process_put(proc->parent);
		tm_process_put(proc); /* process_list releases its pointer */
	}
}
Beispiel #7
0
void
act_set_astkevent(thread_t thread, uint16_t bits)
{
	spl_t s = splsched();

	/*
	 * Do not send an IPI if the thread is running on
	 * another processor, wait for the next quantum
	 * expiration to load the AST.
	 */

	atomic_fetch_or(&thread->kevent_ast_bits, bits);
	thread_ast_set(thread, AST_KEVENT);

	if (thread == current_thread()) {
		ast_propagate(thread);
	}

	splx(s);
}
Beispiel #8
0
/* read in an inode from the inode cache, OR pull it in from the FS */
struct inode *vfs_icache_get(struct filesystem *fs, uint32_t num)
{
	/* create if it doesn't exist */
	struct inode *node;
	assert(fs);
	int newly_created = 0;
	uint32_t key[2] = {fs->id, num};
	mutex_acquire(ic_lock);
	if((node = hash_lookup(icache, key, sizeof(key))) == NULL) {
		/* didn't find it. Okay, create one */
		node = vfs_inode_create();
		node->filesystem = fs;
		node->flags = INODE_NEEDREAD;
		node->id = num;
		node->key[0] = fs->id;
		node->key[1] = num;
		hash_insert(icache, node->key, sizeof(node->key), &node->hash_elem, node);
		newly_created = 1;
	}
	assert(node->filesystem == fs);
	atomic_fetch_add(&node->count, 1);

	/* move to in-use */
	if(!(atomic_fetch_or(&node->flags, INODE_INUSE) & INODE_INUSE)) {
		atomic_fetch_add(&fs->usecount, 1);
		if(!newly_created) {
			queue_remove(ic_lru, &node->lru_item);
			linkedlist_insert(ic_inuse, &node->inuse_item, node);
		}
	}
	if(fs_inode_pull(node) != 0) {
		/* pull failed. Probably EIO. */
		vfs_icache_put(node);
		node = 0;
	}
	mutex_release(ic_lock);

	return node;
}
 void atomic_or(volatile T * const dest, const T val) {
   atomic_fetch_or(dest, val);
 }
Beispiel #10
0
Datei: dec.c Projekt: etix/vlc
/**
 * Marks the audio output for restart, to update any parameter of the output
 * plug-in (e.g. output device or channel mapping).
 */
void aout_RequestRestart (audio_output_t *aout, unsigned mode)
{
    aout_owner_t *owner = aout_owner (aout);
    atomic_fetch_or (&owner->restart, mode);
    msg_Dbg (aout, "restart requested (%u)", mode);
}
KOKKOS_INLINE_FUNCTION
void atomic_or(volatile T * const dest, const T src) {
  (void)atomic_fetch_or(dest,src);
}
Beispiel #12
0
TEST(stdatomic, atomic_fetch_or) {
  atomic_int i = ATOMIC_VAR_INIT(0x100);
  ASSERT_EQ(0x100, atomic_fetch_or(&i, 0x020));
  ASSERT_EQ(0x120, atomic_fetch_or_explicit(&i, 0x003, memory_order_relaxed));
  ASSERT_EQ(0x123, atomic_load(&i));
}
Beispiel #13
0
/*
 * Use stdatomic instructions instead of encoding ASM.
 */
void
atomic_setbits_int(__volatile unsigned int *uip, unsigned int v)
{
	atomic_fetch_or((atomic_uint *)uip, v);
}
Beispiel #14
0
// If physicals hasn't been initialized, initialize it.
static void __init_physicals(struct inode *node)
{
	if(!(atomic_fetch_or(&node->flags, INODE_PCACHE) & INODE_PCACHE)) {
		hash_create(&node->physicals, 0, 1000);
	}
}