Path: utzoo!utgpu!attcan!uunet!lll-winken!lll-lcc!ames!pasteur!ucbvax!decwrl!labrea!rutgers!att!lzaz!hcj From: hcj@lzaz.ATT.COM (HC Johnson) Newsgroups: comp.os.minix Subject: mini_send, should it lock()? Keywords: mini_send Message-ID: <352@lzaz.ATT.COM> Date: 6 Jan 89 15:43:55 GMT Organization: AT&T ISL Lincroft NJ USA Lines: 71 The following is a fragment of code from kernel/proc.c in MINIX/ST. It is probably the same as PC 1.3. It seems to me that this code needs to use lock() and restore() to protect the proc table entry of the receiving process (in effect a global being hit be reentrant code). /*===================================================================* * mini_send * *===================================================================*/ PUBLIC int mini_send(caller, dest, m_ptr) ... CODE DELETED ... /* Check to see if 'dest' is blocked waiting for this message. */ if ( (dest_ptr->p_flags & RECEIVING) && (dest_ptr->p_flags & SENDING) == 0 && (dest_ptr->p_getfrom == ANY || dest_ptr->p_getfrom == caller) ) { /* Destination is indeed waiting for this message. */ CopyMess(caller, caller_ptr, m_ptr, dest_ptr, dest_ptr->p_messbuf); dest_ptr->p_flags &= ~RECEIVING; /* deblock destination */ if (dest_ptr->p_flags == 0) ready(dest_ptr); } else { /* Destination is not waiting. Block and queue caller. */ if (caller == HARDWARE) { if (dest == CLOCK) lost_ticks++; #ifdef NEEDED else if (task_mess[-dest]) printf("interrupt for task %d lost\n", dest); #endif else task_mess[-dest] = m_ptr; /* record message pointer */ return(E_OVERRUN); } ... CODE DELETED ... } return(OK); } Consider the following example. 1. a task, such as rs232 is waiting for a message from anyone. 2. a user process issues a read which : a. sends a message to FS b. FS sends a message to rs232. 3. to send a message, FS has called mini_send and has progressed thru the line : CopyMess(caller, caller_ptr, m_ptr, dest_ptr, dest_ptr->p_messbuf); 4. Now before the next line: dest_ptr->p_flags &= ~RECEIVING; /* deblock destination */ can be executed, an interrupt occurs from the rs232 line which calls interrupt(RS232,...). 5. interrupt calls mini_send, which finds the process rs232 is still receiving and copies its message into the receiver buffer at CopyMess(caller, caller_ptr, m_ptr, dest_ptr, dest_ptr->p_messbuf); and continues to completion. 6. the original caller to mini_send is resumed, who also completes, but his MESSAGE has been OVERWRITTEN by the interrupt message. 7. the original user process is now in an infinite wait, awaiting completion of a send that never occurred. OK, am I right? Or how does it work with using lock()? Howard C. Johnson ATT Bell Labs ...lzaz!hcj