A’ sgrùdadh einnsean Mediastreamer2 VoIP. Pàirt 11

Tha stuth an artaigil air a thoirt bho mo seanail zen.

A’ sgrùdadh einnsean Mediastreamer2 VoIP. Pàirt 11

Uidheam gluasad dàta

  • Bacadh dàta dblk_t
  • Teachdaireachd mblk_t
  • Feartan airson obrachadh le teachdaireachdan mblk_t
  • ciudha ciudha_t
  • Gnìomhan airson a bhith ag obair le ciudha queue_t
  • A’ ceangal sìoltachain
  • Puing chomharran graf giollachd dàta
  • Gnìomhan an ticker air cùl ghnothaichean
  • Bufferizer (MSBufferizer)
  • Gnìomhan airson a bhith ag obair le MSBufferizer

Anns an àm a dh ’fhalbh artaigil tha sinn air ar criathrag fhèin a leasachadh. Bidh an artaigil seo a’ cuimseachadh air an uidheamachd a-staigh airson gluasad dàta eadar sìoltachain sruthadh meadhanan. Leigidh seo leat sìoltachain sòlaimte a sgrìobhadh le nas lugha oidhirp san àm ri teachd.

Uidheam gluasad dàta

Bithear a’ gluasad dàta anns an t-sruthadair mheadhanan a’ cleachdadh ciudha air a mhìneachadh leis an structar ciudha_t. Sreath de theachdaireachdan mar mblk_t, anns nach eil dàta comharran iad fhèin, ach dìreach ceanglaichean ris an fhear roimhe, an ath theachdaireachd agus ris a’ bhloc dàta. A bharrachd air an sin, tha mi airson cuideam sònraichte a chuir air gu bheil raon ann cuideachd airson ceangal gu teachdaireachd den aon sheòrsa, a leigeas leat liosta de theachdaireachdan aon-cheangailte a chuir air dòigh. Canaidh sinn tuple ri buidheann de theachdaireachdan aonaichte le liosta mar sin. Mar sin, faodaidh eileamaid sam bith den ciudha a bhith na aon teachdaireachd mblk_t, agus is dòcha ceann tuple teachdaireachd mblk_t. Faodaidh a bhloc dàta uàrd fhèin a bhith aig gach teachdaireachd tuple. Bruidhnidh sinn carson a tha feum air tuples beagan nas fhaide air adhart.

Mar a chaidh ainmeachadh gu h-àrd, chan eil bloc dàta anns an teachdaireachd fhèin; an àite sin, chan eil ann ach comharradh don raon cuimhne far a bheil am bloca air a stòradh. Anns a’ phàirt seo, tha an dealbh iomlan de dh’ obair an t-sreapadair mheadhanan mar chuimhneachan air taigh-bathair an dorais anns a’ chartùn “Monsters, Inc.,” far a bheil dorsan (ceanglaichean ri dàta - rumannan) a’ gluasad aig astar gealtach ri taobh luchd-giùlain os cionn, fhad ‘s a tha na seòmraichean fhèin. fuireach gun ghluasad.

A-nis, a’ gluasad air adhart san rangachd bho bhonn gu mullach, leig dhuinn beachdachadh gu mionaideach air na buidhnean clàraichte den uidheamachd tar-chuir dàta ann an sruth nam meadhanan.

Bloc dàta dblk_t

Anns a’ bhloc dàta tha bann-cinn agus bufair dàta. Tha an ceann-cinn air a mhìneachadh leis an structar a leanas,

typedef struct datab
{
unsigned char *db_base; // Указатель на начало буфер данных.
unsigned char *db_lim;  // Указатель на конец буфер данных.
void (*db_freefn)(void*); // Функция освобождения памяти при удалении блока.
int db_ref; // Счетчик ссылок.
} dblk_t;

Ann an raointean an structair tha comharran gu toiseach a’ bhufair, deireadh a’ bhufair, agus a’ ghnìomh airson am bufair dàta a dhubhadh às. An eileamaid mu dheireadh ann am bann-cinn db_ref - cuntair iomraidh, ma ruigeas e neoni, bidh seo na chomharradh gus am bloc seo a dhubhadh às cuimhne. Ma chaidh am bloc dàta a chruthachadh leis a’ ghnìomh datab_alloc() , an uairsin thèid am bufair dàta a chuir mar chuimhneachan dìreach às deidh a’ bhann-cinn. Anns a h-uile cùis eile, faodar am bufair a shuidheachadh an àiteigin air leth. Anns a’ bhufair dàta bidh sampallan chomharran no dàta eile a tha sinn airson a phròiseasadh le sìoltachain.

Tha eisimpleir ùr de bhloca dàta air a chruthachadh leis a’ ghnìomh:

dblk_t *datab_alloc(int size);

Mar paramadair cuir a-steach, thathas a’ toirt seachad meud an dàta a bhios am bloca a’ stòradh. Tha barrachd cuimhne air a riarachadh gus ceann-cinn - structar - a chuir aig toiseach a’ chuimhne ainmichte dàta. Ach nuair a bhios tu a’ cleachdadh gnìomhan eile, chan eil seo an-còmhnaidh a’ tachairt; ann an cuid de chùisean, faodaidh am bufair dàta a bhith air a shuidheachadh air leth bho bhann-cinn a’ bhloca dàta. Nuair a chruthaicheas tu structar, tha na raointean air an rèiteachadh gus am bi an raon aige db_bonn chomharraich e toiseach an raon dàta, agus db_lim gu a chrìoch. Cunntas ceangail db_ref air a shuidheachadh gu aon. Tha an comharra gnìomh soilleir dàta air a shuidheachadh gu neoni.

teachdaireachd mblk_t

Mar a chaidh a ràdh, tha eileamaidean ciudha de sheòrsa mblk_t, tha e air a mhìneachadh mar a leanas:

typedef struct msgb
{
  struct msgb *b_prev;   // Указатель на предыдущий элемент списка.
  struct msgb *b_next;   // Указатель на следующий элемент списка.
  struct msgb *b_cont;   // Указатель для подклейки к сообщению других сообщений, для создания кортежа сообщений.
  struct datab *b_datap; // Указатель на структуру блока данных.
  unsigned char *b_rptr; // Указатель на начало области данных для чтения данных буфера b_datap.
  unsigned char *b_wptr; // Указатель на начало области данных для записи данных буфера b_datap.
  uint32_t reserved1;    // Зарезервированное поле1, медиастример помещает туда служебную информацию. 
  uint32_t reserved2;    // Зарезервированное поле2, медиастример помещает туда служебную информацию.
  #if defined(ORTP_TIMESTAMP)
  struct timeval timestamp;
  #endif
  ortp_recv_addr_t recv_addr;
} mblk_t;

structar mblk_t tha comharran ann aig an toiseach b_roimhe, b_ath, a tha riatanach gus liosta le ceangal dùbailte a chuir air dòigh (is e sin ciudha ciudha_t).

An uairsin thig am puing b_ leant, nach tèid a chleachdadh ach nuair a tha an teachdaireachd mar phàirt de thuple. Airson an teachdaireachd mu dheireadh anns an tuple, tha am puing seo fhathast null.

An uairsin chì sinn puing gu bloc dàta b_data, airson a bheil an teachdaireachd ann. Tha e air a leantainn le comharran don sgìre taobh a-staigh bufair dàta a’ bhloc. Achadh b_rptr a’ sònrachadh an t-àite bhon tèid dàta bhon bhufair a leughadh. Achadh b_wptr a’ comharrachadh an àite às an tèid sgrìobhadh chun bufair a dhèanamh.

Tha na raointean a tha air fhàgail de sheòrsa seirbheis agus chan eil iad co-cheangailte ri obrachadh an uidheamachd gluasad dàta.

Gu h-ìosal tha aon teachdaireachd leis an ainm m1 agus bacadh dàta d1.
A’ sgrùdadh einnsean Mediastreamer2 VoIP. Pàirt 11
Tha an dealbh a leanas a’ sealltainn tuple de thrì teachdaireachdan m1, m1_1, m1_2.
A’ sgrùdadh einnsean Mediastreamer2 VoIP. Pàirt 11

Gnìomhan teachdaireachd mblk_t

Teachdaireachd ùr mblk_t air a chruthachadh leis a’ ghnìomh:

mblk_t *allocb(int size, int pri); 

tha i a’ cur teachdaireachd ùr na cuimhne mblk_t le bloc dàta den mheud ainmichte meud, an dàrna argamaid - pri nach deach a chleachdadh san tionndadh seo den leabharlann. Bu chòir dha fuireach neoni. Rè obrachadh na h-obrach, thèid cuimhne a riarachadh airson structar na teachdaireachd ùr agus thèid an gnìomh a ghairm mblk_init(), a nì ath-shuidheachadh air a h-uile raon den eisimpleir cruthaichte den structar agus an uairsin, a’ cleachdadh na chaidh ainmeachadh gu h-àrd datab_alloc(), cruthaichidh e bufair dàta. Às deidh sin thèid na raointean san structar a rèiteachadh:

mp->b_datap=datab;
mp->b_rptr=mp->b_wptr=datab->db_base;
mp->b_next=mp->b_prev=mp->b_cont=NULL;

Aig an toradh gheibh sinn teachdaireachd ùr le raointean tùsail agus bufair dàta falamh. Gus dàta a chur ri teachdaireachd, feumaidh tu a chopaigeadh chun bufair bloc dàta:

memcpy(msg->b_rptr, data, size);

far a bheil dàta na chomharra air stòr an dàta, agus meud - am meud.
an uairsin feumaidh tu am puing ùrachadh chun phuing sgrìobhaidh gus am bi e a’ comharrachadh a-rithist toiseach an àite an-asgaidh sa bhufair:

msg->b_wptr = msg->b_wptr + size

Ma dh'fheumas tu teachdaireachd a chruthachadh bho bhufair a tha ann mar-thà, gun a bhith a 'dèanamh lethbhreac, cleachd an gnìomh:

mblk_t *esballoc(uint8_t *buf, int size, int pri, void (*freefn)(void*)); 

Bidh an gnìomh, às deidh dhut an teachdaireachd agus structar a ’bhloc dàta a chruthachadh, a’ rèiteachadh a chomharran don dàta aig an t-seòladh buff. An fheadhainn sin. anns a 'chùis seo, chan eil am bufair dàta air a shuidheachadh às deidh raointean cinn a' bhloc dàta, mar a bha fìor nuair a chaidh bloc dàta a chruthachadh leis a 'ghnìomh datab_alloc(). Fuirichidh am bufair le dàta a chaidh a chuir chun ghnìomh far an robh e, ach le cuideachadh bho chomharran bidh e ceangailte ri bann-cinn ùr a ’bhloc dàta, agus sin, a rèir sin, ris an teachdaireachd.

Gu aon teachdaireachd mblk_t Faodar grunn bhlocaichean dàta a cho-chruinneachadh ann an sreath. Tha seo air a dhèanamh leis a 'ghnìomh:

mblk_t * appendb(mblk_t *mp, const char *data, int size, bool_t pad); 

mp - teachdaireachd ris an tèid bloc dàta eile a chur ris;
dàta - puing don bhloc, agus thèid leth-bhreac dheth a chuir ris an teachdaireachd;
meud - meud an dàta;
pad - bratach gum feum meud na cuimhne a bhith air a cho-thaobhadh ri crìoch 4-byte (thèid pleadhag a dhèanamh le neamhan).

Ma tha àite gu leòr anns a’ bhufair dàta teachdaireachd a th’ ann mar-thà, thèid an dàta ùr a chuir air cùl an dàta a tha ann mu thràth. Ma tha nas lugha de rùm an-asgaidh ann am bufair dàta na teachdaireachd na meud, an uairsin thèid teachdaireachd ùr a chruthachadh le meud bufair gu leòr agus thèid an dàta a chopaigeadh chun bufair aige. Is e teachdaireachd ùr a tha seo, ceangailte ris an fhear thùsail a’ cleachdadh puing b_ leant. Anns a 'chùis seo, bidh an teachdaireachd a' tionndadh gu tuple.

Ma dh'fheumas tu bloc dàta eile a chur ris an tuple, feumaidh tu an gnìomh a chleachdadh:

void msgappend(mblk_t *mp, const char *data, int size, bool_t pad);

gheibh i an teachdaireachd mu dheireadh anns an tuple (tha aige b_ leant bi null) agus cuiridh e fios gu gnìomh airson na teachdaireachd seo leas-phàipear().

Gheibh thu a-mach meud an dàta ann an teachdaireachd no tuple leis a’ ghnìomh:

int msgdsize(const mblk_t *mp);

lùbaidh e tro na teachdaireachdan gu lèir anns an tuple agus tillidh e an àireamh iomlan de dhàta ann am bufairean dàta nam brathan sin. Airson gach teachdaireachd, tha an àireamh de dhàta air a thomhas mar a leanas:

 mp->b_wptr - mp->b_rptr

Gus dà thuple a chur còmhla, cleachd an gnìomh:

mblk_t *concatb(mblk_t *mp, mblk_t *newm);

tha i a' ceangal an tuple nuadh ri earball an tuple mp agus tillidh e comharra dhan teachdaireachd mu dheireadh bhon tuple a thàinig às.

Ma tha feum air, faodar tuple a thionndadh gu aon teachdaireachd le aon bhloca dàta; tha seo air a dhèanamh leis a’ ghnìomh:

void msgpullup(mblk_t *mp,int len);

ma tha argamaid len is -1, an uairsin tha meud a’ bhufair ainmichte air a dhearbhadh gu fèin-ghluasadach. Ma tha len na àireamh dheimhinneach, thèid bufair den mheud seo a chruthachadh agus thèid dàta teachdaireachd tuple a chopaigeadh a-steach ann. Ma ruitheas am bufair a-mach, stadaidh copaidh an sin. Gheibh a’ chiad teachdaireachd den tuple bufair meud ùr leis an dàta a chaidh a chopaigeadh. Thèid na teachdaireachdan a tha air fhàgail a dhubhadh às agus thèid an cuimhne a thilleadh chun a’ charn.

Nuair a thèid structar a dhubhadh às mblk_t thathas a’ toirt aire do chunntas iomraidh a’ bhloc dàta ma tha, nuair a bhios tu a’ gairm saor() tha e a’ tionndadh a-mach gu bheil e neoni, agus an uairsin thèid am bufair dàta a dhubhadh às còmhla ris an eisimpleir mblk_t, a tha ga chomharrachadh.

A’ tòiseachadh raointean teachdaireachd ùr:

void mblk_init(mblk_t *mp);

A' cur pìos dàta eile ris an teachdaireachd:

mblk_t * appendb(mblk_t *mp, const char *data, size_t size, bool_t pad);

Mura h-eil an dàta ùr a’ freagairt air àite an-asgaidh bufair dàta na teachdaireachd, tha teachdaireachd air a chruthachadh air leth le bufair den mheud a tha a dhìth ceangailte ris an teachdaireachd (tha puing don teachdaireachd a bharrachd air a shuidheachadh sa chiad teachdaireachd) agus an teachdaireachd a 'tionndadh gu tuple.

A’ cur pìos dàta ri tuple:

void msgappend(mblk_t *mp, const char *data, size_t size, bool_t pad); 

Bidh an gnìomh a’ gairm appendb() ann an lùb.

A 'ceangal dà thuple ann an aon:

mblk_t *concatb(mblk_t *mp, mblk_t *newm);

teachdaireachd nuadh bidh ceangailte ris mp.

Dèan lethbhreac de aon teachdaireachd:

mblk_t *copyb(const mblk_t *mp);

Dèan lethbhreac iomlan de thuple leis a h-uile bloc dàta:

mblk_t *copymsg(const mblk_t *mp);

Tha na h-eileamaidean den tuple air an lethbhreacadh leis a 'ghnìomh leth-bhreac().

Cruthaich lethbhreac furasta de theachdaireachd mblk_t. Anns a 'chùis seo, chan eil am bloc dàta air a chopaigeadh, ach tha a chunntair iomraidh air a mheudachadh db_ref:

mblk_t *dupb(mblk_t *mp);

A 'dèanamh leth-bhreac aotrom de thuple. Chan eilear a’ dèanamh lethbhreac de bhlocaichean dàta, chan eil ach na cunntairean fiosrachaidh aca air an àrdachadh db_ref:

mblk_t *dupmsg(mblk_t* m);

A’ giùlan a h-uile teachdaireachd de thuple ann an aon teachdaireachd:

void msgpullup(mblk_t *mp,size_t len);

Ma tha an argamaid len is -1, an uairsin tha meud a’ bhufair ainmichte air a dhearbhadh gu fèin-ghluasadach.

A' sguabadh às teachdaireachd, tuple:

void freemsg(mblk_t *mp);

Tha àireamh iomraidh a’ bhloca dàta air a dhol sìos le aon. Ma ruigeas e neoni, thèid am bloc dàta a dhubhadh às cuideachd.

Obraich a-mach an àireamh iomlan de dhàta ann an teachdaireachd no tuple.

size_t msgdsize(const mblk_t *mp);

A' faighinn teachdaireachd bho earball a' chiudha:

mblk_t *ms_queue_peek_last (q);

A’ dèanamh lethbhreac de shusbaint nan raointean glèidhte ann an aon teachdaireachd gu teachdaireachd eile (gu dearbh, tha brataichean anns na raointean sin a bhios luchd-streap nam meadhanan a’ cleachdadh):

mblk_meta_copy(const mblk_t *source, mblk *dest);

Ciudha ciudha_t

Tha an ciudha teachdaireachd ann an sruth nam meadhanan air a chuir an gnìomh mar liosta cruinn le dà cheangal. Anns gach eileamaid liosta tha comharradh gu bloc dàta le sampallan chomharran. Tha e a ’tionndadh a-mach nach eil ach comharran air gluasad a’ bhloc dàta mu seach, fhad ‘s a tha an dàta fhèin fhathast gun ghluasad. An fheadhainn sin. chan eil ach ceanglaichean riutha air an gluasad.
Structar a' toirt cunntas air a' chiudha ciudha_t, air a shealltainn gu h-ìosal:

typedef struct _queue
{
   mblk_t _q_stopper; /* "Холостой" элемент очереди, не указывает на данные, используется только для управления очередью. При инициализации очереди (qinit()) его указатели настраиваются так, чтобы они указывали на него самого. */
   int q_mcount;        // Количество элементов в очереди.
} queue_t;

Anns an structar tha raon - puing _q_stad seòrsa *mblk_t, tha e a’ comharrachadh a’ chiad eileamaid (teachdaireachd) anns a’ chiudha. Is e an dàrna raon den structar an cuntair de theachdaireachdan anns a’ chiudha.
Tha an dealbh gu h-ìosal a’ sealltainn ciudha leis an ainm q1 anns a bheil 4 teachdaireachdan m1, m2, m3, m4.
A’ sgrùdadh einnsean Mediastreamer2 VoIP. Pàirt 11
Tha an dealbh a leanas a’ sealltainn ciudha leis an ainm q1 anns a bheil 4 brathan m1,m2,m3,m4. Is e teachdaireachd m2 ceann tuple anns a bheil dà theachdaireachd eile m2_1 agus m2_2.

A’ sgrùdadh einnsean Mediastreamer2 VoIP. Pàirt 11

Gnìomhan airson a bhith ag obair le ciudha queue_t

Tòiseachadh ciudha:

void qinit(queue_t *q);

achadh _q_stad (an seo às deidh seo canaidh sinn “stopper”) air a thòiseachadh leis a’ ghnìomh mblk_init(), tha an eileamaid a bh’ ann roimhe agus an ath phuing eile air an atharrachadh gus a chomharrachadh fhèin. Tha an cuntair eileamaid ciudha air ath-shuidheachadh gu neoni.

A’ cur eileamaid ùr ris (teachdaireachdan):

void putq(queue_t *q, mblk_t *m);

Eileamaid ùr m air a chur ri deireadh na liosta, tha na comharran eileamaid air an atharrachadh gus am bi an stopadair mar an ath eileamaid air a shon, agus bidh e na eileamaid roimhe airson an stadadair. Tha cuntair eileamaid ciudha air àrdachadh.

A’ faighinn eileamaid às a’ chiudha:

mblk_t * getq(queue_t *q); 

Tha an teachdaireachd a thig às deidh an stadadair air fhaighinn air ais, agus tha an cuntair eileamaid air a lughdachadh. Mura h-eil eileamaidean anns a’ chiudha ach an stad-stad, thèid 0 a thilleadh.

A' cur teachdaireachd ann an ciudha:

void insq(queue_t *q, mblk_t *emp, mblk_t *mp); 

Element mp air a chuir a-steach air beulaibh an eileamaid emp. Ma tha emp=0, an uairsin thèid an teachdaireachd a chur ri earball na ciudha.

A' faighinn teachdaireachd bho cheann a' chiudha:

void remq(queue_t *q, mblk_t *mp); 

Tha an àireamhair eileamaid air a dhol sìos.

A’ leughadh puing don chiad eileamaid sa chiudha:

mblk_t * peekq(queue_t *q); 

Thoir air falbh a h-uile eileamaid bhon ciudha fhad ‘s a tha thu a’ sguabadh às na h-eileamaidean iad fhèin:

void flushq(queue_t *q, int how);

argamaid ciamar gun chleachdadh. Tha an cuntair eileamaid ciudha air a shuidheachadh gu neoni.

Macro airson puing a leughadh don eileamaid mu dheireadh den ciudha:

mblk_t * qlast(queue_t *q);

Nuair a bhios tu ag obair le ciudha teachdaireachd, bi mothachail nuair a chuireas tu fios thugainn ms_queue_put(q, m) le puing null don teachdaireachd, na lùban gnìomh. Bidh am prògram agad a’ reothadh. giùlan fhèin mar an ceudna ms_queue_an ath-(q, m).

A’ ceangal sìoltachain

Tha an ciudha a tha air a mhìneachadh gu h-àrd air a chleachdadh gus teachdaireachdan a chuir bho aon chriathrag gu criathrag eile no bho aon gu grunn sìoltachain. Bidh sìoltachain agus na ceanglaichean aca a’ cruthachadh graf stiùiridh. Canar am facal coitcheann “pin” ri cuir a-steach no toradh a’ chriathrag. Gus cunntas a thoirt air an òrdugh anns a bheil sìoltachain ceangailte ri chèile, bidh an streapadair mheadhanan a’ cleachdadh bun-bheachd “puing chomharran”. Is e puing comharra structar _MSCPpuing, anns a bheil puing don chriathrag agus àireamh aon de na prìneachan aige; a rèir sin, tha e a ’toirt cunntas air ceangal aon de na cuir a-steach no toraidhean a’ chriathrag.

Puing chomharran graf giollachd dàta

typedef struct _MSCPoint{
struct _MSFilter *filter; // Указатель на фильтр медиастримера.
int pin;                        // Номер одного из входов или выходов фильтра, т.е. пин.
} MSCPoint;

Tha prìneachan sìoltachain air an àireamhachadh a’ tòiseachadh bho neoni.

Tha ceangal dà phrìne le ciudha teachdaireachd air a mhìneachadh leis an structar _MSQueue, anns a bheil ciudha teachdaireachd agus comharran air an dà phuing comharra a tha e a’ ceangal:

typedef struct _MSQueue
{
queue_t q;
MSCPoint prev;
MSCPoint next;
}MSQueue;

Canaidh sinn ceangal chomharran ris an structar seo. Tha clàr de cheanglaichean cuir a-steach agus clàr de cheanglaichean toraidh (MSQueue). Tha meud chlàran air a shuidheachadh nuair a chruthaicheas sinn criathrag; tha sinn air seo a dhèanamh mu thràth a’ cleachdadh caochladair seòrsa às-mhalairt MSFilterDesc, nuair a leasaich sinn ar criathrag fhèin. Gu h-ìosal tha structar a tha a’ toirt cunntas air sìoltachan sam bith ann an streapadair mheadhanan, MSFilter:


struct _MSFilter{
    MSFilterDesc *desc;    /* Указатель на дескриптор фильтра. */
    /* Защищенные атрибуты, их нельзя сдвигать или убирать иначе будет нарушена работа с плагинами. */
    ms_mutex_t lock;      /* Семафор. */
    MSQueue **inputs;     /* Таблица входных линков. */
    MSQueue **outputs;    /* Таблица выходных линков. */
    struct _MSFactory *factory; /* Указатель на фабрику, которая создала данный экземпляр фильтра. */
    void *padding;              /* Не используется, будет задействован если добавятся защищенные поля. */
    void *data;                 /* Указатель на произвольную структуру для хранения данных внутреннего состояния фильтра и промежуточных вычислений. */
    struct _MSTicker *ticker;   /* Указатель на объект тикера, который не должен быть нулевым когда вызывается функция process(). */
    /*private attributes, they can be moved and changed at any time*/
    MSList *notify_callbacks; /* Список обратных вызовов, используемых для обработки событий фильтра. */
    uint32_t last_tick;       /* Номер последнего такта, когда выполнялся вызов process(). */ 
    MSFilterStats *stats;     /* Статистика работы фильтра.*/
    int postponed_task; /*Количество отложенных задач. Некоторые фильтры могут откладывать обработку данных (вызов process()) на несколько тактов.*/
    bool_t seen;  /* Флаг, который использует тикер, чтобы помечать что этот экземпляр фильтра он уже обслужил на данном такте.*/
};
typedef struct _MSFilter MSFilter;

Às deidh dhuinn na sìoltachain a cheangal ann am prògram C a rèir ar plana (ach cha do cheangail sinn an ticker), mar sin chruthaich sinn graf stiùirichte, agus tha na nodan mar eisimpleirean den structar MSFilter, agus tha oirean nan eisimpleirean de cheanglaichean MSQueue.

Gnìomhan an ticker air cùl ghnothaichean

Nuair a dh’ innis mi dhut gur e sìoltachan a th’ anns an ticker airson stòr nan ticeagan, cha b’ e sin an fhìrinn gu lèir mu dheidhinn. Is e rud a th’ ann an ticker a ruitheas gnìomhan air a’ ghleoc pròiseas() a h-uile sìoltachan den chuairt (graf) ris a bheil e ceangailte. Nuair a cheanglas sinn ticker ri criathrag graf ann am prògram C, bidh sinn a’ sealltainn an ticker an graf a bhios e fo smachd bho seo a-mach gus an cuir sinn dheth e. Às deidh ceangal, tòisichidh an ticker a’ sgrùdadh a’ ghraf a tha fo chùram, a’ cur ri chèile liosta de shìoltachain a tha a’ toirt a-steach e. Gus nach bi thu “a’ cunntadh” an aon sìoltachan dà uair, bidh e a’ comharrachadh na sìoltachain a chaidh a lorg le bhith a’ cur bogsa sgrùdaidh annta fhaicinn. Thèid an sgrùdadh a dhèanamh a’ cleachdadh na clàran ceangail a tha aig gach sìoltachan.

Rè a chuairt tòiseachaidh den ghraf, bidh an ticker a’ sgrùdadh a bheil co-dhiù aon am measg nan sìoltachain a bhios ag obair mar stòr de bhlocaichean dàta. Mura h-eil gin ann, thathas den bheachd gu bheil an graf ceàrr agus tuitidh an ticker.

Ma tha coltas gu bheil an graf “ceart”, airson gach criathrag a chaidh a lorg, canar toiseach tòiseachaidh ris a’ ghnìomh ro-phròiseas (). Cho luath ‘s a ruigeas a’ mhionaid airson an ath chearcall giollachd (gach 10 milliseconds gu bunaiteach), bidh an ticker a ’gairm a’ ghnìomh pròiseas() airson a h-uile sìoltachan stòr a chaidh a lorg roimhe, agus an uairsin airson na sìoltachain a tha air fhàgail air an liosta. Ma tha ceanglaichean cuir a-steach aig a’ chriathrag, an uairsin ruith an gnìomh pròiseas() ath-aithris gus am bi na ciudha ceangail a-steach falamh. Às deidh seo, gluaisidh e air adhart chun ath chriathrag air an liosta agus “scrollaich” e gus am bi na ceanglaichean cuir a-steach saor bho theachdaireachdan. Bidh an ticker a’ gluasad bho chriathrag gu criathrag gus an tig an liosta gu crìch. Bidh seo a 'crìochnachadh giollachd a' chearcaill.

A-nis tillidh sinn gu tuples agus bruidhnidh sinn carson a chaidh an leithid de eintiteas a chuir ris an t-sruthadair meadhanan. San fharsaingeachd, chan eil an ìre de dhàta a dh’ fheumas an algairim a tha ag obair taobh a-staigh a’ chriathrag a’ co-fhreagairt agus chan eil e na iomadachadh de mheud nam bufairean dàta a gheibhear aig an cuir a-steach. Mar eisimpleir, tha sinn a’ sgrìobhadh criathrag a nì cruth-atharrachadh luath Fourier, nach urrainn le mìneachadh ach blocaichean dàta aig a bheil meud cumhachd dhà a phròiseasadh. Leig leis a bhith 512 cunntadh. Ma thèid an dàta a chruthachadh le seanal fòn, an uairsin bheir bufair dàta gach teachdaireachd aig an cuir a-steach 160 sampall comharra dhuinn. Tha e tàmailteach gun a bhith a’ cruinneachadh dàta bhon chur-a-steach gus am bi an uiread de dhàta a tha a dhìth ann. Ach anns a ’chùis seo, bidh tubaist a’ tachairt leis an ticker, a dh ’fheuchas gu neo-shoirbheachail ris a’ chriathrag a sgrùdadh gus am bi an ceangal cuir a-steach falamh. Roimhe sin, chomharraich sinn an riaghailt seo mar an treas prionnsapal den chriathrag. A rèir a’ phrionnsapail seo, feumaidh gnìomh pròiseas () a’ chriathrag a h-uile dàta a thoirt bho na ciudhaichean cuir a-steach.

A bharrachd air an sin, cha bhith e comasach ach 512 sampall a thoirt bhon chuir a-steach, leis nach urrainn dhut ach blocaichean slàn a ghabhail, i.e. feumaidh an criathrag 640 sampall a ghabhail agus 512 dhiubh a chleachdadh, an còrr mus cruinnich iad cuibhreann ùr de dhàta. Mar sin, feumaidh ar criathrag, a bharrachd air a phrìomh obair, gnìomhan taice a thoirt seachad airson stòradh eadar-mheadhanach de dhàta cuir a-steach. Tha luchd-leasachaidh nam meadhanan streamer agus fuasgladh don duilgheadas coitcheann seo air rud sònraichte a leasachadh - MSBufferizer (bufferer), a dh ’fhuasglas an duilgheadas seo le bhith a’ cleachdadh tuples.

Bufferizer (MSBufferizer)

Is e seo rud a chruinnicheas dàta cuir a-steach taobh a-staigh a’ chriathrag agus a thòisicheas ga chuir a-steach airson a ghiullachd cho luath ‘s a bhios an ìre de dh’ fhiosrachadh gu leòr airson an algairim sìoltachain a ruith. Fhad ‘s a tha am bufair a’ cruinneachadh dàta, obraichidh an criathrag ann am modh leisg, gun a bhith a’ cleachdadh cumhachd giollachd a’ phròiseasar. Ach cho luath ‘s a thilleas an gnìomh leughaidh bhon bhufair luach a bharrachd air neoni, bidh gnìomh pròiseas () a’ chriathrag a ’tòiseachadh a’ gabhail agus a ’giullachd dàta bhon bhufair ann am pàirtean den mheud riatanach, gus am bi e sgìth.
Tha dàta nach eil a dhìth fhathast fhathast sa bhufair mar a’ chiad eileamaid den tuple, ris a bheil blocaichean dàta cuir a-steach an dèidh sin ceangailte.

An structar a tha a 'toirt cunntas air a' bhufair:

struct _MSBufferizer{
queue_t q; /* Очередь сообщений. */
int size; /* Суммарный размер данных находящихся в буферизаторе в данный момент. */
};
typedef struct _MSBufferizer MSBufferizer;

Gnìomhan airson a bhith ag obair le MSBufferizer

A’ cruthachadh eisimpleir bufair ùr:

MSBufferizer * ms_bufferizer_new(void);

Tha cuimhne air a riarachadh, air a thòiseachadh a-steach ms_bufferizer_init() agus tha comharradh air a thilleadh.

Gnìomh tòiseachaidh:

void ms_bufferizer_init(MSBufferizer *obj); 

Tha an ciudha a’ tòiseachadh q, achadh meud air a shuidheachadh gu neoni.

A' cur teachdaireachd ris:

void ms_bufferizer_put(MSBufferizer *obj, mblk_t *m); 

Tha teachdaireachd m ga chur ris a’ chiudha. Thathas a’ cur ris a’ mheud àireamhaichte de bhlocaichean dàta meud.

A’ gluasad a h-uile teachdaireachd bhon ciudha dàta ceangail chun a’ bhufair q:

void ms_bufferizer_put_from_queue(MSBufferizer *obj, MSQueue *q);   

A' gluasad teachdaireachdan bho cheangal q anns a 'bufair air a choileanadh a' cleachdadh a 'ghnìomh ms_bufferizer_put().

Leughadh bhon bhufair:

int ms_bufferizer_read(MSBufferizer *obj, uint8_t *data, int datalen); 

Ma tha meud an dàta a chaidh a chruinneachadh sa bhufair nas lugha na am fear a chaidh iarraidh (dàta), an uairsin bidh an gnìomh a’ tilleadh neoni, chan eil dàta air a chopaigeadh gu dàta. Rud eile, bithear a’ dèanamh lethbhreac de dhàta bho thuples a tha suidhichte sa bhufair. Às deidh leth-bhreac a dhèanamh, thèid an tuple a dhubhadh às agus thèid an cuimhne a shaoradh. Bidh copaidh a’ tighinn gu crìch an-dràsta nuair a thèid bytes datalen a chopaigeadh. Ma ruitheas àite ann am meadhan bloc dàta, an uairsin anns an teachdaireachd seo, thèid am bloc dàta a lughdachadh chun phàirt nach deach a chopaigeadh. An ath thuras a chuireas tu fòn, leanaidh copaidh air adhart bhon àm seo.

A’ leughadh na tha de dhàta ri fhaighinn sa bhufair an-dràsta:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

A 'tilleadh an raon meud bufair.

A’ cuir air falbh pàirt den dàta anns a’ bhufair:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

Tha an àireamh ainmichte de bytes dàta air fhaighinn air ais agus air a thilgeil air falbh. Tha an dàta as sine air a thilgeil air falbh.

A' sguabadh às a h-uile brath sa bhufair:

void ms_bufferizer_flush(MSBufferizer *obj); 

Tha an cunntas dàta air ath-shuidheachadh gu neoni.

A' sguabadh às a h-uile brath sa bhufair:

void ms_bufferizer_uninit(MSBufferizer *obj); 

Chan eil an cuntair air ath-shuidheachadh.

A’ toirt air falbh am bufair agus a’ saoradh cuimhne:

void ms_bufferizer_destroy(MSBufferizer *obj);  

Gheibhear eisimpleirean de bhith a’ cleachdadh a’ bhufair ann an còd stòr grunn shìoltachain meadhanan. Mar eisimpleir, anns a’ chriathrag MS_L16_ENC, a bhios ag ath-rèiteachadh nam bytes anns na sampallan bho òrdugh an lìonraidh gu òrdugh an aoigh: l16.c

Anns an ath artaigil, seallaidh sinn ris a’ cheist mu bhith a’ toirt tuairmse air an luchd air ticker agus dòighean air cuir an-aghaidh cus luchd coimpiutaireachd ann an streapadair mheadhanan.

Source: www.habr.com

Cuir beachd ann