ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
8 июля
230420 Топик полностью
alman (23.12.2010 14:33, просмотров: 203) ответил koyodza на я не "решил использовать L4:Pistachio", поскольку пока так и не понял зачем. Вообще по-моему не логично принимать решения типа "используем ОС АВС потому что она есть", а только потом разбираться, подходит она или нет
О памяти: В прикладных программах использется стандартный метод - malloc дергает системный вызов sbrk, который динамически расширяет BSS задачи. В системных сервисах и драйверах используется переопределённый оператор new, который выделяет память из статических массивов. Супервизор использует "поток виртуальных страниц" - абстракция над диспетчером страниц, которая используется для динамического выделения объектов определённого типа. Сколько займёт уразанный TCP/IP? Ну вот навскидку - структура сокета: class CSocket { CSocket * m_NextFree; // Next free socket in chain // Socket section int m_nDomain; int m_nType; int m_nProtocol; // ??? int m_nStatus; /// IP section unsigned short m_mLocalPort; unsigned short m_nRemotePort; unsigned long m_mLocalAddress; unsigned long m_nRemoteAddress; // TCP section typeTcpStates m_nState; unsigned long m_nSequenceNumber; unsigned long m_nAckNumber; unsigned long m_nConnectionsAvailable; bool m_SetAcknowledge; // Data buffers unsigned char m_pReceiverBuffer[1024]; unsigned int m_nReceivedBytes; unsigned int m_nUserReceiveBufferSize; // This section has been added after long long postponed period // End of postponed section // Variable that keep L4ThreadID of user's process that wait in accept() unsigned int m_WaitingIncomingConnectionThreadID; // L4_Threaid_t // Variable that keep L4ThreadID of sending user's process unsigned int m_SendingThreadID; // L4_Threaid_t unsigned int m_ReceivingThreadID; // L4_Threaid_t // CSocket * m_ParentSock; // Point to ACCEPT waiting socket ДШЫЕ CSocket * m_PendingConnectionsChain; // Point to ACCEPT waiting socket ДШЫЕ CSocket * m_PendingConnectionsNext; // Remote connected socket chain next element // public: // ================== Public read-only poperties ================== unsigned long LocalAddress() { return m_mLocalAddress; } unsigned long RemoteAddress() { return m_nRemoteAddress; } unsigned short LocalPort() { return m_mLocalPort; } unsigned short RemotePort() { return m_nRemotePort; } typeTcpStates SocketState() { return m_nState; } unsigned long SequenceNumber() { return m_nSequenceNumber; } unsigned long AckNumber() { return m_nAckNumber; } unsigned long NumAvailableConn() { return m_nConnectionsAvailable; } unsigned short Window() { return sizeof(m_pReceiverBuffer) - m_nReceivedBytes; } bool AcknowledgeSet() { return m_SetAcknowledge; } // ================== Public write-only poperties ================== void AcknowledgeDone() { m_SetAcknowledge = false; } void SetAcknowledgeNumber( unsigned long ack_no ) { m_nAckNumber = ack_no; m_SetAcknowledge = true; } void SetSequenceNumber( unsigned long seq_no ); // { m_nSequenceNumber = seq_no; } public: CSocket(); virtual ~CSocket(); int Initialize( void ); int Create( int domain, int type, int protocol ); int Connect( unsigned int waiting_thread_id, char * socket_address_sorage, int size_of_address_sorage_buffer); int Bind(struct sockaddr * sa); int Listen(int max_connections); int Accept( unsigned int waiting_thread_id); int Send( unsigned int sending_thread_id, const unsigned char * pBuff, int nLength); int Recv( unsigned int waiting_thread_id, unsigned char * pBuff, int nLength); int Valid(void); int Close(unsigned int waiting_thread_id); // void Clear(void); char * GetStateName(typeTcpStates nState); char * GetStateName(void) { return GetStateName(m_nState); } int Export_Local_Address( void * socket_address_storage, unsigned int storage_size ); void SetConnection( unsigned long ip_address, unsigned short port); int ChangeSocketState(typeTcpStates); int StoreReceivedData(const unsigned char * pData, const unsigned int nLength); int AbortReceive( int nStatus ); public: // Events int OnCompleteUserCommand(int nStatus); int OnConnect(int nStatus); int OnAcceptIncomingConnection( int status ); int OnClose( int status ); int OnSendData(int status); public: CSocket * NextFree() { return m_NextFree; } void NextFree( CSocket * s ) { m_NextFree = s; } int ProcessIncomingConnection( CSocket *pListenSocket,const typeHeaderTCP *pTcpHeader, const typeIpPseudoHeader * pIpPseudoHeader); int PutConnectionIntoEndOfChain(); bool RemoveConnectionFromChain(); private: int GetControlBits(const typeHeaderTCP* pHeader) { return 0x003f & swap16(pHeader->nFlags); } int GetDataOffest(const typeHeaderTCP* pHeader) { return swap16(pHeader->nFlags)>>12; } private: int SendPacket(const int nFlags, const unsigned char * pData, const unsigned int nLength); int Export_Address( void * socket_address_storage, unsigned int storage_size ); int Import_Address( void * socket_address_storage, unsigned int storage_size ); private: CSocket * GetPendingConnectionFromChain(); // ---------------- Added in 2010 :) -------------------------- ITransportLayer * GetTransport(void); }; Посчитаем размер для 32-х битной архитектуры? 22 * sizeof(void*) + 1024 + 4 = 1116 байт на реализацию сокета. Для 8 соединений достаточно 9 Кб. Но это без учёта буферов сетевой карты и буферов TCP и IP сервисов. Кстати, здесь большое поле для оптимизации и есть желание реализовать идею, подсмотренную в одной из версий для встраиваемых устройств, когда выделяется память сразу на весь ethernet или ppp фрейм, а протоколы только дописывают заголовки к данным. Т.ч. если заинтересуетесь, то будет стимул реализовать эту фичу.