/************************************************************************ * * The MEMO Package * * There are two files, * * memo.h contains the declarations needed to access the memo * package. * * memo.c contains the routines in the memo package. * * The datatypes and routines provided by the package are as follows: * * typedef ???? * MEMO; * a MEMO is a pointer to a block of dynamic storage. *************************************************************************/ typedef void *MEMO; typedef unsigned long int SYMBOL; #define NUM_X 3 typedef struct Folder_Name { SYMBOL S; unsigned long int X[NUM_X]; } FOLDER_NAME; /************************************************************************ * memo_init() * * Memo_init initializes the memo system. (On the Encore, * memo_init calls share_malloc_init.) The call should be first * in main(). * ************************************************************************/ void memo_init(void); /************************************************************************ * void memo_exec(int ,int,char **) * * * * This forks num_workers+1 processes. The main process, which executed * this procedure, is assigned the number 0 and executes the procedure * "boss(argc,argv)". The worker processes are assigned the numbers * 1 through num_workers and execute procedure "worker()". * ************************************************************************/ void memo_exec(int,int,char **); /************************************************************************ * void memo_write(FOLDER_NAME ,char *,int ) * * * Memo_write puts a memo into a shared queue named by the string * key. The contents of the memo are the len bytes beginning at * address block_addr. *************************************************************************/ void memo_write(FOLDER_NAME,char *,int); /*********************************************************************** * void memo_write_delayed(FOLDER_NAME ,FOLDER_NAME,char *,int) * * * Memo_write_delayed behaves like memo_write(key2,block_addr,len) with * the following difference: although memo_write_delayed returns * immediately, the memo is not actually delivered until one or * more memos are present in the folder named key1. * *************************************************************************/ void memo_write_delayed(FOLDER_NAME,FOLDER_NAME,char *,int); /************************************************************************ * MEMO memo_get(FOLDER_NAME) * * Memo_get gets a pointer to a memo removed from the shared * queue named by string key. The length of the body of the memo * can be found by calling memo_len(). Memo_get blocks until there * is a memo present in the queue. The memo is removed from the * queue. To access the body of the memo, do something like: * struct something *p; * ... * p = (struct something *)memo_get(whatever); * ... *************************************************************************/ #ifndef SEQUENTIAL MEMO memo_get(FOLDER_NAME); #endif /************************************************************************ * MEMO memo_get_copy(FOLDER_NAME) * * Memo_get_copy is the same as memo_get except that the memo * is not removed from the queue. *************************************************************************/ #ifndef SEQUENTIAL MEMO memo_get_copy(FOLDER_NAME); #endif /************************************************************************ * MEMO memo_get_skip(FOLDER_NAME) * * Memo_get_skip is the same as memo_get except that if there * is no memo immediately available, it does not block, but returns * a NULL pointer. *************************************************************************/ MEMO memo_get_skip(FOLDER_NAME); /************************************************************************ * MEMO memo_get_copy_skip(FOLDER_NAME) * * Memo_get_copy_skip is the same as memo_get_copy except that if there * is no memo immediately available, it does not block, but returns * a NULL pointer. *************************************************************************/ MEMO memo_get_copy_skip(FOLDER_NAME); /************************************************************************ * MEMO memo_alt(FOLDER_NAME *,int,int *) * * This is a version of memo_get that will return a memo taken * from one or a list of alternative queues. Parameter key_list * points to an array of folder names. As with memo_get, memo_alt blocks * until a memo can be returned. Memo_alt removes the memo from its * folder. Result parameter 'which' will be set to indicate the position * of the folder name in key_list. To find out the name of the queue * from which the memo was removed, use key_list[which] or memo_key(). * An example: * * FOLDER_NAME keys[2],key; * MEMO m; * int i; * ... * m = memo_alt(keys,2,&i); * key = keys[i]; * switch (i) { * ... * } * ... *************************************************************************/ #ifndef SEQUENTIAL MEMO memo_alt(FOLDER_NAME *,int,int *); #endif /************************************************************************ * MEMO memo_alt_skip(FOLDER_NAME *,int,int *) * * This is a version of memo_get_skip that will return a memo * taken from one or a list of alternative queues. Parameter * key_list points to an array of folder names. As with memo_get_skip, * memo_alt_skip returns NULL if a memo can not immediately be returned. * Memo_alt_skip removes the memo from its queue. Result parameter * 'which' will be set to indicate the position of the folder name * in key_list. If no memo was found, 'which' is set to -1. * To find out the name of the queue from which the * memo was removed, use key_list[which] or memo_key(). An * example: * * FOLDER_NAME keys[3]; * MEMO m; * int i; * ... * m = memo_alt_skip(keys,3,&i); * if (m!=NULL) { * switch (i) { * ... * } * } * ... *************************************************************************/ MEMO memo_alt_skip(FOLDER_NAME *,int,int *); /************************************************************************ * MEMO memo_strict_alt_skip(FOLDER_NAME *,int,int *) * * This is a version of memo_get_skip that will return a memo taken * from one or a list of alternative queues. Parameter key_list * points to an array of folder names. As with memo_get_skip, * memo_strict_alt_skip returns NULL if a memo can not immediately * be returned. Memo_strict_alt_skip removes the memo from its * queue. Result parameter 'which' will be set to indicate the * position of the folder name in key_list. If no memo was found, * 'which' is set to -1. To find out the name of the queue from * which the memo was removed, use key_list[which] or memo_key(). * * * If memo_strict_alt_skip returns NULL, then there was some * instant of time between the call and the return during which * there was no memo in any of the folders mentioned in key_list. * *************************************************************************/ MEMO memo_strict_alt_skip(FOLDER_NAME *,int,int *); /************************************************************************ * void memo_free(MEMO) * * This procedure frees the storage that a memo occupies. Use * it instead of free or share_free for MEMO pointers. *************************************************************************/ void memo_free(MEMO); /************************************************************************ * int memo_len(MEMO) * * This function returns the length of the body of a memo. *************************************************************************/ int memo_len(MEMO); /************************************************************************ * FOLDER_NAME *memo_key(MEMO) * * This function returns a pointer to the name of the queue a * memo was removed or copied from by memo_get... or memo_alt.... * Do not change this string, try to free it, or try to use it * after calling memo_free(memo). *************************************************************************/ FOLDER_NAME *memo_key(MEMO); /************************************************************************ * int memo_get_my_id(void) * * This function returns an integer value representing the id * of the process assigned by the memo system. *************************************************************************/ int memo_get_my_id(void); /************************************************************************ * int memo_num_workers(void) * * This function returns an integer value indicating the total * number of workers started by memo_init(). *************************************************************************/ int memo_num_workers(void); /************************************************************************ * SYMBOL memo_symbol(void) * This function generates a unique SYMBOL. It will not be the * same as the value returned by any other call to memo_symbol(), nor to * any "small" integer (unless the system has run for a very long * time). *************************************************************************/ SYMBOL memo_symbol(void); /************************************************************************ * unsigned long int memo_clock(void) * * This function returns an integer value indicating the * raw value of the system clock. *************************************************************************/ unsigned long int memo_clock(void); /************************************************************************ * void memo_put(FOLDER_NAME,MEMO) * * This is the same as memo_write, except that the already * existing memo structure is used, rather than a new one being * created. *************************************************************************/ void memo_put(FOLDER_NAME,MEMO); /************************************************************************ * void memo_put_delayed(FOLDER_NAME, FOLDER_NAME,MEMO) * * Memo_put_delayed behaves like memo_put(key2,memo) with the * following difference: although memo_put_delayed returns * immediately, the memo is not actually delivered until one or more * memos are present in the folder named key1. *************************************************************************/ void memo_put_delayed(FOLDER_NAME,FOLDER_NAME,MEMO); /************************************************************************ * MEMO memo_alloc(int) * * This routine allocates a MEMO structure of the specified * length. It can be used to avoid double copying, first into a user * buffer and then into a memo. It should be sent by calling * memo_put or memo_put_delayed. *************************************************************************/ MEMO memo_alloc(int); /************************************************************************ * void memo_replace(MEMO) * * This procedure replaces the memo in the folder it was taken * from. It is undefined if the memo was created by memo_alloc. *************************************************************************/ void memo_replace(MEMO); /************************************************************************ * int memo_present(FOLDER_NAME) * * This function returns TRUE (non-zero) if there is a memo present * in the folder named by key and FALSE (zero) otherwise. Viewed another * way, memo_present returns TRUE if memo_get_skip would have returned * a memo and FALSE if it wouldn't. *************************************************************************/ int memo_present(FOLDER_NAME);