+
+int
+pmc_acquire(task_t task)
+{
+ kern_return_t retval = KERN_SUCCESS;
+
+ if (!pmc_inited)
+ return KERN_FAILURE;
+
+ simple_lock(&pmc_lock);
+
+ if(pmc_owner == task) {
+ DBG("pmc_acquire - "
+ "ACQUIRED: already owner\n");
+ retval = KERN_SUCCESS;
+ /* already own it */
+ } else if(pmc_owner == TASK_NULL) { /* no one owns it */
+ pmc_owner = task;
+ pmc_thread_count = 0;
+ DBG("pmc_acquire - "
+ "ACQUIRED: no current owner - made new owner\n");
+ retval = KERN_SUCCESS;
+ } else { /* someone already owns it */
+ if(pmc_owner == kernel_task) {
+ if(pmc_thread_count == 0) {
+ /* kernel owns it but no threads using it */
+ pmc_owner = task;
+ pmc_thread_count = 0;
+ DBG("pmc_acquire - "
+ "ACQUIRED: owned by kernel, no threads\n");
+ retval = KERN_SUCCESS;
+ } else {
+ DBG("pmc_acquire - "
+ "DENIED: owned by kernel, in use\n");
+ retval = KERN_RESOURCE_SHORTAGE;
+ }
+ } else { /* non-kernel owner */
+ DBG("pmc_acquire - "
+ "DENIED: owned by another task\n");
+ retval = KERN_RESOURCE_SHORTAGE;
+ }
+ }
+
+ simple_unlock(&pmc_lock);
+ return retval;
+}
+
+int
+pmc_release(task_t task)
+{
+ kern_return_t retval = KERN_SUCCESS;
+ task_t old_pmc_owner = pmc_owner;
+
+ if (!pmc_inited)
+ return KERN_FAILURE;
+
+ simple_lock(&pmc_lock);
+
+ if(task != pmc_owner) {
+ retval = KERN_NO_ACCESS;
+ } else {
+ if(old_pmc_owner == kernel_task) {
+ if(pmc_thread_count>0) {
+ DBG("pmc_release - "
+ "NOT RELEASED: owned by kernel, in use\n");
+ retval = KERN_NO_ACCESS;
+ } else {
+ DBG("pmc_release - "
+ "RELEASED: was owned by kernel\n");
+ pmc_owner = TASK_NULL;
+ retval = KERN_SUCCESS;
+ }
+ } else {
+ DBG("pmc_release - "
+ "RELEASED: was owned by user\n");
+ pmc_owner = TASK_NULL;
+ retval = KERN_SUCCESS;
+ }
+ }
+
+ simple_unlock(&pmc_lock);
+ return retval;
+}
+