Support gcov build for coverage check
[platform/core/multimedia/libmm-sound.git] / server / mm_sound_thread_pool.c
index ebbd251..0ddc346 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <pthread.h>
 #include <unistd.h>
 
 #include <mm_error.h>
 #include <mm_debug.h>
 #include <mm_sound_thread_pool.h>
 
-#define USE_G_THREAD_POOL
-#ifdef USE_G_THREAD_POOL
 #include <glib.h>
-GThreadPool* g_pool;
+
+static GThreadPool *g_pool;
 
 #define MAX_UNUSED_THREADS_IN_THREADPOOL       10
 
-typedef struct __THREAD_INFO
-{
+typedef struct __THREAD_INFO {
        void (*func)(gpointer data);
        void *param;
 } THREAD_INFO;
 
-static void __DummyWork (void* param)
+static void __DummyWork(void *param)
 {
-       debug_msg ("thread index = %d\n", (int)param);
-       sleep (1);
+       debug_msg("thread index = %d", (int)param);
+       sleep(1);
 }
 
 static void __ThreadWork(gpointer data, gpointer user_data)
 {
-       THREAD_INFO* info = (THREAD_INFO*)data;
+       THREAD_INFO *info = (THREAD_INFO *)data;
        if (info) {
-                if (info->func) {
-                               debug_msg ("Calling [%p] with param [%p]\n", info->func, info->param);
-                               info->func (info->param);
-                } else {
-                               debug_warning ("No func to call....\n");
-                }
-
-                /* Info was allocated by MMSoundThreadPoolRun(). 
+               if (info->func) {
+                       debug_log("Calling [%p] with param [%p]", info->func, info->param);
+                       info->func(info->param);
+               } else {
+                       debug_warning("No func to call....");
+               }
+
+               /* Info was allocated by MMSoundThreadPoolRun().
                        The actual content of info should be  freed whether inside func or outside (if handle) */
-                debug_msg ("free [%p]\n", info);
-                free (info);
-                info = NULL;
+               debug_log("free [%p]", info);
+               free(info);
+               info = NULL;
        } else {
-               debug_warning ("No valid thread info...Nothing to do...\n");
+               debug_warning("No valid thread info...Nothing to do...");
        }
 }
 
 int MMSoundThreadPoolDump(int fulldump)
 {
        if (g_pool == NULL) {
-               debug_error ("No thread pool initialized....\n");
+               debug_error("No thread pool initialized....");
                return MM_ERROR_SOUND_INTERNAL;
        }
 
        if (fulldump) {
-               debug_msg ("##### [ThreadPool] max threads=[%d], max unused=[%d], max idle time=[%d]\n",
-                               g_thread_pool_get_max_threads (g_pool),
+               debug_log("##### [ThreadPool] max threads=[%d], max unused=[%d], max idle time=[%d]",
+                               g_thread_pool_get_max_threads(g_pool),
                                g_thread_pool_get_max_unused_threads(),
-                               g_thread_pool_get_max_idle_time()       );
+                               g_thread_pool_get_max_idle_time());
        }
-       debug_msg ("***** [ThreadPool] running=[%d], unused=[%d]\n",
-                       g_thread_pool_get_num_threads (g_pool),
-                       g_thread_pool_get_num_unused_threads() );
+       debug_log("***** [ThreadPool] running=[%d], unused=[%d]",
+                       g_thread_pool_get_num_threads(g_pool),
+                       g_thread_pool_get_num_unused_threads());
 
        return MM_ERROR_NONE;
 }
 
 int MMSoundThreadPoolInit()
 {
-       int i=0;
-       GError* error = NULL;
+       int i = 0;
+       GError *error = NULL;
+
+       debug_enter();
 
        /* Create thread pool (non-exclude mode with infinite max threads) */
-       g_pool = g_thread_pool_new (__ThreadWork, NULL, -1, FALSE, &error);
+       g_pool = g_thread_pool_new(__ThreadWork, NULL, -1, FALSE, &error);
        if (g_pool == NULL && error != NULL) {
-               debug_error ("thread pool created failed : %s\n", error->message);
-               g_error_free (error);
+               debug_error("thread pool created failed : %s", error->message);
+               g_error_free(error);
                return MM_ERROR_SOUND_INTERNAL;
        }
-       debug_msg ("thread pool created successfully\n");
+       debug_msg("thread pool created successfully");
 
        MMSoundThreadPoolDump(TRUE);
 
        /* Thread pool setting : this will maintain at least 10 unused threads and this will be reused. */
        /* If no unused thread left, new thread will be created, but always maintain 10 unused thread */
-       debug_msg ("thread pool set max unused threads to %d\n", MAX_UNUSED_THREADS_IN_THREADPOOL);
-       g_thread_pool_set_max_unused_threads (MAX_UNUSED_THREADS_IN_THREADPOOL);
-
-       /* To reserve unused threads, let's start some threads for beggining 
-          This dummy thread will be remained unused as soon as it started */    
-       debug_msg ("run threads to reserve minimum thread\n");
-       for (i=0; i<MAX_UNUSED_THREADS_IN_THREADPOOL; i++) {
-               MMSoundThreadPoolRun ((void *)i, __DummyWork);
-       }
+       debug_msg("thread pool set max unused threads to %d", MAX_UNUSED_THREADS_IN_THREADPOOL);
+       g_thread_pool_set_max_unused_threads(MAX_UNUSED_THREADS_IN_THREADPOOL);
+
+       /* To reserve unused threads, let's start some threads for beginning
+               his dummy thread will be remained unused as soon as it started */
+       debug_msg("run threads to reserve minimum thread");
+       for (i = 0; i < MAX_UNUSED_THREADS_IN_THREADPOOL; i++)
+               if (MMSoundThreadPoolRun((void *)i, __DummyWork))
+                       return MM_ERROR_SOUND_INTERNAL;
 
        MMSoundThreadPoolDump(TRUE);
 
-     return MM_ERROR_NONE;
+       debug_leave();
+
+       return MM_ERROR_NONE;
 }
 
 int MMSoundThreadPoolRun(void *param, void (*func)(void*))
 {
-       GError* error = NULL;
+       GError *error = NULL;
+
+       debug_enter();
+
+       if (g_pool == NULL) {
+               debug_error("No thread pool initialized....");
+               return MM_ERROR_SOUND_INTERNAL;
+       }
 
        /* Dump current thread pool */
        MMSoundThreadPoolDump(FALSE);
 
-       /* Create thread info structure. 
+       /* Create thread info structure.
           This thread info data will be free in __ThreadWork(), after use. */
-       THREAD_INFO* thread_info = (THREAD_INFO*)malloc (sizeof(THREAD_INFO));
+       THREAD_INFO *thread_info = (THREAD_INFO *)malloc(sizeof(THREAD_INFO));
        if (thread_info) {
                thread_info->func = func;
                thread_info->param = param;
-               debug_msg ("alloc thread_info = %p\n", thread_info);
-       
+               debug_log("alloc thread_info = %p", thread_info);
+
                /* Add thread to queue of thread pool */
-               g_thread_pool_push (g_pool, thread_info, &error);
+               g_thread_pool_push(g_pool, thread_info, &error);
                if (error) {
-                       debug_error ("g_thread_pool_push failed : %s\n", error->message);
-                       g_error_free (error);
+                       debug_error("g_thread_pool_push failed : %s", error->message);
+                       g_error_free(error);
+                       free(thread_info);
                        return MM_ERROR_SOUND_INTERNAL;
                }
        } else {
-               debug_error("failed to alloc thread info\n");
+               debug_error("failed to alloc thread info");
                return MM_ERROR_SOUND_INTERNAL;
        }
 
-    return MM_ERROR_NONE;
-}
-
-int MMSoundThreadPoolFini(void)
-{
-       /* If immediate is TRUE, no new task is processed for pool. 
-       Otherwise pool is not freed before the last task is processed. 
-       Note however, that no thread of this pool is interrupted, while processing a task. 
-       Instead at least all still running threads can finish their tasks before the pool is freed.
+       debug_leave();
 
-       If wait_ is TRUE, the functions does not return before all tasks to be processed 
-       (dependent on immediate, whether all or only the currently running) are ready. 
-       Otherwise the function returns immediately.     */
-       debug_msg ("thread pool will be free\n");
-       g_thread_pool_free (g_pool, TRUE, FALSE);
-    
        return MM_ERROR_NONE;
 }
 
-#else // USE_G_THREAD_POOL
-
-#define THREAD_POOL_MAX 10
-
-struct __control_t
-{
-       pthread_t threadid;
-       pthread_cond_t condition;
-       int stopflag;
-       void *param;
-       void (*func)(void *);
-};
-
-static int threadmap[THREAD_POOL_MAX];
-static struct __control_t control[THREAD_POOL_MAX];
-
-static pthread_cond_t startcond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t startsync = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t controlsync = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t funcsync = PTHREAD_MUTEX_INITIALIZER;
-
-static int __GetEmptyPool(void)
-{
-       int count = 0;
-       while ((count < THREAD_POOL_MAX) && threadmap[count] == 1)
-               ++count;
-       return count == THREAD_POOL_MAX ? -1 : count;
-}
-
-static void __SetPool(int n)
-{
-    threadmap[n] = 1;
-}
-
-static void __ResetPool(int n)
-{
-    threadmap[n] = 0;
-}
-
-static void __InitPool(void)
-{
-    int count = 0;
-    for (count = 0; count < THREAD_POOL_MAX; count++)
-    {
-        threadmap[count] = 0;
-        if (pthread_cond_init(&control[count].condition, NULL) != 0)
-            perror("Make Thread Condition");
-    }
-}
-
-static void __DestroyPool(void)
+int MMSoundThreadPoolFini(void)
 {
-    int count = 0;
-    for (count = 0; count < THREAD_POOL_MAX; count++)
-    {
-        if (pthread_cond_destroy(&control[count].condition) != 0)
-        {
-            perror("Remove Thread Condition");
-            exit(0);
-        }
-    }
-}
+       /* If immediate is TRUE, no new task is processed for pool.
+       Otherwise pool is not freed before the last task is processed.
+       Note however, that no thread of this pool is interrupted, while processing a task.
+       Instead at least all still running threads can finish their tasks before the pool is freed.
 
-static void* __ThreadWork(void *param)
-{
-    int myid = -1;
-
-    myid = (int)param;
-
-    pthread_mutex_lock(&startsync);
-    pthread_cond_signal(&startcond);
-    pthread_mutex_unlock(&startsync);
-
-    while(1)
-    {
-        pthread_mutex_lock(&controlsync);
-        pthread_cond_wait(&control[myid].condition, &controlsync);
-        pthread_mutex_unlock(&controlsync);
-
-        if (control[myid].func != NULL)
-            control[myid].func(control[myid].param);
-/*        if (control[myid].param != NULL)
-            free(control[myid].param);*/
-
-        control[myid].func = NULL;
-        control[myid].param = NULL;
-        pthread_mutex_lock(&startsync);
-        __ResetPool(myid);
-        pthread_mutex_unlock(&startsync);
-
-        if (control[myid].stopflag) {
-            pthread_exit(0);
-        }
-    }
-}
+       If wait_ is TRUE, the functions does not return before all tasks to be processed
+       (dependent on immediate, whether all or only the currently running) are ready.
+       Otherwise the function returns immediately. */
+       debug_enter();
 
-int MMSoundThreadPoolDump(void)
-{
-       int count = 0;
-       int ret = MM_ERROR_NONE;
-
-       fprintf(stdout, "================================================================================\n");
-       fprintf(stdout, "                              Thread States                                     \n");
-       fprintf(stdout, "--------------------------------------------------------------------------------\n");
-       for (count = 0; count < THREAD_POOL_MAX; count ++)
-       {
-               fprintf(stdout, "Thread %d\n", control[count].threadid);
-               fprintf(stdout, "Current State is \"%s\"\n", threadmap[count] ? "Running" : "Ready");
-               if (threadmap[count])
-               {
-                       fprintf(stdout, "Running function address %p\n", control[count].func);
-               }
-               else
-               {
-                       fprintf(stdout, "Threadmap is NULL\n");
-                       ret = MM_ERROR_SOUND_INTERNAL;
-               }
+       if (g_pool) {
+               debug_msg("thread pool will be free");
+               g_thread_pool_free(g_pool, TRUE, FALSE);
+               g_pool = NULL;
        }
-       fprintf(stdout, "================================================================================\n");
-       return ret;
-}
-
-int MMSoundThreadPoolInit(void)
-{
-    volatile int count = 0;
-    pthread_mutex_lock(&funcsync);
-
-    __InitPool();
-
-    for (count = 0; count < THREAD_POOL_MAX; count++)
-    {
-        control[count].stopflag = 0;
-        pthread_mutex_lock(&startsync);
-        if (pthread_create(&control[count].threadid, NULL, __ThreadWork, (void*)count) < 0)
-        {
-            perror("Make Thread Fail");
-            exit(0);
-        }
-        pthread_cond_wait(&startcond, &startsync);
-        pthread_mutex_unlock(&startsync);
-        usleep(100); /* Delay for thread init */
-    }
-    pthread_mutex_unlock(&funcsync);
-    return MM_ERROR_NONE;
-}
-
-int MMSoundThreadPoolRun(void *param, void (*func)(void*))
-{
-    int poolnum = -1;
-
-    pthread_mutex_lock(&funcsync);
-    pthread_mutex_lock(&startsync);
-    poolnum = __GetEmptyPool();
-    if (poolnum < 0) {
-        pthread_mutex_unlock(&startsync);
-        pthread_mutex_unlock(&funcsync);
-        return MM_ERROR_COMMON_NO_FREE_SPACE;
-    }
-    __SetPool(poolnum);
-    pthread_mutex_unlock(&startsync);
-    control[poolnum].param = param;
-    control[poolnum].func = func;
-    pthread_cond_signal(&control[poolnum].condition);
-    pthread_mutex_unlock(&funcsync);
-
-    return MM_ERROR_NONE;
-}
 
-int MMSoundThreadPoolFini(void)
-{
-    int count = 0;
-
-    pthread_mutex_lock(&funcsync);
-    for (count = 0; count < THREAD_POOL_MAX; count++)
-    {
-        control[count].stopflag = 1;
-        pthread_cond_signal(&control[count].condition);
-        if (pthread_join(control[count].threadid, NULL) < 0)
-        {
-            perror("Join Fail");
-            exit(0);
-        }
-    }
-    __DestroyPool();
-    pthread_mutex_unlock(&funcsync);
-
-    return MM_ERROR_NONE;
+       debug_leave();
+       return MM_ERROR_NONE;
 }
-#endif // USE_G_THREAD_POOL
-