- Timestamp:
- Nov 1, 2018, 12:48:51 PM (6 years ago)
- Location:
- trunk/libs
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libs/libalmosmkh/almosmkh.c
r580 r589 79 79 } 80 80 81 ////////////////////////////////// 82 int place_fork( unsigned int cxy ) 83 { 84 return hal_user_syscall( SYS_PLACE_FORK, 85 (reg_t)cxy, 0, 0, 0 ); 86 } 87 81 88 ///////////////////////////////// 82 89 int utls( unsigned int operation, … … 223 230 224 231 ///////////////////////////////////////////////// 225 int display_cluster_processes( unsigned int cxy ) 232 int display_cluster_processes( unsigned int cxy, 233 unsigned int owned ) 226 234 { 227 235 return hal_user_syscall( SYS_DISPLAY, 228 236 DISPLAY_CLUSTER_PROCESSES, 229 (reg_t)cxy, 0, 0 ); 237 (reg_t)cxy, 238 (reg_t)owned, 0 ); 230 239 } 231 240 … … 304 313 "t : display on TXT0 process decriptors attached to TXT[tid]\n" 305 314 "b : display on TXT0 busylocks taken by thread[pid,trdid]\n" 315 "q : display on TXT0 DQDT state\n" 306 316 "y : activate/desactivate trace for core[cxy,lid]\n" 307 317 "x : force calling process to exit\n" … … 313 323 printf("p / cxy = "); 314 324 cxy = get_uint32(); 315 display_cluster_processes( cxy );325 display_cluster_processes( cxy , 0 ); 316 326 } 317 327 else if( cmd == 's' ) … … 336 346 txt = get_uint32(); 337 347 display_txt_processes( txt ); 348 } 349 else if( cmd == 'q' ) 350 { 351 printf("q\n"); 352 display_dqdt(); 338 353 } 339 354 else if( cmd == 'y' ) -
trunk/libs/libalmosmkh/almosmkh.h
r580 r589 39 39 40 40 /*************************************************************************************** 41 * This function is used to give the process identified by the <pid> argument the42 * exclusiveownership of its TXT terminal.41 * This syscall gives the process identified by the <pid> argument the exclusive 42 * ownership of its TXT terminal. 43 43 *************************************************************************************** 44 44 * @ pid : process identifier. … … 48 48 49 49 /*************************************************************************************** 50 * This functionstores in the buffer identified by the <owner> argument a non zero50 * This syscall stores in the buffer identified by the <owner> argument a non zero 51 51 * value when the process identified by the <pid> argument is currently the exclusive 52 52 * owner of its TXT terminal. … … 60 60 61 61 /*************************************************************************************** 62 * This functionreturns the hardware platform parameters.62 * This syscall returns the hardware platform parameters. 63 63 *************************************************************************************** 64 64 * @ x_size : [out] number of clusters in a row. … … 72 72 73 73 /*************************************************************************************** 74 * This functionreturns the cluster an local index for the calling core.74 * This syscall returns the cluster an local index for the calling core. 75 75 *************************************************************************************** 76 76 * @ cxy : [out] cluster identifier. … … 90 90 int get_cycle( unsigned long long * cycle ); 91 91 92 /*************************************************************************************** 93 * This function implement the operations related to User Thread Local Storage. 92 /*************************************************************************************** 93 * This syscall allows the calling thread to specify the target cluster for 94 * a subsequent fork(). It must be called for each fork(). 95 *************************************************************************************** 96 * @ cxy : [in] target cluster identifier. 97 * @ return 0 if success / returns -1 if illegal cxy argument. 98 **************************************************************************************/ 99 int place_fork( unsigned int cxy ); 100 101 /*************************************************************************************** 102 * This syscall implements the operations related to User Thread Local Storage. 94 103 *************************************************************************************** 95 104 * @ operation : UTLS operation type as defined in "shared_sycalls.h" file. … … 101 110 102 111 /*************************************************************************************** 103 * This functionreturns an unsigned 32 bits integer from the standard "stdin" stream.112 * This syscall returns an unsigned 32 bits integer from the standard "stdin" stream. 104 113 * Both decimal numbers and hexadecimal numbers (prefixed by 0x) are supported. 105 114 *************************************************************************************** 106 115 * returns the integer value if success / returns -1 if failure. 107 116 **************************************************************************************/ 108 unsigned int get int32( void );117 unsigned int get_uint32( void ); 109 118 110 119 … … 113 122 114 123 /*************************************************************************************** 115 * This debug functiondisplays on the kernel terminal TXT0124 * This debug syscall displays on the kernel terminal TXT0 116 125 * the thread / process / core identifiers, the current cycle, plus a user defined 117 126 * message as specified by the <string> argument. … … 132 141 133 142 /*************************************************************************************** 134 * This debug functiondisplays on the kernel terminal TXT0143 * This debug syscall displays on the kernel terminal TXT0 135 144 * the state of the core scheduler identified by the <cxy> and <lid> arguments. 136 145 * It can be called by any thread running in any cluster. … … 144 153 145 154 /*************************************************************************************** 146 * This debug functiondisplays on the kernel terminal TXT0155 * This debug syscall displays on the kernel terminal TXT0 147 156 * the list of process registered in a given cluster identified by the <cxy> argument. 157 * Only the owned processes are displayed when the <owned> argument is non zero. 148 158 * It can be called by any thread running in any cluster. 149 159 *************************************************************************************** 150 160 * @ cxy : [in] target cluster identifier. 161 * @ owned : [in] only owned processes if non zero. 151 162 * @ return 0 if success / return -1 if illegal argument. 152 163 **************************************************************************************/ 153 int display_cluster_processes( unsigned int cxy ); 154 155 /*************************************************************************************** 156 * This debug function displays on the kernel terminal TXT0 164 int display_cluster_processes( unsigned int cxy, 165 unsigned int owned ); 166 167 /*************************************************************************************** 168 * This debug syscall displays on the kernel terminal TXT0 157 169 * the list of processes attached to a given TXT channel. 158 170 * It can be called by any thread running in any cluster. … … 164 176 165 177 /*************************************************************************************** 166 * This debug functiondisplays on the kernel terminal TXT0178 * This debug syscall displays on the kernel terminal TXT0 167 179 * the list of channel devices available in the architecture. 168 180 * It can be called by any thread running in any cluster. … … 173 185 174 186 /*************************************************************************************** 175 * This debug functiondisplays on the kernel terminal TXT0187 * This debug syscall displays on the kernel terminal TXT0 176 188 * the list of channel device or pseudo-files registered in the VFS cache. 177 189 * It can be called by any thread running in any cluster. … … 182 194 183 195 /*************************************************************************************** 184 * This debug functiondisplays on the kernel terminal TXT0 the current DQDT state.196 * This debug syscall displays on the kernel terminal TXT0 the current DQDT state. 185 197 * It can be called by any thread running in any cluster. 186 198 *************************************************************************************** … … 190 202 191 203 /***************************************************************************************** 192 * This debug functionis used to activate / desactivate the context switches trace204 * This debug syscall is used to activate / desactivate the context switches trace 193 205 * for a core identified by the <cxy> and <lid> arguments. 194 206 * It can be called by any thread running in any cluster. … … 204 216 205 217 /**************************************************************************************** 206 * This blocking functionimplements an user-level interactive debugger that can be218 * This syscall implements an user-level interactive debugger that can be 207 219 * introduced in any user application to display various kernel distributed structures. 208 220 * The supported commands are: -
trunk/libs/mini-libc/signal.h
r449 r589 36 36 * This function associate a specific signal handler to a given signal type. 37 37 * The handlers for the SIGKILL and SIGSTOP signals cannot be redefined. 38 * TODO : this function is not implemented yet. 38 39 ***************************************************************************************** 39 40 * @ sig_id : index defining signal type (from 1 to 31). … … 50 51 * containing threads for the target process. 51 52 * It can be executed by any thread running in any cluster, as this function uses 52 * remote access to traverse the list of process copies stored in the owner cluster, 53 * and the RPC_SIGNAL_RISE to signal the remote threads. 53 * remote access to traverse the list of process copies stored in the owner cluster. 54 54 * This function does nothing for (sig_id == 0). This can be used to check process pid. 55 * TODO : This first implementation supports only SIGKILL / SIGSTOP / SIGCONT values. 55 * The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored. 56 * TODO : only SIGKILL / SIGSTOP / SIGCONT values. 56 57 ***************************************************************************************** 57 58 * @ pid : target process identifier. -
trunk/libs/mini-libc/stdlib.c
r476 r589 120 120 } 121 121 122 ////////// 122 //////////////// 123 123 int rand( void ) 124 124 { -
trunk/libs/mini-libc/unistd.c
r476 r589 26 26 #include <hal_user.h> 27 27 #include <syscalls_numbers.h> 28 #include <shared_signal.h> 29 30 ////////////////////////////////// 31 unsigned alarm( unsigned seconds ) 32 { 33 return hal_user_syscall( SYS_ALARM, 34 (reg_t)seconds, 0, 0, 0 ); 35 } 36 37 ////////////////////////////////// 38 int chdir( const char * pathname ) 39 { 40 return hal_user_syscall( SYS_CHDIR, 41 (reg_t)pathname, 0, 0, 0 ); 42 } 43 44 /////////////////// 45 int close( int fd ) 46 { 47 return hal_user_syscall( SYS_CLOSE, 48 (reg_t)fd, 0, 0, 0 ); 49 } 50 51 /////////////////////////// 52 int execve( char * pathname, 53 char ** argv, 54 char ** envp ) 55 { 56 return hal_user_syscall( SYS_EXEC, 57 (reg_t)pathname, 58 (reg_t)argv, 59 (reg_t)envp, 0 ); 60 } 61 62 //////////////// 63 int fork( void ) 64 { 65 return hal_user_syscall( SYS_FORK, 0, 0, 0, 0 ); 66 } 28 67 29 68 ///////////////////////////// … … 35 74 (reg_t)bytes, 0, 0 ); 36 75 } 76 77 //////////// 78 int getpid( void ) 79 { 80 return hal_user_syscall( SYS_GETPID, 0, 0, 0, 0 ); 81 } 82 83 /////////////////// 84 int isatty(int fd ) 85 { 86 return hal_user_syscall( SYS_ISATTY, 87 (reg_t)fd, 0, 0, 0 ); 88 } 89 90 /////////////////////////// 91 int lseek( int fd, 92 unsigned int offset, 93 int whence ) 94 { 95 return hal_user_syscall( SYS_LSEEK, 96 (reg_t)fd, 97 (reg_t)offset, 98 (reg_t)whence, 0 ); 99 } 100 101 ///////////////// 102 int pause( void ) 103 { 104 return hal_user_syscall( SYS_KILL, 105 getpid(), 106 SIGSTOP, 0, 0 ); 107 } 108 109 ///////////////////// 110 int pipe( int fd[2] ) 111 { 112 return hal_user_syscall( SYS_PIPE, 113 (reg_t)fd, 0, 0, 0 ); 114 } 115 37 116 ////////////////////////// 38 117 int read( int fd, … … 44 123 (reg_t)buf, 45 124 (reg_t)count, 0 ); 125 } 126 127 //////////////////////////// 128 int rmdir( char * pathname ) 129 { 130 return hal_user_syscall( SYS_RMDIR, 131 (reg_t)pathname, 0, 0, 0 ); 132 } 133 134 /////////////////////////////////// 135 int unlink( const char * pathname ) 136 { 137 return hal_user_syscall( SYS_UNLINK, 138 (reg_t)pathname, 0, 0, 0 ); 46 139 } 47 140 … … 57 150 } 58 151 59 ///////////////////////////60 int lseek( int fd,61 unsigned int offset,62 int whence )63 {64 return hal_user_syscall( SYS_LSEEK,65 (reg_t)fd,66 (reg_t)offset,67 (reg_t)whence, 0 );68 }69 70 ///////////////////71 int close( int fd )72 {73 return hal_user_syscall( SYS_CLOSE,74 (reg_t)fd, 0, 0, 0 );75 }76 77 /////////////////////78 int pipe( int fd[2] )79 {80 return hal_user_syscall( SYS_PIPE,81 (reg_t)fd, 0, 0, 0 );82 }83 84 //////////////////////////////////85 int chdir( const char * pathname )86 {87 return hal_user_syscall( SYS_CHDIR,88 (reg_t)pathname, 0, 0, 0 );89 }90 91 ////////////////////////////92 int rmdir( char * pathname )93 {94 return hal_user_syscall( SYS_RMDIR,95 (reg_t)pathname, 0, 0, 0 );96 }97 98 //////////99 int fork( void )100 {101 return hal_user_syscall( SYS_FORK, 0, 0, 0, 0 );102 }103 104 ////////////105 int getpid( void )106 {107 return hal_user_syscall( SYS_GETPID, 0, 0, 0, 0 );108 }109 152 110 153 111 ///////////////////////////112 int execve( char * pathname,113 char ** argv,114 char ** envp )115 {116 return hal_user_syscall( SYS_EXEC,117 (reg_t)pathname,118 (reg_t)argv,119 (reg_t)envp, 0 );120 }121 122 123 ///////////////////////////////////124 int unlink( const char * pathname )125 {126 return hal_user_syscall( SYS_UNLINK,127 (reg_t)pathname, 0, 0, 0 );128 }129 130 ///////////////////131 int isatty(int fd )132 {133 return hal_user_syscall( SYS_ISATTY,134 (reg_t)fd, 0, 0, 0 );135 }136 137 //////////////////////////////////138 unsigned alarm( unsigned seconds )139 {140 return hal_user_syscall( SYS_ALARM,141 (reg_t)seconds, 0, 0, 0 );142 }143 144 -
trunk/libs/mini-libc/unistd.h
r476 r589 26 26 27 27 /***************************************************************************************** 28 * This file defines the user level , memory mapping related <mman> library.28 * This file defines the user level <unistd> library. 29 29 * All these functions make a system call to access the kernel structures. 30 30 * The user/kernel shared structures and mnemonics are defined in … … 35 35 36 36 /***************************************************************************************** 37 * This function returns the pathname of the current working directory. 38 ***************************************************************************************** 39 * buf : buffer addres in user space. 40 * nbytes : user buffer size in bytes. 41 * @ return 0 if success / returns -1 if failure. 42 ****************************************************************************************/ 43 int getcwd( char * buf, 44 unsigned int nbytes ); 45 46 /***************************************************************************************** 47 * This function read bytes from an open file identified by the <fd> file descriptor. 48 * This file can be a regular file or a character oriented device. 49 ***************************************************************************************** 50 * @ fd : open file index in fd_array. 51 * @ buf : buffer virtual address in user space. 52 * @ count : number of bytes. 53 * @ return number of bytes actually read if success / returns -1 if failure. 54 ****************************************************************************************/ 55 int read( int fd, 56 void * buf, 57 unsigned int count ); 58 59 /***************************************************************************************** 60 * This function writes bytes to an open file identified by the <fd> file descriptor. 61 * This file can be a regular file or character oriented device. 62 ***************************************************************************************** 63 * @ fd : open file index in fd_array. 64 * @ buf : buffer virtual address in user space. 65 * @ count : number of bytes. 66 * @ return number of bytes actually written if success / returns -1 if failure. 67 ****************************************************************************************/ 68 int write( int fd, 69 const void * buf, 70 unsigned int count ); 71 72 /***************************************************************************************** 73 * This function repositions the offset of the file descriptor identified by <file_id>, 74 * according to the operation type defined by the <whence> argument. 75 ***************************************************************************************** 76 * @ fd : open file index in fd_array. 77 * @ offset : used to compute new offset value. 78 * @ whence : operation type (SEEK_SET / SEEK_CUR / SEEK_END defined in syscalls.h) 79 * @ return 0 if success / returns -1 if failure. 80 ****************************************************************************************/ 81 int lseek( int fd, 82 unsigned int offset, 83 int whence ); 37 * This function sets a timer to deliver the signal SIGALRM to the calling process, 38 * after the specified number of seconds. 39 * If an alarm has already been set with alarm() but has not been delivered, 40 * another call to alarm() will supersede the prior call. 41 * The request alarm(0) cancels the current alarm and the signal will not be delivered. 42 ***************************************************************************************** 43 * @ seconds : number of seconds. 44 * @ returns the amount of time left on the timer from a previous call to alarm(). 45 * If no alarm is currently set, the return value is 0. 46 ****************************************************************************************/ 47 unsigned alarm( unsigned seconds ); 48 49 /***************************************************************************************** 50 * This function change the current working directory in reference process descriptor. 51 ***************************************************************************************** 52 * @ pathname : pathname (can be relative or absolute). 53 * @ return 0 if success / returns -1 if failure. 54 ****************************************************************************************/ 55 int chdir( const char * pathname ); 84 56 85 57 /***************************************************************************************** 86 58 * This function release the memory allocated for the file descriptor identified by 87 * the <file_id> argument, and remove the fd array_entry in all copies of the process 88 * descriptor. 59 * the <fd> argument, and remove the fd array_entry in all process descriptor copies. 89 60 ***************************************************************************************** 90 61 * @ fd : file descriptor index in fd_array. … … 92 63 ****************************************************************************************/ 93 64 int close( int fd ); 94 95 /*****************************************************************************************96 * This function removes a directory entry identified by the <pathname> from the97 * directory, and decrement the link count of the file referenced by the link.98 * If the link count reduces to zero, and no process has the file open, then all resources99 * associated with the file are released. If one or more process have the file open when100 * the last link is removed, the link is removed, but the removal of the file is delayed101 * until all references to it have been closed.102 *****************************************************************************************103 * @ pathname : pathname (can be relative or absolute).104 * @ return 0 if success / returns -1 if failure.105 ****************************************************************************************/106 int unlink( const char * pathname );107 108 /*****************************************************************************************109 * This function creates in the calling thread cluster an unnamed pipe, and two110 * (read and write) file descriptors to access this pipe. The calling function must pass111 * the pointer on the fd[] array.112 * TODO not implemented yet...113 *****************************************************************************************114 * @ fd[0] : [out] read only file descriptor index.115 * @ fd[1] : [out] write only file descriptor index.116 * @ return 0 if success / return -1 if failure.117 ****************************************************************************************/118 int pipe( int fd[2] );119 120 /*****************************************************************************************121 * This function change the current working directory in reference process descriptor.122 *****************************************************************************************123 * @ pathname : pathname (can be relative or absolute).124 * @ return 0 if success / returns -1 if failure.125 ****************************************************************************************/126 int chdir( const char * pathname );127 128 /*****************************************************************************************129 * This function removes a directory file whose name is given by <pathname>.130 * The directory must not have any entries other than `.' and `..'.131 *****************************************************************************************132 * @ pathname : pathname (can be relative or absolute).133 * @ return 0 if success / returns -1 if failure.134 ****************************************************************************************/135 int rmdir( char * pathname );136 137 /*****************************************************************************************138 * This function implement the "fork" system call on the user side.139 * The calling process descriptor (parent process), and the associated thread descriptor140 * are replicated in a - likely - remote cluster, that becomes the new process owner.141 * The child process get a new PID is linked to the parent PID. The child process inherit142 * from the parent process the memory image, and all open files (including the TXT).143 * The child process becomes the TXT terminal owner.144 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be145 * stored in the calling thread descriptor by the specific fork_place() system call.146 * If not, the kernel function makes a query to the DQDT to select the target cluster.147 *****************************************************************************************148 * @ if success, returns child process PID to parent, and return O to child.149 * @ if failure, returns -1 to parent / no child process is created.150 ****************************************************************************************/151 int fork( void );152 65 153 66 /***************************************************************************************** … … 174 87 175 88 /***************************************************************************************** 89 * This function implement the "fork" system call on the user side. 90 * The calling process descriptor (parent process), and the associated thread descriptor 91 * are replicated in a - likely - remote cluster, that becomes the new process owner. 92 * The child process get a new PID is linked to the parent PID. The child process inherit 93 * from the parent process the memory image, and all open files (including the TXT). 94 * The child process becomes the TXT terminal owner. 95 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be 96 * stored in the calling thread descriptor by the specific fork_place() system call. 97 * If not, the kernel function makes a query to the DQDT to select the target cluster. 98 ***************************************************************************************** 99 * @ if success, returns child process PID to parent, and return O to child. 100 * @ if failure, returns -1 to parent / no child process is created. 101 ****************************************************************************************/ 102 int fork( void ); 103 104 /***************************************************************************************** 105 * This function returns the pathname of the current working directory. 106 ***************************************************************************************** 107 * buf : buffer addres in user space. 108 * nbytes : user buffer size in bytes. 109 * @ return 0 if success / returns -1 if failure. 110 ****************************************************************************************/ 111 int getcwd( char * buf, 112 unsigned int nbytes ); 113 114 /***************************************************************************************** 176 115 * This function implements the "getpid" system call on the user side. 177 116 ***************************************************************************************** … … 189 128 190 129 /***************************************************************************************** 191 * This function sets a timer to deliver the signal SIGALRM to the calling process, 192 * after the specified number of seconds. 193 * If an alarm has already been set with alarm() but has not been delivered, 194 * another call to alarm() will supersede the prior call. 195 * The request alarm(0) cancels the current alarm and the signal will not be delivered. 196 ***************************************************************************************** 197 * @ seconds : number of seconds. 198 * @ returns the amount of time left on the timer from a previous call to alarm(). 199 * If no alarm is currently set, the return value is 0. 200 ****************************************************************************************/ 201 unsigned alarm( unsigned seconds ); 130 * This function repositions the offset of the file descriptor identified by <fd>, 131 * according to the operation type defined by the <whence> argument. 132 ***************************************************************************************** 133 * @ fd : open file index in fd_array. 134 * @ offset : used to compute new offset value. 135 * @ whence : operation type (SEEK_SET / SEEK_CUR / SEEK_END) 136 * @ return 0 if success / returns -1 if failure. 137 ****************************************************************************************/ 138 int lseek( int fd, 139 unsigned int offset, 140 int whence ); 141 142 /***************************************************************************************** 143 * This function stops the calling process until any signal is received. 144 ***************************************************************************************** 145 * @ return 0 if success / returns -1 if failure. 146 ****************************************************************************************/ 147 int pause( void ); 148 149 /***************************************************************************************** 150 * This function creates in the calling thread cluster an unnamed pipe, and two 151 * (read and write) file descriptors to access this pipe. The calling function must pass 152 * the pointer on the fd[] array. 153 * TODO not implemented yet... 154 ***************************************************************************************** 155 * @ fd[0] : [out] read only file descriptor index. 156 * @ fd[1] : [out] write only file descriptor index. 157 * @ return 0 if success / return -1 if failure. 158 ****************************************************************************************/ 159 int pipe( int fd[2] ); 160 161 /***************************************************************************************** 162 * This function read bytes from an open file identified by the <fd> file descriptor. 163 * This file can be a regular file or a character oriented device. 164 ***************************************************************************************** 165 * @ fd : open file index in fd_array. 166 * @ buf : buffer virtual address in user space. 167 * @ count : number of bytes. 168 * @ return number of bytes actually read if success / returns -1 if failure. 169 ****************************************************************************************/ 170 int read( int fd, 171 void * buf, 172 unsigned int count ); 173 174 /***************************************************************************************** 175 * This function removes a directory file whose name is given by <pathname>. 176 * The directory must not have any entries other than `.' and `..'. 177 ***************************************************************************************** 178 * @ pathname : pathname (can be relative or absolute). 179 * @ return 0 if success / returns -1 if failure. 180 ****************************************************************************************/ 181 int rmdir( char * pathname ); 182 183 /***************************************************************************************** 184 * This function removes a directory entry identified by the <pathname> from the 185 * directory, and decrement the link count of the file referenced by the link. 186 * If the link count reduces to zero, and no process has the file open, then all resources 187 * associated with the file are released. If one or more process have the file open when 188 * the last link is removed, the link is removed, but the removal of the file is delayed 189 * until all references to it have been closed. 190 ***************************************************************************************** 191 * @ pathname : pathname (can be relative or absolute). 192 * @ return 0 if success / returns -1 if failure. 193 ****************************************************************************************/ 194 int unlink( const char * pathname ); 195 196 /***************************************************************************************** 197 * This function writes bytes to an open file identified by the <fd> file descriptor. 198 * This file can be a regular file or character oriented device. 199 ***************************************************************************************** 200 * @ fd : open file index in fd_array. 201 * @ buf : buffer virtual address in user space. 202 * @ count : number of bytes. 203 * @ return number of bytes actually written if success / returns -1 if failure. 204 ****************************************************************************************/ 205 int write( int fd, 206 const void * buf, 207 unsigned int count ); 202 208 203 209 #endif
Note: See TracChangeset
for help on using the changeset viewer.