subdirs : @for i in $(SUBDIRS) ; do ( cd $$i && $(MAKE) ) ; done
.c.o: $(CC) $(INCLUDE) $(CFLAGS) $<
ctags: ctags -R .
++++++++++++++++++++++++++ * Input Data ++++++++++++++++++++++++++
0.txt와 1.txt에서 차례대로 10개의 문자를 읽어들인다. 0.txt 0000000000
1.txt 1111111111
++++++++++++++++++++++++++ * Result Data ++++++++++++++++++++++++++ issue_aio_calls aiocblist_free_index found : 1 aio_call excuted.. ret_val from execute_aio_calls : 0 issue_aio_calls aiocblist_free_index found : 2 aio_call excuted.. ret_val from execute_aio_calls : 0
rtsig_handler handle_event called [Info] aiocb_index : 2 get_result_status nbytes : 10 0000000000 application_specific_code media's handler function get_result_status nbytes : 10 1111111111 application_specific_code media's handler function handle_event end
/** * posix asynchronous result * <BR> * asynchronous reqeust를 요청한 곳 ( handler, data ) 에 요청된 결과가 처리되었을 때 * 알리기 위한 구조 */ typedef struct posix_asynch_result{
/// allocated aiocb struct aiocb *aiocb;
/// file description int fd;
/// Bytes transferred by this operation. size_t size;
/** * This really make sense only when doing file I/O. * * @@ On POSIX4-Unix, offset_high should be supported using * aiocb64. * */ unsigned long offset; unsigned long offset_high;
/// Priority of the operation. int priority;
/** * POSIX4 realtime signal number to be used for the * operation. <signal_number> ranges from SIGRTMIN to SIGRTMAX. By * default, SIGRTMIN is used to issue <aio_> calls. */ int signal_number;
/// Success indicator. int success;
/// Error if operation failed. unsigned long error;
/// on receiving signal in signal_hander, to call media's handler function void * (*hndlr)(void *);
/// on receiving signal in signal_hander, to give a parameter to media's handler function void * data;
}posix_asynch_result; /** * aiocb에 대한 요청이 READ인지, WRITE인지를 나타내는 값 */ typedef enum{ READ = 1, WRITE = 2 }Opcode;
/// number of aiocb struct aiocb **aiocb_list; //AIOCB_MAX_SIZE만큼 posix_asynch_result **result_list;
/// signal set static sigset_t RT_completion_signal;
/// To maintain the maximum size of the array (list). size_t aiocb_list_max_size; /// To maintain the current size of the array (list). size_t aiocb_list_cur_size; /// Number of posix_asynch_result's waiting for start /// i.e. deferred AIOs size_t num_deferred_aiocb; /// Number active,i.e. running requests size_t num_started_aio;
///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////PROACTOR INIT//////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// /** * @author 박학선 * @param max_aio_operations System Interface에서 사용할 aiocb_list의 최대 갯수 * @retval -1 proactor init error * @retval 0 proactor init ok * @brief System Interface이 초기화될 때 posix_proactor를 초기화 * 하면서 시그널 세팅!! */ int posix_proactor_init(size_t max_aio_operations);
///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////REQEUEST//////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// /** * @author 박학선 * @param file_fd * @param size * @param offset * @param buf * @param data * @param hndlr_ftn * @param priority * @param op * @brief media에서 asynchronous read를 요청하기 위해 호출하는 함수. * 실제로는 이 파일안에 정의되어 있지는 않음. 단지 테스트를 위해서... */ int si_read_req(int file_fd, int size, int offset, void *buf, void *data, void *hndlr_ftn, int priority, Opcode op);
/** * @author 박학선 * @param result * @param op * @retval 0 started OK * @retval 1 OS AIO queue overflow * @retval -1 do not started * @brief System Interface(si_read_req())에서 Proactor에 * read를 요청하기 위해 사용!! */ int issue_aio_calls (posix_asynch_result *result, Opcode op);
/** * @author 박학선 * @param aiocb * @retval 0 AIO was started successfully * @retval 1 AIO was not started, OS AIO queue overflow * @retval -1 AIO was not started, other errors * @brief 파일의 미디어 트랙에서 aio_read, aio_write를 실행!! */ int execute_aio_calls (struct aiocb * aiocb);
/** * @author 박학선 * @param aiocb * @retval retval > 0 allocated aiocb_list's slot * @retval -1 no free slot * @brief 이 시스템에서 관리하는 aiocb_list의 free slot을 반환한다. */ ssize_t allocate_aio_slot(struct aiocb * aiocb);
#ifdef __cplusplus } #endif//__cplusplus
#endif //__POSIX_PROACTOR__
++++++++++++++++++++++++++ + Source File ++++++++++++++++++++++++++ // posix_proactor.c, v 0.1 2005/05/19 // ============================================================================ /** * * * * @file posix_proactor.c * * posix_proactor which use RT Signal. * * struct aiocb * int aio_fildes; //file descriptor * volatile void *aio_buf; //buffer allocation * size_t aio_nbytes; //length of transfer * off_t aio_offet; //file offset. starting position * int aio_reqprio; //request priority offset(_POSIX_PRIORITIZED_IO and _POSIX_PRORITY_SCHEDULING * struct sigevent aio_sigevent; //signal number and offset * int aio_lio_opcode; //listio operation * * @author sunsson <sunsson@varovision.com> */ // ============================================================================
for (ai = 0; ai < aiocb_list_max_size; ai++){ aiocb_list[ai] = 0; result_list[ai] = 0; } return 0; }
/** * @author 박학선 * @param * @retval -1 setup signal init or setup signal_hanlder fail * @retval 0 setup signal init(handler) success * @brief System이 사용할 signal(RTSIG_MIN) set up!! */ int signal_init() { int ret_val; /// Get full set if(sigemptyset(&RT_completion_signal) == -1) fprintf(stderr, "[Error] Couldnt empty signal set\n");
if(sigaddset(&RT_completion_signal, SIGRTMIN) == -1) fprintf(stderr, "[Error] Couldnt init the RT completion signal set\n");
///block the signal if(sigprocmask(SIG_BLOCK, &RT_completion_signal, 0) == -1) { fprintf(stderr, "Could not block SIGRTMAX or SIGRTMAX-1"); return -1; }
ret_val = setup_signal_handler(SIGRTMIN);
///unblock the signal //if(sigprocmask(SIG_UNBLOCK, &newact.sa_mask, NULL) == -1){ if(sigprocmask(SIG_UNBLOCK, &RT_completion_signal, 0) == -1) { fprintf(stderr, "Could not unblock SIGRTMAX or SIGRTMAX-1"); return -1; }
return ret_val; }
/** * @author 박학선 * @param signal_number signal handler를 띄울 RTSIG * @retval -1 setup signal handler fail * @retval 0 setup signal handler success * @brief System Interface이 초기화될 때 시그널 핸들러 세팅!! */ int setup_signal_handler(int signal_number) { struct sigaction newact; int sigaction_return;
sigemptyset(&newact.sa_mask); //Nothing else to mask newact.sa_flags = SA_SIGINFO; // Realtime flag. newact.sa_sigaction = rtsig_handler ; //set up "null_handler" sigaction_return = sigaction (signal_number, &newact, 0); //specify the action to be associated with a specific signal if(sigaction_return == -1){ fprintf(stderr, "[Error]couldnt do sigaction for the RT SIGNAL\n"); return -1; } return 0; }
///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////CALLBACK///////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// /** * @author 박학선 * @param signal_number signal handler를 깨운 signal * @param info signal과 연관된 정보들(aiocb_list의 index) * @param context 사용한 바 없음. * @retval * @brief 요청된 read를 수행한 후에 호출되는 signal_handler */ void rtsig_handler (int signal_number, siginfo_t* info, void* context) { int result = 0; // struct timespec timeout;
/** * @author 박학선 * @param result * @param op * @retval 0 started OK * @retval 1 OS AIO queue overflow * @retval -1 do not started * @brief System Interface(si_read_req())에서 Proactor에 * read를 요청하기 위해 사용!! */ int issue_aio_calls (posix_asynch_result *result, Opcode op) { struct aiocb * aiocb; int ret_val;
if (aiocb == 0) // Just check the status of the list return ret_val;
// Save operation code in the aiocb switch (op){ case READ: aiocb->aio_lio_opcode = LIO_READ; break; case WRITE: aiocb->aio_lio_opcode = LIO_WRITE; break; default: fprintf(stderr, "start_aio: Invalid operation code\n"); }
// Find a free slot and store. ssize_t slot = allocate_aio_slot (aiocb); if (slot < 0) return -1; size_t index = (size_t) slot;
// setup OS notification methods for this aio // store index!!, not pointer in signal info aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocb->aio_sigevent.sigev_signo = SIGRTMIN; //Proactor에서 사용하는 signal aiocb->aio_sigevent.sigev_value.sival_int = (int)index; //시그널이 발생했을 때 사용할 index
result_list[index]= result; //Store result ptr anyway aiocb_list_cur_size++;
ret_val = execute_aio_calls (aiocb); #ifdef PROACTOR_DEBUG printf("ret_val from execute_aio_calls : %d\n", ret_val); #endif switch (ret_val){ case 0: // started OK aiocb_list[index] = aiocb; //요청을 처리한 aiocb를 aiocb_list에 저장해 놓았다가 signal_handler에서 처리 return 0; case 1: // OS AIO queue overflow num_deferred_aiocb ++; return 0;
default: // Invalid request, there is no point break; // to start it later } result_list[index] = 0; aiocb_list_cur_size--; return -1; }
/** * @author 박학선 * @param aiocb * @retval 0 AIO was started successfully * @retval 1 AIO was not started, OS AIO queue overflow * @retval -1 AIO was not started, other errors * @brief 파일의 미디어 트랙에서 aio_read, aio_write를 실행!! */ int execute_aio_calls (struct aiocb * aiocb) { int ret_val;