Esempio n. 1
0
void PionOneToOneScheduler::startup(void)
{
	// lock mutex for thread safety
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	
	if (! m_is_running) {
		PION_LOG_INFO(m_logger, "Starting thread scheduler");
		m_is_running = true;
		
		// make sure there are enough services initialized
		while (m_service_pool.size() < m_num_threads) {
			boost::shared_ptr<ServicePair>	service_ptr(new ServicePair());
			m_service_pool.push_back(service_ptr);
		}

		// schedule a work item for each service to make sure that it doesn't complete
		for (ServicePool::iterator i = m_service_pool.begin(); i != m_service_pool.end(); ++i) {
			keepRunning((*i)->first, (*i)->second);
		}
		
		// start multiple threads to handle async tasks
		for (boost::uint32_t n = 0; n < m_num_threads; ++n) {
			boost::shared_ptr<boost::thread> new_thread(new boost::thread( boost::bind(&PionScheduler::processServiceWork,
																					   this, boost::ref(m_service_pool[n]->first)) ));
			m_thread_pool.push_back(new_thread);
		}
	}
}
Esempio n. 2
0
void timer_dump ()
{
    usize_t index;

    scheduler_lock ();
    console_print ("\n");
    console_print ("Summary\n");
    console_print ("-------\n");
    console_print ("  Supported: %u\n", CONFIG_MAX_TIMER);
    console_print ("  Allocated: %u\n", CONFIG_MAX_TIMER -
                   dll_size (&g_free_timer));
    console_print ("  .BSS Used: %u\n", ((address_t)&g_bucket_firing
                                         - (address_t)g_timer_pool) + sizeof (g_bucket_firing));
    console_print ("\n");
    console_print ("Statistics\n");
    console_print ("----------\n");
    console_print ("    No Timer: %u\n", g_statistics.notimer_);
    console_print ("    Abnormal: %u\n", g_statistics.abnormal_);
    console_print ("   Traversed: %u\n", g_statistics.traversed_);
    console_print ("  Queue Full: %u\n", g_statistics.queue_full_);
    console_print ("\n");
    console_print ("Bucket Details\n");
    console_print ("--------------\n");
    for (index = 0; index <= BUCKET_LAST_INDEX; ++ index) {
        console_print ("  [%u]: hit (%u), redo (%u), timer held (%u)\n",
                       index, g_buckets [index].hit_, g_buckets [index].redo_,
                       dll_size (&g_buckets [index].dll_));
    }
    console_print ("\n");
    scheduler_unlock ();
}
Esempio n. 3
0
void mutex_dump ()
{
    if (is_in_interrupt ()) {
        return;
    }

    scheduler_lock ();
    console_print ("\n\n");
    console_print ("Summary\n");
    console_print ("-------\n");
    console_print ("  Supported: %u\n", CONFIG_MAX_MUTEX);
    console_print ("  Allocated: %u\n", dll_size (&g_mutex_container.used_));
    console_print ("  .BSS Used: %u\n", ((address_t)&g_mutex_container 
        - (address_t)g_mutex_pool) + sizeof (g_mutex_container));
    console_print ("\n");
    console_print ("Statistics\n");
    console_print ("----------\n");
    console_print ("  No Object: %u\n", g_mutex_container.stats_noobj_);
    console_print ("\n");
    console_print ("Mutex Details\n");
    console_print ("-------------\n");
    (void) dll_traverse (&g_mutex_container.used_, mutex_dump_for_each, 0);
    console_print ("\n");
    scheduler_unlock ();
}
void scheduler::join(void) {
    std::unique_lock<std::mutex> scheduler_lock(mutex);
    while (running) {
        // sleep until scheduler_has_stopped condition is signaled
        scheduler_has_stopped.wait(scheduler_lock);
    }
}
Esempio n. 5
0
void PionScheduler::join(void)
{
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	while (m_is_running) {
		// sleep until scheduler_has_stopped condition is signaled
		m_scheduler_has_stopped.wait(scheduler_lock);
	}
}
Esempio n. 6
0
/*
 * net_buffer_lock
 * @fd: Networking buffer file descriptor.
 * This function will get the lock for net buffer file descriptor.
 */
static int32_t net_buffer_lock(void *fd)
{
#ifdef CONFIG_SEMAPHORE
    /* Obtain data lock for networking buffers. */
    return semaphore_obtain(&((NET_BUFFER_FS *)fd)->lock, MAX_WAIT);
#else
    /* Remove some compiler warnings. */
    UNUSED_PARAM(fd);

    /* Lock scheduler. */
    scheduler_lock();

    /* Return success. */
    return (SUCCESS);
#endif
} /* net_buffer_lock */
Esempio n. 7
0
/*
 * console_lock
 * @fd: File descriptor for the console.
 * This function will get the lock for a given console.
 */
static int32_t console_lock(void *fd)
{
#ifdef CONFIG_SEMAPHORE
    /* Obtain data lock for this console. */
    return semaphore_obtain(&((CONSOLE *)fd)->lock, MAX_WAIT);
#else
    /* Remove some compiler warnings. */
    UNUSED_PARAM(fd);

    /* Lock scheduler. */
    scheduler_lock();

    /* Return success. */
    return (SUCCESS);
#endif
} /* console_lock */
Esempio n. 8
0
/*
 * scheduler_task_remove
 * @tcb: Task control block that is needed to be removed.
 * This function removes a finished task from the global task list. Once
 * removed user can call scheduler_task_add to run a finished task.
 */
void scheduler_task_remove(TASK *tcb)
{
    /* Lock the scheduler. */
    scheduler_lock();

    /* Task should be in finished state. */
    ASSERT(tcb->state != TASK_FINISHED);

#ifdef TASK_STATS
    /* Remove this task from global task list. */
    sll_remove(&sch_task_list, tcb, OFFSETOF(TASK, next_global));
#endif /* TASK_STATS */

    /* Enable scheduling. */
    scheduler_unlock();

} /* scheduler_task_remove */
Esempio n. 9
0
void PionSingleServiceScheduler::startup(void)
{
	// lock mutex for thread safety
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	
	if (! m_is_running) {
		PION_LOG_INFO(m_logger, "Starting thread scheduler");
		m_is_running = true;
		
		// schedule a work item to make sure that the service doesn't complete
		m_service.reset();
		keepRunning(m_service, m_timer);
		
		// start multiple threads to handle async tasks
		for (boost::uint32_t n = 0; n < m_num_threads; ++n) {
			boost::shared_ptr<boost::thread> new_thread(new boost::thread( boost::bind(&PionScheduler::processServiceWork,
																					   this, boost::ref(m_service)) ));
			m_thread_pool.push_back(new_thread);
		}
	}
}
Esempio n. 10
0
void PionScheduler::shutdown(void)
{
	// lock mutex for thread safety
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	
	if (m_is_running) {
		
		PION_LOG_INFO(m_logger, "Shutting down the thread scheduler");
		
		while (m_active_users > 0) {
			// first, wait for any active users to exit
			PION_LOG_INFO(m_logger, "Waiting for " << m_active_users << " scheduler users to finish");
			m_no_more_active_users.wait(scheduler_lock);
		}

		// shut everything down
		m_is_running = false;
		stopServices();
		stopThreads();
		finishServices();
		finishThreads();
		
		PION_LOG_INFO(m_logger, "The thread scheduler has shutdown");

		// Make sure anyone waiting on shutdown gets notified
		m_scheduler_has_stopped.notify_all();
		
	} else {
		
		// stop and finish everything to be certain that no events are pending
		stopServices();
		stopThreads();
		finishServices();
		finishThreads();
		
		// Make sure anyone waiting on shutdown gets notified
		// even if the scheduler did not startup successfully
		m_scheduler_has_stopped.notify_all();
	}
}
void scheduler::startup() {
    // lock mutex for thread safety
    std::lock_guard<std::mutex> scheduler_lock(mutex);

    if (!running) {
        STATICLIB_PION_LOG_INFO(log, "Starting thread scheduler");
        running = true;

        // schedule a work item to make sure that the service doesn't complete
        asio_service.reset();
        keep_running(asio_service, timer);

        // start multiple threads to handle async tasks
        for (uint32_t n = 0; n < num_threads; ++n) {
            std::unique_ptr<std::thread> new_thread(new std::thread([this]() {
                this->process_service_work(this->asio_service);
                this->thread_stop_hook();
            }));
            thread_pool.emplace_back(std::move(new_thread));
        }
    }
}
Esempio n. 12
0
/*
 * console_unregister
 * @console: Console data.
 * This function will unregister a console.
 */
void console_unregister(CONSOLE *console)
{
    /* This could be a file descriptor chain, so destroy it. */
    fs_destroy_chain((FD)&console->fs);

#ifndef CONFIG_SEMAPHORE
    /* Lock the scheduler. */
    scheduler_lock();
#else
    /* Obtain the global data lock. */
    OS_ASSERT(semaphore_obtain(&console_data.lock, MAX_WAIT) != SUCCESS);

    /* Obtain the lock for the console needed to be unregistered. */
    if (semaphore_obtain(&console->lock, MAX_WAIT) == SUCCESS)
    {
#endif
        /* Resume all tasks waiting on this file descriptor. */
        fd_handle_criteria((FD)console, NULL, FS_NODE_DELETED);

#ifdef CONFIG_SEMAPHORE
        /* Delete the console lock. */
        semaphore_destroy(&console->lock);
#endif

        /* Just remove this console from console list. */
        OS_ASSERT(sll_remove(&console_data.list, console, OFFSETOF(CONSOLE, fs.next)) != console);

#ifdef CONFIG_SEMAPHORE
    }

    /* Release the global data lock. */
    semaphore_release(&console_data.lock);
#else
    /* Enable scheduling. */
    scheduler_unlock();
#endif

} /* console_unregister */
Esempio n. 13
0
/*
 * sleep_ticks
 * @ticks: Number of ticks for which this task is needed to sleep.
 * This function sleeps/suspends the current task for the given number of system
 * ticks.
 */
void sleep_ticks(uint32_t ticks)
{
    TASK *tcb;
    uint32_t interrupt_level;

    /* Save the current task pointer. */
    tcb = get_current_task();

    /* Current task should not be null. */
    OS_ASSERT(tcb == NULL);

    /* Interrupts must not be locked. */
    OS_ASSERT(tcb->interrupt_lock_count != 0);

    /* Lock the scheduler. */
    scheduler_lock();

    /* Add current task to the sleep list. */
    sleep_add_to_list(tcb, ticks);

    /* Disable interrupts. */
    interrupt_level = GET_INTERRUPT_LEVEL();
    DISABLE_INTERRUPTS();

    /* Task is being suspended. */
    tcb->status = TASK_SUSPENDED;

    /* Return control to the system.
     * We will resume from here when our required delay has been achieved. */
    CONTROL_TO_SYSTEM();

    /* Restore old interrupt level. */
    SET_INTERRUPT_LEVEL(interrupt_level);

    /* Enable scheduling. */
    scheduler_unlock();

} /* sleep_ticks */
Esempio n. 14
0
/*
 * console_register
 * @console: Console data.
 * This function will register a console.
 */
void console_register(CONSOLE *console)
{
#ifndef CONFIG_SEMAPHORE
    /* Lock the scheduler. */
    scheduler_lock();
#else
    /* Obtain the global data lock. */
    OS_ASSERT(semaphore_obtain(&console_data.lock, MAX_WAIT) != SUCCESS);

    /* Create a semaphore to protect this console device. */
    memset(&console->lock, 0, sizeof(SEMAPHORE));
    semaphore_create(&console->lock, 1, 1, SEMAPHORE_PRIORITY);
#endif

    /* This utility is called by drivers for registering consoles for the
     * applicable devices, so no need to check for name conflicts. */
    /* Just push this file system in the list. */
    sll_push(&console_data.list, console, OFFSETOF(CONSOLE, fs.next));

    /* Initialize console FS data. */
    console->fs.get_lock = console_lock;
    console->fs.release_lock = console_unlock;
    console->fs.timeout = MAX_WAIT;

    /* Initialize file system condition. */
    fs_condition_init(&console->fs);

#ifdef CONFIG_SEMAPHORE
    /* Release the global data lock. */
    semaphore_release(&console_data.lock);
#else
    /* Enable scheduling. */
    scheduler_unlock();
#endif

} /* console_register */
Esempio n. 15
0
/*
 * mem_dynamic_print_usage
 * @mem_dynamic: The memory region.
 * @level: Flags to specify level of required information.
 * This function will print the information about a given dynamic region.
 */
void mem_dynamic_print_usage(MEM_DYNAMIC *mem_dynamic, uint32_t level)
{
    uint32_t start, end, i, free, total_free = 0;
    MEM_FREE *free_mem;

#ifdef CONFIG_SEMAPHORE
    /* Obtain the memory lock. */
    OS_ASSERT(semaphore_obtain(&mem_dynamic->lock, MAX_WAIT) != SUCCESS);
#else
    /* Lock the scheduler. */
    scheduler_lock();
#endif /* CONFIG_SEMAPHORE */

    /* Memory general information.  */
    if (level & STAT_MEM_GENERAL)
    {
        start = (uint32_t)mem_dynamic->pages[0].base_start;
        end = (uint32_t)mem_dynamic->pages[mem_dynamic->num_pages - 1].base_end;

        /* Print general information about this memory region. */
        printf("Memory Region Information:\r\n");
        printf("Start\t\t: 0x%X\r\n", start);
        printf("End\t\t: 0x%X\r\n", end);
        printf("Total Size\t: %d\r\n", (end - start));
    }

    /* Page information.  */
    if ((level & STAT_MEM_PAGE_INFO) || (level & STAT_MEM_GENERAL))
    {
        /* If we are only printing page information. */
        if (!(level & STAT_MEM_GENERAL))
        {
            printf("Memory Page(s) Information:\r\n");
        }

        /* If we need to print page information. */
        if (level & STAT_MEM_PAGE_INFO)
        {
            printf("P[n]\tStart\t\tEnd\t\tFree\r\n");
        }

        /* Go through all the pages in this memory region. */
        for (i = 0; i < mem_dynamic->num_pages; i++)
        {
            /* Calculate free memory on this page. */
            free = 0;
            free_mem = mem_dynamic->pages[i].free_list.head;

            /* Go through free memory list. */
            while (free_mem)
            {
                free += free_mem->descriptor.size;
                free_mem = free_mem->next;
            }

            /* Add it to total free. */
            total_free += free;

            /* If we need to print per page information. */
            if (level & STAT_MEM_PAGE_INFO)
            {
                printf("[%d]\t0x%X\t0x%X\t%d\r\n", i,
                                                   mem_dynamic->pages[i].base_start,
                                                   mem_dynamic->pages[i].base_end,
                                                   free);
            }
        }

        /* Print total number of bytes free in this memory region. */
        printf("Total Free\t: %d\r\n", total_free);
    }

#ifdef CONFIG_SEMAPHORE
    /* Release the memory lock. */
    semaphore_release(&mem_dynamic->lock);
#else
    /* Enable scheduling. */
    scheduler_unlock();
#endif /* CONFIG_SEMAPHORE */

} /* mem_dynamic_print_usage */
void scheduler::remove_active_user() {
    std::lock_guard<std::mutex> scheduler_lock(mutex);
    if (--active_users == 0) {
        no_more_active_users.notify_all();
    }
}
Esempio n. 17
0
void PionScheduler::removeActiveUser(void)
{
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	if (--m_active_users == 0)
		m_no_more_active_users.notify_all();
}
Esempio n. 18
0
void PionScheduler::addActiveUser(void)
{
	if (!m_is_running) startup();
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	++m_active_users;
}
void scheduler::add_active_user() {
    if (!running) startup();
    std::lock_guard<std::mutex> scheduler_lock(mutex);
    ++active_users;
}