Added error checking to vp8cx_create_encoder_threads()
authorScott LaVarnway <slavarnway@google.com>
Tue, 14 Aug 2012 19:00:23 +0000 (12:00 -0700)
committerScott LaVarnway <slavarnway@google.com>
Tue, 14 Aug 2012 19:00:23 +0000 (12:00 -0700)
Added checks for pthread_create() errors.

Change-Id: Ie198ef5c14314fe252d2e02f7fe5bfacc7e16377

vp8/encoder/ethreading.c
vp8/encoder/onyx_if.c

index e0bb1b0..964d8b3 100644 (file)
@@ -484,7 +484,7 @@ void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
     }
 }
 
-void vp8cx_create_encoder_threads(VP8_COMP *cpi)
+int vp8cx_create_encoder_threads(VP8_COMP *cpi)
 {
     const VP8_COMMON * cm = &cpi->common;
 
@@ -496,6 +496,7 @@ void vp8cx_create_encoder_threads(VP8_COMP *cpi)
     {
         int ithread;
         int th_count = cpi->oxcf.multi_threaded - 1;
+        int rc = 0;
 
         /* don't allocate more threads than cores available */
         if (cpi->oxcf.multi_threaded > cm->processor_core_count)
@@ -509,11 +510,14 @@ void vp8cx_create_encoder_threads(VP8_COMP *cpi)
         }
 
         if(th_count == 0)
-            return;
-
-        CHECK_MEM_ERROR(cpi->h_encoding_thread, vpx_malloc(sizeof(pthread_t) * th_count));
-        CHECK_MEM_ERROR(cpi->h_event_start_encoding, vpx_malloc(sizeof(sem_t) * th_count));
-        CHECK_MEM_ERROR(cpi->mb_row_ei, vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count));
+            return 0;
+
+        CHECK_MEM_ERROR(cpi->h_encoding_thread,
+                        vpx_malloc(sizeof(pthread_t) * th_count));
+        CHECK_MEM_ERROR(cpi->h_event_start_encoding,
+                        vpx_malloc(sizeof(sem_t) * th_count));
+        CHECK_MEM_ERROR(cpi->mb_row_ei,
+                        vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count));
         vpx_memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * th_count);
         CHECK_MEM_ERROR(cpi->en_thread_data,
                         vpx_malloc(sizeof(ENCODETHREAD_DATA) * th_count));
@@ -542,9 +546,33 @@ void vp8cx_create_encoder_threads(VP8_COMP *cpi)
             ethd->ptr1 = (void *)cpi;
             ethd->ptr2 = (void *)&cpi->mb_row_ei[ithread];
 
-            pthread_create(&cpi->h_encoding_thread[ithread], 0, thread_encoding_proc, ethd);
+            rc = pthread_create(&cpi->h_encoding_thread[ithread], 0,
+                                thread_encoding_proc, ethd);
+            if(rc)
+                break;
+        }
+
+        if(rc)
+        {
+            /* shutdown other threads */
+            cpi->b_multi_threaded = 0;
+            for(--ithread; ithread >= 0; ithread--)
+            {
+                pthread_join(cpi->h_encoding_thread[ithread], 0);
+                sem_destroy(&cpi->h_event_start_encoding[ithread]);
+            }
+            sem_destroy(&cpi->h_event_end_encoding);
+
+            /* free thread related resources */
+            vpx_free(cpi->h_event_start_encoding);
+            vpx_free(cpi->h_encoding_thread);
+            vpx_free(cpi->mb_row_ei);
+            vpx_free(cpi->en_thread_data);
+
+            return -1;
         }
 
+
         {
             LPFTHREAD_DATA * lpfthd = &cpi->lpf_thread_data;
 
@@ -552,10 +580,34 @@ void vp8cx_create_encoder_threads(VP8_COMP *cpi)
             sem_init(&cpi->h_event_end_lpf, 0, 0);
 
             lpfthd->ptr1 = (void *)cpi;
-            pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter, lpfthd);
+            rc = pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter,
+                                lpfthd);
+
+            if(rc)
+            {
+                /* shutdown other threads */
+                cpi->b_multi_threaded = 0;
+                for(--ithread; ithread >= 0; ithread--)
+                {
+                    sem_post(&cpi->h_event_start_encoding[ithread]);
+                    pthread_join(cpi->h_encoding_thread[ithread], 0);
+                    sem_destroy(&cpi->h_event_start_encoding[ithread]);
+                }
+                sem_destroy(&cpi->h_event_end_encoding);
+                sem_destroy(&cpi->h_event_end_lpf);
+                sem_destroy(&cpi->h_event_start_lpf);
+
+                /* free thread related resources */
+                vpx_free(cpi->h_event_start_encoding);
+                vpx_free(cpi->h_encoding_thread);
+                vpx_free(cpi->mb_row_ei);
+                vpx_free(cpi->en_thread_data);
+
+                return -2;
+            }
         }
     }
-
+    return 0;
 }
 
 void vp8cx_remove_encoder_threads(VP8_COMP *cpi)
index bb11475..7403ba4 100644 (file)
@@ -56,7 +56,7 @@ extern void vp8_deblock_frame(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *po
 extern void print_parms(VP8_CONFIG *ocf, char *filenam);
 extern unsigned int vp8_get_processor_freq();
 extern void print_tree_update_probs();
-extern void vp8cx_create_encoder_threads(VP8_COMP *cpi);
+extern int vp8cx_create_encoder_threads(VP8_COMP *cpi);
 extern void vp8cx_remove_encoder_threads(VP8_COMP *cpi);
 
 int vp8_estimate_entropy_savings(VP8_COMP *cpi);
@@ -1954,7 +1954,11 @@ struct VP8_COMP* vp8_create_compressor(VP8_CONFIG *oxcf)
 #endif
 
 #if CONFIG_MULTITHREAD
-    vp8cx_create_encoder_threads(cpi);
+    if(vp8cx_create_encoder_threads(cpi))
+    {
+        vp8_remove_compressor(&cpi);
+        return 0;
+    }
 #endif
 
     cpi->fn_ptr[BLOCK_16X16].sdf            = vp8_sad16x16;