/******************************************************************* * DMW_Mcm.c * * Private routines to be used in M/W * * Copyright 2003 Digital STREAM Technology, Inc. * All Rights Reserved * * $Id: DMW_Mcm.c,v 1.? 2003/03/24 cafrii Exp $ * ********************************************************************/ #include "DMW_Platform.h" #include "DHL_DBG.h" #include "DMW_Config.h" #include "DMW_ChannelAPI.h" #include "DMW_DebugUtil.h" #include "dmw_mcm_priv.h" #include "dmw_ucm_priv.h" #include "DMW_Mutex.h" //#include DHL_MODULE("$mcm", 0); #define USE_STATIC_MCM 1 //static mcmÀ» »ç¿ëÇÔ->memory fragmentationÀ» ¹æÁöÇϱâ À§ÇÔ #define equiv_mcm_major_minor(a, b) \ ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor ) // && (a)->RF==(b)->RF && (a)->VctFlag==(b)->VctFlag) #define equiv_mcm_major_minor_rf(a, b) \ ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->RF==(b)->RF) #define equiv_mcm_major_minor_vf(a, b) \ ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->VctFlag==(b)->VctFlag) #define equiv_mcm_major_minor_rf_vf(a, b) \ ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->RF==(b)->RF && (a)->VctFlag==(b)->VctFlag) // // a ~= b ÀÎÁö¸¦ üũÇÏ´Â ¸ÅÅ©·Î. // ´ëÇ¥ mcm itemÀ» ¼±ÅÃÇϱâ À§Çؼ­ Áߺ¹µÇ´Â ä³Î Á¤º¸¸¦ ¾Ë¾Æ³»±â À§ÇÑ ºñ±³ ±¸¹®¿¡¼­ »ç¿ëÇÑ´Ù. // ÇöÀç ¹æÄ§Àº Major/Minor/Vf °ªÀÌ ÀÏÄ¡Çϴ ä³Î Áß¿¡¼­ ½ÅÈ£ ¼¼±â°¡ °¡Àå Å« Á¤º¸¸¦ »ç¿ëÇÑ´Ù. /* #define not_ordered(a1, a2, a3, a4, b1, b2, b3, b4) \ (((a1)>(b1)) || ((a1)==(b1) && (a2)>(b2)) || ((a1)==(b1) && (a2)==(b2) && (a3)>(b3)) \ ((a1)==(b1) && (a2)==(b2) && (a3)==(b3) && (a4)>(b4)) ) #define require_mcm_swap(a, b) \ not_ordered((a)->Major, (a)->Minor, (a)->RF, (a)->VctFlag, (b)->Major, (b)->Minor, (b)->RF, (b)->VctFlag) */ #define require_mcm_swap(a, b) \ (((a)->Major>(b)->Major) || \ ((a)->Major==(b)->Major && (a)->Minor>(b)->Minor) || \ ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->RF>(b)->RF) || \ ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->RF==(b)->RF && \ (a)->VctFlag<(b)->VctFlag) ) // MCM Á¤·Ä¿¡¼­ a¿Í b µÎ MCM item À§Ä¡¸¦ ¹Ù²ã¾ß µÇ´ÂÁö üũÇÏ´Â ¸ÅÅ©·Î. // ±âº»ÀûÀ¸·Î Major/Minor/RF/VctFlag ¼ø¼­·Î ¼øÀ§¸¦ µÎ°í, Major/Minor/Rf´Â ¿À¸§Â÷¼ø, // VctFlag´Â ³»¸²Â÷¼øÀ¸·Î Á¤·ÄÇØ¾ß ÇÑ´Ù. //----------------------------------------------------- #define IMPLEMENT_MCM_ARRAY 1 // 1À̸é 1Â÷¿ø array·Î MCMÀ» ±¸Çö. // 0À̸é linked list·Î ±¸Çö.. //======================================================================= // MCM °ü¸® ·çƾ. // // MCM °ü·Ã ÆíÀÇ ÇÔ¼öµé.. // MCMÀÇ ±¸Á¶´Â Çì´õ ÆÄÀÏ¿¡ °ø°³µÇ¾î ÀÖÁö¸¸, MCM DB ÀÚü´Â AutoScan °úÁ¤¿¡¼­¸¸ ÇÊ¿äÇÑ // Àӽà µ¥ÀÌÅÍÀ̱⠶§¹®¿¡ ³»ºÎ static º¯¼ö·Î Á¤ÀÇÇÑ´Ù. // // °Ë»öµÈ ä³Î Á¤º¸´Â Áß°£Áß°£¿¡ callback ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© applicationÀ¸·Î º¸°íµÈ´Ù. // À̶§ Àü´ÞµÇ´Â µ¥ÀÌÅÍ´Â MCM DB itemÀÇ ¹øÁöÀÌ´Ù. // ±×·¯³ª callback ÇÔ¼ö ¾È¿¡¼­¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù´Â Á¦¾àÁ¶°ÇÀÌ ÀÖÀ¸¹Ç·Î // "Àӽà µ¥ÀÌÅÍ"·Î¼­ÀÇ MCMÀ̶ó´Â ¿ø·¡ Á¤Ã¥À» À§¹ÝÇÏÁö´Â ¾Ê°ÔµÈ´Ù. // // MCMÀº Çʿ信 µû¶ó óÀ½ ÇÒ´çµÈ Å©±â ÀÌ»óÀ¸·Î Áõ°¡µÉ ¼ö ÀÖ´Ù. (¸Þ¸ð¸® ÀçÇÒ´ç) // // // Mutex = { SemID, Owner, lockCnt, FailCnt, UseOsMutex, Name, flag, traceLvl } // DMW_MUTEX mcmMutex = { 0, 0, 0, 0, FALSE, "McmMtx", OS_SEM_PRIO, FALSE, }; STATUS lock_mcm(int timeout) { return DMW_LockMutexWait(&mcmMutex, timeout); } void unlock_mcm() { DMW_UnlockMutex(&mcmMutex); } DHL_OS_TASK_ID get_mcm_owner() { return DMW_GetOwnerTaskId(&mcmMutex); } //======================================================================= #if IMPLEMENT_MCM_ARRAY #if 0 ______New_Code________() #endif #if USE_STATIC_MCM #define MAX_MCM_SIZE 512 //ÃÖ´ë 512°³±îÁö mcm Áö¿øÇÔ. //140bytes*512=70k. ´ë·« 70k Á¤µµÀÓ. static MCM_DB_T static_mcm[MAX_MCM_SIZE]; static MCM_DB_T *g_MCM = static_mcm; // MCM DB pointer #else static MCM_DB_T *g_MCM = NULL; // MCM DB pointer static UINT32 g_MCM_max = 0; // ÇöÀç ÀúÀå °¡´ÉÇÑ ÃÖ´ë MCM item °¹¼ö. DB Å©±â. #endif // MCM DB¿¡ ÀúÀåµÇ¾î Àִ ä³Î Á¤º¸ °¹¼ö. static UINT32 g_MCM_number = 0; // MCMÀº ÀÏÂ÷¿ø ¹è¿­ ±¸Á¶¸¦ °®´Â´Ù. // MCM È®ÀåÀÌ ÇÊ¿äÇÒ °æ¿ì, ¸Þ¸ð¸®¸¦ Reallocation ÇØ¾ß ÇÑ´Ù. // #if USE_STATIC_MCM==0 STATUS prepare_mcm_space(int margin) { // MCM 1°³¸¦ À§ÇÑ °ø°£À» ÇÒ´çÀ» ÇÑ´Ù. margin ¸¸Å­ È®ÀåÇÏ´Â°Ô ¾Æ´Ô!! // marginÀÇ Àǹ̺¸´Ù increse_stepÀÇ °³³äÀ¸·Î ÀÌÇØÇØ¾ß ÇÑ´Ù. // ¸¸¾à 1°³¸¦ À§ÇÑ °ø°£ÀÌ ¾øÀ» °æ¿ì margin ¸¸Å­ÀÇ Ãß°¡ °ø°£À» È®º¸ÇÑ´Ù. (¹è¿­À» È®Àå) // if (g_MCM_number >= g_MCM_max) // °ø°£ÀÌ ºÎÁ·Çϸé, { g_MCM_number = g_MCM_max; // for safety.. if (margin < 8) margin = 8; dprint(1, "prepare_mcm_space: increase mcm +%d, -> total %d \n", margin, g_MCM_max+margin); if (g_MCM) { #if 0 // ¸Þ¸ð¸® ÀçÇÒ´ç.. if (OS_Realloc(&g_MCM, g_MCM_max * sizeof(MCM_DB_T), (g_MCM_max + margin)*sizeof(MCM_DB_T))) { g_MCM_max += margin; } else // OS_Realloc()ÀÌ ½ÇÆÐÇØµµ g_MCM¿¡´Â º¯È­°¡ ¾ø´Ù. return statusOutOfMemory; #else // cafrii 031112 TL_OS bugfix.. MCM_DB_T *tmpMcm = DHL_OS_Malloc(sizeof(MCM_DB_T) * (g_MCM_max + margin)); if (tmpMcm == NULL) return statusOutOfMemory; memcpy(tmpMcm, g_MCM, sizeof(MCM_DB_T) * g_MCM_number); DHL_OS_Free((void**)&g_MCM); g_MCM = tmpMcm; g_MCM_max += margin; #endif } else { // ¸Þ¸ð¸® ½Å±Ô ÇÒ´ç. g_MCM_number = 0; g_MCM_max = margin; g_MCM = DHL_OS_Malloc(sizeof(MCM_DB_T) * g_MCM_max); if (g_MCM == NULL) { g_MCM_max = 0; return statusOutOfMemory; } } } return statusOK; } MCM_DB_T *new_mcm() { // MCM Çϳª¸¦ ÁغñÇÑ´Ù. // MCM_DB_T *m; if (prepare_mcm_space(32) != statusOK) { dprint(0, "new_mcm: !! out of memory!\n"); return NULL; } #if DEVELOPMENT_BUILD DHL_ASSERT(g_MCM_number < g_MCM_max, "MCM corrupt! g_MCM_number >= g_MCM_max"); // Àû¾îµµ Çϳª ÀÌ»óÀÇ °ø°£ÀÌ ÀÖ´ÂÁö È®ÀÎ. // post-check ¿¡¼­ pre-check·Î º¯°æÇÔ. #endif m = &g_MCM[g_MCM_number++]; memset(m, 0, sizeof(MCM_DB_T)); // ÃʱâÈ­.. return m; } void free_mcm(MCM_DB_T *m) { // MCM Çϳª¸¦ »èÁ¦ÇÑ´Ù. // mÀÌ MCM array»ó¿¡ ÀÖ´Â À¯È¿ÇÑ Æ÷ÀÎÅÍÀÎÁö È®ÀÎÇϰí, // m ÀÌÈÄÀÇ ¸ðµç MCM itemÀ» Çϳª¾¿ ¾ÕÀ¸·Î shiftÇÑ´Ù. // // ½ÇÁ¦·Î ÀÌ ÇÔ¼ö¸¦ »ç¿ëÇÒ ÇÊ¿ä´Â °ÅÀÇ ¾ø´Ù. ÇÊ¿ä½Ã È®Àå (prepare_mcm_space) Çϰí // ¸Þ¸ð¸® 'Ãà¼Ò'´Â ÇÏÁö ¾Ê´Â ¹æ½ÄÀ» äÅÃÇϱ⠶§¹®ÀÌ´Ù. // MCM Çϳª¸¦ deleteÇÒ °æ¿ì¿¡´Â ´ëºÎºÐ caller¿¡¼­ ¾Ë¾Æ¼­ shift½Ã۰í ÀÖ´Ù. // unsigned int i; int k; for (i=0; i=0; i--) { dprint(3, " delete csd of mcm[%d], 0x%x, %d csds\n", i, g_MCM[i].csd, g_MCM[i].num_csd); for (k=0; k=MAX_MCM_SIZE) { DHL_ASSERT(g_MCM_number=0; i--) { dprint(3, " delete csd of mcm[%d], 0x%x, %d csds\n", i, g_MCM[i].csd, g_MCM[i].num_csd); for (k=0; k g_MCM[k].Major) { // swap tmp = g_MCM[i]; g_MCM[i] = g_MCM[k]; g_MCM[k] = tmp; } else if (g_MCM[i].Major == g_MCM[k].Major) { if (g_MCM[i].Minor > g_MCM[k].Minor) { // swap tmp = g_MCM[i]; g_MCM[i] = g_MCM[k]; g_MCM[k] = tmp; } else if (g_MCM[i].Minor == g_MCM[k].Minor) { if (g_MCM[i].RF > g_MCM[k].RF) { // swap tmp = g_MCM[i]; g_MCM[i] = g_MCM[k]; g_MCM[k] = tmp; } } } #endif } } //compile warming Á¦°Å : return 0Ãß°¡ probability return 0; } STATUS select_max_mcms() { // MCM¿¡¼­ °°Àº ¹øÈ£¸¦ °®´Â ä³Îµé Áß¿¡¼­ "´ëǥä³Î"À» ¼±ÅÃÇÏ°í ±× Ã¤³Î¸¸À» enable½ÃŲ´Ù. // ¿©±â¼­ °°Àº ¹øÈ£¶õ, ÇöÀç ¹æÄ§¿¡ µû¸£¸é major/minor/vf ÀÌ´Ù. // ÇöÀç sortingµÇ¾î ÀÖ´Â »óÅÂÀ̹ǷΠÀÛÀº ¹øÈ£ÀÇ Ã¤³ÎºÎÅÍ ½ÃÀÛÇØ¼­ // µ¿ÀÏÇÑ Mj/Mn/Rf °ªÀ» °®´Â ä³Îµé Áß¿¡¼­ ½ÅÈ£ ¼¼±â°¡ °¡Àå Å« °ÍÀ» ¼±ÅÃÇϰí, // ³ª¸ÓÁö´Â skip flag¸¦ ¼¼ÆÃÇÑ´Ù. int maxnd; unsigned int n; if (g_MCM == NULL || g_MCM_number <= 0) return statusOK; maxnd = -1; // maxnd´Â ÇöÀç±îÁö ÃÖ´ë strength¸¦ °®´Â mcmÀÇ À妽º. // mj/mn/rf/vctf ¸¸À¸·Î ÆÇ´ÜÇÑ´Ù. // À§ µ¥ÀÌÅͰ¡ ¸ðµÎ µ¿ÀÏÇϸ鼭 ntsc/8vsb/64qam/256qamÀÌ ¼­·Î ´Ù¸¥ °ÍµéÀº // Àû´çÇÑ °ÍÀ¸·Î ÀÌ¹Ì ¼±ÅõǾî ÅëÀÏ µÇ¾î ÀÖ´Ù°í °¡Á¤. // // ¸ÕÀú VctFlag == 1ÀÎ °æ¿ìºÎÅÍ ½ÃÀÛÇÏÀÚ. for (n=0; n