void USART6_IRQHandler() { if (USART_GetITStatus(USART6,USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART6, USART_IT_RXNE); RingBufferWrite(&GPS_USART_RxRingBuffer, (char)USART_ReceiveData(USART6)); } }
COUNT SerialWrite(char * buf, COUNT len) { COUNT write; IsrDisable(IRQ_LEVEL_SERIAL_WRITE); write = RingBufferWrite(buf, len, &SerialOutputRing); IsrEnable(IRQ_LEVEL_SERIAL_WRITE); HalRaiseInterrupt(IRQ_LEVEL_SERIAL_WRITE); return write; }
COUNT PipeWriteInner( char * buff, COUNT size, PIPE_WRITE pipe ) { BOOL wasEmpty; BOOL spaceLeft; COUNT write; //Acquire FullLock - No writers can progress until we are done. SemaphoreDown( & pipe->FullLock, NULL ); //Acqure mutex lock - No one can do any io until //we leave the buffer. SemaphoreDown( & pipe->Mutex, NULL ); //Check and see if the buffer is empty. //If it is, then the EmptyLock should //have been leaked, and readers should be blocking. wasEmpty = RingBufferIsEmpty( & pipe->Ring ); ASSERT( wasEmpty ? (pipe->EmptyLock.Count == 0) : TRUE ); //Perform the write. write = RingBufferWrite( buff, size, & pipe->Ring ); // Ring is protected by a write lock which should prevent zero length writes. ASSERT( write > 0 ); //See if the ring buffer is empty. //If it is then we need to leak the reader lock. spaceLeft = !RingBufferIsFull( & pipe->Ring ); //Release mutex lock - We are out of the ring, so //let other IO go if its already passed. SemaphoreUp( & pipe->Mutex ); //If the ring was empty while we have exclusive access, //and we wrote some data, then we should release //the EmptyLock so readers can go. if( wasEmpty && write > 0 ) { SemaphoreUp( & pipe->EmptyLock ); } //If there is space left in the buffer, release the //FullLock so that other writers can go. //If there is no space in the buffer, we cant let //writers progress, so we leak the lock. if( spaceLeft ) { SemaphoreUp( & pipe->FullLock ); } return write; }
void GetBytesInterrupt(void) { while (!RingBufferIsFull(&SerialInputRing)) { char data; if (HalSerialGetChar(&data)) { ASSUME(RingBufferWrite(&data, sizeof(data), &SerialInputRing), 1); } else { break; } } if ( HandlerIsFinished(&ReadGenerationCritObject) ) { GenerationUpdateSafe( &ReadGeneration, ++ReadGenerationCount, &ReadGenerationContext, &ReadGenerationCritObject); } }
s32 DispatchLooper(struct NetLooper * looper, const s32 millisecond) { struct epoll_event * events = (struct epoll_event *)alloca(sizeof(struct epoll_event) * looper->size); memset(events, 0, sizeof(struct epoll_event) * looper->size); s32 retCount = epoll_wait(looper->fd, events, looper->size, millisecond); if (retCount == -1) { if (errno != EINTR) { printf("epoll_wait error %d\n", errno); } return; } if (retCount == 0) return; s32 i = 0; for (i = 0; i < retCount; i++) { s32 code; s32 fd; struct sockaddr_in addr; socklen_t len = sizeof(addr); char type = ((struct NetBase *)events[i].data.ptr)->type; switch (type) { case BNEV_ACCEPT: { struct NetBase * accepter = events[i].data.ptr; if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) { code = -1; OASSERT(0, "wtf"); } else if (events[i].events & EPOLLIN) { memset(&addr, 0, sizeof(addr)); s32 i = 0; while (i++ < 30 && (fd = accept(accepter->fd, (struct sockaddr *)&addr, &len)) >= 0) { if (0 == SetNonBlocking(fd) && 0 == SetSendBuf(fd, 0) && 0 == SetNonNegal(fd)) { struct NetBase * base = (struct NetBase *)MALLOC(sizeof(struct NetBase)); base->fd = fd; base->type = BNEV_IO; base->looper = NULL; base->maxRecvSize = accepter->maxRecvSize; base->maxSendSize = accepter->maxSendSize; if (0 != (*looper->fnAccept)(accepter, base)) { FreeBase(base); } } else { close(fd); } } } break; } case BNEV_CONNECT: { struct NetBase * connecter = events[i].data.ptr; if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) code = -1; else if (events[i].events & EPOLLOUT) code = 0; if (UnbindLooper(connecter) != 0) { printf("epoll add fd error %s\n", strerror(errno)); //return; OASSERT(0, "wtf"); } connecter->type = BNEV_IO; (*looper->fnConnect)(connecter, code); if (-1 == code) FreeBase(connecter); break; } case BNEV_IO: { struct NetBase * base = events[i].data.ptr; if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) { UnbindLooper(base); (*looper->fnRecv)(base, -1, NULL, 0); FreeBase(base); break; } if (events[i].events & EPOLLIN) { s32 res = 0; while (1) { u32 size = 0; s32 len = 0; char * buf = RingBufferWrite(base->recvBuff, &size); if (buf && size > 0) { len = recv(base->fd, buf, size, 0); if (len < 0 && errno == EAGAIN) break; } else len = -1; if (len <= 0) { UnbindLooper(base); (*looper->fnRecv)(base, -1, NULL, 0); FreeBase(base); res = -1; break; } if (-1 == (*looper->fnRecv)(base, 0, buf, len)) { UnbindLooper(base); FreeBase(base); res = -1; break; } } if (-1 == res) break; } if (events[i].events & EPOLLOUT) { if (0 != (*looper->fnSend)(base)) { UnbindLooper(base); FreeBase(base); } } break; } default: OASSERT(0, "wtf"); break; } } }