예제 #1
0
void monkey_climb()
{
  sem_acquire(&dominant_monkey);
  sem_acquire(&tree);
 printf(1,"monkey %d gets coconut\n", getpid());
sem_signal(&tree);
  sem_signal(&dominant_monkey);
  texit();
}
예제 #2
0
void oReady(void *arg_ptr) {
	sem_acquire(&h);
	sem_acquire(&h);
	sem_signal(&o);
	sem_signal(&o);
	lock_acquire(&mutex);
	water_molecules++;
	lock_release(&mutex);
	texit();
}
예제 #3
0
파일: qsem.c 프로젝트: danilaslau/frotznet
void qsem_acquire (qsem_t *s)
{
#ifdef I386
	/* no atomic_add() in i386 */
	sem_acquire(s->mutex);
#else
	if (atomic_add (&s->count, -1) <= 0)
		sem_acquire (s->mutex);
#endif
}
예제 #4
0
파일: h2o.c 프로젝트: athai005/xv6_lab2
void oReady(void* v)
{
   sem_acquire(&h);
   sem_acquire(&h);
   sem_signal(&o);
   sem_signal(&o);
   sem_acquire(&l);
   water++;
   printf(1,"water molecule created\n");
   sem_signal(&l);

   texit();
}
예제 #5
0
/*
    block_cache_sync() - flush all dirty blocks.
*/
s32 block_cache_sync()
{
    block_descriptor_t *bd, * const end = bc.descriptors + bc.nblocks;
    u32 one = 1;
    s32 ret;

    for(bd = bc.descriptors; bd != end; ++bd)
    {
        sem_acquire(&bd->sem);

        if(bd->flags & BC_DIRTY)
        {
            void *data = bc.cache + ((bd - bc.descriptors) * BLOCK_SIZE);
            ret = bd->dev->write(bd->dev, bd->block, &one, data);
            if(ret != SUCCESS)
                return ret;

            bd->flags &= ~BC_DIRTY;
        }

        sem_release(&bd->sem);
    }

    return SUCCESS;
}
예제 #6
0
void canarrive(void* daddy) { 
	sem_acquire(&lock);
  numcan++;
	if(numcan == 3 || (numcan > 0 && nummiss == 2)){
	  sem_signal(&can);
		sem_signal(&can);
		printf(1, "\nRow Boat");
		if (nummiss == 3){
		  printf(1, " with 3 missionaries");
			nummiss = 0;
		}
		else if(numcan == 3){
			printf(1, " with 3 cannibals");
			numcan = 0;
		}
		else{
			printf(1, " with 1 cannibal 2 missionaries");
			numcan = numcan - 1;
			nummiss = nummiss -2;
		}

	}
	sem_signal(&lock);
	texit();
}
예제 #7
0
void consumer(void* arg)
{
	int itm, id;
	id = *(int *)arg;
	printf("Consumer %d\n", id);
	while(1)
	{
		sem_acquire(shared.full);
		sem_acquire(shared.mutex);
		itm = shared.buf[shared.out];
		shared.out = (shared.out + 1) % SH_SIZE;
		printf("Consumer %d consumed item no %d\n", id, itm);
		sem_release(shared.mutex);
		sem_release(shared.empty);
		sleep(rand() % 3);
	}	
}
예제 #8
0
파일: ide_sim.c 프로젝트: HTshandou/newos
static void scan_device( ide_bus_info *bus, int device )
{
	SHOW_FLOW0( 3, "" );
	
	schedule_synced_pc( bus, &bus->scan_bus_syncinfo, (void *)device );
	
	sem_acquire( bus->scan_device_sem, 1 );
}
예제 #9
0
void test_func2(void *arg) {
	int* num = (void*)arg;
	
	sem_acquire(&s);  
	printf(1,"hey %d.\n",*num); 
	sem_signal(&s); 

	texit(); 
} 
예제 #10
0
void producer(void* arg)
{
	int id;
	id = *(int *)arg;
	printf("Producer %d\n", id);

	while(1)
	{
		sem_acquire(shared.empty);
		sem_acquire(shared.mutex);
		shared.buf[shared.in] = item++;
		shared.in = (shared.in + 1) % SH_SIZE;
		printf("Producer %d produced item no : %d\n", id, item);
		sem_release(shared.mutex);
		sem_release(shared.full);
		sleep(rand() % 3);
	}
}
예제 #11
0
void save(struct virtscreen *vscr)
{
    sem_acquire(vscr->lock);
    if(vscr->data != vscr->back) {
        memcpy(vscr->back,vscr->data,vscr->num_bytes);
        vscr->data = vscr->back;
    }
    sem_release(vscr->lock);
}
예제 #12
0
파일: lock.c 프로젝트: HTshandou/newos
void mutex_lock(mutex *m)
{
	thread_id me = thread_get_current_thread_id();

	if(me == m->holder)
		panic("mutex_lock failure: mutex %p acquired twice by thread 0x%x\n", m, me);

	sem_acquire(m->sem, 1);
	m->holder = me;
}
예제 #13
0
void vputs(struct virtscreen *vscr, char *s)
{
    sem_acquire(vscr->lock);
	while(*s) {
		char_to_virtscreen(vscr, *s);
        if(*s == '\n') char_to_virtscreen(vscr, '\r');
		s++;
	}
    sem_release(vscr->lock);
}
예제 #14
0
파일: wav_multi.c 프로젝트: ZigZagJoe/68k
void task_time() {
	printf("TIME TASK (ID %d) started.\n",CURRENT_TASK_ID);
	yield();
	while(true) {
	    sem_acquire(&lcd_sem);
		lcd_cursor(0,0);
        lcd_printf("Runtime: %d.%d    ",millis()/1000, (millis()%1000)/100);
        sem_release(&lcd_sem);
 		sleep_for(100);
    }
}
예제 #15
0
파일: rhine_dev.c 프로젝트: HTshandou/newos
void rhine_xmit(rhine *r, const char *ptr, ssize_t len)
{
#if 0
	PANIC_UNIMPLEMENTED();
#if 0
	int i;
#endif

//restart:
	sem_acquire(r->tx_sem, 1);
	mutex_lock(&r->lock);

#if 0
	dprintf("XMIT %d %x (%d)\n",r->txbn, ptr, len);

	dprintf("dumping packet:");
	for(i=0; i<len; i++) {
		if(i%8 == 0)
			dprintf("\n");
		dprintf("0x%02x ", ptr[i]);
	}
	dprintf("\n");
#endif

	int_disable_interrupts();
	acquire_spinlock(&r->reg_spinlock);

#if 0
	/* wait for clear-to-send */
	if(!(RTL_READ_32(r, RT_TXSTATUS0 + r->txbn*4) & RT_TX_HOST_OWNS)) {
		dprintf("rhine_xmit: no txbuf free\n");
		rhine_dumptxstate(r);
		release_spinlock(&r->reg_spinlock);
		int_restore_interrupts();
		mutex_unlock(&r->lock);
		sem_release(r->tx_sem, 1);
		goto restart;
	}
#endif

	memcpy((void*)(r->txbuf + r->txbn * 0x800), ptr, len);
	if(len < ETHERNET_MIN_SIZE)
		len = ETHERNET_MIN_SIZE;

	RTL_WRITE_32(r, RT_TXSTATUS0 + r->txbn*4, len | 0x80000);
	if(++r->txbn >= 4)
		r->txbn = 0;

	release_spinlock(&r->reg_spinlock);
	int_restore_interrupts();

	mutex_unlock(&r->lock);
#endif
}
예제 #16
0
void keypress(int key)
{
	char c;
	
	sem_acquire(active->lock);
	char_to_virtscreen(active, key);
	sem_release(active->lock);	
	if(remote_port > 0) {
		c = key;
		port_send(send_port, remote_port, &c, 1, 0);
	}
}
예제 #17
0
void load(struct virtscreen *vscr)
{
    sem_acquire(vscr->lock);
    if(vscr->data == vscr->back) {
        vscr->data = screen;
        memcpy(vscr->data,vscr->back,vscr->num_bytes);
    }
    active = vscr;
    movecursor(vscr->xpos,vscr->ypos);
    sem_release(vscr->lock);
    status(vscr - con);
}
예제 #18
0
void reaper(void)
{
	task_t *task;
	
	asm("cli");	/* XXX race condition? */
	for(;;){
		sem_acquire(reaper_sem);
		task = rsrc_dequeue(reaper_queue);		
//		kprintf("reaper reclaiming thread #%d (%s)",task->rsrc.id,task->rsrc.name);
		task_destroy(task);
	}
	
}
예제 #19
0
파일: monkey.c 프로젝트: avana002/xv6_lab2
void monkey(void* v)
{
   int i = (int)v;
   while(dominant > 0);
   sem_acquire(&t);
   printf(1,"%d\n",i);
   coconuts++;
   int j;
   for(j = 0; j < 100000; j++);
   printf(1,"%d\n",i);
   sem_signal(&t);
   texit();
}
예제 #20
0
파일: lock.c 프로젝트: HTshandou/newos
bool recursive_lock_lock(recursive_lock *lock)
{
	thread_id thid = thread_get_current_thread_id();
	bool retval = false;

	if(thid != lock->holder) {
		sem_acquire(lock->sem, 1);

		lock->holder = thid;
		retval = true;
	}
	lock->recursion++;
	return retval;
}
예제 #21
0
파일: monkey.c 프로젝트: avana002/xv6_lab2
void dmonkey(void* v)
{
   int i = (int)v;
   dominant++;
   sem_acquire(&t);
   dominant--;
   printf(1,"d%d\n",i);
   coconuts++;
   int j;
   for(j = 0; j < 100000; j++);
   printf(1,"d%d\n",i);
   sem_signal(&t);
   texit();
}
예제 #22
0
int main(int argc, char *argv[])
{
  //Monkeys climb the tree six times to demonstrate the phenomenom of
  //dominant monkeys.
  int n_m=atoi(argv[1]);
  int d_m=atoi(argv[2]);
  printf(1,"normal monkeys created: %d\n",n_m);
  printf(1,"dominant monkeys created: %d\n",d_m);
  sem_init(&tree,3);
  if(d_m==0)
  sem_init(&dominant_monkey,1);
  else
  sem_init(&dominant_monkey, d_m);
  lock_init(&mutex);
  int j=0;
  if(argc!=3)
  {
    printf(1,"invalid number of arguments\n");
    exit();
  }
  void *norm_monkey;
  int i;
  for(i=0;i<n_m;i++)
  {
    norm_monkey=thread_create(monkey_climb, (void*)&j);
    if(norm_monkey==0)
    {
      printf(1,"thread create fail\n");
      exit();
    }
  }

  void *dom_monkey;
  for(i=0;i<d_m;i++)
  {
    dom_monkey=thread_create(dominant_monkey_climb, (void*)&j);
    if(dom_monkey==0)
    {
      printf(1,"thread create fail\n");
      exit();
    }
    //printf(1,"dominant monkey thread created\n");
    sem_acquire(&dominant_monkey);
  }
  while(wait()>0);
  printf(1,"Oprah: coconuts for everybody!\n");
  exit();

}
예제 #23
0
static void if_tx_thread(void *args)
{
    ifnet *i = args;
    cbuf *buf;
    ssize_t len;

    t_current_set_name("IF Xmit");

#if IF_PRIO
    thread_set_priority(i->tx_thread, THREAD_MAX_RT_PRIORITY - 2);
#endif
    //if(i->fd < 0)        return -1;


//printf("if %x tx thread inited", i);
    for(;;) {
        sem_acquire(i->tx_queue_sem);
//printf("if %x tx thread gogo\n", i);

        for(;;) {
            // pull a packet out of the queue
            mutex_lock(&i->tx_queue_lock);
            buf = fixed_queue_dequeue(&i->tx_queue);
            mutex_unlock(&i->tx_queue_lock);
            if(!buf)
                break;

#if LOSE_TX_PACKETS
            if(rand() % 100 < LOSE_TX_PERCENTAGE) {
                cbuf_free_chain(buf);
                continue;
            }
#endif

            // put the cbuf chain into a flat buffer
            len = cbuf_get_len(buf);
            cbuf_memcpy_from_chain(i->tx_buf, buf, 0, len);

            cbuf_free_chain(buf);

#if 0||NET_CHATTY
            dprintf("if_tx_thread: sending packet size %ld\n", (long)len);
#endif
            //sys_write(i->fd, i->tx_buf, 0, len);
            i->dev->dops.write(i->dev, i->tx_buf, len);
        }
    }
}
예제 #24
0
파일: wav_multi.c 프로젝트: ZigZagJoe/68k
void task_scroller() {
	printf("SCROLLER TASK (ID %d) started.\n",CURRENT_TASK_ID);
	yield();

    uint8_t mode = 0;
	while(true) {
	    mode = !mode;
	    for(uint8_t i = 0; i < 16; i++) {
		    sem_acquire(&lcd_sem);
		    lcd_cursor(i,1);
            lcd_data(mode?0xFF:' ');
		    sem_release(&lcd_sem);
 		    sleep_for(20);
		}
	}
}
예제 #25
0
//
//	Test malloc()
//
int malloc_thread(void*)
{
	for (int i = 0; i < 50000; i++){
#if LOOK_ITS_A_RACE
		sem_acquire(malloc_sem);
#endif
		free(malloc(10000));

#if LOOK_ITS_A_RACE
		sem_release(malloc_sem);
#endif
	}

	printf("malloc thread finished\n");		
	os_terminate(0);
	return 0;
}
예제 #26
0
void rtl8169_xmit(rtl8169 *r, const char *ptr, ssize_t len)
{
	int i;

#if debug_level_flow >= 3
	dprintf("rtl8169_xmit dumping packet:");
	hexdump(ptr, len);
#endif

restart:
	sem_acquire(r->tx_sem, 1);
	mutex_lock(&r->lock);

	int_disable_interrupts();
	acquire_spinlock(&r->reg_spinlock);

	/* look at the descriptor pointed to by tx_idx_free */
	if (r->txdesc[r->tx_idx_free].flags & RTL_DESC_OWN) {
		/* card owns this one, wait and try again later */
		release_spinlock(&r->reg_spinlock);
		int_restore_interrupts();
		mutex_unlock(&r->lock);
//		sem_release(r->tx_sem, 1);
		goto restart;
	}

	/* queue it up */
	memcpy(TXBUF(r, r->tx_idx_free), ptr, len);
	if (len < 64)
		len = 64;

	r->txdesc[r->tx_idx_free].frame_len = len;
	r->txdesc[r->tx_idx_free].flags = (r->txdesc[r->tx_idx_free].flags & RTL_DESC_EOR) | RTL_DESC_FS | RTL_DESC_LS | RTL_DESC_OWN;
	inc_tx_idx_free(r);
	RTL_WRITE_8(r, REG_TPPOLL, (1<<6)); // something is on the normal queue

	release_spinlock(&r->reg_spinlock);
	int_restore_interrupts();

	mutex_unlock(&r->lock);
}
예제 #27
0
파일: if.c 프로젝트: HTshandou/newos
static int if_tx_thread(void *args)
{
	ifnet *i = args;
	cbuf *buf;
	ssize_t len;

	if(i->fd < 0)
		return -1;

	for(;;) {
 		sem_acquire(i->tx_queue_sem, 1);

		for(;;) {
	 		// pull a packet out of the queue
			mutex_lock(&i->tx_queue_lock);
			buf = fixed_queue_dequeue(&i->tx_queue);
			mutex_unlock(&i->tx_queue_lock);
			if(!buf)
				break;

#if LOSE_TX_PACKETS
			if(rand() % 100 < LOSE_TX_PERCENTAGE) {
				cbuf_free_chain(buf);
				continue;
			}
#endif

			// put the cbuf chain into a flat buffer
			len = cbuf_get_len(buf);
			cbuf_memcpy_from_chain(i->tx_buf, buf, 0, len);

			cbuf_free_chain(buf);

#if NET_CHATTY
		dprintf("if_tx_thread: sending packet size %Ld\n", (long long)len);
#endif
			sys_write(i->fd, i->tx_buf, 0, len);
		}
	}
}
예제 #28
0
파일: rhine_dev.c 프로젝트: HTshandou/newos
ssize_t rhine_rx(rhine *r, char *buf, ssize_t buf_len)
{
	PANIC_UNIMPLEMENTED();
#if 0
	rx_entry *entry;
	uint32 tail;
	uint16 len;
	int rc;
	bool release_sem = false;

//	dprintf("rhine_rx: entry\n");

	if(buf_len < 1500)
		return -1;

restart:
	sem_acquire(r->rx_sem, 1);
	mutex_lock(&r->lock);

	int_disable_interrupts();
	acquire_spinlock(&r->reg_spinlock);

	tail = TAILREG_TO_TAIL(RTL_READ_16(r, RT_RXBUFTAIL));
//	dprintf("tailreg = 0x%x, actual tail 0x%x\n", RTL_READ_16(r, RT_RXBUFTAIL), tail);
	if(tail == RTL_READ_16(r, RT_RXBUFHEAD)) {
		release_spinlock(&r->reg_spinlock);
		int_restore_interrupts();
		mutex_unlock(&r->lock);
		goto restart;
	}

	if(RTL_READ_8(r, RT_CHIPCMD) & RT_CMD_RX_BUF_EMPTY) {
		release_spinlock(&r->reg_spinlock);
		int_restore_interrupts();
		mutex_unlock(&r->lock);
		goto restart;
	}

	// grab another buffer
	entry = (rx_entry *)((uint8 *)r->rxbuf + tail);
//	dprintf("entry->status = 0x%x\n", entry->status);
//	dprintf("entry->len = 0x%x\n", entry->len);

	// see if it's an unfinished buffer
	if(entry->len == 0xfff0) {
		release_spinlock(&r->reg_spinlock);
		int_restore_interrupts();
		mutex_unlock(&r->lock);
		goto restart;
	}

	// figure the len that we need to copy
	len = entry->len - 4; // minus the crc

	// see if we got an error
	if((entry->status & RT_RX_STATUS_OK) == 0 || len > ETHERNET_MAX_SIZE) {
		// error, lets reset the card
		rhine_resetrx(r);
		release_spinlock(&r->reg_spinlock);
		int_restore_interrupts();
		mutex_unlock(&r->lock);
		goto restart;
	}

	// copy the buffer
	if(len > buf_len) {
		dprintf("rhine_rx: packet too large for buffer (len %d, buf_len %ld)\n", len, (long)buf_len);
		RTL_WRITE_16(r, RT_RXBUFTAIL, TAILREG_TO_TAIL(RTL_READ_16(r, RT_RXBUFHEAD)));
		rc = ERR_TOO_BIG;
		release_sem = true;
		goto out;
	}
	if(tail + len > 0xffff) {
//		dprintf("packet wraps around\n");
		memcpy(buf, (const void *)&entry->data[0], 0x10000 - (tail + 4));
		memcpy((uint8 *)buf + 0x10000 - (tail + 4), (const void *)r->rxbuf, len - (0x10000 - (tail + 4)));
	} else {
		memcpy(buf, (const void *)&entry->data[0], len);
	}
	rc = len;

	// calculate the new tail
	tail = ((tail + entry->len + 4 + 3) & ~3) % 0x10000;
//	dprintf("new tail at 0x%x, tailreg will say 0x%x\n", tail, TAIL_TO_TAILREG(tail));
	RTL_WRITE_16(r, RT_RXBUFTAIL, TAIL_TO_TAILREG(tail));

	if(tail != RTL_READ_16(r, RT_RXBUFHEAD)) {
		// we're at last one more packet behind
		release_sem = true;
	}

out:
	release_spinlock(&r->reg_spinlock);
	int_restore_interrupts();

	if(release_sem)
		sem_release(r->rx_sem, 1);
	mutex_unlock(&r->lock);

#if 0
{
	int i;
	dprintf("RX %x (%d)\n", buf, len);

	dprintf("dumping packet:");
	for(i=0; i<len; i++) {
		if(i%8 == 0)
			dprintf("\n");
		dprintf("0x%02x ", buf[i]);
	}
	dprintf("\n");
}
#endif

	return rc;
#endif
}
예제 #29
0
/*
    block_cache_init() - initialise a fixed-size block cache
*/
s32 block_cache_init(ku32 size)
{
    u32 i;

    bc.descriptors = (block_descriptor_t *) umalloc(size * sizeof(block_descriptor_t));
    if(!bc.descriptors)
        return ENOMEM;

    bc.cache = (u8 *) umalloc(size * BLOCK_SIZE);
    if(!bc.cache)
    {
        ufree(bc.descriptors);
        return ENOMEM;
    }

    for(i = 0; i < size; ++i)
    {
        bc.descriptors[i] = (block_descriptor_t)
        {
            .dev   = NULL,
            .block = 0,
            .flags = 0
        };

        sem_init(&bc.descriptors[i].sem);
    }

    bc.stats = (block_cache_stats_t) {0};
    bc.nblocks = size;

    printf("block cache: allocated %u bytes (%u blocks)\n", size * BLOCK_SIZE, size);
    return SUCCESS;
}


/*
    block_cache_get_slot() - return the slot in which a cached block must be stored.
*/
u32 block_cache_get_slot(const dev_t * const dev, ku32 block)
{
    return (((addr_t) dev ^ block) * GREAT_BIG_PRIME) % bc.nblocks;
}


/*
    block_read() - read a block, using the block cache.
*/
s32 block_read(dev_t * const dev, ku32 block, void *buf)
{
    block_descriptor_t *bd;
    void *data;
    u32 slot, one = 1;
    s32 ret;

    if(dev->type != DEV_TYPE_BLOCK)
        return EINVAL;

    if(!bc.nblocks)
        return dev->read(dev, 0, &one, buf);

    slot = block_cache_get_slot(dev, block);
    bd = bc.descriptors + slot;
    data = bc.cache + (slot * BLOCK_SIZE);

    sem_acquire(&bd->sem);

    if((bd->dev != dev) || (bd->block != block))
    {
        if(bd->flags & BC_DIRTY)
        {
            /* Descriptor in use; block is dirty; evict it. */

            /* FIXME: a failed write here should probably not fail the whole operation */
            ret = bd->dev->write(bd->dev, bd->block, &one, data);
            if(ret != SUCCESS)
            {
                sem_release(&bd->sem);
                return ret;
            }

            ++bc.stats.evictions;
            bd->flags = 0;
        }

        /* Read new block into slot */
        ret = dev->read(dev, block, &one, data);
        if(ret != SUCCESS)
        {
            sem_release(&bd->sem);
            return ret;
        }

        /* Update descriptor */
        bd->dev = dev;
        bd->block = block;

        ++bc.stats.misses;
    }
    else
        ++bc.stats.hits;

    ++bc.stats.reads;
    memcpy(buf, data, BLOCK_SIZE);
    sem_release(&bd->sem);

    return SUCCESS;
}
예제 #30
0
ssize_t rtl8169_rx(rtl8169 *r, char *buf, ssize_t buf_len)
{
	uint32 tail;
	size_t len;
	int rc;
	bool release_sem = false;

	SHOW_FLOW0(3, "rtl8169_rx: entry\n");

	if(buf_len < 1500)
		return -1;

restart:
	sem_acquire(r->rx_sem, 1);
	mutex_lock(&r->lock);

	int_disable_interrupts();
	acquire_spinlock(&r->reg_spinlock);

	/* look at the descriptor pointed to by rx_idx_free */
	if (r->rxdesc[r->rx_idx_free].flags & RTL_DESC_OWN) {
		/* for some reason it's owned by the card, wait for more packets */
		release_spinlock(&r->reg_spinlock);
		int_restore_interrupts();
		mutex_unlock(&r->lock);
		goto restart;
	}

	/* process this packet */
	len =  r->rxdesc[r->rx_idx_free].frame_len & 0x3fff;
	SHOW_FLOW(3, "rtl8169_rx: desc idx %d: len %d\n", r->rx_idx_free, len);

	if (len > buf_len) {
		rc = ERR_TOO_BIG;
		release_sem = true;
		goto out;
	}

	memcpy(buf, RXBUF(r, r->rx_idx_free), len);
	rc = len;

#if debug_level_flow >= 3
	hexdump(RXBUF(r, r->rx_idx_free), len);
#endif

	/* stick it back in the free list */
	r->rxdesc[r->rx_idx_free].buffer_size = BUFSIZE_PER_FRAME;
	r->rxdesc[r->rx_idx_free].flags = (r->rxdesc[r->rx_idx_free].flags & RTL_DESC_EOR) | RTL_DESC_OWN;
	inc_rx_idx_free(r);

	/* see if there are more packets pending */
	if ((r->rxdesc[r->rx_idx_free].flags & RTL_DESC_OWN) == 0)
		release_sem = true; // if so, release the rx sem so the next reader gets a shot

out:
	release_spinlock(&r->reg_spinlock);
	int_restore_interrupts();

	if(release_sem)
		sem_release(r->rx_sem, 1);
	mutex_unlock(&r->lock);

	return rc;
}