Exemple #1
0
DECLARE_TEST(mutex, basic) {
	mutex_t* mutex;

	mutex = mutex_allocate(STRING_CONST("test"));

	EXPECT_CONSTSTRINGEQ(mutex_name(mutex), string_const(STRING_CONST("test")));
	EXPECT_TRUE(mutex_try_lock(mutex));
	EXPECT_TRUE(mutex_lock(mutex));
	EXPECT_TRUE(mutex_try_lock(mutex));
	EXPECT_TRUE(mutex_lock(mutex));

	EXPECT_TRUE(mutex_unlock(mutex));
	EXPECT_TRUE(mutex_unlock(mutex));
	EXPECT_TRUE(mutex_unlock(mutex));
	EXPECT_TRUE(mutex_unlock(mutex));

	log_set_suppress(0, ERRORLEVEL_WARNING);
	EXPECT_FALSE(mutex_unlock(mutex));
	log_set_suppress(0, ERRORLEVEL_INFO);

	mutex_signal(mutex);
	thread_yield();
	EXPECT_TRUE(mutex_try_wait(mutex, 1));
	EXPECT_TRUE(mutex_unlock(mutex));

	mutex_signal(mutex);
	thread_yield();
	EXPECT_TRUE(mutex_wait(mutex));
	EXPECT_TRUE(mutex_unlock(mutex));

	log_set_suppress(0, ERRORLEVEL_WARNING);
	EXPECT_FALSE(mutex_try_wait(mutex, 100));
	EXPECT_FALSE(mutex_unlock(mutex));
	log_set_suppress(0, ERRORLEVEL_INFO);

	mutex_signal(mutex);
	thread_yield();
	EXPECT_TRUE(mutex_try_wait(mutex, 1));
	log_set_suppress(0, ERRORLEVEL_WARNING);
	EXPECT_FALSE(mutex_try_wait(mutex, 100));
	EXPECT_TRUE(mutex_unlock(mutex));
	EXPECT_FALSE(mutex_unlock(mutex));
	log_set_suppress(0, ERRORLEVEL_INFO);

	mutex_deallocate(mutex);

	return 0;
}
Exemple #2
0
boolean_t
uniproc_preempt(void)
{
	if (mutex_try_lock(&uniproc_preemption_mutex)) {
		uniproc_change_current(current, get_current_task());
#if	CONFIG_OSFMACH3_DEBUG
		{
			struct server_thread_priv_data	*priv_datap;

			priv_datap =
				server_thread_get_priv_data(cthread_self());
			if (priv_datap->preemptive) {
				/*
				 * We actually preempted another thread...
				 * account for this glorious deed !
				 */
				uniproc_preemptions++;
			} else {
				/*
				 * It's just the preemptible thread
				 * preempting itself
				 */
			}
		}
#endif	/* CONFIG_OSFMACH3_DEBUG */
		return TRUE;
	}
	return FALSE;
}
Exemple #3
0
boolean_t
uniproc_try_enter(void)
{
	if (mutex_try_lock(&uniproc_mutex)) {
		uniproc_has_entered();
		return TRUE;
	}
	return FALSE;
}
Exemple #4
0
void
uniproc_enter(void)
{
	struct server_thread_priv_data	*priv_datap;

#if	UNIPROC_PREEMPTION
	if (!mutex_try_lock(&uniproc_mutex)) {
		priv_datap = server_thread_get_priv_data(cthread_self());
		if (priv_datap->preemptive && uniproc_allow_preemption) {
			/* prioritary thread: try to preempt */
			while (!uniproc_try_enter() &&
			       !uniproc_preempt()) {
				server_thread_yield(1);	/* yield for 1 ms */
			}
			/* we're all set */
			return;
		} else {
			/* just block and wait for our turn */
			mutex_lock(&uniproc_mutex);
		}
	}
#else	/* UNIPROC_PREEMPTION */
	if (use_antechamber_mutex) {
		priv_datap = server_thread_get_priv_data(cthread_self());
		if (priv_datap->current_task &&
		    priv_datap->current_task->mm == &init_mm) {
			/*
			 * We're working for a system thread: carry on.
			 */
			mutex_lock(&uniproc_mutex);
		} else {
			/*
			 * We're working for a user thread: we don't want
			 * loads of user threads contending with system
			 * threads on the uniproc mutex, so take the
			 * uniproc_antechamber_mutex first to ensure that
			 * only one user thread will be contending with
			 * system threads at a given time.
			 */
			mutex_lock(&uniproc_antechamber_mutex);
			mutex_lock(&uniproc_mutex);
			mutex_unlock(&uniproc_antechamber_mutex);
		}
	} else {
		mutex_lock(&uniproc_mutex);
	}
#endif	/* UNIPROC_PREEMPTION */
	uniproc_has_entered();
}
Exemple #5
0
static void*
mutex_thread(void* arg) {
	mutex_t* mutex = arg;
	size_t i;

	for (i = 0; i < 128; ++i) {
		if (!mutex_try_lock(mutex))
			mutex_lock(mutex);

		++thread_counter;

		mutex_unlock(mutex);
	}

	return 0;
}
Exemple #6
0
static void* mutex_thread( object_t thread, void* arg )
{
	mutex_t* mutex = arg;
	int i;
	FOUNDATION_UNUSED( thread );
	FOUNDATION_UNUSED( arg );

	for( i = 0; i < 128; ++i )
	{
		if( !mutex_try_lock( mutex ) )
			mutex_lock( mutex );

		++thread_counter;

		mutex_unlock( mutex );
	}

	return 0;
}
Exemple #7
0
int
ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
{
	return mutex_try_lock( mutex );
}
/* Implement dir_rename as described in <hurd/fs.defs>. */
kern_return_t
diskfs_S_dir_rename (struct protid *fromcred,
		     char *fromname,
		     struct protid *tocred,
		     char *toname,
		     int excl)
{
  struct node *fdp, *tdp, *fnp, *tnp, *tmpnp;
  error_t err;
  struct dirstat *ds = alloca (diskfs_dirstat_size);
  
  if (!fromcred)
    return EOPNOTSUPP;

  /* Verify that tocred really is a port to us. */
  if (! tocred)
    return EXDEV;

  if (!strcmp (fromname, ".") || !strcmp (fromname, "..")
   || !strcmp (toname,   ".") || !strcmp (toname,   ".."))
    return EINVAL;

  if (tocred->po->shadow_root != fromcred->po->shadow_root)
    /* Same translator, but in different shadow trees.  */
    return EXDEV;

  if (diskfs_check_readonly ())
    return EROFS;

  fdp = fromcred->po->np;
  tdp = tocred->po->np;

 try_again:
  /* Acquire the source; hold a reference to it.  This 
     will prevent anyone from deleting it before we create
     the new link. */
  mutex_lock (&fdp->lock);
  err = diskfs_lookup (fdp, fromname, LOOKUP, &fnp, 0, fromcred);
  mutex_unlock (&fdp->lock);
  if (err == EAGAIN)
    err = EINVAL;
  if (err)
    return err;

  if (S_ISDIR (fnp->dn_stat.st_mode))
    {
      mutex_unlock (&fnp->lock);
      if (!mutex_try_lock (&renamedirlock))
	{
	  diskfs_nrele (fnp);
	  mutex_lock (&renamedirlock);
	  goto try_again;
	}
      err = diskfs_rename_dir (fdp, fnp, fromname, tdp, toname, fromcred,
			       tocred);
      if (diskfs_synchronous)
	{
	  mutex_lock (&fdp->lock);
	  diskfs_file_update (fdp, 1);
	  mutex_unlock (&fdp->lock);
	  
	  mutex_lock (&fnp->lock);
	  diskfs_file_update (fnp, 1);
	  mutex_unlock (&fnp->lock);

	  mutex_lock (&tdp->lock);
	  diskfs_file_update (tdp, 1);
	  mutex_unlock (&tdp->lock);
	}
      
      diskfs_nrele (fnp);
      mutex_unlock (&renamedirlock);
      if (!err)
	/* MiG won't do this for us, which it ought to. */
	mach_port_deallocate (mach_task_self (), tocred->pi.port_right);
      return err;
    }

  mutex_unlock (&fnp->lock);

  /* We now hold no locks */

  /* Link the node into the new directory. */
  mutex_lock (&tdp->lock);
  
  err = diskfs_lookup (tdp, toname, RENAME, &tnp, ds, tocred);
  if (err == EAGAIN)
    err = EINVAL;
  else if (!err && excl)
    {
      err = EEXIST;
      diskfs_nput (tnp);
    }
  if (err && err != ENOENT)
    {
      diskfs_drop_dirstat (tdp, ds);
      diskfs_nrele (fnp);
      mutex_unlock (&tdp->lock);
      return err;
    }

  /* rename("foo", "link-to-foo") is guaranteed to return 0 and
     do nothing by Posix. */
  if (tnp == fnp)
    {
      diskfs_drop_dirstat (tdp, ds);
      diskfs_nrele (fnp);
      diskfs_nput (tnp);
      mutex_unlock (&tdp->lock);
      mach_port_deallocate (mach_task_self (), tocred->pi.port_right);
      return 0;
    }

  /* rename("foo", dir) should fail. */
  if (tnp && S_ISDIR (tnp->dn_stat.st_mode))
    {
      diskfs_drop_dirstat (tdp, ds);
      diskfs_nrele (fnp);
      diskfs_nput (tnp);
      mutex_unlock (&tdp->lock);
      return EISDIR;
    }

  mutex_lock (&fnp->lock);

  /* Increment the link count for the upcoming link */
  if (fnp->dn_stat.st_nlink == diskfs_link_max - 1)
    {
      diskfs_drop_dirstat (tdp, ds);
      diskfs_nput (fnp);
      if (tnp)
        diskfs_nput (tnp);
      mutex_unlock (&tdp->lock);
      return EMLINK;
    }
  fnp->dn_stat.st_nlink++;
  fnp->dn_set_ctime = 1;
  diskfs_node_update (fnp, 1);

  if (tnp)
    {
      err = diskfs_dirrewrite (tdp, tnp, fnp, toname, ds);
      if (!err)
	{
	  tnp->dn_stat.st_nlink--;
	  tnp->dn_set_ctime = 1;
	  if (diskfs_synchronous)
	    diskfs_node_update (tnp, 1);
	}
      diskfs_nput (tnp);
    }
  else
    err = diskfs_direnter (tdp, toname, fnp, ds, tocred);

  if (diskfs_synchronous)
    diskfs_node_update (tdp, 1);

  mutex_unlock (&tdp->lock);
  mutex_unlock (&fnp->lock);
  if (err)
    {
      diskfs_nrele (fnp);
      return err;
    }

  /* We now hold no locks */

  /* Now we remove the source.  Unfortunately, we haven't held 
     fdp locked (nor could we), so someone else might have already
     removed it. */
  mutex_lock (&fdp->lock);
  err = diskfs_lookup (fdp, fromname, REMOVE, &tmpnp, ds, fromcred);
  if (err)
    {
      diskfs_drop_dirstat (tdp, ds);
      mutex_unlock (&fdp->lock);
      diskfs_nrele (fnp);
      return err;
    }

  if (tmpnp != fnp)
    {
      /* This is no longer the node being renamed, so just return. */
      diskfs_drop_dirstat (tdp, ds);
      diskfs_nput (tmpnp);
      diskfs_nrele (fnp);
      mutex_unlock (&fdp->lock);
      mach_port_deallocate (mach_task_self (), tocred->pi.port_right);
      return 0;
    }
  
  diskfs_nrele (tmpnp);

  err = diskfs_dirremove (fdp, fnp, fromname, ds);
  if (diskfs_synchronous)
    diskfs_node_update (fdp, 1);

  fnp->dn_stat.st_nlink--;
  fnp->dn_set_ctime = 1;
  
  if (diskfs_synchronous)
    diskfs_node_update (fnp, 1);
  
  diskfs_nput (fnp);
  mutex_unlock (&fdp->lock);
  if (!err)
    mach_port_deallocate (mach_task_self (), tocred->pi.port_right);

  return err;
}
Exemple #9
0
void usbdbg_data_in(void *buffer, int length)
{
    switch (cmd) {
        case USBDBG_FW_VERSION: {
            uint32_t *ver_buf = buffer;
            ver_buf[0] = FIRMWARE_VERSION_MAJOR;
            ver_buf[1] = FIRMWARE_VERSION_MINOR;
            ver_buf[2] = FIRMWARE_VERSION_PATCH;
            cmd = USBDBG_NONE;
            break;
        }

        case USBDBG_TX_BUF_LEN: {
            uint32_t tx_buf_len = usbd_cdc_tx_buf_len();
            memcpy(buffer, &tx_buf_len, sizeof(tx_buf_len));
            cmd = USBDBG_NONE;
            break;
        }

        case USBDBG_TX_BUF: {
            uint8_t *tx_buf = usbd_cdc_tx_buf(length);
            memcpy(buffer, tx_buf, length);
            if (xfer_bytes == xfer_length) {
                cmd = USBDBG_NONE;
            }
            break;
        }

        case USBDBG_FRAME_SIZE:
            // Return 0 if FB is locked or not ready.
            ((uint32_t*)buffer)[0] = 0;
            // Try to lock FB. If header size == 0 frame is not ready
            if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_IDE)) {
                // If header size == 0 frame is not ready
                if (JPEG_FB()->size == 0) {
                    // unlock FB
                    mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
                } else {
                    // Return header w, h and size/bpp
                    ((uint32_t*)buffer)[0] = JPEG_FB()->w;
                    ((uint32_t*)buffer)[1] = JPEG_FB()->h;
                    ((uint32_t*)buffer)[2] = JPEG_FB()->size;
                }
            }
            cmd = USBDBG_NONE;
            break;

        case USBDBG_FRAME_DUMP:
            if (xfer_bytes < xfer_length) {
                memcpy(buffer, JPEG_FB()->pixels+xfer_bytes, length);
                xfer_bytes += length;
                if (xfer_bytes == xfer_length) {
                    cmd = USBDBG_NONE;
                    JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0;
                    mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
                }
            }
            break;

        case USBDBG_ARCH_STR: {
            snprintf((char *) buffer, 64, "%s [%s:%08X%08X%08X]",
                    OMV_ARCH_STR, OMV_BOARD_TYPE,
                    *((unsigned int *) (OMV_UNIQUE_ID_ADDR + 8)),
                    *((unsigned int *) (OMV_UNIQUE_ID_ADDR + 4)),
                    *((unsigned int *) (OMV_UNIQUE_ID_ADDR + 0)));
            cmd = USBDBG_NONE;
            break;
        }

        case USBDBG_SCRIPT_RUNNING: {
            uint32_t *buf = buffer;
            buf[0] = (uint32_t) script_running;
            cmd = USBDBG_NONE;
            break;
        }
        default: /* error */
            break;
    }
}
Exemple #10
0
void usbdbg_data_in(void *buffer, int length)
{
    switch (cmd) {
        case USBDBG_FW_VERSION: {
            uint32_t *ver_buf = buffer;
            ver_buf[0] = FIRMWARE_VERSION_MAJOR;
            ver_buf[1] = FIRMWARE_VERSION_MINOR;
            ver_buf[2] = FIRMWARE_VERSION_PATCH;
            cmd = USBDBG_NONE;
            break;
        }

        case USBDBG_TX_BUF_LEN: {
            uint32_t tx_buf_len = usbd_cdc_tx_buf_len();
            memcpy(buffer, &tx_buf_len, length);
            cmd = USBDBG_NONE;
            break;
        }

        case USBDBG_TX_BUF: {
            uint8_t *tx_buf = usbd_cdc_tx_buf(length);
            memcpy(buffer, tx_buf, length);
            if (xfer_bytes == xfer_length) {
                cmd = USBDBG_NONE;
            }
            break;
        }

        case USBDBG_FRAME_SIZE:
            memcpy(buffer, fb, length);
            cmd = USBDBG_NONE;
            break;

        case USBDBG_FRAME_LOCK:
            // try to lock FB, return fb hdr if locked
            if (fb->ready && mutex_try_lock(&fb->lock)) {
                fb->lock_tried = 0;
                memcpy(buffer, fb, length);
            } else {
                // no valid frame or failed to lock, return 0
                fb->lock_tried = 1;
                ((uint32_t*)buffer)[0] = 0;
            }
            cmd = USBDBG_NONE;
            break;

        case USBDBG_FRAME_DUMP:
            if (xfer_bytes < xfer_length) {
                memcpy(buffer, fb->pixels+xfer_bytes, length);
                xfer_bytes += length;
                if (xfer_bytes == xfer_length) {
                    mutex_unlock(&fb->lock);
                    cmd = USBDBG_NONE;
                }
            }
            break;

        default: /* error */
            break;
    }
}
Exemple #11
0
ide_dbg_status_t ide_dbg_ack_data(machine_uart_obj_t* uart)
{
    uint32_t length = 0;
ack_start:
    length = xfer_length - xfer_bytes;
    length = (length>IDE_DBG_MAX_PACKET) ? IDE_DBG_MAX_PACKET : length;
    if(length == 0)
    {
        if(cmd == USBDBG_NONE)
            is_busy_sending = false;
        return IDE_DBG_STATUS_OK;
    }

    switch (cmd)
    {
        case USBDBG_FW_VERSION:
        {
            ((uint32_t*)ide_dbg_cmd_buf)[0] = MICROPY_VERSION_MAJOR;
            ((uint32_t*)ide_dbg_cmd_buf)[1] = MICROPY_VERSION_MINOR;
            ((uint32_t*)ide_dbg_cmd_buf)[2] = MICROPY_VERSION_MICRO;
            cmd = USBDBG_NONE;
            break;
        }

        case USBDBG_TX_BUF_LEN:
        {
            *((uint32_t*)ide_dbg_cmd_buf) = Buffer_Size(&g_uart_send_buf_ide);
            cmd = USBDBG_NONE;
            break;
        }

        case USBDBG_TX_BUF:
        {
            Buffer_Gets(&g_uart_send_buf_ide, ide_dbg_cmd_buf, length);
            if (xfer_bytes+ length == xfer_length)
            {
                cmd = USBDBG_NONE;
            }
            break;
        }

        case USBDBG_FRAME_SIZE:
            {
                // Return 0 if FB is locked or not ready.
                ((uint32_t*)ide_dbg_cmd_buf)[0] = 0;
                // Try to lock FB. If header size == 0 frame is not ready
                if (mutex_try_lock(&(JPEG_FB()->lock), MUTEX_TID_IDE))
                {
                    // If header size == 0 frame is not ready
                    if (JPEG_FB()->size == 0)
                    {
                        // unlock FB
                        mutex_unlock(&(JPEG_FB()->lock), MUTEX_TID_IDE);
                    } else
                    {
                        // Return header w, h and size/bpp
                        ((uint32_t*)ide_dbg_cmd_buf)[0] = JPEG_FB()->w;
                        ((uint32_t*)ide_dbg_cmd_buf)[1] = JPEG_FB()->h;
                        ((uint32_t*)ide_dbg_cmd_buf)[2] = JPEG_FB()->size;
                    }
                }
            }
            cmd = USBDBG_NONE;
            break;

        case USBDBG_FRAME_DUMP:
            if (xfer_bytes < xfer_length)
            {
                if(MICROPY_UARTHS_DEVICE == uart->uart_num)
                {
                    temp_size = uarths_send_data(JPEG_FB()->pixels, xfer_length);
                }
                else if(UART_DEVICE_MAX > uart->uart_num)
                {
                    // uart_configure(uart->uart_num, (size_t)uart->baudrate, (size_t)uart->bitwidth, uart->stop,  uart->parity);
                    temp_size= uart_send_data(uart->uart_num, JPEG_FB()->pixels, xfer_length);
                }
                cmd = USBDBG_NONE;
                xfer_bytes = xfer_length;
                JPEG_FB()->w = 0;
                JPEG_FB()->h = 0;
                JPEG_FB()->size = 0;
                mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
            }
            break;

        case USBDBG_ARCH_STR:
        {
            snprintf((char *) ide_dbg_cmd_buf, IDE_DBG_MAX_PACKET, "%s [%s:%08X%08X%08X]",
                    OMV_ARCH_STR, OMV_BOARD_TYPE,0,0,0);//TODO: UID
            cmd = USBDBG_NONE;
            break;
        }

        case USBDBG_SCRIPT_RUNNING:
        {
            *((uint32_t*)ide_dbg_cmd_buf) = script_running?1:0;
            cmd = USBDBG_NONE;
            break;
        }
        case USBDBG_FILE_SAVE_STATUS:
        {
            *((uint32_t*)ide_dbg_cmd_buf) = ide_file_save_status;
            cmd = USBDBG_NONE;
            break;
        }
        default: /* error */
            break;
    }
    if(length && !is_sending_jpeg)
    {
        if(MICROPY_UARTHS_DEVICE == uart->uart_num)
        {
            temp_size = uarths_send_data(ide_dbg_cmd_buf, length);
        }
        else if(UART_DEVICE_MAX > uart->uart_num)
            temp_size= uart_send_data(uart->uart_num, ide_dbg_cmd_buf, length);
        xfer_bytes += length;
        if( xfer_bytes < xfer_length )
            goto ack_start;
    }
    if(cmd == USBDBG_NONE)
    {
        is_sending_jpeg = false;
        is_busy_sending = false;
    }
}