예제 #1
0
파일: hdapsd.c 프로젝트: t-8ch/hdapsd
/*
 * free_disk (disk) - free the allocated memory
 */
void free_disk (struct list *disk)
{
	if (disk != NULL) {
		if (disk->next != NULL)
			free_disk(disk->next);
		free(disk);
	}
}
예제 #2
0
파일: vmem.c 프로젝트: blakemcbride/VMEM
void	VM_free(VMPTR_TYPE i)
{
	VMPTR	p;
	VMHEAD	HUGE *h, HUGE *t;
	FNAME(VM_free);

	TEST(fun, 0);
	p.i = i;
	if (!i	||  p.p.b >= VMBASESIZ	||  p.p.l >= VMLEGSIZ  ||  !VMbase[p.p.b])
		return;
	h = (VMHEAD HUGE *) &VMbase[p.p.b][p.p.l];
	if (h->type == MT_NOTUSED)
		return;
	if (h->type & MT_IMEDIATE)  {
		if (h->type & MT_FREEZE)  {
			VMnfreez--;
			VMnifrez--;
		}
		vmfree_head(i);
		VMlive--;
		TEST(fun, 1);
		return;
	}
	VMtotal	-= h->size;
	free_disk(h->size, h->diskadd, 0);

	/* this	must be	redone because free_disk calls dfree_new, rmalloc, compact so the address may change  */

	h = (VMHEAD HUGE *) &VMbase[p.p.b][p.p.l];

	if (h->type & MT_FREEZE)
		VMnfreez--;
	if (h->type & MT_DISK) {
		vmfree_head(i);
		VMdisk--;
		TEST(fun, 2);
		return;
	}
	if (!(h->type &	MT_FREEZE))
		vm_unlink(h);
	rmfree((RMHEAD_PTR) h->mem, h->size);
	vmfree_head(i);
	VMlive--;
	TEST(fun, 3);
}
예제 #3
0
파일: vmem.c 프로젝트: blakemcbride/VMEM
static	long	disk_next(long s, char HUGE *buf)
{
	/* variable prefix:  b=best,  c=current	 */
	/* variable suffix:  a=address,	s=size,	i=index	 */

	register int	ci, bi;
	long	bs, cs,	da = -1L;
	DFREE HUGE *ca, HUGE *ba;
	int	rtf = 1;
	FNAME(disk_next);

retry:
	if (DMnfree >= s) {
		bi = -1;
		bs = 0L;
		ca = DMflist;
		for ( ;	ca  &&	bs != s	; ca = ca->next)
			for (ci=0 ; ci != DHEADSIZE  ; ++ci)
				if ((cs=ca->nfree[ci]) == s)  {
					bi = ci;
					bs = cs;
					ba = ca;
					break;
				}  else	if (cs > s  &&	(cs < bs || bi == -1))	{
					bi = ci;
					bs = cs;
					ba = ca;
				}
		if (bs >= s)  {
			da = ba->diskaddr[bi];
			DMnfree	-= s;
			if (bs == s)  {
				DMnfblks--;
				ba->diskaddr[bi] = -1L;
			}  else
				ba->diskaddr[bi] += s;
			ba->nfree[bi] -= s;
		}
	}
	if (da == -1L)	{
		long	sw;

		if (-1L	== lseek(DMhandle, 0L, SEEK_END))
			error(fun, "lseek");
		if ((long) s != (sw = longwrite(DMhandle, buf, (long) s)))

/*  by checking	DMflist	I know that d_compact1 will not	rmalloc	which is something disk_next must NEVER	do */

			if (rtf	 &&  DMflist)  {
				long	ta = DMnext;
				int	add;

				if (sw != -1L)  {
					DMnext += sw;
					add = free_disk((MAX_SIZ_TYP) sw, ta, 1);
				}
				d_compact1();
				if (sw != -1L  &&  add)
					if (free_disk((MAX_SIZ_TYP) sw,	ta, 1))
						error(fun, "internal");
				rtf = 0;
				goto retry;
			}  else
				error(fun, "write");
		DMneedflg = 1;	/* I had to extend the swap file to meet system	needs  */
		da = DMnext;
		DMnext += s;
	}  else	 {
		DMneedflg = 0;	/* no need to extend swap file	*/
		if (-1L	== lseek(DMhandle, da, SEEK_SET))
			error(fun, "lseek");
		if ((long) s != longwrite(DMhandle, buf, (long) s))
			error(fun, "write");
	}
	return(da);
}
예제 #4
0
파일: hdapsd.c 프로젝트: t-8ch/hdapsd
/*
 * main() - loop forever, reading the hdaps values and 
 *          parking/unparking as necessary
 */
int main (int argc, char** argv)
{
	struct utsname sysinfo;
	struct list *p = NULL;
	int c, park_now, protect_factor;
	int x = 0, y = 0, z = 0;
	int fd, i, ret, threshold = 15, adaptive = 0,
	pidfile = 0, parked = 0, forceadd = 0;
	double unow = 0, parked_utime = 0;

	struct option longopts[] =
	{
		{"device", required_argument, NULL, 'd'},
		{"sensitivity", required_argument, NULL, 's'},
		{"adaptive", no_argument, NULL, 'a'},
		{"verbose", no_argument, NULL, 'v'},
		{"background", no_argument, NULL, 'b'},
		{"pidfile", optional_argument, NULL, 'p'},
		{"dry-run", no_argument, NULL, 't'},
		{"poll-sysfs", no_argument, NULL, 'y'},
		{"version", no_argument, NULL, 'V'},
		{"help", no_argument, NULL, 'h'},
		{"syslog", no_argument, NULL, 'l'},
		{"force", no_argument, NULL, 'f'},
		{NULL, 0, NULL, 0}
	};

	if (uname(&sysinfo) < 0 || strcmp("2.6.27", sysinfo.release) <= 0) {
		protect_factor = 1000;
		kernel_interface = UNLOAD_HEADS;
	}
	else {
		protect_factor = 1;
		kernel_interface = PROTECT;
	}

	openlog(PACKAGE_NAME, LOG_PID, LOG_DAEMON);

	while ((c = getopt_long(argc, argv, "d:s:vbap::tyVhlf", longopts, NULL)) != -1) {
		switch (c) {
			case 'd':
				add_disk(optarg);
				break;
			case 's':
				threshold = atoi(optarg);
				break;
			case 'b':
				background = 1;
				break;
			case 'a':
				adaptive = 1;
				break;
			case 'v':
				verbose = 1;
				break;
			case 'p':
				pidfile = 1;
				if (optarg == NULL) {
					snprintf(pid_file, sizeof(pid_file), "%s", PID_FILE);
				} else {
					snprintf(pid_file, sizeof(pid_file), "%s", optarg);
				}
				break;
			case 't':
				printlog(stdout, "Dry run, will not actually park heads or freeze queue.");
				dry_run = 1;
				break;
			case 'y':
				poll_sysfs = 1;
				break;
			case 'V':
				version();
				break;
			case 'l':
				dosyslog = 1;
				break;
			case 'f':
				forceadd = 1;
				break;
			case 'h':
			default:
				usage();
				break;
		}
	}

	printlog(stdout, "Starting "PACKAGE_NAME);
	
	if (disklist && forceadd) {
		char protect_method[FILENAME_MAX] = "";
		p = disklist;
		while (p != NULL) {
			snprintf(protect_method, sizeof(protect_method), QUEUE_METHOD_FMT, p->name);
			if (kernel_interface == UNLOAD_HEADS)
				fd = open (p->protect_file, O_RDWR);
			else
				fd = open (protect_method, O_RDWR);
			if (fd > 0) {
				if (kernel_interface == UNLOAD_HEADS)
					ret = write(fd, FORCE_UNLOAD_HEADS, strlen(FORCE_UNLOAD_HEADS));
				else
					ret = write(fd, FORCE_PROTECT_METHOD, strlen(FORCE_PROTECT_METHOD));
				if (ret == -1)
					printlog(stderr, "Could not forcely enable UNLOAD feature for %s", p->name);
				else
					printlog(stdout, "Forcely enabled UNLOAD for %s", p->name);
				close(fd);
			}
			else
				printlog(stderr, "Could not open %s for forcely enabling UNLOAD feature", p->protect_file);

			p = p->next;
		}
	}

	if (disklist == NULL) {
		printlog(stdout, "WARNING: You did not supply any devices to protect, trying autodetection.");
		if (autodetect_devices() < 1)
			printlog(stderr, "Could not detect any devices.");
	}

	if (disklist == NULL)
		usage(argv);

	/* Let's see if we're on a ThinkPad or on an *Book */
	select_interface(0);
	if (!position_interface)
		select_interface(1);

	if (!position_interface) {
		printlog(stdout, "Could not find a suitable interface");
		return -1;
	}
	else
		printlog(stdout, "Selected interface: %s", interface_names[position_interface]);

	if (!poll_sysfs) {
		if (position_interface == INTERFACE_HDAPS) {
			hdaps_input_nr = device_find_byphys("hdaps/input1");
			hdaps_input_fd = device_open(hdaps_input_nr);
			if (hdaps_input_fd < 0) {
				printlog(stdout,
				        "WARNING: Could not find hdaps input device (%s). "
				        "You may be using an incompatible version of the hdaps module. "
				        "Falling back to reading the position from sysfs (uses more power).\n"
				        "Use '-y' to silence this warning.",
				        strerror(errno));
				poll_sysfs = 1;
			}
			else {
				printlog(stdout, "Selected HDAPS input device: /dev/input/event%d", hdaps_input_nr);
			}
		} else if (position_interface == INTERFACE_AMS) {
			hdaps_input_nr = device_find_byname("Apple Motion Sensor");
			hdaps_input_fd = device_open(hdaps_input_nr);
			if (hdaps_input_fd < 0) {
				printlog(stdout,
					"WARNING: Could not find AMS input device, do you need to set joystick=1?");
				poll_sysfs = 1;
			}
			else {
				printlog(stdout, "Selected AMS input device /dev/input/event%d", hdaps_input_nr);
			}
		}
	}

	if (background) {
		verbose = 0;
		if (pidfile) {
			fd = open (pid_file, O_WRONLY | O_CREAT, 0644);
			if (fd < 0) {
				printlog (stderr, "Could not create pidfile: %s", pid_file);
				return 1;
			}
		}
		daemon(0,0);
		if (pidfile) {
			char buf[BUF_LEN];
			snprintf (buf, sizeof(buf), "%d\n", getpid());
			ret = write (fd, buf, strlen(buf));
			if (ret < 0) {
				printlog (stderr, "Could not write to pidfile %s", pid_file);
				return 1;
			}
			if (close (fd)) {
				printlog (stderr, "Could not close pidfile %s", pid_file);
				return 1;
			}
		}
	}

	mlockall(MCL_FUTURE);

	if (verbose) {
		p = disklist;
		while (p != NULL) {
			printf("disk: %s\n", p->name);
			p = p->next;
		}
		printf("threshold: %i\n", threshold);
		printf("read_method: %s\n", poll_sysfs ? "poll-sysfs" : "input-dev");
	}

	/* check the protect attribute exists */
	/* wait for it if it's not there (in case the attribute hasn't been created yet) */
	p = disklist;
	while (p != NULL && !dry_run) {
		fd = open (p->protect_file, O_RDWR);
		if (background)
			for (i = 0; fd < 0 && i < 100; ++i) {
				usleep (100000);	/* 10 Hz */
				fd = open (p->protect_file, O_RDWR);
			}
		if (fd < 0) {
			printlog (stderr, "Could not open %s\nDoes your kernel/drive support IDLE_IMMEDIATE with UNLOAD?", p->protect_file);
			free_disk(disklist);
			return 1;
		}
		close (fd);
		p = p->next;
	}

	/* see if we can read the sensor */
	/* wait for it if it's not there (in case the attribute hasn't been created yet) */
	ret = read_position_from_sysfs (&x, &y, &z);
	if (background)
		for (i = 0; ret && i < 100; ++i) {
			usleep (100000);	/* 10 Hz */
			ret = read_position_from_sysfs (&x, &y, &z);
		}
	if (ret) {
		printlog(stderr, "Could not read position from sysfs.");
		return 1;
	}

    /* adapt to the driver's sampling rate */
	if (position_interface == INTERFACE_HDAPS)
		sampling_rate = read_int(SAMPLING_RATE_FILE);
	if (sampling_rate <= 0)
		sampling_rate = DEFAULT_SAMPLING_RATE;
	if (verbose)
		printf("sampling_rate: %d\n", sampling_rate);

	signal(SIGUSR1, SIGUSR1_handler);

	signal(SIGTERM, SIGTERM_handler);

	while (running) {
		if (poll_sysfs) {
			usleep (1000000/sampling_rate);
			ret = read_position_from_sysfs (&x, &y, &z);
			unow = get_utime(); /* microsec */
		} else {
			double oldunow = unow;
			int oldx = x, oldy = y, oldz = z;
			ret = read_position_from_inputdev (&x, &y, &z, &unow);

			/* The input device issues events only when the position changed.
			 * The analysis state needs to know how long the position remained
			 * unchanged, so send analyze() a fake retroactive update before sending
			 * the new one. */
			if (!ret && oldunow && unow-oldunow > 1.5/sampling_rate)
				analyze(oldx, oldy, unow-1.0/sampling_rate, threshold, adaptive, parked);
				
		}

		if (ret) {
			if (verbose)
				printf("readout error (%d)\n", ret);
			continue;
		}

		park_now = analyze(x, y, unow, threshold, adaptive, parked);

		if (park_now && !pause_now) {
			if (!parked || unow>parked_utime+REFREEZE_SECONDS) {
				/* Not frozen or freeze about to expire */
				p = disklist;
				while (p != NULL) {
					write_protect(p->protect_file,
					      (FREEZE_SECONDS+FREEZE_EXTRA_SECONDS) * protect_factor);
					p = p->next;
				}
				/* Write protect before any output (xterm, or 
				 * whatever else is handling our stdout, may be 
				 * swapped out).
				*/
				if (!parked)
					printlog(stdout, "parking");
				parked = 1;
				parked_utime = unow;
			} 
		} else {
			if (parked &&
			    (pause_now || unow>parked_utime+FREEZE_SECONDS)) {
				/* Sanity check */
				p = disklist;
				while (p != NULL) {
					if (!dry_run && !read_int(p->protect_file))
						printlog(stderr, "Error! Not parked when we "
						       "thought we were... (paged out "
					               "and timer expired?)");
					/* Freeze has expired */
					write_protect(p->protect_file, 0); /* unprotect */
					p = p->next;
				}
				parked = 0;
				printlog(stdout, "un-parking");
			}
			while (pause_now) {
				pause_now = 0;
				printlog(stdout, "pausing for %d seconds", SIGUSR1_SLEEP_SEC);
				sleep(SIGUSR1_SLEEP_SEC);
			}
		}

	}

	free_disk(disklist);
	printlog(stdout, "Terminating "PACKAGE_NAME);
	closelog();
	if (pidfile)
		unlink(pid_file);
	munlockall();
	return ret;
}