Example #1
0
/* Walk through the table and remove all entries which lifetime ended.

   We have a problem here.  To actually remove the entries we must get
   the write-lock.  But since we want to keep the time we have the
   lock as short as possible we cannot simply acquire the lock when we
   start looking for timedout entries.

   Therefore we do it in two stages: first we look for entries which
   must be invalidated and remember them.  Then we get the lock and
   actually remove them.  This is complicated by the way we have to
   free the data structures since some hash table entries share the same
   data.  */
time_t
prune_cache (struct database_dyn *table, time_t now, int fd)
{
  size_t cnt = table->head->module;

  /* If this table is not actually used don't do anything.  */
  if (cnt == 0)
    {
      if (fd != -1)
	{
	  /* Reply to the INVALIDATE initiator.  */
	  int32_t resp = 0;
	  writeall (fd, &resp, sizeof (resp));
	}

      /* No need to do this again anytime soon.  */
      return 24 * 60 * 60;
    }

  /* If we check for the modification of the underlying file we invalidate
     the entries also in this case.  */
  if (table->check_file && now != LONG_MAX)
    {
      struct traced_file *runp = table->traced_files;

      while (runp != NULL)
	{
#ifdef HAVE_INOTIFY
	  if (runp->inotify_descr == -1)
#endif
	    {
	      struct stat64 st;

	      if (stat64 (runp->fname, &st) < 0)
		{
		  char buf[128];
		  /* We cannot stat() the file, disable file checking if the
		     file does not exist.  */
		  dbg_log (_("cannot stat() file `%s': %s"),
			   runp->fname, strerror_r (errno, buf, sizeof (buf)));
		  if (errno == ENOENT)
		    table->check_file = 0;
		}
	      else
		{
		  if (st.st_mtime != table->file_mtime)
		    {
		      /* The file changed.  Invalidate all entries.  */
		      now = LONG_MAX;
		      table->file_mtime = st.st_mtime;
		    }
		}
	    }

	  runp = runp->next;
	}
    }

  /* We run through the table and find values which are not valid anymore.

     Note that for the initial step, finding the entries to be removed,
     we don't need to get any lock.  It is at all timed assured that the
     linked lists are set up correctly and that no second thread prunes
     the cache.  */
  bool *mark;
  size_t memory_needed = cnt * sizeof (bool);
  bool mark_use_alloca;
  if (__builtin_expect (memory_needed <= MAX_STACK_USE, 1))
    {
      mark = alloca (cnt * sizeof (bool));
      memset (mark, '\0', memory_needed);
      mark_use_alloca = true;
    }
  else
    {
      mark = xcalloc (1, memory_needed);
      mark_use_alloca = false;
    }
  size_t first = cnt + 1;
  size_t last = 0;
  char *const data = table->data;
  bool any = false;

  if (__builtin_expect (debug_level > 2, 0))
    dbg_log (_("pruning %s cache; time %ld"),
	     dbnames[table - dbs], (long int) now);

#define NO_TIMEOUT LONG_MAX
  time_t next_timeout = NO_TIMEOUT;
  do
    {
      ref_t run = table->head->array[--cnt];

      while (run != ENDREF)
	{
	  struct hashentry *runp = (struct hashentry *) (data + run);
	  struct datahead *dh = (struct datahead *) (data + runp->packet);

	  /* Some debug support.  */
	  if (__builtin_expect (debug_level > 2, 0))
	    {
	      char buf[INET6_ADDRSTRLEN];
	      const char *str;

	      if (runp->type == GETHOSTBYADDR || runp->type == GETHOSTBYADDRv6)
		{
		  inet_ntop (runp->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
			     data + runp->key, buf, sizeof (buf));
		  str = buf;
		}
	      else
		str = data + runp->key;

	      dbg_log (_("considering %s entry \"%s\", timeout %" PRIu64),
		       serv2str[runp->type], str, dh->timeout);
	    }

	  /* Check whether the entry timed out.  */
	  if (dh->timeout < now)
	    {
	      /* This hash bucket could contain entries which need to
		 be looked at.  */
	      mark[cnt] = true;

	      first = MIN (first, cnt);
	      last = MAX (last, cnt);

	      /* We only have to look at the data of the first entries
		 since the count information is kept in the data part
		 which is shared.  */
	      if (runp->first)
		{

		  /* At this point there are two choices: we reload the
		     value or we discard it.  Do not change NRELOADS if
		     we never not reload the record.  */
		  if ((reload_count != UINT_MAX
		       && __builtin_expect (dh->nreloads >= reload_count, 0))
		      /* We always remove negative entries.  */
		      || dh->notfound
		      /* Discard everything if the user explicitly
			 requests it.  */
		      || now == LONG_MAX)
		    {
		      /* Remove the value.  */
		      dh->usable = false;

		      /* We definitely have some garbage entries now.  */
		      any = true;
		    }
		  else
		    {
		      /* Reload the value.  We do this only for the
			 initially used key, not the additionally
			 added derived value.  */
		      assert (runp->type < LASTREQ
			      && readdfcts[runp->type] != NULL);

		      time_t timeout = readdfcts[runp->type] (table, runp, dh);
		      next_timeout = MIN (next_timeout, timeout);

		      /* If the entry has been replaced, we might need
			 cleanup.  */
		      any |= !dh->usable;
		    }
		}
	    }
	  else
	    {
	      assert (dh->usable);
	      next_timeout = MIN (next_timeout, dh->timeout);
	    }

	  run = runp->next;
	}
    }
  while (cnt > 0);

  if (__builtin_expect (fd != -1, 0))
    {
      /* Reply to the INVALIDATE initiator that the cache has been
	 invalidated.  */
      int32_t resp = 0;
      writeall (fd, &resp, sizeof (resp));
    }

  if (first <= last)
    {
      struct hashentry *head = NULL;

      /* Now we have to get the write lock since we are about to modify
	 the table.  */
      if (__builtin_expect (pthread_rwlock_trywrlock (&table->lock) != 0, 0))
	{
	  ++table->head->wrlockdelayed;
	  pthread_rwlock_wrlock (&table->lock);
	}

      while (first <= last)
	{
	  if (mark[first])
	    {
	      ref_t *old = &table->head->array[first];
	      ref_t run = table->head->array[first];

	      assert (run != ENDREF);
	      do
		{
		  struct hashentry *runp = (struct hashentry *) (data + run);
		  struct datahead *dh
		    = (struct datahead *) (data + runp->packet);

		  if (! dh->usable)
		    {
		      /* We need the list only for debugging but it is
			 more costly to avoid creating the list than
			 doing it.  */
		      runp->dellist = head;
		      head = runp;

		      /* No need for an atomic operation, we have the
			 write lock.  */
		      --table->head->nentries;

		      run = *old = runp->next;
		    }
		  else
		    {
		      old = &runp->next;
		      run = runp->next;
		    }
		}
	      while (run != ENDREF);
	    }

	  ++first;
	}

      /* It's all done.  */
      pthread_rwlock_unlock (&table->lock);

      /* Make sure the data is saved to disk.  */
      if (table->persistent)
	msync (table->head,
	       data + table->head->first_free - (char *) table->head,
	       MS_ASYNC);

      /* One extra pass if we do debugging.  */
      if (__builtin_expect (debug_level > 0, 0))
	{
	  struct hashentry *runp = head;

	  while (runp != NULL)
	    {
	      char buf[INET6_ADDRSTRLEN];
	      const char *str;

	      if (runp->type == GETHOSTBYADDR || runp->type == GETHOSTBYADDRv6)
		{
		  inet_ntop (runp->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
			     data + runp->key, buf, sizeof (buf));
		  str = buf;
		}
	      else
		str = data + runp->key;

	      dbg_log ("remove %s entry \"%s\"", serv2str[runp->type], str);

	      runp = runp->dellist;
	    }
	}
    }

  if (__builtin_expect (! mark_use_alloca, 0))
    free (mark);

  /* Run garbage collection if any entry has been removed or replaced.  */
  if (any)
    gc (table);

  /* If there is no entry in the database and we therefore have no new
     timeout value, tell the caller to wake up in 24 hours.  */
  return next_timeout == NO_TIMEOUT ? 24 * 60 * 60 : next_timeout - now;
}
Example #2
0
void sync_mmap(void)
{
	msync(mmap_shared_dirents_region, mmap_dirents_size, MS_SYNC);
	msync(mmap_shared_num_region, mmap_num_size, MS_SYNC);
}
Example #3
0
void PruTimer::push_block(uint8_t* blockMemory, size_t blockLen, unsigned int unit, unsigned int pathID, unsigned long totalTime) {
	
	if(!ddr_write_location) return;
	
	//Split the block in smaller blocks if needed
	size_t nbBlocks = ceil((blockLen+12)/(FLOAT_T)(ddr_size-12));
	
	size_t blockSize = blockLen / nbBlocks;
	
	//Make sure block size is a multiple of unit
	blockSize = (blockSize/unit) * unit;
	
	if(blockSize*nbBlocks<blockLen)
		nbBlocks++;
	
	assert(blockSize*nbBlocks>=blockLen);
	
	size_t nbStepsWritten = 0;
	
	for(unsigned int i=0;i<nbBlocks;i++) {
		
		uint8_t *blockStart = blockMemory + i*blockSize;
		
		size_t currentBlockSize;
		
		if(i+1<nbBlocks) {
			currentBlockSize = blockSize;
		} else {
			currentBlockSize = blockLen - i*blockSize;
		}
		
		assert(ddr_size>=currentBlockSize+12);
		
		{
			//LOG( "Waiting for " << std::dec << currentBlockSize+12 << " bytes available. Currently: " << getFreeMemory() << std::endl);
			
			std::unique_lock<std::mutex> lk(mutex_memory);
			blockAvailable.wait(lk, [this,currentBlockSize]{ return ddr_size-ddr_mem_used-8>=currentBlockSize+12 || stop; });
			
			if(!ddr_mem || stop) return;
			
			
			//Copy at the right location
			if(ddr_write_location+currentBlockSize+12>ddr_mem_end) {
				//Split into two blocks
				
				//First block size
				size_t maxSize = ddr_mem_end-ddr_write_location-8;
				
				//make sure we are in a multiple of unit size
				maxSize = (maxSize/unit)*unit;
				
				bool resetDDR = false;
				
				if(!maxSize) {
					//Dont have the size for a single command! Reset the DDR
					//LOG( "No more space at 0x" << std::hex << ddr_write_location << ". Resetting DDR..." << std::endl);
					uint32_t nb;
	
					//First put 0 for next command
					nb=0;
					memcpy(ddr_mem, &nb, sizeof(nb));
					msync(ddr_mem, sizeof(nb), MS_SYNC);
					
					nb=DDR_MAGIC;
					memcpy(ddr_write_location, &nb, sizeof(nb));
					
					msync(ddr_write_location, sizeof(nb), MS_SYNC);
					
					//It is now the begining
					ddr_write_location=ddr_mem;
					
					resetDDR = true;
					
					if(ddr_write_location+currentBlockSize+12>ddr_mem_end) {
						maxSize = ddr_mem_end-ddr_write_location-8;
						
						//make sure we are in a multiple of unit size
						maxSize = (maxSize/unit)*unit;
					} else {
						maxSize = currentBlockSize;
					}
					
					
				}
				
				assert(maxSize>0);
				unsigned long t = currentBlockSize-maxSize > 0 ? totalTime/2 : totalTime;
				blocksID.emplace(maxSize+4,t); //FIXME: TotalTime is not /2 but doesn't it to be precise to make it work...
				
				ddr_mem_used+=maxSize+4;
				totalQueuedMovesTime += t;
				
				//First copy the data
				//LOG( std::dec << "Writing " << maxSize+4 << " bytes to 0x" << std::hex << (unsigned long)ddr_write_location << std::endl);
				
				memcpy(ddr_write_location+4, blockStart, maxSize);
				
				//Then write on the next free area OF DDR MAGIC
				uint32_t nb;
				
				if(resetDDR) {
					nb=0;
				} else {
					nb=DDR_MAGIC;
				}
				
				assert(ddr_write_location+maxSize+sizeof(nb)*2<=ddr_mem_end);
				
				memcpy(ddr_write_location+maxSize+sizeof(nb), &nb, sizeof(nb));
				
				if(!resetDDR) {
					nb=0;
					memcpy(ddr_mem, &nb, sizeof(nb));
					msync(ddr_mem, sizeof(nb), MS_SYNC);
				}
				
				//Need it?
				msync(ddr_write_location+4, maxSize+4, MS_SYNC);
				
				//Then signal how much data we have to the PRU
				nb = (uint32_t)maxSize/unit;
				
				nbStepsWritten+=nb;
				
				memcpy(ddr_write_location, &nb, sizeof(nb));
				
				//LOG( "Written " << std::dec << maxSize << " bytes of stepper commands." << std::endl);
				
				//LOG( "Remaining free memory: " << std::dec << ddr_size-ddr_mem_used << " bytes." << std::endl);
				
				msync(ddr_write_location, 4, MS_SYNC);
				
				
				if(resetDDR) {
					ddr_write_location+=maxSize+sizeof(nb);;
				} else {
					//It is now the begining
					ddr_write_location=ddr_mem;
				}
				
				
				size_t remainingSize = currentBlockSize-maxSize;
				
				
				
				if(remainingSize) {
					
					assert(remainingSize == (remainingSize/unit)*unit);

					
					blocksID.emplace(remainingSize+4,totalTime-t); //FIXME: TotalTime is not /2 but doesn't it to be precise to make it work...
					
					ddr_mem_used+=remainingSize+4;
					totalQueuedMovesTime += totalTime-t;
					

					assert(ddr_write_location+remainingSize+sizeof(nb)*2<=ddr_mem_end);
					
					//First copy the data
					//LOG( std::dec << "Writing " << remainingSize+4 << " bytes to 0x" << std::hex << (unsigned long)ddr_write_location << std::endl);
					
					//LOG( std::hex << "Writing second part of data to 0x" << (unsigned long)ddr_write_location+4 << std::endl);
					
					memcpy(ddr_write_location+4, blockStart+maxSize, remainingSize);
					
					//Then write on the next free area OF DDR MAGIC
					uint32_t nb = 0;
					
					assert(ddr_write_location+remainingSize+sizeof(nb)*2<=ddr_mem_end);
					
					memcpy(ddr_write_location+remainingSize+sizeof(nb), &nb, sizeof(nb));
					
					//Need it?
					msync(ddr_write_location+sizeof(nb), remainingSize, MS_SYNC);
					
					//Then signal how much data we have to the PRU
					nb = (uint32_t)remainingSize/unit;
					nbStepsWritten+=nb;
					//LOG( std::hex << "Writing nb command to 0x" << (unsigned long)ddr_write_location << std::endl);
					memcpy(ddr_write_location, &nb, sizeof(nb));
					
					//LOG( "Written " << std::dec << remainingSize << " bytes of stepper commands." << std::endl);
					
					//LOG( "Remaining free memory: " << std::dec << ddr_size-ddr_mem_used << " bytes." << std::endl);
					
					msync(ddr_write_location, sizeof(nb), MS_SYNC);
					
					//It is now the begining
					ddr_write_location+=remainingSize+sizeof(nb);
					
				}
				
				
				
			} else {
				
				blocksID.emplace(currentBlockSize+4,totalTime); //FIXME: TotalTime is not /2 but doesn't it to be precise to make it work...
				
				ddr_mem_used+=currentBlockSize+4;
				totalQueuedMovesTime += totalTime;


				//First copy the data
				//LOG( std::hex << "Writing data to 0x" << (unsigned long)ddr_write_location+4 << std::endl);
				//LOG( std::dec << "Writing " << currentBlockSize+4 << " bytes to 0x" << std::hex << (unsigned long)ddr_write_location << std::endl);
				
				memcpy(ddr_write_location+4, blockStart, currentBlockSize);
				
				//Then write on the next free area than there is no command to execute
				uint32_t nb = 0;
				
				assert(ddr_write_location+currentBlockSize+sizeof(nb)*2<=ddr_mem_end);
				memcpy(ddr_write_location+currentBlockSize+sizeof(nb), &nb, sizeof(nb));
				//Need it?
				msync(ddr_write_location+sizeof(nb), currentBlockSize, MS_SYNC);
				//Then signal how much data we have to the PRU
				nb = (uint32_t)currentBlockSize/unit;
				nbStepsWritten+=nb;
				//LOG( std::hex << "Writing nb command to 0x" << (unsigned long)ddr_write_location << std::endl);
				memcpy(ddr_write_location, &nb, sizeof(nb));
				
				//LOG( "Written " << std::dec << currentBlockSize << " bytes of stepper commands." << std::endl);
				
				//LOG( "Remaining free memory: " << std::dec << ddr_size-ddr_mem_used << " bytes." << std::endl);
				
				ddr_write_location+=currentBlockSize+sizeof(nb);
				
				msync(ddr_write_location, sizeof(nb), MS_SYNC);
				
			}
			
			
		}
	}
	
	assert(nbStepsWritten == blockLen/unit);
	
}
Example #4
0
int main(int argc, const char *argv[])
{
	int i;
	int count = 0;
	int fd;
	int ret;

	/* Open a file for writing.
  *  - Creating the file if it doesn't exist.
  *  - Truncating it to 0 size if it already exists. (not really needed)
  *
  * Note: "O_WRONLY" mode is not sufficient when mmaping.
  */
loop:
	fd = ashmem_create_region("zzytest", LEN);
	if (fd < 0)
	{
	    perror("Error opening file for writing");
	    exit(EXIT_FAILURE);
	}

	char ash_name[ASHMEM_NAME_LEN] = {0};
	ret = ioctl(fd, ASHMEM_GET_NAME, ash_name);
	if(ret >= 0) {
		printf("ash_name=%s\n", ash_name);	
	}

	// Now the file is ready to be mmapped.
	char *map = mmap(0, LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (map == MAP_FAILED)
	{
	    close(fd);
	    perror("Error mmapping the file");
	    exit(EXIT_FAILURE);
	}
	
	char s[256], name[256];
	memset(s, 0, 256);
	memset(name, 0, 256);
	snprintf(s, 255, "/proc/%d/fd/%d", getpid(), fd);
	readlink(s, name, 255);
	printf("Succeeded to mmap program binaries. File descriptor is %d, and path is %s\n", fd, name);

	printf("memset data\n");
	memset(map, '1', LEN-1);
	//printf("%c\n", map[count%textsize]);
	
	// Write it now to disk
	if (msync(map, LEN, MS_SYNC) == -1)
	{
	    perror("Could not sync the file to disk");
	}
	sleep(1);
	printf("count=%d\n", count++);
	printf("fd=%d\n", fd);
	printf("map=%x\n", map);
	
	// close fd
	close(fd);
	
	// Don't forget to free the mmapped memory
	#if 1
	if (munmap(map, LEN) == -1)
	{
	    close(fd);
	    perror("Error un-mmapping the file");
	    exit(EXIT_FAILURE);
	}
	#endif
goto loop;

	return 0;
}
Example #5
0
/* Finds NaCl/Chromium shm memory using external handler.
 * Reply must be in the form PID:file */
struct cache_entry* find_shm(uint64_t paddr, uint64_t sig, size_t length) {
    struct cache_entry* entry = NULL;

    /* Find entry in cache */
    if (cache[0].paddr == paddr) {
        entry = &cache[0];
    } else if (cache[1].paddr == paddr) {
        entry = &cache[1];
    } else {
        /* Not found: erase an existing entry. */
        entry = &cache[next_entry];
        next_entry = (next_entry + 1) % 2;
        close_mmap(entry);
    }

    int try;
    for (try = 0; try < 2; try++) {
        /* Check signature */
        if (entry->map) {
            if (*((uint64_t*)entry->map) == sig)
                return entry;

            log(1, "Invalid signature, fetching new shm!");
            close_mmap(entry);
        }

        /* Setup parameters and run command */
        char arg1[32], arg2[32];
        int c;

        c = snprintf(arg1, sizeof(arg1), "%08lx", (long)paddr & 0xffffffff);
        trueorabort(c > 0, "snprintf");
        int i, p = 0;
        for (i = 0; i < 8; i++) {
            c = snprintf(arg2 + p, sizeof(arg2) - p, "%02x",
                         ((uint8_t*)&sig)[i]);
            trueorabort(c > 0, "snprintf");
            p += c;
        }

        char* cmd = "croutonfindnacl";
        char* args[] = {cmd, arg1, arg2, NULL};
        char buffer[256];
        log(2, "Running %s %s %s", cmd, arg1, arg2);
        c = popen2(cmd, args, NULL, 0, buffer, sizeof(buffer));
        if (c <= 0) {
            error("Error running helper.");
            return NULL;
        }
        buffer[c < sizeof(buffer) ? c : (sizeof(buffer)-1)] = 0;
        log(2, "Result: %s", buffer);

        /* Parse PID:file output */
        char* cut = strchr(buffer, ':');
        if (!cut) {
            error("No ':' in helper reply: %s.", cut);
            return NULL;
        }
        *cut = 0;

        char* endptr;
        long pid = strtol(buffer, &endptr, 10);
        if(buffer == endptr || *endptr != '\0') {
            error("Invalid pid: %s", buffer);
            return NULL;
        }
        char* file = cut+1;
        log(2, "PID:%ld, FILE:%s", pid, file);

        entry->paddr = paddr;
        entry->fd = open(file, O_RDWR);
        if (entry->fd < 0) {
            error("Cannot open file %s\n", file);
            return NULL;
        }

        entry->length = length;
        entry->map = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED,
                          entry->fd, 0);
        if (!entry->map) {
            error("Cannot mmap %s\n", file);
            close(entry->fd);
            return NULL;
        }

        log(2, "mmap ok %p %zu %d", entry->map, entry->length, entry->fd);
    }

    error("Cannot find shm.");
    return NULL;
}

/* WebSocket functions */

XImage* img = NULL;
XShmSegmentInfo shminfo;

/* Writes framebuffer image to websocket/shm */
int write_image(const struct screen* screen) {
    char reply_raw[FRAMEMAXHEADERSIZE + sizeof(struct screen_reply)];
    struct screen_reply* reply =
        (struct screen_reply*)(reply_raw + FRAMEMAXHEADERSIZE);
    int refresh = 0;

    memset(reply_raw, 0, sizeof(reply_raw));

    reply->type = 'S';
    reply->width = screen->width;
    reply->height = screen->height;

    /* Allocate XShmImage */
    if (!img || img->width != screen->width || img->height != screen->height) {
        if (img) {
            XDestroyImage(img);
            shmdt(shminfo.shmaddr);
            shmctl(shminfo.shmid, IPC_RMID, 0);
        }

        /* FIXME: Some error checking should happen here... */
        img = XShmCreateImage(dpy, DefaultVisual(dpy, 0), 24,
                              ZPixmap, NULL, &shminfo,
                              screen->width, screen->height);
        trueorabort(img, "XShmCreateImage");
        shminfo.shmid = shmget(IPC_PRIVATE, img->bytes_per_line*img->height,
                               IPC_CREAT|0777);
        trueorabort(shminfo.shmid != -1, "shmget");
        shminfo.shmaddr = img->data = shmat(shminfo.shmid, 0, 0);
        trueorabort(shminfo.shmaddr != (void*)-1, "shmat");
        shminfo.readOnly = False;
        int ret = XShmAttach(dpy, &shminfo);
        trueorabort(ret, "XShmAttach");
        /* Force refresh */
        refresh = 1;
    }

    if (screen->refresh) {
        log(1, "Force refresh from client.");
        /* refresh forced by the client */
        refresh = 1;
    }

    XEvent ev;
    /* Register damage on new windows */
    while (XCheckTypedEvent(dpy, MapNotify, &ev)) {
        register_damage(dpy, ev.xcreatewindow.window);
        refresh = 1;
    }

    /* Check for damage */
    while (XCheckTypedEvent(dpy, damageEvent + XDamageNotify, &ev)) {
        refresh = 1;
    }

    /* Check for cursor events */
    reply->cursor_updated = 0;
    while (XCheckTypedEvent(dpy, fixesEvent + XFixesCursorNotify, &ev)) {
        XFixesCursorNotifyEvent* curev = (XFixesCursorNotifyEvent*)&ev;
        if (verbose >= 2) {
            char* name = XGetAtomName(dpy, curev->cursor_name);
            log(2, "cursor! %ld %s", curev->cursor_serial, name);
            XFree(name);
        }
        reply->cursor_updated = 1;
        reply->cursor_serial = curev->cursor_serial;
    }

    /* No update */
    if (!refresh) {
        reply->shm = 0;
        reply->updated = 0;
        socket_client_write_frame(reply_raw, sizeof(*reply),
                                  WS_OPCODE_BINARY, 1);
        return 0;
    }

    /* Get new image from framebuffer */
    XShmGetImage(dpy, DefaultRootWindow(dpy), img, 0, 0, AllPlanes);

    int size = img->bytes_per_line * img->height;

    trueorabort(size == screen->width*screen->height*4,
                "Invalid screen byte count");

    trueorabort(screen->shm, "Non-SHM rendering is not supported");

    struct cache_entry* entry = find_shm(screen->paddr, screen->sig, size);

    reply->shm = 1;
    reply->updated = 1;
    reply->shmfailed = 0;

    if (entry && entry->map) {
        if (size == entry->length) {
            memcpy(entry->map, img->data, size);
            msync(entry->map, size, MS_SYNC);
        } else {
            /* This should never happen (it means the client passed an
             * outdated buffer to us). */
            error("Invalid shm entry length (client bug!).");
            reply->shmfailed = 1;
        }
    } else {
        /* Keep the flow going, even if we cannot find the shm. Next time
         * the NaCl client reallocates the buffer, we are likely to be able
         * to find it. */
        error("Cannot find shm, moving on...");
        reply->shmfailed = 1;
    }

    /* Confirm write is done */
    socket_client_write_frame(reply_raw, sizeof(*reply),
                              WS_OPCODE_BINARY, 1);

    return 0;
}

/* Writes cursor image to websocket */
int write_cursor() {
    XFixesCursorImage *img = XFixesGetCursorImage(dpy);
    if (!img) {
        error("XFixesGetCursorImage returned NULL");
        return -1;
    }
    int size = img->width*img->height;
    const int replylength = sizeof(struct cursor_reply) + size*sizeof(uint32_t);
    char reply_raw[FRAMEMAXHEADERSIZE + replylength];
    struct cursor_reply* reply =
        (struct cursor_reply*)(reply_raw + FRAMEMAXHEADERSIZE);

    memset(reply_raw, 0, sizeof(*reply_raw));

    reply->type = 'P';
    reply->width = img->width;
    reply->height = img->height;
    reply->xhot = img->xhot;
    reply->yhot = img->yhot;
    reply->cursor_serial = img->cursor_serial;
    /* This casts long[] to uint32_t[] */
    int i;
    for (i = 0; i < size; i++)
        reply->pixels[i] = img->pixels[i];

    socket_client_write_frame(reply_raw, replylength, WS_OPCODE_BINARY, 1);
    XFree(img);

    return 0;
}
Example #6
0
template<typename PointT> int
pcl::PCDWriter::appendBinary(const std::string &file_name, 
                             const pcl::PointCloud<PointT> &cloud)
{
  if(cloud.empty())
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Input point cloud has no data!");
    return -1;
  }

  if(!boost::filesystem::exists(file_name))
    return writeBinary(file_name, cloud);

  std::ifstream file_istream;
  file_istream.open(file_name.c_str(), std::ifstream::binary);
  if(!file_istream.good())
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Error opening file for reading");
    return -1;
  }
  file_istream.seekg(0, std::ios_base::end);
  size_t file_size = file_istream.tellg();
  file_istream.close();

  pcl::PCLPointCloud2 tmp_cloud;
  PCDReader reader;
  if(reader.readHeader(file_name, tmp_cloud) != 0)
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Failed reading header");
    return -1;
  }
  if(tmp_cloud.height != 1 || cloud.height != 1)
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] can't use appendBinary with a point cloud that "
      "has height different than 1!");
    return -1;
  }
  tmp_cloud.width += cloud.width;
  std::ostringstream oss;
  pcl::PointCloud<PointT> tmp_cloud2;
  // copy the header values:
  tmp_cloud2.header = tmp_cloud.header;
  tmp_cloud2.width = tmp_cloud.width;
  tmp_cloud2.height = tmp_cloud.height;
  tmp_cloud2.is_dense = tmp_cloud.is_dense;
  
  oss << PCDWriter::generateHeader(tmp_cloud2, tmp_cloud2.width) << "DATA binary\n";
  size_t data_idx = oss.tellp();
  
#if _WIN32
  HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_APPEND, static_cast<mode_t> (0600));
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during open!");
    return (-1);
  }
#endif
  // Mandatory lock file
  boost::interprocess::file_lock file_lock;
  setLockingPermissions (file_name, file_lock);

  std::vector<pcl::PCLPointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;

    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);

  data_size = cloud.points.size () * fsize;

  data_idx += (tmp_cloud.width - cloud.width) * fsize;
  if (data_idx != file_size)
  {
    const char *msg = "[pcl::PCDWriter::appendBinary] The expected data size and the current data size are different!";
    PCL_WARN(msg);
    throw pcl::IOException (msg);
    return -1;
  }

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMappingA (h_native_file, NULL, PAGE_READWRITE, 0, (DWORD) (data_idx + data_size), NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
  CloseHandle (fm);
#else
  // Stretch the file size to the size of the data
  off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);

  if (result < 0)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    PCL_ERROR ("[pcl::PCDWriter::appendBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));

    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = static_cast<int> (::write (fd, "", 1));
  if (result != 1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during write ()!");
    return (-1);
  }

  char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
  if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  char* out = &map[0] + data_idx;
  // Copy the data
  for (size_t i = 0; i < cloud.points.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, reinterpret_cast<const char*> (&cloud.points[i]) + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

  // write the new header:
  std::string header(oss.str());
  memcpy(map, header.c_str(), header.size());


  // If the user set the synchronization flag on, call msync
#if !_WIN32
  if (map_synchronization_)
    msync (map, data_idx + data_size, MS_SYNC);
#endif

  // Unmap the pages of memory
#if _WIN32
  UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle (h_native_file);
#else
  pcl_close (fd);
#endif

  resetLockingPermissions (file_name, file_lock);
  return 0;
}
Example #7
0
void MemoryMappedFile::flush(bool sync) {
    if ( views.empty() || fd == 0 )
        return;
    if ( msync(viewForFlushing(), len, sync ? MS_SYNC : MS_ASYNC) )
        problem() << "msync " << errnoWithDescription() << endl;
}
Example #8
0
static int msync_validate (void *addr, size_t len)
{
  return msync (addr, len, MS_ASYNC);
}
Example #9
0
int
main(int argc, char *argv[])
{
	int count = DCOUNT;	/* times to do each file */
	int ct;
	off_t size = DSIZE;
	off_t si;
	int fd;
	off_t bytes = 0;
	int roflags;			/* open read-only flags */
	char *bigfile = "bigfile";
	struct timeval time;
	char *opts;
	char buf[BUFSZ];
	double etime;
#ifdef MMAP
	caddr_t maddr;
#endif

	umask(0);
	setbuf(stdout, NULL);
	Myname = *argv++;
	argc--;
	while (argc && **argv == '-') {
		for (opts = &argv[0][1]; *opts; opts++) {
			switch (*opts) {
				case 'h':	/* help */
					usage();
					exit(1);
					break;

				case 't':	/* time */
					Tflag++;
					break;

				case 'f':	/* funtionality */
					Fflag++;
					break;

				case 'n':	/* No Test Directory create */
					Nflag++;
					break;

				default:
					error("unknown option '%c'", *opts);
					usage();
					exit(1);
			}
		}
		argc--;
		argv++;
	}

	if (argc) {
		size = getparm(*argv, 1, "size");
		if (size <= 0) {
			usage();
			exit(1);
		}
		argv++;
		argc--;
	}
	if (argc) {
		count = getparm(*argv, 1, "count");
		if (count <= 0) {
			usage();
			exit(1);
		}
		argv++;
		argc--;
	}
	if (argc) {
		bigfile = *argv;
		argv++;
		argc--;
	}
	if (argc) {
		usage();
		exit(1);
	}

	if (Fflag) {
		Tflag = 0;
		count = 1;
	}

	roflags = O_RDONLY;
#ifdef DOSorWIN32
	roflags |= O_BINARY;
#endif

	fprintf(stdout, "%s: read\n", Myname);

	mtestdir(NULL);

	if (Tflag) {
		starttime();
	}

	for (ct = 0; ct < count; ct++) {
		if ((fd = open(bigfile, roflags)) < 0) {
			error("can't open '%s'", bigfile);
			exit(1);
		}
#ifdef MMAP
		maddr = mmap((caddr_t)0, (size_t)size, PROT_READ,
				MAP_PRIVATE, fd, (off_t)0);
		if (maddr == MAP_FAILED) {
			error("can't mmap '%s'", bigfile);
			exit(1);
		}
		if (msync(maddr, (size_t)size, MS_INVALIDATE) < 0) {
			error("can't invalidate pages for '%s'", bigfile);
			exit(1);
		}
		if (munmap(maddr, (size_t)size) < 0) {
			error("can't munmap '%s'", bigfile);
			exit(1);
		}
#endif
		for (si = size; si > 0; si -= bytes) {
			bytes = MIN(BUFSZ, si);
			if (read(fd, buf, bytes) != bytes) {
				error("'%s' read failed", bigfile);
				exit(1);
			}
		}
		close(fd);
	}

	if (Tflag) {
		endtime(&time);
	}

	fprintf(stdout, "\tread %ld byte file %d times", (long)size, count);

	if (Tflag) {
		etime = (double)time.tv_sec + (double)time.tv_usec / 1000000.0;
		if (etime != 0.0) {
			fprintf(stdout, " in %ld.%-2ld seconds (%ld bytes/sec)",
				(long)time.tv_sec, (long)time.tv_usec / 10000,
				(long)((double)size * ((double)count / etime)));
		} else {
			fprintf(stdout, " in %ld.%-2ld seconds (> %ld bytes/sec)",
				(long)time.tv_sec, (long)time.tv_usec / 10000,
				(long)size * count);
		}
	}
	fprintf(stdout, "\n");

	if (unlink(bigfile) < 0) {
		error("can't unlink '%s'", bigfile);
		exit(1);
	}
	complete();
	return 0;
}
Example #10
0
void QuickFile::sync_file() {
  msync(fptr, filesize, MS_SYNC);
}
Example #11
0
//Returns -1 on failure, 0 on success, sets up the module
int setupGraphicModule(int fd, GraphicModule * module){

	//Zero the buffered array
	memset(buffered,0,sizeof(buffered));

	//Setup the void pointer for the mapped file
	module->memShareAddr = (void*)malloc(sizeof(void*));
	module->memShareFD = -1;
	if(module->memShareAddr == NULL){
		puts("Failed allocating memory for Graphics Module");
		return -1;
	}

	module->memShareAddr = mmap(NULL, MEMSHARESIZE, PROT_READ, MAP_SHARED, fd, 0);
	if(module->memShareAddr == MAP_FAILED){
		perror("memsharegraphic");
		puts("Failed to map memory share to network module");
		return -1;
	}
	module->memShareFD = fd;
	msync(module->memShareAddr,sizeof(int),MS_SYNC|MS_INVALIDATE);

	//Set up the graphics
	if (SDL_Init(SDL_INIT_VIDEO) < 0 ){
		puts("Failed to initalize video");
		return -1;
	}

	module->screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, SCREENDEPTH, SDL_HWSURFACE);
	if(module->screen == NULL){
		puts("Failed to set video mode");
		SDL_Quit();
		return -1;
	}

    //Create the drawing and document surfaces 
    module->drawing = createSurface(SDL_SWSURFACE, SCREENWIDTH,SCREENHEIGHT,module->screen);
    if(module->drawing == NULL){
        puts("failed to create drawing surface");
        SDL_Quit();
        return -1;
    }
   
    //Load the bitmap engine within the module
    
    module->font = malloc(sizeof(BitFont*));
    if(setupBitFont(module->font) < 0){
        puts("Failed to create the bitmap engine");
        SDL_Quit();
        return -1;
    }

    if(loadUI(module) < 0){
        puts("Failed to load User Interface");
        SDL_Quit();
        return -1;
    }

    //Set the stop flag
    module->stopFlag = 0;

    SDL_WM_SetCaption( "Smart Desk | Interactive Learning Software", NULL);

	return 0;
}
Example #12
0
static inline int
sp_mapsync(spfile *f) {
	return msync(f->map, f->size, MS_SYNC);
}
Example #13
0
void *rszshm_mk(struct rszshm *r, size_t flen, const char *fname, struct rszshm_scan scan)
{
	long pgsz = sysconf(_SC_PAGE_SIZE);
	int i, errno_;
	char *m, *tgt, *p = NULL;

	if (!r || flen == 0 || scan.len < flen + sizeof(*r->hdr) ||
	    !scan.start || scan.len == 0 || scan.hop == 0 || scan.iter == 0 ||
	    (fname && strnlen(fname, RSZSHM_PATH_MAX) == RSZSHM_PATH_MAX)) {
		errno = EINVAL;
		return NULL;
	}

	*r = (typeof(*r)) { -1, 0, "", NULL, NULL };
	strcpy(r->fname, fname ? fname : RSZSHM_DFLT_FNAME);

	flen = pgup(flen + sizeof(*r->hdr), pgsz);
	scan.len = pgup(scan.len, pgsz);

	for (i = 1, tgt = scan.start; i <= scan.iter; i++) {
		m = mmap(tgt, scan.len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON|MAP_NORESERVE, -1, 0);
		if (m == MAP_FAILED)
			return NULL;
		if (m == tgt)
			break;
		munmap(m, scan.len);
		m = NULL;
		tgt += (i % 2 == 0 ? 1 : -1) * i * scan.hop;
	}
	if (!m) {
		errno = ENOSPC;
		return NULL;
	}

	if ((p = strstr(r->fname, "XXXXXX/")) != NULL) {
		p += 6;
		*p = '\0';
		if (!mkdtemp(r->fname))
			goto err;
		*p = '/';
	}

	if ((r->fd = open(r->fname, O_CREAT|O_EXCL|O_RDWR, p ? 0600 : 0666)) == -1)
		goto err;

	if (ftruncate(r->fd, flen) == -1)
		goto err;

	if (mmap(m, flen, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, r->fd, 0) == MAP_FAILED)
		goto err;

	*(r->hdr = (typeof(r->hdr)) m) = (typeof(*r->hdr)) { flen, scan.len, m };

	if (msync(m, sizeof(*r->hdr), MS_SYNC) == -1)
		goto err;

	r->flen = flen;
	r->cap = flen - sizeof(*r->hdr);
	r->dat = m + sizeof(*r->hdr);

	return r->dat;

err:
	errno_ = errno;
	if (m && m != MAP_FAILED)
		munmap(m, scan.len);
	if (r->fd != -1) {
		close(r->fd);
		unlink(r->fname);
	}
	if (p) {
		*p = '\0';
		rmdir(r->fname);
		*p = '/';
	}
	errno = errno_;
	return NULL;
}
Example #14
0
void PruTimer::run() {
	
	LOG( "Starting PruTimer thread..." << std::endl);
	
	while(!stop) {
#ifdef DEMO_PRU
		
		unsigned int* nbCommand = (unsigned int *)currentReadingAddress;
		
		if(!nbCommand || stop || !*nbCommand)
			continue;
		SteppersCommand * cmd = (SteppersCommand*)(currentReadingAddress+4);
		FLOAT_T totalWait = 0;
		for(int i=0;i<*nbCommand;i++) {
			totalWait+=cmd->delay/200000.0;
			cmd++;
		}
		
		std::this_thread::sleep_for( std::chrono::milliseconds((unsigned)totalWait) );
		currentReadingAddress+=(*nbCommand)*8+4;
		nbCommand = (unsigned int *)currentReadingAddress;
		if(*nbCommand == DDR_MAGIC) {
			currentReadingAddress = ddr_mem;
		}
		*ddr_nr_events=(*ddr_nr_events)+1;
#else
		unsigned int nbWaitedEvent = prussdrv_pru_wait_event (PRU_EVTOUT_0,1000); // 250ms timeout
#endif

		if(stop) break;
		
		/*
		if (nbWaitedEvent)
			LOG( ("\tINFO: PRU0 completed transfer.\r\n"));
		else
			LOG( ("\tINFO: PRU0 transfer timeout.\r\n"));
		*/
		
		
#ifndef DEMO_PRU
		if(nbWaitedEvent)
			prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
#endif
		
		msync(ddr_nr_events, 4, MS_SYNC);
		uint32_t nb = *ddr_nr_events;
		
		
		
		{
			std::lock_guard<std::mutex> lk(mutex_memory);
			
//			LOG( "NB event " << nb << " / " << currentNbEvents << "\t\tRead event from UIO = " << nbWaitedEvent << ", block in the queue: " << ddr_mem_used << std::endl);

			while(currentNbEvents!=nb && !blocksID.empty()) { //We use != to handle the overflow case
				
				BlockDef & front = blocksID.front();
				
				ddr_mem_used-=front.size;
				totalQueuedMovesTime -=front.totalTime;
				
				assert(ddr_mem_used<ddr_size);
				
//				LOG( "Block of size " << std::dec << front.size << " and time " << front.totalTime << " done." << std::endl);

				blocksID.pop();
				
				currentNbEvents++;
			}
			
			currentNbEvents = nb;
		}
		
		
//		LOG( "NB event after " << std::dec << nb << " / " << currentNbEvents << std::endl);
//		LOG( std::dec <<ddr_mem_used << " bytes used, free: " <<std::dec <<  ddr_size-ddr_mem_used<< "." << std::endl);
		
		blockAvailable.notify_all();
	}
}
Example #15
0
template <typename PointT> int
pcl::PCDWriter::writeBinaryCompressed (const std::string &file_name, 
                                       const pcl::PointCloud<PointT> &cloud)
{
  if (cloud.points.empty ())
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Input point cloud has no data!");
    return (-1);
  }
  int data_idx = 0;
  std::ostringstream oss;
  oss << generateHeader<PointT> (cloud) << "DATA binary_compressed\n";
  oss.flush ();
  data_idx = static_cast<int> (oss.tellp ());

#if _WIN32
  HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during open!");
    return (-1);
  }
#endif

  // Mandatory lock file
  boost::interprocess::file_lock file_lock;
  setLockingPermissions (file_name, file_lock);

  std::vector<pcl::PCLPointField> fields;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  std::vector<int> fields_sizes (fields.size ());
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;
    
    fields_sizes[nri] = fields[i].count * pcl::getFieldSize (fields[i].datatype);
    fsize += fields_sizes[nri];
    fields[nri] = fields[i];
    ++nri;
  }
  fields_sizes.resize (nri);
  fields.resize (nri);
 
  // Compute the size of data
  data_size = cloud.points.size () * fsize;

  //////////////////////////////////////////////////////////////////////
  // Empty array holding only the valid data
  // data_size = nr_points * point_size 
  //           = nr_points * (sizeof_field_1 + sizeof_field_2 + ... sizeof_field_n)
  //           = sizeof_field_1 * nr_points + sizeof_field_2 * nr_points + ... sizeof_field_n * nr_points
  char *only_valid_data = static_cast<char*> (malloc (data_size));

  // Convert the XYZRGBXYZRGB structure to XXYYZZRGBRGB to aid compression. For
  // this, we need a vector of fields.size () (4 in this case), which points to
  // each individual plane:
  //   pters[0] = &only_valid_data[offset_of_plane_x];
  //   pters[1] = &only_valid_data[offset_of_plane_y];
  //   pters[2] = &only_valid_data[offset_of_plane_z];
  //   pters[3] = &only_valid_data[offset_of_plane_RGB];
  //
  std::vector<char*> pters (fields.size ());
  size_t toff = 0;
  for (size_t i = 0; i < pters.size (); ++i)
  {
    pters[i] = &only_valid_data[toff];
    toff += static_cast<size_t>(fields_sizes[i]) * cloud.points.size();
  }
  
  // Go over all the points, and copy the data in the appropriate places
  for (size_t i = 0; i < cloud.points.size (); ++i)
  {
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (pters[j], reinterpret_cast<const char*> (&cloud.points[i]) + fields[j].offset, fields_sizes[j]);
      // Increment the pointer
      pters[j] += fields_sizes[j];
    }
  }

  char* temp_buf = static_cast<char*> (malloc (static_cast<size_t> (static_cast<float> (data_size) * 1.5f + 8.0f)));
  // Compress the valid data
  unsigned int compressed_size = pcl::lzfCompress (only_valid_data, 
                                                   static_cast<uint32_t> (data_size), 
                                                   &temp_buf[8], 
                                                   static_cast<uint32_t> (static_cast<float>(data_size) * 1.5f));
  unsigned int compressed_final_size = 0;
  // Was the compression successful?
  if (compressed_size)
  {
    char *header = &temp_buf[0];
    memcpy (&header[0], &compressed_size, sizeof (unsigned int));
    memcpy (&header[4], &data_size, sizeof (unsigned int));
    data_size = compressed_size + 8;
    compressed_final_size = static_cast<uint32_t> (data_size) + data_idx;
  }
  else
  {
#if !_WIN32
    pcl_close (fd);
#endif
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during compression!");
    return (-1);
  }

#if !_WIN32
  // Stretch the file size to the size of the data
  off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
  if (result < 0)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    PCL_ERROR ("[pcl::PCDWriter::writeBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));
    
    throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = static_cast<int> (::write (fd, "", 1));
  if (result != 1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during write ()!");
    return (-1);
  }
#endif

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, compressed_final_size, NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, compressed_final_size));
  CloseHandle (fm);

#else
  char *map = static_cast<char*> (mmap (0, compressed_final_size, PROT_WRITE, MAP_SHARED, fd, 0));
  if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during mmap ()!");
    return (-1);
  }
#endif

  // Copy the header
  memcpy (&map[0], oss.str ().c_str (), data_idx);
  // Copy the compressed data
  memcpy (&map[data_idx], temp_buf, data_size);

#if !_WIN32
  // If the user set the synchronization flag on, call msync
  if (map_synchronization_)
    msync (map, compressed_final_size, MS_SYNC);
#endif

  // Unmap the pages of memory
#if _WIN32
    UnmapViewOfFile (map);
#else
  if (munmap (map, (compressed_final_size)) == -1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinaryCompressed] Error during munmap ()!");
    return (-1);
  }
#endif

  // Close file
#if _WIN32
  CloseHandle (h_native_file);
#else
  pcl_close (fd);
#endif
  resetLockingPermissions (file_name, file_lock);

  free (only_valid_data);
  free (temp_buf);
  return (0);
}
Example #16
0
int
main(int argc, char **argv)
{
	int fd, pfd, ret;
	char *buf;
	/*
	 * gcc -O2 will optimize foo's storage, prevent reproducing
	 * this issue.
	 * foo is never actually used after fault in value stored.
	 */
	volatile char foo __attribute__((__unused__));
	int pagesize = getpagesize();

	if (argc < 3) {
		printf("Usage: %s <file> <pmem file>\n", basename(argv[0]));
		exit(0);
	}

	 /* O_DIRECT is necessary for reproduce this bug. */
	fd = open(argv[1], O_RDONLY|O_DIRECT);
	if (fd < 0)
		err_exit("open");

	pfd = open(argv[2], O_RDONLY);
	if (pfd < 0)
		err_exit("pmem open");

	buf = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, pfd, 0);
	if (buf == MAP_FAILED)
		err_exit("mmap");

	/*
	 * Read from the DAX mmap to populate the first page in the
	 * address_space with a read-only mapping.
	 */
	foo = *buf;

	/*
	 * Now write to the DAX mmap.  This *should* fail, but if the bug is
	 * present in __get_user_pages_fast(), it will succeed.
	 */
	ret = read(fd, buf, pagesize);
	if (ret != pagesize)
		err_exit("read");

	ret = msync(buf, pagesize, MS_SYNC);
	if (ret != 0)
		err_exit("msync");

	ret = munmap(buf, pagesize);
	if (ret < 0)
		err_exit("munmap");

	ret = close(fd);
	if (ret < 0)
		err_exit("clsoe fd");

	ret = close(pfd);
	if (ret < 0)
		err_exit("close pfd");

	exit(0);
}
Example #17
0
template <typename PointT> int
pcl::PCDWriter::writeBinary (const std::string &file_name, 
                             const pcl::PointCloud<PointT> &cloud, 
                             const std::vector<int> &indices)
{
  if (cloud.points.empty () || indices.empty ())
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Input point cloud has no data or empty indices given!");
    return (-1);
  }
  int data_idx = 0;
  std::ostringstream oss;
  oss << generateHeader<PointT> (cloud, static_cast<int> (indices.size ())) << "DATA binary\n";
  oss.flush ();
  data_idx = static_cast<int> (oss.tellp ());

#if _WIN32
  HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
    return (-1);
  }
#endif
  // Mandatory lock file
  boost::interprocess::file_lock file_lock;
  setLockingPermissions (file_name, file_lock);

  std::vector<pcl::PCLPointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;
    
    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);
  
  data_size = indices.size () * fsize;

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, data_idx + data_size, NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
  CloseHandle (fm);

#else
  // Stretch the file size to the size of the data
  off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
  if (result < 0)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    PCL_ERROR ("[pcl::PCDWriter::writeBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));
    
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = static_cast<int> (::write (fd, "", 1));
  if (result != 1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during write ()!");
    return (-1);
  }

  char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
  if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  // Copy the header
  memcpy (&map[0], oss.str ().c_str (), data_idx);

  char *out = &map[0] + data_idx;
  // Copy the data
  for (size_t i = 0; i < indices.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, reinterpret_cast<const char*> (&cloud.points[indices[i]]) + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

#if !_WIN32
  // If the user set the synchronization flag on, call msync
  if (map_synchronization_)
    msync (map, data_idx + data_size, MS_SYNC);
#endif

  // Unmap the pages of memory
#if _WIN32
    UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle(h_native_file);
#else
  pcl_close (fd);
#endif
  
  resetLockingPermissions (file_name, file_lock);
  return (0);
}
static void test_mmap_wrong_format_version (const char * tmpFile)
{
	// first write a mmap file
	{
		Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
		KeySet * conf = ksNew (0, KS_END);
		PLUGIN_OPEN ("mmapstorage");

		KeySet * ks = simpleTestKeySet ();
		succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");

		keyDel (parentKey);
		ksDel (ks);
		PLUGIN_CLOSE ();
	}

	// set wrong version number in mmap header
	FILE * fp;
	if ((fp = fopen (tmpFile, "r+")) == 0)
	{
		yield_error ("fopen() error");
	}
	struct stat sbuf;
	if (stat (tmpFile, &sbuf) == -1)
	{
		yield_error ("stat() error");
	}

	int fd = fileno (fp);
	char * mappedRegion = mmap (0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (mappedRegion == MAP_FAILED)
	{
		ELEKTRA_LOG_WARNING ("error mapping file %s\nmmapSize: " ELEKTRA_STAT_ST_SIZE_F, tmpFile, sbuf.st_size);
		yield_error ("mmap() error");
		return;
	}
	if (fp)
	{
		fclose (fp);
	}

	MmapHeader * mmapHeader = (MmapHeader *) mappedRegion;
	mmapHeader->formatVersion = ELEKTRA_MMAP_FORMAT_VERSION + 1;

	if (msync ((void *) mappedRegion, sbuf.st_size, MS_SYNC) != 0)
	{
		yield_error ("msync() error");
		return;
	}

	if (munmap (mappedRegion, sbuf.st_size) != 0)
	{
		yield_error ("munmap() error");
		return;
	}

	// wrong format version should be detected now
	{
		// we expect an error here
		Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
		KeySet * conf = ksNew (0, KS_END);
		PLUGIN_OPEN ("mmapstorage");

		KeySet * ks = ksNew (0, KS_END);
		succeed_if (plugin->kdbGet (plugin, ks, parentKey) == ELEKTRA_PLUGIN_STATUS_ERROR,
			    "kdbGet did not detect wrong format version");

		keyDel (parentKey);
		ksDel (ks);
		PLUGIN_CLOSE ();
	}
}
int
main(int ac, char **av)
{
	const char *const name = ac > 1 ? av[1] : "mmap";
	const intmax_t pagesize = get_page_size();
	const unsigned long length1 = pagesize * 6;
	const unsigned long length2 = pagesize * 3;
	const unsigned long length3 = pagesize * 2;
	const int fd = -1;
	off_t offset;
	void *addr, *p;

#if ULONG_MAX > 4294967295UL
	offset = 0xcafedeadbeef000 & -pagesize;
	addr = (void *) (uintmax_t) (0xfacefeed000 & -pagesize);
#else
	offset = 0xdeadbeef000 & -pagesize;
	addr = (void *) (unsigned int) (0xfaced000 & -pagesize);
#endif
	const uintmax_t uoffset =
	       sizeof(offset) == sizeof(int) ? (uintmax_t) (unsigned int) offset
					     : (uintmax_t) offset;

	(void) close(0);
	(void) close(0);
	printf("%s(NULL, 0, PROT_NONE, MAP_FILE, 0, 0) = -1 EBADF (%m)\n",
	       name);
	mmap(NULL, 0, PROT_NONE, MAP_FILE, 0, 0);

	p = mmap(addr, length1, PROT_READ | PROT_WRITE,
		 MAP_PRIVATE | MAP_ANONYMOUS, fd, offset);
	if (MAP_FAILED == p)
		perror_msg_and_fail("mmap");
	printf("%s(%p, %lu, PROT_READ|PROT_WRITE, "
	       "MAP_PRIVATE|MAP_ANONYMOUS, %d, %#jx) = %p\n",
	       name, addr, length1, fd, uoffset, p);

	if (msync(p, length1, MS_SYNC))
		perror_msg_and_fail("msync");
	printf("msync(%p, %lu, MS_SYNC) = 0\n", p, length1);

	if (mprotect(p, length1, PROT_NONE))
		perror_msg_and_fail("mprotect");
	printf("mprotect(%p, %lu, PROT_NONE) = 0\n", p, length1);

	addr = mremap(p, length1, length2, 0);
	if (MAP_FAILED == addr)
		perror_msg_and_fail("mremap");
	printf("mremap(%p, %lu, %lu, 0) = %p\n", p, length1, length2, addr);

	p =  mremap(addr, length2, length3, MREMAP_MAYMOVE | MREMAP_FIXED,
		    addr + length2);
	if (MAP_FAILED == p)
		perror_msg_and_fail("mremap");
	printf("mremap(%p, %lu, %lu, MREMAP_MAYMOVE|MREMAP_FIXED"
	       ", %p) = %p\n", addr, length2, length3, addr + length2, p);

	if (madvise(p, length3, MADV_NORMAL))
		perror_msg_and_fail("madvise");
	printf("madvise(%p, %lu, MADV_NORMAL) = 0\n", p, length3);

	if (munmap(p, length3))
		perror_msg_and_fail("munmap");
	printf("munmap(%p, %lu) = 0\n", p, length3);

	if (mlockall(MCL_FUTURE))
		perror_msg_and_fail("mlockall");
	puts("mlockall(MCL_FUTURE) = 0");

	puts("+++ exited with 0 +++");
	return 0;
}
static void test_mmap_wrong_magic_keyset (const char * tmpFile)
{
	// first write a mmap file
	{
		Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
		KeySet * conf = ksNew (0, KS_END);
		PLUGIN_OPEN ("mmapstorage");

		KeySet * ks = simpleTestKeySet ();
		succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");

		keyDel (parentKey);
		ksDel (ks);
		PLUGIN_CLOSE ();
	}

	// now manipulate magic keyset inside the mapped region
	FILE * fp;
	if ((fp = fopen (tmpFile, "r+")) == 0)
	{
		yield_error ("fopen() error");
	}
	struct stat sbuf;
	if (stat (tmpFile, &sbuf) == -1)
	{
		yield_error ("stat() error");
	}

	int fd = fileno (fp);
	char * mappedRegion = mmap (0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (mappedRegion == MAP_FAILED)
	{
		ELEKTRA_LOG_WARNING ("error mapping file %s\nmmapSize: " ELEKTRA_STAT_ST_SIZE_F, tmpFile, sbuf.st_size);
		yield_error ("mmap() error");
		return;
	}
	if (fp)
	{
		fclose (fp);
	}

	KeySet * magicKs = (KeySet *) (mappedRegion + sizeof (MmapHeader));
	magicKs->size = 1234; // magic keyset contains SIZE_MAX here

	if (msync ((void *) mappedRegion, sbuf.st_size, MS_SYNC) != 0)
	{
		yield_error ("msync() error");
		return;
	}

	if (munmap (mappedRegion, sbuf.st_size) != 0)
	{
		yield_error ("munmap() error");
		return;
	}

	// manipulated magic keyset should be detected now
	{
		// we expect an error here
		Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
		KeySet * conf = ksNew (0, KS_END);
		PLUGIN_OPEN ("mmapstorage");

		KeySet * ks = ksNew (0, KS_END);
		succeed_if (plugin->kdbGet (plugin, ks, parentKey) == ELEKTRA_PLUGIN_STATUS_ERROR,
			    "kdbGet did not detect wrong magic keyset");

		keyDel (parentKey);
		ksDel (ks);
		PLUGIN_CLOSE ();
	}
}
Example #21
0
    void flush() {
        if ( _view && _fd )
            if ( msync(_view, _len, MS_SYNC ) )
                problem() << "msync " << errnoWithDescription() << endl;

    }
Example #22
0
/* Regenerate NVRAM. */
int _nvram_commit(nvram_handle_t *h)
{
	nvram_header_t *header = nvram_header(h);
	char *init, *config, *refresh, *ncdl;
	char *ptr, *end;
	int i;
	nvram_tuple_t *t;
	nvram_header_t tmp;
	uint8_t crc;

	/* Regenerate header */
	header->magic = NVRAM_MAGIC;
	header->crc_ver_init = (NVRAM_VERSION << 8);
	header->crc_ver_init |= 0x419 << 16;
	header->config_refresh = 0x0000;
	header->config_refresh |= 0x8040 << 16;
	header->config_ncdl = 0;

	/* Clear data area */
	ptr = (char *) header + sizeof(nvram_header_t);
	memset(ptr, 0xFF, NVRAM_SPACE - sizeof(nvram_header_t));
	memset(&tmp, 0, sizeof(nvram_header_t));

	/* Leave space for a double NUL at the end */
	end = (char *) header + NVRAM_SPACE - 2;

	/* Write out all tuples */
	for (i = 0; i < NVRAM_ARRAYSIZE(h->nvram_hash); i++) {
		for (t = h->nvram_hash[i]; t; t = t->next) {
			if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end)
				break;
			ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1;
		}
	}

	/* End with a double NULL and pad to 4 bytes */
	*ptr = '\0';
	ptr++;

	if( (int)ptr % 4 )
		memset(ptr, 0, 4 - ((int)ptr % 4));

	ptr++;

	/* Set new length */
	header->len = NVRAM_ROUNDUP(ptr - (char *) header, 4);

	/* Little-endian CRC8 over the last 11 bytes of the header */
	tmp.crc_ver_init   = header->crc_ver_init;
	tmp.config_refresh = header->config_refresh;
	tmp.config_ncdl    = header->config_ncdl;
	crc = hndcrc8((unsigned char *) &tmp + NVRAM_CRC_START_POSITION,
			sizeof(nvram_header_t) - NVRAM_CRC_START_POSITION, 0xff);

	/* Continue CRC8 over data bytes */
	crc = hndcrc8((unsigned char *) &header[0] + sizeof(nvram_header_t),
			header->len - sizeof(nvram_header_t), crc);

	/* Set new CRC8 */
	header->crc_ver_init |= crc;

	/* Write out */
	msync(h->mmap, h->length, MS_SYNC);
	fsync(h->fd);

	/* Reinitialize hash table */
	return _nvram_rehash(h);
}
Example #23
0
//exc_server uses dlsym to find symbol
JL_DLLEXPORT
kern_return_t catch_exception_raise(mach_port_t            exception_port,
                                    mach_port_t            thread,
                                    mach_port_t            task,
                                    exception_type_t       exception,
                                    exception_data_t       code,
                                    mach_msg_type_number_t code_count)
{
    unsigned int count = MACHINE_THREAD_STATE_COUNT;
    unsigned int exc_count = X86_EXCEPTION_STATE64_COUNT;
    x86_exception_state64_t exc_state;
    x86_thread_state64_t state;
#ifdef LIBOSXUNWIND
    if (thread == mach_profiler_thread) {
        return profiler_segv_handler(exception_port, thread, task, exception, code, code_count);
    }
#endif
    int16_t tid;
#ifdef JULIA_ENABLE_THREADING
    jl_tls_states_t *ptls = NULL;
    for (tid = 0;tid < jl_n_threads;tid++) {
        if (pthread_mach_thread_np(jl_all_task_states[tid].system_id) == thread) {
            ptls = jl_all_task_states[tid].ptls;
            break;
        }
    }
    if (!ptls) {
        // We don't know about this thread, let the kernel try another handler
        // instead. This shouldn't actually happen since we only register the
        // handler for the threads we know about.
        jl_safe_printf("ERROR: Exception handler triggered on unmanaged thread.\n");
        return KERN_INVALID_ARGUMENT;
    }
#else
    jl_tls_states_t *ptls = &jl_tls_states;
    tid = 0;
#endif
    kern_return_t ret = thread_get_state(thread, x86_EXCEPTION_STATE64, (thread_state_t)&exc_state, &exc_count);
    HANDLE_MACH_ERROR("thread_get_state", ret);
    uint64_t fault_addr = exc_state.__faultvaddr;
#ifdef JULIA_ENABLE_THREADING
    if (fault_addr == (uintptr_t)jl_gc_signal_page) {
        JL_LOCK_NOGC(gc_suspend);
        if (!jl_gc_safepoint_activated) {
            // GC is done before we get the message, do nothing and return
            JL_UNLOCK_NOGC(gc_suspend);
            return KERN_SUCCESS;
        }
        // Otherwise, set the gc state of the thread, suspend and record it
        int8_t gc_state = ptls->gc_state;
        ptls->gc_state = JL_GC_STATE_WAITING;
        uintptr_t item = tid | (((uintptr_t)gc_state) << 16);
        arraylist_push(&suspended_threads, (void*)item);
        thread_suspend(thread);
        JL_UNLOCK_NOGC(gc_suspend);
        return KERN_SUCCESS;
    }
#endif
#ifdef SEGV_EXCEPTION
    if (1) {
#else
    if (msync((void*)(fault_addr & ~(jl_page_size - 1)), 1, MS_ASYNC) == 0) { // check if this was a valid address
#endif
        jl_value_t *excpt;
        if (is_addr_on_stack(ptls, (void*)fault_addr)) {
            excpt = jl_stackovf_exception;
        }
#ifdef SEGV_EXCEPTION
        else if (msync((void*)(fault_addr & ~(jl_page_size - 1)), 1, MS_ASYNC) != 0) {
            // no page mapped at this address
            excpt = jl_segv_exception;
        }
#endif
        else {
            if (!(exc_state.__err & WRITE_FAULT))
                return KERN_INVALID_ARGUMENT; // rethrow the SEGV since it wasn't an error with writing to read-only memory
            excpt = jl_readonlymemory_exception;
        }
        jl_throw_in_thread(tid, thread, excpt);

        return KERN_SUCCESS;
    }
    else {
        kern_return_t ret = thread_get_state(thread, x86_THREAD_STATE64, (thread_state_t)&state, &count);
        HANDLE_MACH_ERROR("thread_get_state", ret);
        jl_critical_error(SIGSEGV, (unw_context_t*)&state,
                          ptls->bt_data, &ptls->bt_size);
        return KERN_INVALID_ARGUMENT;
    }
}

static void attach_exception_port(thread_port_t thread)
{
    kern_return_t ret;
    // http://www.opensource.apple.com/source/xnu/xnu-2782.1.97/osfmk/man/thread_set_exception_ports.html
    ret = thread_set_exception_ports(thread, EXC_MASK_BAD_ACCESS, segv_port, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);
    HANDLE_MACH_ERROR("thread_set_exception_ports", ret);
}
Example #24
0
int main (int    argc, char **argv)
{
    const char *file_name;
    const char *set_value;
    const char *attr_name;
    int         watch_mode;

    struct sigaction sigact;

    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags     = SA_SIGINFO;
    sigact.sa_restorer  = NULL;
    sigact.sa_sigaction = sig_handler;

    sigaction(SIGUSR1, &sigact, 0);
    sigaction(SIGINT, &sigact, 0);
    sigaction(SIGTERM, &sigact, 0);

    /* Parse command line arguments. */
    file_name  = "./person.dat";
    set_value  = NULL;
    watch_mode = 0;

    while (1)
    {
        int opt;

        opt = getopt (argc, argv, "ws:f:");
        if (opt < 0)
            break;

        switch (opt)
        {
            case 'w':
                watch_mode = 1;
                break;
            case 's':
                set_value = optarg;
                break;
            case 'f':
                file_name = optarg;
                break;
            default:
                print_usage (argv[0]);
                return -1;
        }
    }
    if (!watch_mode && optind >= argc)
    {
        print_usage (argv[0]);
        return -1;
    }
    attr_name = argv[optind];

    /* ###################################################### */

    setup(file_name);

    if(watch_mode) // watch mode 
    {
        int i = 0;

        printf("waiting...\n");
        printf("my pid is %x\n", getpid());

        // add self on watchers list
        for(i = 0; i < NOTIFY_MAX * sizeof(pid_t); i += sizeof(pid_t))
        {
            pid_t* p_pid = (pid_t *)((char *)p_mmap + i);

            if( *p_pid == 0 )
            {
                *p_pid = getpid();
                break;
            }
        }

        if(i/sizeof(pid_t) == NOTIFY_MAX)
        {
            *((pid_t *)p_mmap) = getpid();
        }

        while(1){
            sleep(2);
        }
    }

    else // not watch_mode
    {
        int         off;
        char *      data;

        if( 0 > (off = person_get_offset_of_attr(attr_name)) )
        {
            fprintf(stderr, "invalid attr name \'%s\'\n", attr_name);
            return -1;
        }

        if(set_value != NULL) // set mode
        {
            printf("attr name is %s(%d)\n", attr_name, off);

            if( person_attr_is_integer(attr_name) )
            {
                int * addr = (int *)(((char *)p_mmap) + off);

                *addr = atoi(set_value);
                msync(addr, sizeof(int), MS_SYNC);
            }
            else
            {
                char* addr = ((char *)p_mmap) + off;
                int len = strlen(set_value) * sizeof(char) + 1;

                memcpy(addr, set_value, len);
                msync(addr, sizeof(Person), MS_SYNC);
            }
            send_signal(off);
        }

        else // print mode
        {
            if( person_attr_is_integer(attr_name) )
            {
                int * addr = (int *)(((char *)p_mmap) + off);
                printf("%d\n", *addr);
            }
            else
            {
                char* addr = ((char *)p_mmap) + off;
                printf("%s\n", addr);
            }
        }
        print_person(p_mmap);
    }

    cleanup();
    return 0;
}
Example #25
0
int armsoc_bo_cpu_fini(struct armsoc_bo *bo, enum armsoc_gem_op op)
{
	assert(bo->refcnt > 0);
	return msync(bo->map_addr, bo->size, MS_SYNC | MS_INVALIDATE);
}
Example #26
0
/* Add a new entry to the cache.  The return value is zero if the function
   call was successful.

   This function must be called with the read-lock held.

   We modify the table but we nevertheless only acquire a read-lock.
   This is ok since we use operations which would be safe even without
   locking, given that the `prune_cache' function never runs.  Using
   the readlock reduces the chance of conflicts.  */
int
cache_add (int type, const void *key, size_t len, struct datahead *packet,
	   bool first, struct database_dyn *table,
	   uid_t owner, bool prune_wakeup)
{
  if (__builtin_expect (debug_level >= 2, 0))
    {
      const char *str;
      char buf[INET6_ADDRSTRLEN + 1];
      if (type == GETHOSTBYADDR || type == GETHOSTBYADDRv6)
	str = inet_ntop (type == GETHOSTBYADDR ? AF_INET : AF_INET6,
			 key, buf, sizeof (buf));
      else
	str = key;

      dbg_log (_("add new entry \"%s\" of type %s for %s to cache%s"),
	       str, serv2str[type], dbnames[table - dbs],
	       first ? _(" (first)") : "");
    }

  unsigned long int hash = __nis_hash (key, len) % table->head->module;
  struct hashentry *newp;

  newp = mempool_alloc (table, sizeof (struct hashentry), 0);
  /* If we cannot allocate memory, just do not do anything.  */
  if (newp == NULL)
    {
      /* If necessary mark the entry as unusable so that lookups will
	 not use it.  */
      if (first)
	packet->usable = false;

      return -1;
    }

  newp->type = type;
  newp->first = first;
  newp->len = len;
  newp->key = (char *) key - table->data;
  assert (newp->key + newp->len <= table->head->first_free);
  newp->owner = owner;
  newp->packet = (char *) packet - table->data;
  assert ((newp->packet & BLOCK_ALIGN_M1) == 0);

  /* Put the new entry in the first position.  */
  do
    newp->next = table->head->array[hash];
  while (atomic_compare_and_exchange_bool_rel (&table->head->array[hash],
					       (ref_t) ((char *) newp
							- table->data),
					       (ref_t) newp->next));

  /* Update the statistics.  */
  if (packet->notfound)
    ++table->head->negmiss;
  else if (first)
    ++table->head->posmiss;

  /* We depend on this value being correct and at least as high as the
     real number of entries.  */
  atomic_increment (&table->head->nentries);

  /* It does not matter that we are not loading the just increment
     value, this is just for statistics.  */
  unsigned long int nentries = table->head->nentries;
  if (nentries > table->head->maxnentries)
    table->head->maxnentries = nentries;

  if (table->persistent)
    // XXX async OK?
    msync ((void *) table->head,
	   (char *) &table->head->array[hash] - (char *) table->head
	   + sizeof (ref_t), MS_ASYNC);

  /* We do not have to worry about the pruning thread if we are
     re-adding the data since this is done by the pruning thread.  We
     also do not have to do anything in case this is not the first
     time the data is entered since different data heads all have the
     same timeout.  */
  if (first && prune_wakeup)
    {
      /* Perhaps the prune thread for the table is not running in a long
	 time.  Wake it if necessary.  */
      pthread_mutex_lock (&table->prune_lock);
      time_t next_wakeup = table->wakeup_time;
      bool do_wakeup = false;
      if (next_wakeup > packet->timeout + CACHE_PRUNE_INTERVAL)
	{
	  table->wakeup_time = packet->timeout;
	  do_wakeup = true;
	}
      pthread_mutex_unlock (&table->prune_lock);
      if (do_wakeup)
	pthread_cond_signal (&table->prune_cond);
    }

  return 0;
}
Example #27
0
File: jgfs.c Project: jgottula/jgfs
static void jgfs_msync(void) {
	if (msync(dev_mem, dev_size, MS_SYNC) == -1) {
		warn("msync failed");
	}
}
Example #28
0
int main()
{
  char tmpfname[256];
  char* data;
  long total_size; 

  void *pa = NULL; 
  void *addr = NULL;
  size_t size;
  int flag;
  int fd;
  off_t off = 0;
  int prot;
  struct stat stat_buff;

  total_size = 1024;
  size = total_size;

  time_t mtime1, mtime2, ctime1, ctime2;
   
  char *ch;
 
  snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_14_1_%d",
           getpid());
  unlink(tmpfname);
  fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL,
            S_IRUSR | S_IWUSR);
  if (fd == -1)
  {  
    printf(TNAME " Error at open(): %s\n", 
           strerror(errno));    
    exit(PTS_UNRESOLVED);
  }
  
  data = (char *) malloc(total_size); 
  memset(data, 'a', total_size);
  printf("Time before write(): %jd\n", (intmax_t)time(NULL));
  if (write(fd, data, total_size) != total_size)
  {
    printf(TNAME "Error at write(): %s\n", 
            strerror(errno));    
    unlink(tmpfname);
    exit(PTS_UNRESOLVED);
  }
  free(data);
  sleep(1); 
  flag = MAP_SHARED;
  prot = PROT_READ | PROT_WRITE;
  printf("Time before mmap(): %jd\n", (intmax_t)time(NULL));
  pa = mmap(addr, size, prot, flag, fd, off);
  if (pa == MAP_FAILED)
  {
  	printf ("Test Fail: " TNAME " Error at mmap: %s\n", 
            strerror(errno));    
    unlink(tmpfname);
    exit(PTS_FAIL);
  }
  sleep(1); 
  printf("Time before write reference: %jd\n", (intmax_t)time(NULL));
  /* Before write reference */
  if (stat(tmpfname, &stat_buff) == -1)
  {
    printf(TNAME " Error at 1st stat(): %s\n", 
           strerror(errno));    
    unlink(tmpfname);
    exit(PTS_UNRESOLVED);
  }
  
  ctime1 = stat_buff.st_ctime;
  mtime1 = stat_buff.st_mtime;

  ch = pa;
  *ch = 'b';
  
  /* Wait a while in case the precision of the sa_time 
  * is not acurate enough to reflect the update
  */
  sleep(1);
  printf("Time before msync(): %jd\n", (intmax_t)time(NULL));
  msync(pa, size, MS_SYNC);

  /* FIXME: Update the in-core meta data to the disk */
  fsync(fd);
  
  if (stat(tmpfname, &stat_buff) == -1)
  {
    printf(TNAME " Error at stat(): %s\n", 
           strerror(errno));    
    unlink(tmpfname);
    exit(PTS_UNRESOLVED);
  }

  ctime2 = stat_buff.st_ctime;
  mtime2 = stat_buff.st_mtime;
 
  printf("ctime1: %jd, ctime2: %jd\nmtime1: %jd, mtime2: %jd\n",
                  (intmax_t)ctime1, (intmax_t)ctime2, (intmax_t)mtime1, (intmax_t)mtime2); 
  if (ctime2 == ctime1 || mtime2 == mtime1)
  {
    printf("Test Fail " TNAME 
           " st_ctime and st_mtime were not updated properly\n"); 
    unlink(tmpfname);
    exit(PTS_FAIL);
  }
   
  munmap(pa, size);
  close(fd);
  printf("Test Pass\n");
  return PTS_PASS;
}